AnyPS5/core/relinker/cli/include/RuntimeLayout.hpp

54 lines
2.0 KiB
C++

#pragma once
#include <map>
#include <iterator>
#include <ostream>
#include <string>
#include <vector>
namespace Cli {
class RuntimeLayout {
public:
static void Print(std::ostream& stream, const std::string& executable, const std::vector<std::string>& modules, const std::vector<std::string>& extraExecutables = {}) {
Node root;
for (const auto& module : modules) {
auto* node = &root;
std::size_t start = 0;
for (;;) {
const auto end = module.find('/', start);
const auto name = module.substr(start, end == std::string::npos ? end : end - start);
node = &node->children[name];
if (end == std::string::npos) break;
start = end + 1;
}
}
stream << "Runtime layout\n\n"
<< " output/\n"
<< " |-- " << executable << "\n";
for (const auto& extra : extraExecutables) stream << " |-- " << extra << '\n';
stream << " |-- libs/\n"
<< " | `-- *.prx (system libraries)\n"
<< " `-- app0/\n"
<< (root.children.empty() ? " `-- " : " |-- ") << "<original game files>\n";
printChildren(stream, root, " ");
stream << "\nCopy the original game files into app0/ and system libraries into libs/.\n\n";
}
private:
struct Node {
std::map<std::string, Node> children;
};
static void printChildren(std::ostream& stream, const Node& node, const std::string& prefix) {
for (auto iterator = node.children.begin(); iterator != node.children.end(); ++iterator) {
const auto& [name, child] = *iterator;
const bool last = std::next(iterator) == node.children.end();
stream << prefix << (last ? "`-- " : "|-- ") << name << (child.children.empty() ? "\n" : "/\n");
printChildren(stream, child, prefix + (last ? " " : "| "));
}
}
};
}