/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmProcessTools.h" #include "cmProcessOutput.h" #include "cmsys/Process.h" #include void cmProcessTools::RunProcess(struct cmsysProcess_s* cp, OutputParser* out, OutputParser* err, Encoding encoding) { cmsysProcess_Execute(cp); char* data = nullptr; int length = 0; int p; cmProcessOutput processOutput(encoding); std::string strdata; while ((out || err) && (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr), p)) { if (out && p == cmsysProcess_Pipe_STDOUT) { processOutput.DecodeText(data, length, strdata, 1); if (!out->Process(strdata.c_str(), int(strdata.size()))) { out = nullptr; } } else if (err && p == cmsysProcess_Pipe_STDERR) { processOutput.DecodeText(data, length, strdata, 2); if (!err->Process(strdata.c_str(), int(strdata.size()))) { err = nullptr; } } } if (out) { processOutput.DecodeText(std::string(), strdata, 1); if (!strdata.empty()) { out->Process(strdata.c_str(), int(strdata.size())); } } if (err) { processOutput.DecodeText(std::string(), strdata, 2); if (!strdata.empty()) { out->Process(strdata.c_str(), int(strdata.size())); } } cmsysProcess_WaitForExit(cp, nullptr); } cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR) : Log(nullptr) , Prefix(nullptr) , Separator(sep) , LineEnd('\0') , IgnoreCR(ignoreCR) { } 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 || *c == '\0') { this->LineEnd = *c; // 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.clear(); return false; } this->Line.clear(); } else if (*c != '\r' || !this->IgnoreCR) { // Append this character to the line under construction. this->Line.append(1, *c); } } return true; }