Files
Alessandro Di Federico 934e2a92f5 Make argv non-const char *
2026-04-23 13:40:42 +02:00

154 lines
5.3 KiB
C++

//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/YAMLTraits.h"
#include "revng/PipeboxCommon/Helpers/Native/CLI/ContainerHandler.h"
#include "revng/PipeboxCommon/Helpers/Native/CLI/Helpers.h"
#include "revng/PipeboxCommon/Helpers/Native/Registry.h"
#include "revng/Support/InitRevng.h"
static llvm::ExitOnError AbortOnError;
namespace Options {
using namespace llvm::cl;
using OptString = opt<std::string>;
static OptionCategory RunPipeCategory("pipe run options");
static OptString FileStorage("file-storage",
desc("Unsupported, present for compatibility"),
cat(RunPipeCategory));
static OptString Dependencies("dependencies",
desc("dependencies tar output"),
cat(RunPipeCategory));
static OptString StaticConfiguration("static-configuration",
desc("static configuration"),
cat(RunPipeCategory));
static OptString Configuration("configuration",
desc("dynamic configuration"),
cat(RunPipeCategory));
static list<std::string> Objects("objects",
ZeroOrMore,
multi_val(2),
desc("pair-wise container outgoing requests"),
cat(RunPipeCategory));
static OptString Pipe(Positional, Required, desc("PIPE"), cat(RunPipeCategory));
static OptString
Model(Positional, Required, desc("MODEL"), cat(RunPipeCategory));
static list<std::string> Arguments(Positional,
ZeroOrMore,
desc("CONTAINER_FILES..."),
cat(RunPipeCategory));
} // namespace Options
static void
serializeDependencies(const revng::pypeline::ObjectDependencies &Dependencies,
llvm::raw_ostream &OS) {
bool Written = false;
for (size_t Index = 0; Index < Dependencies.size(); Index++) {
for (const auto &Entry : Dependencies[Index]) {
std::string SerializedObject = std::get<0>(Entry).serialize();
OS << "- [" << Index << ", \"" << llvm::yaml::escape(SerializedObject)
<< "\", \"" << llvm::yaml::escape(std::get<1>(Entry)) << "\"]\n";
Written = true;
}
}
// Handle the case where the Dependencies object is empty, write an empty
// array
if (not Written)
OS << "[]";
}
int main(int Argc, char *Argv[]) {
using namespace revng::pypeline;
using namespace revng::pypeline::helpers::native;
revng::InitRevng X(Argc, Argv, "", { &Options::RunPipeCategory });
// Create the pipe instance
revng_assert(Registry.Pipes.count(Options::Pipe));
std::unique_ptr<Pipe>
ThePipe = Registry.Pipes[Options::Pipe](Options::StaticConfiguration);
auto Signature = ThePipe->signature();
// Deserialize model
Model TheModel = AbortOnError(cli::modelFromPath(Options::Model));
// Create containers and deserialize them if needed
cli::ContainerHandler ContainerHandler(Signature);
AbortOnError(ContainerHandler.parseCommandline(Options::Arguments));
AbortOnError(ContainerHandler.loadContainers());
// Deserialize Outgoing requests
revng_assert(Options::Objects.size() % 2 == 0);
Request Incoming(Signature.size());
Request Outgoing(Signature.size());
// Since Request objects do not own the objects, store them in this vector
std::vector<std::unique_ptr<ObjectID>> ObjectsPool;
AbortOnError(cli::parseRequest(Signature,
Options::Objects,
ObjectsPool,
Outgoing));
// Get the vector of container pointers
auto ContainersPointers = ContainerHandler.getContainers();
// Enable caching
TheModel.enableCaching();
// Run the actual pipe
PipeOutput Output = ThePipe->run(TheModel,
ContainersPointers,
Incoming,
Outgoing,
Options::Configuration);
AbortOnError(ContainerHandler.storeContainers());
// Store dependency output
if (not Options::Dependencies.empty()) {
std::error_code EC;
llvm::raw_fd_ostream OS(Options::Dependencies, EC);
if (EC)
AbortOnError(llvm::errorCodeToError(EC));
revng::TarWriter Writer(OS, revng::TarFormat::Plain);
// Serialize normal dependencies as a yaml
{
std::string DependenciesString;
{
llvm::raw_string_ostream OS(DependenciesString);
serializeDependencies(Output.Dependencies, OS);
}
Writer.addMember("dependencies.yml",
llvm::ArrayRef<char>{ &*DependenciesString.begin(),
&*DependenciesString.end() });
}
// Serialize custom invalidation
for (size_t Index = 0; Index < Output.CustomInvalidation.size(); Index++) {
for (auto &Element : Output.CustomInvalidation[Index]) {
std::string Name = std::to_string(Index)
+ std::get<0>(Element).serialize();
Writer.addMember(Name, std::get<1>(Element).data());
}
}
}
return EXIT_SUCCESS;
}