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"
11 #include "cmProcessOutput.h"
12 #include "cmUVHandlePtr.h"
13 #include "cmUVStream.h"
15 std::vector
<cmUVProcessChain::Status
> cmProcessTools::RunProcess(
16 cmUVProcessChainBuilder
& builder
, OutputParser
* out
, OutputParser
* err
,
19 cmProcessOutput
processOutput(encoding
);
21 builder
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT
)
22 .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR
);
24 auto chain
= builder
.Start();
27 cm::uv_pipe_ptr outputPipe
;
28 outputPipe
.init(chain
.GetLoop(), 0);
29 uv_pipe_open(outputPipe
, chain
.OutputStream());
30 auto outputHandle
= cmUVStreamRead(
32 [&out
, &processOutput
, &strdata
](std::vector
<char> data
) {
34 processOutput
.DecodeText(data
.data(), data
.size(), strdata
, 1);
35 if (!out
->Process(strdata
.c_str(), static_cast<int>(strdata
.size()))) {
40 [&out
]() { out
= nullptr; });
41 cm::uv_pipe_ptr errorPipe
;
42 errorPipe
.init(chain
.GetLoop(), 0);
43 uv_pipe_open(errorPipe
, chain
.ErrorStream());
44 auto errorHandle
= cmUVStreamRead(
46 [&err
, &processOutput
, &strdata
](std::vector
<char> data
) {
48 processOutput
.DecodeText(data
.data(), data
.size(), strdata
, 2);
49 if (!err
->Process(strdata
.c_str(), static_cast<int>(strdata
.size()))) {
54 [&err
]() { err
= nullptr; });
55 while (out
|| err
|| !chain
.Finished()) {
56 uv_run(&chain
.GetLoop(), UV_RUN_ONCE
);
59 std::vector
<cmUVProcessChain::Status
> result
;
60 auto status
= chain
.GetStatus();
62 status
.begin(), status
.end(), std::back_inserter(result
),
63 [](const cmUVProcessChain::Status
* s
) -> cmUVProcessChain::Status
{
69 cmProcessTools::LineParser::LineParser(char sep
, bool ignoreCR
)
75 void cmProcessTools::LineParser::SetLog(std::ostream
* log
, const char* prefix
)
78 this->Prefix
= prefix
? prefix
: "";
81 bool cmProcessTools::LineParser::ProcessChunk(const char* first
, int length
)
83 const char* last
= first
+ length
;
84 for (const char* c
= first
; c
!= last
; ++c
) {
85 if (*c
== this->Separator
|| *c
== '\0') {
89 if (this->Log
&& this->Prefix
) {
90 *this->Log
<< this->Prefix
<< this->Line
<< "\n";
93 // Hand this line to the subclass implementation.
94 if (!this->ProcessLine()) {
100 } else if (*c
!= '\r' || !this->IgnoreCR
) {
101 // Append this character to the line under construction.
102 this->Line
.append(1, *c
);