Files
revng-revng/lib/Support/ProgramRunner.cpp
T
Alessandro Di Federico c7868b4e7d Runner: improve logging
2024-03-01 14:53:06 +01:00

81 lines
2.3 KiB
C++

/// \file ProgramRunner.cpp
/// A program runner is used to invoke external programs a bit more safelly than
/// to compose a string and invoke system.
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include <cstdlib>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "revng/Support/Assert.h"
#include "revng/Support/Debug.h"
#include "revng/Support/PathList.h"
#include "revng/Support/ProgramRunner.h"
using namespace llvm;
static Logger<> DILogger("program-runner");
ProgramRunner Runner;
ProgramRunner::ProgramRunner() {
using namespace llvm::sys::path;
llvm::SmallString<128> BinPath;
append(BinPath, getCurrentRoot(), "bin");
Paths = { BinPath.str().str() };
// Append PATH
char *Path = getenv("PATH");
if (Path == nullptr)
return;
llvm::SmallVector<llvm::StringRef, 64> BasePaths;
StringRef(Path).split(BasePaths, ":");
for (llvm::StringRef BasePath : BasePaths)
Paths.push_back(BasePath.str());
}
bool ProgramRunner::isProgramAvailable(llvm::StringRef ProgramName) {
llvm::SmallVector<llvm::StringRef, 64> PathsRef;
for (const std::string &Path : Paths)
PathsRef.push_back(llvm::StringRef(Path));
auto MaybeProgramPath = llvm::sys::findProgramByName(ProgramName, PathsRef);
if (!MaybeProgramPath)
return false;
return true;
}
int ProgramRunner::run(llvm::StringRef ProgramName,
ArrayRef<std::string> Args) {
llvm::SmallVector<llvm::StringRef, 64> PathsRef;
for (const std::string &Path : Paths)
PathsRef.push_back(llvm::StringRef(Path));
auto MaybeProgramPath = llvm::sys::findProgramByName(ProgramName, PathsRef);
revng_assert(not Paths.empty());
revng_assert(MaybeProgramPath,
(ProgramName + " was not found in " + getenv("PATH"))
.str()
.c_str());
// Prepare actual arguments
std::vector<StringRef> StringRefs{ *MaybeProgramPath };
DILogger << "Running " << StringRefs[0].str()
<< " with the following arguments:\n";
for (const std::string &Arg : Args) {
StringRefs.push_back(Arg);
DILogger << " " << Arg << "\n";
}
DILogger << DoLog;
int ExitCode = llvm::sys::ExecuteAndWait(StringRefs[0], StringRefs);
return ExitCode;
}