Imported Upstream version 3.24.0
[platform/upstream/cmake.git] / Source / cmProcessTools.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include "cmProcessTools.h"
4
5 #include <ostream>
6
7 #include "cmsys/Process.h"
8
9 #include "cmProcessOutput.h"
10
11 void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out,
12                                 OutputParser* err, Encoding encoding)
13 {
14   cmsysProcess_Execute(cp);
15   char* data = nullptr;
16   int length = 0;
17   int p;
18   cmProcessOutput processOutput(encoding);
19   std::string strdata;
20   while ((out || err) &&
21          (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
22     if (out && p == cmsysProcess_Pipe_STDOUT) {
23       processOutput.DecodeText(data, length, strdata, 1);
24       if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
25         out = nullptr;
26       }
27     } else if (err && p == cmsysProcess_Pipe_STDERR) {
28       processOutput.DecodeText(data, length, strdata, 2);
29       if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
30         err = nullptr;
31       }
32     }
33   }
34   if (out) {
35     processOutput.DecodeText(std::string(), strdata, 1);
36     if (!strdata.empty()) {
37       out->Process(strdata.c_str(), static_cast<int>(strdata.size()));
38     }
39   }
40   if (err) {
41     processOutput.DecodeText(std::string(), strdata, 2);
42     if (!strdata.empty()) {
43       err->Process(strdata.c_str(), static_cast<int>(strdata.size()));
44     }
45   }
46   cmsysProcess_WaitForExit(cp, nullptr);
47 }
48
49 cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR)
50   : Separator(sep)
51   , IgnoreCR(ignoreCR)
52 {
53 }
54
55 void cmProcessTools::LineParser::SetLog(std::ostream* log, const char* prefix)
56 {
57   this->Log = log;
58   this->Prefix = prefix ? prefix : "";
59 }
60
61 bool cmProcessTools::LineParser::ProcessChunk(const char* first, int length)
62 {
63   const char* last = first + length;
64   for (const char* c = first; c != last; ++c) {
65     if (*c == this->Separator || *c == '\0') {
66       this->LineEnd = *c;
67
68       // Log this line.
69       if (this->Log && this->Prefix) {
70         *this->Log << this->Prefix << this->Line << "\n";
71       }
72
73       // Hand this line to the subclass implementation.
74       if (!this->ProcessLine()) {
75         this->Line.clear();
76         return false;
77       }
78
79       this->Line.clear();
80     } else if (*c != '\r' || !this->IgnoreCR) {
81       // Append this character to the line under construction.
82       this->Line.append(1, *c);
83     }
84   }
85   return true;
86 }