diff options
author | Regina Pfeifer <regina@mailbox.org> | 2019-07-18 09:30:44 (GMT) |
---|---|---|
committer | Regina Pfeifer <regina@mailbox.org> | 2019-07-18 09:49:28 (GMT) |
commit | d26e6cb1c2f352da12200727a887e940aac463a7 (patch) | |
tree | a205fd70917ffefb3e97f3e3dd71212d15e13315 /Source/cmLoadCommandCommand.cxx | |
parent | b1199680489b402e3b73229d79eb06e3bd440f81 (diff) | |
download | CMake-d26e6cb1c2f352da12200727a887e940aac463a7.zip CMake-d26e6cb1c2f352da12200727a887e940aac463a7.tar.gz CMake-d26e6cb1c2f352da12200727a887e940aac463a7.tar.bz2 |
cmLoadCommandCommand: Code cleanup
Diffstat (limited to 'Source/cmLoadCommandCommand.cxx')
-rw-r--r-- | Source/cmLoadCommandCommand.cxx | 164 |
1 files changed, 91 insertions, 73 deletions
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 235dcd4..2697f44 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -25,21 +25,89 @@ class cmExecutionStatus; # include <malloc.h> /* for malloc/free on QNX */ #endif -extern "C" void TrapsForSignalsCFunction(int sig); +namespace { + +const char* LastName = nullptr; + +extern "C" void TrapsForSignals(int sig) +{ + fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", + LastName, sig); +} + +struct SignalHandlerGuard +{ + explicit SignalHandlerGuard(const char* name) + { + LastName = name != nullptr ? name : "????"; + + signal(SIGSEGV, TrapsForSignals); +#ifdef SIGBUS + signal(SIGBUS, TrapsForSignals); +#endif + signal(SIGILL, TrapsForSignals); + } + + ~SignalHandlerGuard() + { + signal(SIGSEGV, nullptr); +#ifdef SIGBUS + signal(SIGBUS, nullptr); +#endif + signal(SIGILL, nullptr); + } + + SignalHandlerGuard(SignalHandlerGuard const&) = delete; + SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete; +}; + +struct LoadedCommandImpl : cmLoadedCommandInfo +{ + explicit LoadedCommandImpl(CM_INIT_FUNCTION init) + : cmLoadedCommandInfo{ 0, 0, &cmStaticCAPI, 0, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr } + { + init(this); + } + + ~LoadedCommandImpl() + { + if (this->Destructor) { + SignalHandlerGuard guard(this->Name); + this->Destructor(this); + } + if (this->Error != nullptr) { + free(this->Error); + } + } + + LoadedCommandImpl(LoadedCommandImpl const&) = delete; + LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete; + + int DoInitialPass(cmMakefile* mf, int argc, char* argv[]) + { + SignalHandlerGuard guard(this->Name); + return this->InitialPass(this, mf, argc, argv); + } + + void DoFinalPass(cmMakefile* mf) + { + SignalHandlerGuard guard(this->Name); + this->FinalPass(this, mf); + } +}; // a class for loadabple commands class cmLoadedCommand : public cmCommand { public: - cmLoadedCommand() + cmLoadedCommand() = default; + explicit cmLoadedCommand(CM_INIT_FUNCTION init) + : Impl(std::make_shared<LoadedCommandImpl>(init)) { - memset(&this->info, 0, sizeof(this->info)); - this->info.CAPI = &cmStaticCAPI; } - //! clean up any memory allocated by the plugin - ~cmLoadedCommand() override; - /** * This is a virtual constructor for the command. */ @@ -47,8 +115,8 @@ public: { auto newC = cm::make_unique<cmLoadedCommand>(); // we must copy when we clone - memcpy(&newC->info, &this->info, sizeof(info)); - return std::unique_ptr<cmLoadedCommand>(std::move(newC)); + newC->Impl = this->Impl; + return std::unique_ptr<cmCommand>(std::move(newC)); } /** @@ -67,57 +135,23 @@ public: void FinalPass() override; bool HasFinalPass() const override { - return this->info.FinalPass != nullptr; - } - - static const char* LastName; - static void TrapsForSignals(int sig) - { - fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", - cmLoadedCommand::LastName, sig); - } - static void InstallSignalHandlers(const char* name, int remove = 0) - { - cmLoadedCommand::LastName = name; - if (!name) { - cmLoadedCommand::LastName = "????"; - } - - if (!remove) { - signal(SIGSEGV, TrapsForSignalsCFunction); -#ifdef SIGBUS - signal(SIGBUS, TrapsForSignalsCFunction); -#endif - signal(SIGILL, TrapsForSignalsCFunction); - } else { - signal(SIGSEGV, nullptr); -#ifdef SIGBUS - signal(SIGBUS, nullptr); -#endif - signal(SIGILL, nullptr); - } + return this->Impl->FinalPass != nullptr; } - cmLoadedCommandInfo info; +private: + std::shared_ptr<LoadedCommandImpl> Impl; }; -extern "C" void TrapsForSignalsCFunction(int sig) -{ - cmLoadedCommand::TrapsForSignals(sig); -} - -const char* cmLoadedCommand::LastName = nullptr; - bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus&) { - if (!info.InitialPass) { + if (!this->Impl->InitialPass) { return true; } // clear the error string - if (this->info.Error) { - free(this->info.Error); + if (this->Impl->Error) { + free(this->Impl->Error); } // create argc and argv and then invoke the command @@ -130,9 +164,7 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, for (i = 0; i < argc; ++i) { argv[i] = strdup(args[i].c_str()); } - cmLoadedCommand::InstallSignalHandlers(info.Name); - int result = info.InitialPass(&info, this->Makefile, argc, argv); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + int result = this->Impl->DoInitialPass(this->Makefile, argc, argv); cmFreeArguments(argc, argv); if (result) { @@ -140,32 +172,20 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args, } /* Initial Pass must have failed so set the error string */ - if (this->info.Error) { - this->SetError(this->info.Error); + if (this->Impl->Error) { + this->SetError(this->Impl->Error); } return false; } void cmLoadedCommand::FinalPass() { - if (this->info.FinalPass) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.FinalPass(&this->info, this->Makefile); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + if (this->Impl->FinalPass) { + this->Impl->DoFinalPass(this->Makefile); } } -cmLoadedCommand::~cmLoadedCommand() -{ - if (this->info.Destructor) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.Destructor(&this->info); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } - if (this->info.Error) { - free(this->info.Error); - } -} +} // namespace // cmLoadCommandCommand bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, @@ -240,10 +260,8 @@ bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args, // if the symbol is found call it to set the name on the // function blocker if (initFunction) { - // create a function blocker and set it up - auto f = cm::make_unique<cmLoadedCommand>(); - (*initFunction)(&f->info); - this->Makefile->GetState()->AddScriptedCommand(args[0], std::move(f)); + this->Makefile->GetState()->AddScriptedCommand( + args[0], cm::make_unique<cmLoadedCommand>(initFunction)); return true; } this->SetError("Attempt to load command failed. " |