feat: output docs

This commit is contained in:
LordMZTE 2022-11-08 21:59:56 +01:00
parent 612bc161df
commit 531c918ba5
Signed by: LordMZTE
GPG Key ID: B64802DC33A64FF6
5 changed files with 151 additions and 30 deletions

View File

@ -9,4 +9,6 @@ include_directories(${Boost_INCLUDE_DIR})
add_executable(portingtools ${sources})
set_property(TARGET portingtools PROPERTY CXX_STANDARD 20)
target_link_libraries(portingtools LINK_PUBLIC ${Boost_LIBRARIES})

73
src/csv.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "csv.hpp"
#include <istream>
#include <string>
#include <vector>
namespace csv {
enum class CSVState { UnquotedField, QuotedField, QuotedQuote };
// this function has been made in collaboration with
// StackOverflow https://stackoverflow.com/a/30338543
void readCSVRow(const std::string &row, std::vector<std::string> &fields) {
fields.push_back("");
CSVState state = CSVState::UnquotedField;
size_t i = 0; // index of the current field
for (char c : row) {
switch (state) {
case CSVState::UnquotedField:
switch (c) {
case ',': // end of field
fields.push_back("");
i++;
break;
case '"':
state = CSVState::QuotedField;
break;
default:
fields[i].push_back(c);
break;
}
break;
case CSVState::QuotedField:
switch (c) {
case '"':
state = CSVState::QuotedQuote;
break;
default:
fields[i].push_back(c);
break;
}
break;
case CSVState::QuotedQuote:
switch (c) {
case ',': // , after closing quote
fields.push_back("");
i++;
state = CSVState::UnquotedField;
break;
case '"': // "" -> "
fields[i].push_back('"');
state = CSVState::QuotedField;
break;
default: // end of quote
state = CSVState::UnquotedField;
break;
}
break;
}
}
}
bool CsvReader::operator>>(std::vector<std::string> &line) {
line.clear();
if (!m_stream) {
return false;
}
std::string row;
std::getline(m_stream, row);
readCSVRow(row, line);
return !!m_stream;
}
} // namespace csv

15
src/csv.hpp Normal file
View File

@ -0,0 +1,15 @@
#include <fstream>
#include <string>
#include <vector>
namespace csv {
class CsvReader {
private:
std::ifstream m_stream;
public:
CsvReader(auto stream) : m_stream(stream){};
~CsvReader() = default;
bool operator>>(std::vector<std::string> &line);
};
} // namespace csv

View File

@ -1,4 +1,5 @@
#include "mappings.hpp"
#include "csv.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
@ -6,30 +7,16 @@
#include <boost/filesystem/directory.hpp>
#include <boost/log/trivial.hpp>
#include <fstream>
#include <optional>
#include <ostream>
#include <string>
#include <vector>
namespace fs = boost::filesystem;
namespace mappings {
void loadFile(std::string path, std::map<std::string, std::string> *map) {
std::ifstream file(path);
std::string line;
while (std::getline(file, line)) {
std::vector<std::string> splits;
boost::algorithm::split(splits, line, boost::is_any_of(",\t|"));
if (splits.size() < 2) {
BOOST_LOG_TRIVIAL(warning) << "found invalid mapping '" << line << "'";
continue;
}
(*map)[splits[0]] = splits[1];
}
}
Mappings Mappings::load() {
std::map<std::string, std::string> mappings;
std::map<std::string, Mapping> mappings;
std::map<std::string, std::string> renames;
// load mappings
@ -39,11 +26,31 @@ Mappings Mappings::load() {
!boost::algorithm::ends_with(itr->path().string(), ".csv"))
continue;
loadFile(itr->path().string(), &mappings);
csv::CsvReader csv(itr->path().string());
std::vector<std::string> l;
while (csv >> l) {
if (l.size() < 2) {
BOOST_LOG_TRIVIAL(warning) << "found invalid mapping";
continue;
}
mappings[l[0]] = {l[0], l[1],
l.size() >= 4 ? std::optional(l[3]) : std::nullopt};
}
}
if (fs::is_regular_file("renames.csv")) {
loadFile("renames.csv", &renames);
csv::CsvReader csv("renames.csv");
std::vector<std::string> l;
while (csv >> l) {
if (l.size() < 2) {
BOOST_LOG_TRIVIAL(warning) << "found invalid rename";
continue;
}
renames[l[0]] = l[1];
}
}
BOOST_LOG_TRIVIAL(info) << "loaded " << mappings.size() << " mappings and "
@ -51,20 +58,36 @@ Mappings Mappings::load() {
return {mappings, renames};
}
void showMapInfo(Mapping mapping, std::optional<std::string> rename) {
auto doc = mapping.doc.has_value() ? "\n\n\t" + *mapping.doc + "\n" : "";
if (rename.has_value()) {
BOOST_LOG_TRIVIAL(info)
<< "\nFound mapping:\n"
<< "\n\tOriginal\t" << mapping.orig << "\n\tRemapped\t" << mapping.name
<< "\n\tRenamed \t" << *rename << doc;
} else {
BOOST_LOG_TRIVIAL(info) << "\nFound mapping:\n"
<< "\n\tOriginal\t" << mapping.orig
<< "\n\tRemapped\t" << mapping.name << doc;
}
}
std::string Mappings::map(std::string inp) {
if (!this->mappings.count(inp)) {
if (!this->m_mappings.count(inp)) {
BOOST_LOG_TRIVIAL(warning) << "unknown mapping '" << inp << "'";
return "<unknown>";
}
auto mapped = this->mappings[inp];
auto mapped = this->m_mappings[inp];
if (this->renames.count(mapped)) {
if (this->m_renames.count(mapped.name)) {
BOOST_LOG_TRIVIAL(info)
<< "found rename " << mapped << " -> " << renames[mapped];
return renames[mapped];
<< "found rename " << mapped.name << " -> " << m_renames[mapped.name];
showMapInfo(mapped, m_renames[mapped.name]);
return m_renames[mapped.name];
}
return mapped;
showMapInfo(mapped, std::nullopt);
return mapped.name;
}
} // namespace mappings

View File

@ -1,15 +1,23 @@
#include <map>
#include <optional>
#include <string>
namespace mappings {
struct Mapping {
std::string orig;
std::string name;
std::optional<std::string> doc;
};
class Mappings {
std::map<std::string, std::string> mappings;
std::map<std::string, std::string> renames;
std::map<std::string, Mapping> m_mappings;
std::map<std::string, std::string> m_renames;
public:
Mappings(std::map<std::string, std::string> mappings,
Mappings(std::map<std::string, Mapping> mappings,
std::map<std::string, std::string> renames) {
this->mappings = mappings;
this->renames = renames;
this->m_mappings = mappings;
this->m_renames = renames;
}
~Mappings() = default;
static Mappings load();