Sfoglia il codice sorgente

ENH: Create cmProcessTools to parse child output

This class provides a RunProcess method to run a child process and send
its output to an abstract parsing interface.  This also provides a
simple line parser and logger implementing the parsing interface.
Brad King 16 anni fa
parent
commit
1936499250
3 ha cambiato i file con 177 aggiunte e 0 eliminazioni
  1. 2 0
      Source/CMakeLists.txt
  2. 93 0
      Source/cmProcessTools.cxx
  3. 82 0
      Source/cmProcessTools.h

+ 2 - 0
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

+ 93 - 0
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;
+}

+ 82 - 0
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