diff options
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmProcessTools.cxx | 93 | ||||
-rw-r--r-- | Source/cmProcessTools.h | 82 |
3 files changed, 177 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3180339..964099c 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -187,6 +187,8 @@ SET(SRCS cmOrderDirectories.h cmPolicies.h cmPolicies.cxx + cmProcessTools.cxx + cmProcessTools.h cmProperty.cxx cmProperty.h cmPropertyDefinition.cxx diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx new file mode 100644 index 0000000..ef40f57 --- /dev/null +++ b/Source/cmProcessTools.cxx @@ -0,0 +1,93 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmProcessTools.h" + +#include <cmsys/Process.h> + +//---------------------------------------------------------------------------- +void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, + OutputParser* out, OutputParser* err) +{ + cmsysProcess_Execute(cp); + char* data = 0; + int length = 0; + int p; + while((out||err) && (p=cmsysProcess_WaitForData(cp, &data, &length, 0), p)) + { + if(out && p == cmsysProcess_Pipe_STDOUT) + { + if(!out->Process(data, length)) + { + out = 0; + } + } + else if(err && p == cmsysProcess_Pipe_STDERR) + { + if(!err->Process(data, length)) + { + err = 0; + } + } + } + cmsysProcess_WaitForExit(cp, 0); +} + + +//---------------------------------------------------------------------------- +cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR): + Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0) +{ +} + +//---------------------------------------------------------------------------- +void cmProcessTools::LineParser::SetLog(std::ostream* log, const char* prefix) +{ + this->Log = log; + this->Prefix = prefix? prefix : ""; +} + +//---------------------------------------------------------------------------- +bool cmProcessTools::LineParser::ProcessChunk(const char* first, int length) +{ + const char* last = first + length; + for(const char* c = first; c != last; ++c) + { + if(*c == this->Separator) + { + // Log this line. + if(this->Log && this->Prefix) + { + *this->Log << this->Prefix << this->Line << "\n"; + } + + // Hand this line to the subclass implementation. + if(!this->ProcessLine()) + { + this->Line = ""; + return false; + } + + this->Line = ""; + } + else if(*c != '\r' || !this->IgnoreCR) + { + // Append this character to the line under construction. + this->Line.append(1, *c); + } + } + return true; +} diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h new file mode 100644 index 0000000..c438527 --- /dev/null +++ b/Source/cmProcessTools.h @@ -0,0 +1,82 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmProcessTools_h +#define cmProcessTools_h + +#include "cmStandardIncludes.h" + +/** \class cmProcessTools + * \brief Helper classes for process output parsing + * + */ +class cmProcessTools +{ +public: + /** Abstract interface for process output parsers. */ + class OutputParser + { + public: + /** Process the given output data from a tool. Processing may be + done incrementally. Returns true if the parser is interested + in any more data and false if it is done. */ + bool Process(const char* data, int length) + { return this->ProcessChunk(data, length); } + protected: + /** Implement in a subclass to process a chunk of data. It should + return true only if it is interested in more data. */ + virtual bool ProcessChunk(const char* data, int length) = 0; + }; + + /** Process output parser that extracts one line at a time. */ + class LineParser: public OutputParser + { + public: + /** Construct with line separation character and choose whether to + ignore carriage returns. */ + LineParser(char sep = '\n', bool ignoreCR = true); + + /** Configure logging of lines as they are extracted. */ + void SetLog(std::ostream* log, const char* prefix); + protected: + char Separator; + bool IgnoreCR; + std::ostream* Log; + const char* Prefix; + std::string Line; + virtual bool ProcessChunk(const char* data, int length); + + /** Implement in a subclass to process one line of input. It + should return true only if it is interested in more data. */ + virtual bool ProcessLine() = 0; + }; + + /** Trivial line handler for simple logging. */ + class OutputLogger: public LineParser + { + public: + OutputLogger(std::ostream& log, const char* prefix = 0) + { this->SetLog(&log, prefix); } + private: + virtual bool ProcessLine() { return true; } + }; + + /** Run a process and send output to given parsers. */ + static void RunProcess(struct cmsysProcess_s* cp, + OutputParser* out, OutputParser* err = 0); +}; + +#endif |