From 3655464b6f4d84b1e657c3acae8a9e11d308819b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 8 Apr 2024 12:25:00 +0300 Subject: [PATCH] minor refactor --- src/coders/commons.cpp | 30 +++---------------------- src/coders/commons.h | 17 +++++++------- src/coders/json.cpp | 5 +++-- src/coders/toml.cpp | 50 ++++++++++++++++++++--------------------- src/coders/toml.h | 10 ++++----- src/coders/xml.cpp | 8 +++---- src/util/stringutil.cpp | 32 +++++++++++++++++++++++++- src/util/stringutil.h | 6 +++++ 8 files changed, 85 insertions(+), 73 deletions(-) diff --git a/src/coders/commons.cpp b/src/coders/commons.cpp index 35e78221..68f977d5 100644 --- a/src/coders/commons.cpp +++ b/src/coders/commons.cpp @@ -1,5 +1,7 @@ #include "commons.h" +#include "../util/stringutil.h" + #include #include #include @@ -38,32 +40,6 @@ std::string parsing_error::errorLog() const { } ss << "^"; return ss.str(); - -} - -std::string escape_string(std::string s) { - std::stringstream ss; - ss << '"'; - for (char c : s) { - switch (c) { - case '\n': ss << "\\n"; break; - case '\r': ss << "\\r"; break; - case '\t': ss << "\\t"; break; - case '\f': ss << "\\f"; break; - case '\b': ss << "\\b"; break; - case '"': ss << "\\\""; break; - case '\\': ss << "\\\\"; break; - default: - if (c < ' ') { - ss << "\\" << std::oct << uint(ubyte(c)); - break; - } - ss << c; - break; - } - } - ss << '"'; - return ss.str(); } BasicParser::BasicParser(std::string file, std::string source) : filename(file), source(source) { @@ -151,7 +127,7 @@ void BasicParser::expect(const std::string& substring) { return; for (uint i = 0; i < substring.length(); i++) { if (source.length() <= pos + i || source[pos+i] != substring[i]) { - throw error(escape_string(substring)+" expected"); + throw error(util::quote(substring)+" expected"); } } pos += substring.length(); diff --git a/src/coders/commons.h b/src/coders/commons.h index ee844d06..c7169785 100644 --- a/src/coders/commons.h +++ b/src/coders/commons.h @@ -49,8 +49,6 @@ inline int hexchar2int(int c) { return -1; } -extern std::string escape_string(std::string s); - class parsing_error : public std::runtime_error { public: std::string filename; @@ -59,13 +57,14 @@ public: uint line; uint linestart; - parsing_error(std::string message, - std::string filename, - std::string source, - uint pos, - uint line, - uint linestart); - + parsing_error( + std::string message, + std::string filename, + std::string source, + uint pos, + uint line, + uint linestart + ); std::string errorLog() const; }; diff --git a/src/coders/json.cpp b/src/coders/json.cpp index 74b6dc15..32eb4d8e 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -7,6 +7,7 @@ #include "commons.h" #include "../data/dynamic.h" +#include "../util/stringutil.h" using namespace json; using namespace dynamic; @@ -74,7 +75,7 @@ void stringify(const Value* value, } else if (value->type == valtype::integer) { ss << std::get(value->value); } else if (value->type == valtype::string) { - ss << escape_string(std::get(value->value)); + ss << util::escape(std::get(value->value)); } } @@ -95,7 +96,7 @@ void stringifyObj(const Map* obj, newline(ss, nice, indent, indentstr); } Value* value = entry.second.get(); - ss << escape_string(key) << ": "; + ss << util::escape(key) << ": "; stringify(value, ss, indent+1, indentstr, nice); index++; if (index < obj->values.size()) { diff --git a/src/coders/toml.cpp b/src/coders/toml.cpp index bca14d38..648ad574 100644 --- a/src/coders/toml.cpp +++ b/src/coders/toml.cpp @@ -1,5 +1,6 @@ #include "toml.h" #include "commons.h" +#include "../util/stringutil.h" #include #include @@ -7,11 +8,9 @@ #include #include -using std::string; - using namespace toml; -Section::Section(string name) : name(name) { +Section::Section(std::string name) : name(name) { } void Section::add(std::string name, Field field) { @@ -22,35 +21,35 @@ void Section::add(std::string name, Field field) { keyOrder.push_back(name); } -void Section::add(string name, bool* ptr) { +void Section::add(std::string name, bool* ptr) { add(name, {fieldtype::ftbool, ptr}); } -void Section::add(string name, int* ptr) { +void Section::add(std::string name, int* ptr) { add(name, {fieldtype::ftint, ptr}); } -void Section::add(string name, uint* ptr) { +void Section::add(std::string name, uint* ptr) { add(name, {fieldtype::ftuint, ptr}); } -void Section::add(string name, float* ptr) { +void Section::add(std::string name, float* ptr) { add(name, {fieldtype::ftfloat, ptr}); } -void Section::add(string name, double* ptr) { +void Section::add(std::string name, double* ptr) { add(name, {fieldtype::ftdouble, ptr}); } -void Section::add(string name, string* ptr) { +void Section::add(std::string name, std::string* ptr) { add(name, {fieldtype::ftstring, ptr}); } -string Section::getName() const { +const std::string& Section::getName() const { return name; } -const Field* Section::field(std::string name) const { +const Field* Section::field(const std::string& name) const { auto found = fields.find(name); if (found == fields.end()) { return nullptr; @@ -88,10 +87,10 @@ Section* Wrapper::section(std::string name) { std::string Wrapper::write() const { std::stringstream ss; - for (string key : keyOrder) { + for (const std::string& key : keyOrder) { const Section* section = sections.at(key); ss << "[" << key << "]\n"; - for (const string& key : section->keys()) { + for (const std::string& key : section->keys()) { ss << key << " = "; const Field* field = section->field(key); assert(field != nullptr); @@ -104,7 +103,7 @@ std::string Wrapper::write() const { case fieldtype::ftfloat: ss << *((float*)field->ptr); break; case fieldtype::ftdouble: ss << *((double*)field->ptr); break; case fieldtype::ftstring: - ss << escape_string(*((const string*)field->ptr)); + ss << util::escape(*((const std::string*)field->ptr)); break; } ss << "\n"; @@ -114,7 +113,8 @@ std::string Wrapper::write() const { return ss.str(); } -Reader::Reader(Wrapper* wrapper, string file, string source) : BasicParser(file, source), wrapper(wrapper) { +Reader::Reader(Wrapper* wrapper, std::string file, std::string source) +: BasicParser(file, source), wrapper(wrapper) { } void Reader::skipWhitespace() { @@ -135,7 +135,7 @@ void Reader::read() { readSection(nullptr); } -void Section::set(string name, double value) { +void Section::set(const std::string& name, double value) { const Field* field = this->field(name); if (field == nullptr) { std::cerr << "warning: unknown key '" << name << "'" << std::endl; @@ -146,14 +146,14 @@ void Section::set(string name, double value) { case fieldtype::ftuint: *(uint*)(field->ptr) = value; break; case fieldtype::ftfloat: *(float*)(field->ptr) = value; break; case fieldtype::ftdouble: *(double*)(field->ptr) = value; break; - case fieldtype::ftstring: *(string*)(field->ptr) = std::to_string(value); break; + case fieldtype::ftstring: *(std::string*)(field->ptr) = std::to_string(value); break; default: std::cerr << "error: type error for key '" << name << "'" << std::endl; } } } -void Section::set(std::string name, bool value) { +void Section::set(const std::string& name, bool value) { const Field* field = this->field(name); if (field == nullptr) { std::cerr << "warning: unknown key '" << name << "'" << std::endl; @@ -164,20 +164,20 @@ void Section::set(std::string name, bool value) { case fieldtype::ftuint: *(uint*)(field->ptr) = (uint)value; break; case fieldtype::ftfloat: *(float*)(field->ptr) = (float)value; break; case fieldtype::ftdouble: *(double*)(field->ptr) = (double)value; break; - case fieldtype::ftstring: *(string*)(field->ptr) = value ? "true" : "false"; break; + case fieldtype::ftstring: *(std::string*)(field->ptr) = value ? "true" : "false"; break; default: std::cerr << "error: type error for key '" << name << "'" << std::endl; } } } -void Section::set(std::string name, std::string value) { +void Section::set(const std::string& name, std::string value) { const Field* field = this->field(name); if (field == nullptr) { std::cerr << "warning: unknown key '" << name << "'" << std::endl; } else { switch (field->type) { - case fieldtype::ftstring: *(string*)(field->ptr) = value; break; + case fieldtype::ftstring: *(std::string*)(field->ptr) = value; break; default: std::cerr << "error: type error for key '" << name << "'" << std::endl; } @@ -192,14 +192,14 @@ void Reader::readSection(Section* section /*nullable*/) { } char c = nextChar(); if (c == '[') { - string name = parseName(); + std::string name = parseName(); Section* section = wrapper->section(name); pos++; readSection(section); return; } pos--; - string name = parseName(); + std::string name = parseName(); expect('='); c = peek(); if (is_digit(c)) { @@ -223,7 +223,7 @@ void Reader::readSection(Section* section /*nullable*/) { section->set(name, std::get(num)); } } else if (is_identifier_start(c)) { - string identifier = parseName(); + std::string identifier = parseName(); if (identifier == "true" || identifier == "false") { bool flag = identifier == "true"; if (section) { @@ -240,7 +240,7 @@ void Reader::readSection(Section* section /*nullable*/) { } } else if (c == '"' || c == '\'') { pos++; - string str = parseString(c); + std::string str = parseString(c); if (section) { section->set(name, str); } diff --git a/src/coders/toml.h b/src/coders/toml.h index 3bf1791e..be3efe5a 100644 --- a/src/coders/toml.h +++ b/src/coders/toml.h @@ -36,13 +36,13 @@ namespace toml { void add(std::string name, double* ptr); void add(std::string name, std::string* ptr); - const Field* field(std::string name) const; + const Field* field(const std::string& name) const; - void set(std::string name, double value); - void set(std::string name, bool value); - void set(std::string name, std::string value); + void set(const std::string& name, double value); + void set(const std::string& name, bool value); + void set(const std::string& name, std::string value); - std::string getName() const; + const std::string& getName() const; const std::vector& keys() const; }; diff --git a/src/coders/xml.cpp b/src/coders/xml.cpp index 34579835..384de5c1 100644 --- a/src/coders/xml.cpp +++ b/src/coders/xml.cpp @@ -52,7 +52,7 @@ glm::vec3 Attribute::asVec3() const { } size_t pos2 = text.find(',', pos1+1); if (pos2 == std::string::npos) { - throw std::runtime_error("invalid vec3 value "+escape_string(text)); + throw std::runtime_error("invalid vec3 value "+util::quote(text)); } return glm::vec3( util::parse_double(text, 0, pos1), @@ -69,11 +69,11 @@ glm::vec4 Attribute::asVec4() const { } size_t pos2 = text.find(',', pos1+1); if (pos2 == std::string::npos) { - throw std::runtime_error("invalid vec4 value "+escape_string(text)); + throw std::runtime_error("invalid vec4 value "+util::quote(text)); } size_t pos3 = text.find(',', pos2+1); if (pos3 == std::string::npos) { - throw std::runtime_error("invalid vec4 value "+escape_string(text)); + throw std::runtime_error("invalid vec4 value "+util::quote(text)); } return glm::vec4( util::parse_double(text, 0, pos1), @@ -382,7 +382,7 @@ static void stringifyElement( auto attr = entry.second; ss << attr.getName(); if (!attr.getText().empty()) { - ss << "=" << escape_string(attr.getText()); + ss << "=" << util::escape(attr.getText()); } if (count + 1 < int(attrs.size())) { ss << " "; diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index a40b9251..6ae4c437 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -7,6 +7,36 @@ #include #include +// TODO: finish +std::string util::escape(const std::string& s) { + std::stringstream ss; + ss << '"'; + for (char c : s) { + switch (c) { + case '\n': ss << "\\n"; break; + case '\r': ss << "\\r"; break; + case '\t': ss << "\\t"; break; + case '\f': ss << "\\f"; break; + case '\b': ss << "\\b"; break; + case '"': ss << "\\\""; break; + case '\\': ss << "\\\\"; break; + default: + if (c < ' ') { + ss << "\\" << std::oct << uint(ubyte(c)); + break; + } + ss << c; + break; + } + } + ss << '"'; + return ss.str(); +} + +std::string util::quote(const std::string& s) { + return escape(s); +} + std::wstring util::lfill(std::wstring s, uint length, wchar_t c) { if (s.length() >= length) { return s; @@ -62,7 +92,7 @@ struct utf_t { }; const utf_t utf[] = { - /* mask lead beg end bits */ + /* mask lead beg end bits */ {(char)0b00111111, (char)0b10000000, 0, 0, 6}, {(char)0b01111111, (char)0b00000000, 0000, 0177, 7}, {(char)0b00011111, (char)0b11000000, 0200, 03777, 5}, diff --git a/src/util/stringutil.h b/src/util/stringutil.h index 93b1ff19..d3bb4772 100644 --- a/src/util/stringutil.h +++ b/src/util/stringutil.h @@ -6,6 +6,12 @@ #include "../typedefs.h" namespace util { + /// @brief Function used for string serialization in text formats + extern std::string escape(const std::string& s); + + /// @brief Function used for error messages + extern std::string quote(const std::string& s); + extern std::wstring lfill(std::wstring s, uint length, wchar_t c); extern std::wstring rfill(std::wstring s, uint length, wchar_t c);