mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-01-27 03:14:21 +00:00
Merge topic 'cmuvprocesschain-external-stream-fd'
b65d54e876 cmUVStreambuf: Update URL for example code 0878306386 cmUVStream: Add cmUVStreamRead() function b8fd273ed7 cmUVProcessChain: Return output and error streams as file descriptors ec81d40be4 cmUVPipeIStream: Add cmUVPipeIStream 3b6c5efc08 cm::append: Add support for std::basic_string on SPARC/SunPro Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !8559
This commit is contained in:
commit
a84c996947
@ -438,6 +438,7 @@ add_library(
|
||||
cmUVHandlePtr.h
|
||||
cmUVProcessChain.cxx
|
||||
cmUVProcessChain.h
|
||||
cmUVStream.h
|
||||
cmUVStreambuf.h
|
||||
cmUVSignalHackRAII.h
|
||||
cmVariableWatch.cxx
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "cmRuntimeDependencyArchive.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::
|
||||
cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool(
|
||||
@ -46,7 +47,8 @@ bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
|
||||
static const cmsys::RegularExpression neededRegex("^ *NEEDED *([^\n]*)$");
|
||||
static const cmsys::RegularExpression rpathRegex("^ *RPATH *([^\n]*)$");
|
||||
static const cmsys::RegularExpression runpathRegex("^ *RUNPATH *([^\n]*)$");
|
||||
while (std::getline(*process.OutputStream(), line)) {
|
||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
||||
while (std::getline(output, line)) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (neededRegex.find(line.c_str(), match)) {
|
||||
needed.push_back(match.match(1));
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include "cmRuntimeDependencyArchive.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::
|
||||
cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool(
|
||||
@ -49,11 +50,12 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
|
||||
"^ *path (.*) \\(offset [0-9]+\\)$");
|
||||
static const cmsys::RegularExpression nameRegex(
|
||||
"^ *name (.*) \\(offset [0-9]+\\)$");
|
||||
while (std::getline(*process.OutputStream(), line)) {
|
||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
||||
while (std::getline(output, line)) {
|
||||
cmsys::RegularExpressionMatch cmdMatch;
|
||||
if (rpathRegex.find(line.c_str(), cmdMatch)) {
|
||||
if (!std::getline(*process.OutputStream(), line) ||
|
||||
!std::getline(*process.OutputStream(), line)) {
|
||||
// NOLINTNEXTLINE(misc-redundant-expression)
|
||||
if (!std::getline(output, line) || !std::getline(output, line)) {
|
||||
this->SetError("Invalid output from otool");
|
||||
return false;
|
||||
}
|
||||
@ -66,8 +68,8 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
|
||||
return false;
|
||||
}
|
||||
} else if (loadDylibRegex.find(line.c_str(), cmdMatch)) {
|
||||
if (!std::getline(*process.OutputStream(), line) ||
|
||||
!std::getline(*process.OutputStream(), line)) {
|
||||
// NOLINTNEXTLINE(misc-redundant-expression)
|
||||
if (!std::getline(output, line) || !std::getline(output, line)) {
|
||||
this->SetError("Invalid output from otool");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include "cmRuntimeDependencyArchive.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::
|
||||
cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool(
|
||||
@ -43,7 +44,8 @@ bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
|
||||
std::string line;
|
||||
static const cmsys::RegularExpression regex(
|
||||
"^ ([^\n]*\\.[Dd][Ll][Ll])\r$");
|
||||
while (std::getline(*process.OutputStream(), line)) {
|
||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
||||
while (std::getline(output, line)) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (regex.find(line.c_str(), match)) {
|
||||
needed.push_back(match.match(1));
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "cmRuntimeDependencyArchive.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::
|
||||
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool(
|
||||
@ -44,7 +45,8 @@ bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
|
||||
std::string line;
|
||||
static const cmsys::RegularExpression regex(
|
||||
"^\t*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])$");
|
||||
while (cmSystemTools::GetLineFromStream(*process.OutputStream(), line)) {
|
||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
||||
while (cmSystemTools::GetLineFromStream(output, line)) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (regex.find(line.c_str(), match)) {
|
||||
needed.push_back(match.match(1));
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "cmRuntimeDependencyArchive.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
|
||||
cmLDConfigLDConfigTool::cmLDConfigLDConfigTool(
|
||||
cmRuntimeDependencyArchive* archive)
|
||||
@ -50,7 +51,8 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
|
||||
|
||||
std::string line;
|
||||
static const cmsys::RegularExpression regex("^([^\t:]*):");
|
||||
while (std::getline(*process.OutputStream(), line)) {
|
||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
||||
while (std::getline(output, line)) {
|
||||
cmsys::RegularExpressionMatch match;
|
||||
if (regex.find(line.c_str(), match)) {
|
||||
paths.push_back(match.match(1));
|
||||
|
||||
@ -17,36 +17,15 @@
|
||||
|
||||
#include "cmGetPipes.h"
|
||||
#include "cmUVHandlePtr.h"
|
||||
#include "cmUVStreambuf.h"
|
||||
|
||||
struct cmUVProcessChain::InternalData
|
||||
{
|
||||
struct BasicStreamData
|
||||
struct StreamData
|
||||
{
|
||||
cmUVStreambuf Streambuf;
|
||||
cm::uv_pipe_ptr BuiltinStream;
|
||||
int BuiltinStream = -1;
|
||||
uv_stdio_container_t Stdio;
|
||||
};
|
||||
|
||||
template <typename IOStream>
|
||||
struct StreamData : public BasicStreamData
|
||||
{
|
||||
StreamData()
|
||||
: BuiltinIOStream(&this->Streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
IOStream BuiltinIOStream;
|
||||
|
||||
IOStream* GetBuiltinStream()
|
||||
{
|
||||
if (this->BuiltinStream.get()) {
|
||||
return &this->BuiltinIOStream;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct ProcessData
|
||||
{
|
||||
cmUVProcessChain::InternalData* Data;
|
||||
@ -64,9 +43,9 @@ struct cmUVProcessChain::InternalData
|
||||
|
||||
cm::uv_loop_ptr Loop;
|
||||
|
||||
StreamData<std::ostream> InputStreamData;
|
||||
StreamData<std::istream> OutputStreamData;
|
||||
StreamData<std::istream> ErrorStreamData;
|
||||
StreamData InputStreamData;
|
||||
StreamData OutputStreamData;
|
||||
StreamData ErrorStreamData;
|
||||
cm::uv_pipe_ptr TempOutputPipe;
|
||||
cm::uv_pipe_ptr TempErrorPipe;
|
||||
|
||||
@ -215,12 +194,7 @@ bool cmUVProcessChain::InternalData::Prepare(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (errorData.BuiltinStream.init(*this->Loop, 0) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
|
||||
return false;
|
||||
}
|
||||
errorData.BuiltinStream = pipeFd[0];
|
||||
errorData.Stdio.flags = UV_INHERIT_FD;
|
||||
errorData.Stdio.data.fd = pipeFd[1];
|
||||
|
||||
@ -231,7 +205,6 @@ bool cmUVProcessChain::InternalData::Prepare(
|
||||
return false;
|
||||
}
|
||||
|
||||
errorData.Streambuf.open(errorData.BuiltinStream);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -251,6 +224,7 @@ bool cmUVProcessChain::InternalData::Prepare(
|
||||
|
||||
case cmUVProcessChainBuilder::Builtin:
|
||||
if (this->Builder->MergedBuiltinStreams) {
|
||||
outputData.BuiltinStream = errorData.BuiltinStream;
|
||||
outputData.Stdio.flags = UV_INHERIT_FD;
|
||||
outputData.Stdio.data.fd = errorData.Stdio.data.fd;
|
||||
} else {
|
||||
@ -259,12 +233,7 @@ bool cmUVProcessChain::InternalData::Prepare(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outputData.BuiltinStream.init(*this->Loop, 0) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (uv_pipe_open(outputData.BuiltinStream, pipeFd[0]) < 0) {
|
||||
return false;
|
||||
}
|
||||
outputData.BuiltinStream = pipeFd[0];
|
||||
outputData.Stdio.flags = UV_INHERIT_FD;
|
||||
outputData.Stdio.data.fd = pipeFd[1];
|
||||
|
||||
@ -274,8 +243,6 @@ bool cmUVProcessChain::InternalData::Prepare(
|
||||
if (uv_pipe_open(this->TempOutputPipe, outputData.Stdio.data.fd) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outputData.Streambuf.open(outputData.BuiltinStream);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -411,17 +378,14 @@ uv_loop_t& cmUVProcessChain::GetLoop()
|
||||
return *this->Data->Loop;
|
||||
}
|
||||
|
||||
std::istream* cmUVProcessChain::OutputStream()
|
||||
int cmUVProcessChain::OutputStream()
|
||||
{
|
||||
if (this->Data->Builder->MergedBuiltinStreams) {
|
||||
return this->Data->ErrorStreamData.GetBuiltinStream();
|
||||
}
|
||||
return this->Data->OutputStreamData.GetBuiltinStream();
|
||||
return this->Data->OutputStreamData.BuiltinStream;
|
||||
}
|
||||
|
||||
std::istream* cmUVProcessChain::ErrorStream()
|
||||
int cmUVProcessChain::ErrorStream()
|
||||
{
|
||||
return this->Data->ErrorStreamData.GetBuiltinStream();
|
||||
return this->Data->ErrorStreamData.BuiltinStream;
|
||||
}
|
||||
|
||||
bool cmUVProcessChain::Valid() const
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include <array>
|
||||
#include <cstddef> // IWYU pragma: keep
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -99,8 +98,8 @@ public:
|
||||
uv_loop_t& GetLoop();
|
||||
|
||||
// FIXME: Add stdin support
|
||||
std::istream* OutputStream();
|
||||
std::istream* ErrorStream();
|
||||
int OutputStream();
|
||||
int ErrorStream();
|
||||
|
||||
bool Valid() const;
|
||||
bool Wait(int64_t milliseconds = -1);
|
||||
|
||||
140
Source/cmUVStream.h
Normal file
140
Source/cmUVStream.h
Normal file
@ -0,0 +1,140 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <istream>
|
||||
|
||||
#include <cm3p/uv.h>
|
||||
|
||||
#include "cmUVHandlePtr.h"
|
||||
#include "cmUVStreambuf.h"
|
||||
|
||||
template <typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
class cmBasicUVIStream : public std::basic_istream<CharT>
|
||||
{
|
||||
public:
|
||||
cmBasicUVIStream();
|
||||
cmBasicUVIStream(uv_stream_t* stream);
|
||||
|
||||
bool is_open() const;
|
||||
|
||||
void open(uv_stream_t* stream);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
cmBasicUVStreambuf<CharT, Traits> Buffer;
|
||||
};
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream()
|
||||
: std::basic_istream<CharT, Traits>(&this->Buffer)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
cmBasicUVIStream<CharT, Traits>::cmBasicUVIStream(uv_stream_t* stream)
|
||||
: cmBasicUVIStream()
|
||||
{
|
||||
this->open(stream);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
bool cmBasicUVIStream<CharT, Traits>::is_open() const
|
||||
{
|
||||
return this->Buffer.is_open();
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
void cmBasicUVIStream<CharT, Traits>::open(uv_stream_t* stream)
|
||||
{
|
||||
this->Buffer.open(stream);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
void cmBasicUVIStream<CharT, Traits>::close()
|
||||
{
|
||||
this->Buffer.close();
|
||||
}
|
||||
|
||||
using cmUVIStream = cmBasicUVIStream<char>;
|
||||
|
||||
template <typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
class cmBasicUVPipeIStream : public cmBasicUVIStream<CharT, Traits>
|
||||
{
|
||||
public:
|
||||
cmBasicUVPipeIStream();
|
||||
cmBasicUVPipeIStream(uv_loop_t& loop, int fd);
|
||||
|
||||
using cmBasicUVIStream<CharT, Traits>::is_open;
|
||||
|
||||
void open(uv_loop_t& loop, int fd);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
cm::uv_pipe_ptr Pipe;
|
||||
};
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream() = default;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
cmBasicUVPipeIStream<CharT, Traits>::cmBasicUVPipeIStream(uv_loop_t& loop,
|
||||
int fd)
|
||||
{
|
||||
this->open(loop, fd);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
void cmBasicUVPipeIStream<CharT, Traits>::open(uv_loop_t& loop, int fd)
|
||||
{
|
||||
this->Pipe.init(loop, 0);
|
||||
uv_pipe_open(this->Pipe, fd);
|
||||
this->cmBasicUVIStream<CharT, Traits>::open(this->Pipe);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
void cmBasicUVPipeIStream<CharT, Traits>::close()
|
||||
{
|
||||
this->cmBasicUVIStream<CharT, Traits>::close();
|
||||
this->Pipe.reset();
|
||||
}
|
||||
|
||||
using cmUVPipeIStream = cmBasicUVPipeIStream<char>;
|
||||
|
||||
template <typename ReadCallback, typename FinishCallback>
|
||||
void cmUVStreamRead(uv_stream_t* stream, ReadCallback onRead,
|
||||
FinishCallback onFinish)
|
||||
{
|
||||
struct ReadData
|
||||
{
|
||||
std::vector<char> Buffer;
|
||||
ReadCallback OnRead;
|
||||
FinishCallback OnFinish;
|
||||
};
|
||||
|
||||
stream->data = new ReadData{ {}, std::move(onRead), std::move(onFinish) };
|
||||
uv_read_start(
|
||||
stream,
|
||||
[](uv_handle_t* s, std::size_t suggestedSize, uv_buf_t* buffer) {
|
||||
auto* data = static_cast<ReadData*>(s->data);
|
||||
data->Buffer.resize(suggestedSize);
|
||||
buffer->base = data->Buffer.data();
|
||||
buffer->len = suggestedSize;
|
||||
},
|
||||
[](uv_stream_t* s, ssize_t nread, const uv_buf_t* buffer) {
|
||||
auto* data = static_cast<ReadData*>(s->data);
|
||||
if (nread > 0) {
|
||||
(void)buffer;
|
||||
assert(buffer->base == data->Buffer.data());
|
||||
data->Buffer.resize(nread);
|
||||
data->OnRead(std::move(data->Buffer));
|
||||
} else if (nread < 0 /*|| nread == UV_EOF*/) {
|
||||
data->OnFinish();
|
||||
uv_read_stop(s);
|
||||
delete data;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -14,7 +14,8 @@
|
||||
/*
|
||||
* This file is based on example code from:
|
||||
*
|
||||
* http://www.voidcn.com/article/p-vjnlygmc-gy.html
|
||||
* https://web.archive.org/web/20170515211805/
|
||||
* http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
|
||||
*
|
||||
* The example code was distributed under the following license:
|
||||
*
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTransformDepfile.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
#include "cmUtils.hxx"
|
||||
#include "cmValue.h"
|
||||
#include "cmVersion.h"
|
||||
@ -2017,10 +2018,8 @@ int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
|
||||
return 1;
|
||||
}
|
||||
if (process.GetStatus(0).ExitStatus != 0) {
|
||||
auto* errorStream = process.ErrorStream();
|
||||
if (errorStream) {
|
||||
std::cerr << errorStream->rdbuf();
|
||||
}
|
||||
cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
|
||||
std::cerr << errorStream.rdbuf();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2144,10 +2143,8 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
||||
return result;
|
||||
}
|
||||
if (process.GetStatus(0).ExitStatus != 0) {
|
||||
auto* errorStream = process.ErrorStream();
|
||||
if (errorStream) {
|
||||
std::cerr << errorStream->rdbuf();
|
||||
}
|
||||
cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
|
||||
std::cerr << errorStream.rdbuf();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmUVHandlePtr.h"
|
||||
#include "cmUVProcessChain.h"
|
||||
#include "cmUVStream.h"
|
||||
#include "cmUVStreambuf.h"
|
||||
|
||||
struct ExpectedStatus
|
||||
@ -301,16 +302,19 @@ bool testUVProcessChainBuiltin(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!chain->OutputStream()) {
|
||||
std::cout << "OutputStream() was null, expecting not null" << std::endl;
|
||||
if (chain->OutputStream() < 0) {
|
||||
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!chain->ErrorStream()) {
|
||||
std::cout << "ErrorStream() was null, expecting not null" << std::endl;
|
||||
if (chain->ErrorStream() < 0) {
|
||||
std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkOutput(*chain->OutputStream(), *chain->ErrorStream())) {
|
||||
cmUVPipeIStream output(chain->GetLoop(), chain->OutputStream());
|
||||
cmUVPipeIStream error(chain->GetLoop(), chain->ErrorStream());
|
||||
|
||||
if (!checkOutput(output, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -330,12 +334,12 @@ bool testUVProcessChainBuiltinMerged(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!chain->OutputStream()) {
|
||||
std::cout << "OutputStream() was null, expecting not null" << std::endl;
|
||||
if (chain->OutputStream() < 0) {
|
||||
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!chain->ErrorStream()) {
|
||||
std::cout << "ErrorStream() was null, expecting not null" << std::endl;
|
||||
if (chain->ErrorStream() < 0) {
|
||||
std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (chain->OutputStream() != chain->ErrorStream()) {
|
||||
@ -344,7 +348,9 @@ bool testUVProcessChainBuiltinMerged(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string merged = getInput(*chain->OutputStream());
|
||||
cmUVPipeIStream mergedStream(chain->GetLoop(), chain->OutputStream());
|
||||
|
||||
std::string merged = getInput(mergedStream);
|
||||
auto qemuErrorPos = merged.find("qemu:");
|
||||
if (qemuErrorPos != std::string::npos) {
|
||||
merged.resize(qemuErrorPos);
|
||||
@ -398,12 +404,12 @@ bool testUVProcessChainExternal(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chain->OutputStream()) {
|
||||
std::cout << "OutputStream() was not null, expecting null" << std::endl;
|
||||
if (chain->OutputStream() >= 0) {
|
||||
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (chain->ErrorStream()) {
|
||||
std::cout << "ErrorStream() was not null, expecting null" << std::endl;
|
||||
if (chain->ErrorStream() >= 0) {
|
||||
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -446,12 +452,12 @@ bool testUVProcessChainNone(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chain->OutputStream()) {
|
||||
std::cout << "OutputStream() was not null, expecting null" << std::endl;
|
||||
if (chain->OutputStream() >= 0) {
|
||||
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (chain->ErrorStream()) {
|
||||
std::cout << "ErrorStream() was not null, expecting null" << std::endl;
|
||||
if (chain->ErrorStream() >= 0) {
|
||||
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -473,7 +479,8 @@ bool testUVProcessChainCwdUnchanged(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto cwd = getInput(*chain.OutputStream());
|
||||
cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
|
||||
auto cwd = getInput(output);
|
||||
if (!cmHasLiteralSuffix(cwd, "/Tests/CMakeLib")) {
|
||||
std::cout << "Working directory was \"" << cwd
|
||||
<< "\", expected to end in \"/Tests/CMakeLib\"" << std::endl;
|
||||
@ -499,7 +506,8 @@ bool testUVProcessChainCwdChanged(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
auto cwd = getInput(*chain.OutputStream());
|
||||
cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
|
||||
auto cwd = getInput(output);
|
||||
if (!cmHasLiteralSuffix(cwd, "/Tests")) {
|
||||
std::cout << "Working directory was \"" << cwd
|
||||
<< "\", expected to end in \"/Tests\"" << std::endl;
|
||||
@ -633,7 +641,8 @@ bool testUVProcessChainInputFile(const char* helperCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string output = getInput(*chain.OutputStream());
|
||||
cmUVPipeIStream stream(chain.GetLoop(), chain.OutputStream());
|
||||
std::string output = getInput(stream);
|
||||
if (output != "HELO WRD!") {
|
||||
std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
|
||||
<< std::endl;
|
||||
|
||||
@ -3,11 +3,14 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include <cm3p/uv.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cmGetPipes.h"
|
||||
#include "cmUVHandlePtr.h"
|
||||
#include "cmUVStream.h"
|
||||
#include "cmUVStreambuf.h"
|
||||
|
||||
#define TEST_STR_LINE_1 "This string must be exactly 128 characters long so"
|
||||
@ -437,6 +440,90 @@ end:
|
||||
return success;
|
||||
}
|
||||
|
||||
bool testUVPipeIStream()
|
||||
{
|
||||
int pipe[] = { -1, -1 };
|
||||
if (cmGetPipes(pipe) < 0) {
|
||||
std::cout << "cmGetPipes() returned an error" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
cm::uv_loop_ptr loop;
|
||||
loop.init();
|
||||
cm::uv_pipe_ptr pipeSink;
|
||||
pipeSink.init(*loop, 0);
|
||||
uv_pipe_open(pipeSink, pipe[1]);
|
||||
|
||||
std::string str = "Hello world!\n";
|
||||
uv_write_t writeReq;
|
||||
uv_buf_t buf;
|
||||
buf.base = &str.front();
|
||||
buf.len = str.length();
|
||||
uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
cmUVPipeIStream pin(*loop, pipe[0]);
|
||||
std::string line;
|
||||
std::getline(pin, line);
|
||||
if (line != "Hello world!") {
|
||||
std::cout << "Line was \"" << line << "\", should be \"Hello world!\""
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testUVStreamRead()
|
||||
{
|
||||
int pipe[] = { -1, -1 };
|
||||
if (cmGetPipes(pipe) < 0) {
|
||||
std::cout << "cmGetPipes() returned an error" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
cm::uv_loop_ptr loop;
|
||||
loop.init();
|
||||
cm::uv_pipe_ptr pipeSink;
|
||||
pipeSink.init(*loop, 0);
|
||||
uv_pipe_open(pipeSink, pipe[1]);
|
||||
|
||||
std::string str = "Hello world!";
|
||||
uv_write_t writeReq;
|
||||
uv_buf_t buf;
|
||||
buf.base = &str.front();
|
||||
buf.len = str.length();
|
||||
uv_write(&writeReq, pipeSink, &buf, 1, nullptr);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
pipeSink.reset();
|
||||
|
||||
cm::uv_pipe_ptr pipeSource;
|
||||
pipeSource.init(*loop, 0);
|
||||
uv_pipe_open(pipeSource, pipe[0]);
|
||||
|
||||
std::string output;
|
||||
bool finished = false;
|
||||
cmUVStreamRead(
|
||||
pipeSource,
|
||||
[&output](std::vector<char> data) { cm::append(output, data); },
|
||||
[&output, &finished]() {
|
||||
if (output != "Hello world!") {
|
||||
std::cout << "Output was \"" << output
|
||||
<< "\", should be \"Hello world!\"" << std::endl;
|
||||
return;
|
||||
}
|
||||
finished = true;
|
||||
});
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
if (!finished) {
|
||||
std::cout << "finished was not set" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int testUVStreambuf(int argc, char** const argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
@ -454,5 +541,15 @@ int testUVStreambuf(int argc, char** const argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!testUVPipeIStream()) {
|
||||
std::cout << "While executing testUVPipeIStream().\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!testUVStreamRead()) {
|
||||
std::cout << "While executing testUVPipeIStream().\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#if defined(__SUNPRO_CC) && defined(__sparc)
|
||||
# include <list>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
#endif
|
||||
|
||||
@ -67,11 +68,15 @@ namespace cm {
|
||||
APPEND_TWO(C1, C2) \
|
||||
APPEND_TWO(C2, C1)
|
||||
|
||||
// For now, manage only support for std::vector and std::list.
|
||||
// Other sequential container support can be added if needed.
|
||||
// For now, manage only support for std::vector, std::list, and
|
||||
// std::basic_string. Other sequential container support can be added if
|
||||
// needed.
|
||||
APPEND(std::vector)
|
||||
APPEND(std::list)
|
||||
APPEND(std::basic_string)
|
||||
APPEND_MIX(std::vector, std::list)
|
||||
APPEND_MIX(std::vector, std::basic_string)
|
||||
APPEND_MIX(std::list, std::basic_string)
|
||||
|
||||
# undef APPEND
|
||||
# undef APPEND_MIX
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user