feat: output docs
This commit is contained in:
parent
612bc161df
commit
531c918ba5
|
@ -9,4 +9,6 @@ include_directories(${Boost_INCLUDE_DIR})
|
||||||
|
|
||||||
add_executable(portingtools ${sources})
|
add_executable(portingtools ${sources})
|
||||||
|
|
||||||
|
set_property(TARGET portingtools PROPERTY CXX_STANDARD 20)
|
||||||
|
|
||||||
target_link_libraries(portingtools LINK_PUBLIC ${Boost_LIBRARIES})
|
target_link_libraries(portingtools LINK_PUBLIC ${Boost_LIBRARIES})
|
||||||
|
|
73
src/csv.cpp
Normal file
73
src/csv.cpp
Normal 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
15
src/csv.hpp
Normal 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
|
|
@ -1,4 +1,5 @@
|
||||||
#include "mappings.hpp"
|
#include "mappings.hpp"
|
||||||
|
#include "csv.hpp"
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/algorithm/string/classification.hpp>
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
#include <boost/algorithm/string/split.hpp>
|
#include <boost/algorithm/string/split.hpp>
|
||||||
|
@ -6,30 +7,16 @@
|
||||||
#include <boost/filesystem/directory.hpp>
|
#include <boost/filesystem/directory.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <optional>
|
||||||
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
namespace mappings {
|
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() {
|
Mappings Mappings::load() {
|
||||||
std::map<std::string, std::string> mappings;
|
std::map<std::string, Mapping> mappings;
|
||||||
std::map<std::string, std::string> renames;
|
std::map<std::string, std::string> renames;
|
||||||
|
|
||||||
// load mappings
|
// load mappings
|
||||||
|
@ -39,11 +26,31 @@ Mappings Mappings::load() {
|
||||||
!boost::algorithm::ends_with(itr->path().string(), ".csv"))
|
!boost::algorithm::ends_with(itr->path().string(), ".csv"))
|
||||||
continue;
|
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")) {
|
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 "
|
BOOST_LOG_TRIVIAL(info) << "loaded " << mappings.size() << " mappings and "
|
||||||
|
@ -51,20 +58,36 @@ Mappings Mappings::load() {
|
||||||
return {mappings, renames};
|
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) {
|
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 << "'";
|
BOOST_LOG_TRIVIAL(warning) << "unknown mapping '" << inp << "'";
|
||||||
return "<unknown>";
|
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)
|
BOOST_LOG_TRIVIAL(info)
|
||||||
<< "found rename " << mapped << " -> " << renames[mapped];
|
<< "found rename " << mapped.name << " -> " << m_renames[mapped.name];
|
||||||
return renames[mapped];
|
showMapInfo(mapped, m_renames[mapped.name]);
|
||||||
|
return m_renames[mapped.name];
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapped;
|
showMapInfo(mapped, std::nullopt);
|
||||||
|
return mapped.name;
|
||||||
}
|
}
|
||||||
} // namespace mappings
|
} // namespace mappings
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mappings {
|
namespace mappings {
|
||||||
|
struct Mapping {
|
||||||
|
std::string orig;
|
||||||
|
std::string name;
|
||||||
|
std::optional<std::string> doc;
|
||||||
|
};
|
||||||
|
|
||||||
class Mappings {
|
class Mappings {
|
||||||
std::map<std::string, std::string> mappings;
|
std::map<std::string, Mapping> m_mappings;
|
||||||
std::map<std::string, std::string> renames;
|
std::map<std::string, std::string> m_renames;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Mappings(std::map<std::string, std::string> mappings,
|
Mappings(std::map<std::string, Mapping> mappings,
|
||||||
std::map<std::string, std::string> renames) {
|
std::map<std::string, std::string> renames) {
|
||||||
this->mappings = mappings;
|
this->m_mappings = mappings;
|
||||||
this->renames = renames;
|
this->m_renames = renames;
|
||||||
}
|
}
|
||||||
~Mappings() = default;
|
~Mappings() = default;
|
||||||
static Mappings load();
|
static Mappings load();
|
||||||
|
|
Loading…
Reference in a new issue