blob: 9cc9f439e60fa261622f2bdfa8ae54f0813570fe [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "interceptor_utils.h"
#include <iomanip>
#include <iterator>
#include <sstream>
#include <android-base/strings.h>
#include "interceptor.h"
namespace interceptor {
template <typename C>
struct PrintableSequence {
PrintableSequence(const C& c) : container(c) {}
const C& container;
};
template <typename C>
static std::ostream& operator<<(std::ostream& os, const PrintableSequence<C>& sequence) {
bool comma = false;
for (const auto& e : sequence.container) {
if (comma) {
os << ", ";
}
os << std::quoted(e);
comma = true;
}
return os;
}
std::ostream& operator<<(std::ostream& os, const interceptor::Command& command) {
os << "[(" << PrintableSequence(command.inputs()) << ") => ("
<< PrintableSequence(command.outputs()) << ")] " << command_line(command);
return os;
}
std::string command_line(const Command& command) {
// TODO: chain output iterators instead and find a common expression
const static auto escape = [](auto in) {
in = android::base::StringReplace(in, "\t", "\\t", true);
in = android::base::StringReplace(in, "\n", "\\n", true);
return in;
};
std::ostringstream cmd;
cmd << command.program();
for (auto iter = std::next(command.arguments().cbegin()); iter != command.arguments().cend();
++iter) {
cmd << ' ' << escape(*iter);
}
return cmd.str();
}
} // namespace interceptor