diff options
author | Michael Lutz <michi@icosahedron.de> | 2020-05-17 23:31:56 +0200 |
---|---|---|
committer | Michael Lutz <michi@icosahedron.de> | 2020-05-21 20:02:34 +0200 |
commit | 9b6f5e3bb850b6cff02cc761767fcdf49c681645 (patch) | |
tree | 1989b13b0ac5f06f78df1064124486e626f8811f /src/game | |
parent | 9c2e47d03cbc4c7af416a34b09e0c8d0de7c3474 (diff) | |
download | openttd-9b6f5e3bb850b6cff02cc761767fcdf49c681645.tar.xz |
Codechange: Store GS lang texts in std::strings.
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/game_text.cpp | 120 | ||||
-rw-r--r-- | src/game/game_text.hpp | 29 |
2 files changed, 67 insertions, 82 deletions
diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index 64281c60c..39732f789 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.cpp @@ -59,69 +59,46 @@ void NORETURN CDECL strgen_fatal(const char *s, ...) } /** - * Create a new container for language strings. - * @param language The language name. - * @param end If not nullptr, terminate \a language at this position. - */ -LanguageStrings::LanguageStrings(const char *language, const char *end) -{ - this->language = stredup(language, end != nullptr ? end - 1 : nullptr); -} - -/** Free everything. */ -LanguageStrings::~LanguageStrings() -{ - free(this->language); -} - -/** * Read all the raw language strings from the given file. * @param file The file to read from. * @return The raw strings, or nullptr upon error. */ -std::unique_ptr<LanguageStrings> ReadRawLanguageStrings(const char *file) +LanguageStrings ReadRawLanguageStrings(const std::string &file) { - try { - size_t to_read; - FILE *fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read); - if (fh == nullptr) return nullptr; + size_t to_read; + FILE *fh = FioFOpenFile(file.c_str(), "rb", GAME_DIR, &to_read); + if (fh == nullptr) return LanguageStrings(); - FileCloser fhClose(fh); + FileCloser fhClose(fh); - const char *langname = strrchr(file, PATHSEPCHAR); - if (langname == nullptr) { - langname = file; - } else { - langname++; - } + auto pos = file.rfind(PATHSEPCHAR); + if (pos == std::string::npos) return LanguageStrings(); + std::string langname = file.substr(pos + 1); - /* Check for invalid empty filename */ - if (*langname == '.' || *langname == 0) return nullptr; + /* Check for invalid empty filename */ + if (langname.empty() || langname.front() == '.') return LanguageStrings(); - std::unique_ptr<LanguageStrings> ret(new LanguageStrings(langname, strchr(langname, '.'))); + LanguageStrings ret(langname.substr(0, langname.find('.'))); - char buffer[2048]; - while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) { - size_t len = strlen(buffer); + char buffer[2048]; + while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) { + size_t len = strlen(buffer); - /* Remove trailing spaces/newlines from the string. */ - size_t i = len; - while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--; - buffer[i] = '\0'; + /* Remove trailing spaces/newlines from the string. */ + size_t i = len; + while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--; + buffer[i] = '\0'; - ret->lines.emplace_back(buffer, i); + ret.lines.emplace_back(buffer, i); - if (len > to_read) { - to_read = 0; - } else { - to_read -= len; - } + if (len > to_read) { + to_read = 0; + } else { + to_read -= len; } - - return ret; - } catch (...) { - return nullptr; } + + return ret; } @@ -138,7 +115,7 @@ struct StringListReader : StringReader { * @param translation Are we reading a translation? */ StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) : - StringReader(data, strings.language, master, translation), p(strings.lines.begin()), end(strings.lines.end()) + StringReader(data, strings.language.c_str(), master, translation), p(strings.lines.begin()), end(strings.lines.end()) { } @@ -215,12 +192,11 @@ struct StringNameWriter : HeaderWriter { class LanguageScanner : protected FileScanner { private: GameStrings *gs; - char *exclude; + std::string exclude; public: /** Initialise */ - LanguageScanner(GameStrings *gs, const char *exclude) : gs(gs), exclude(stredup(exclude)) {} - ~LanguageScanner() { free(exclude); } + LanguageScanner(GameStrings *gs, const std::string &exclude) : gs(gs), exclude(exclude) {} /** * Scan. @@ -232,10 +208,10 @@ public: bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override { - if (strcmp(filename, exclude) == 0) return true; + if (exclude == filename) return true; auto ls = ReadRawLanguageStrings(filename); - if (ls == nullptr) return false; + if (!ls.IsValid()) return false; gs->raw_strings.push_back(std::move(ls)); return true; @@ -249,17 +225,16 @@ public: GameStrings *LoadTranslations() { const GameInfo *info = Game::GetInfo(); - char filename[512]; - strecpy(filename, info->GetMainScript(), lastof(filename)); - char *e = strrchr(filename, PATHSEPCHAR); - if (e == nullptr) return nullptr; - e++; // Make 'e' point after the PATHSEPCHAR + std::string basename(info->GetMainScript()); + auto e = basename.rfind(PATHSEPCHAR); + if (e == std::string::npos) return nullptr; + basename.erase(e + 1); - strecpy(e, "lang" PATHSEP "english.txt", lastof(filename)); - if (!FioCheckFileExists(filename, GAME_DIR)) return nullptr; + std::string filename = basename + "lang" PATHSEP "english.txt"; + if (!FioCheckFileExists(filename.c_str() , GAME_DIR)) return nullptr; auto ls = ReadRawLanguageStrings(filename); - if (ls == nullptr) return nullptr; + if (!ls.IsValid()) return nullptr; GameStrings *gs = new GameStrings(); try { @@ -267,8 +242,7 @@ GameStrings *LoadTranslations() /* Scan for other language files */ LanguageScanner scanner(gs, filename); - strecpy(e, "lang" PATHSEP, lastof(filename)); - size_t len = strlen(filename); + std::string ldir = basename + "lang" PATHSEP; const char *tar_filename = info->GetTarFile(); TarList::iterator iter; @@ -281,14 +255,14 @@ GameStrings *LoadTranslations() if (tar->second.tar_filename != iter->first) continue; /* Check the path and extension. */ - if (tar->first.size() <= len || tar->first.compare(0, len, filename) != 0) continue; + if (tar->first.size() <= ldir.size() || tar->first.compare(0, ldir.size(), ldir) != 0) continue; if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue; scanner.AddFile(tar->first.c_str(), 0, tar_filename); } } else { /* Scan filesystem */ - scanner.Scan(filename); + scanner.Scan(ldir.c_str()); } gs->Compile(); @@ -303,7 +277,7 @@ GameStrings *LoadTranslations() void GameStrings::Compile() { StringData data(32); - StringListReader master_reader(data, *this->raw_strings[0], true, false); + StringListReader master_reader(data, this->raw_strings[0], true, false); master_reader.ParseFile(); if (_errors != 0) throw std::exception(); @@ -314,12 +288,12 @@ void GameStrings::Compile() for (const auto &p : this->raw_strings) { data.FreeTranslation(); - StringListReader translation_reader(data, *p, false, strcmp(p->language, "english") != 0); + StringListReader translation_reader(data, p, false, p.language != "english"); translation_reader.ParseFile(); if (_errors != 0) throw std::exception(); - this->compiled_strings.emplace_back(new LanguageStrings(p->language)); - TranslationWriter writer(this->compiled_strings.back()->lines); + this->compiled_strings.emplace_back(p.language); + TranslationWriter writer(this->compiled_strings.back().lines); writer.WriteLang(data); } } @@ -387,11 +361,11 @@ void ReconsiderGameScriptLanguage() language++; for (auto &p : _current_data->compiled_strings) { - if (strcmp(p->language, language) == 0) { - _current_data->cur_language = p; + if (p.language == language) { + _current_data->cur_language = &p; return; } } - _current_data->cur_language = _current_data->compiled_strings[0]; + _current_data->cur_language = &_current_data->compiled_strings[0]; } diff --git a/src/game/game_text.hpp b/src/game/game_text.hpp index 20cccff54..91d85847d 100644 --- a/src/game/game_text.hpp +++ b/src/game/game_text.hpp @@ -18,23 +18,34 @@ void ReconsiderGameScriptLanguage(); /** Container for the raw (unencoded) language strings of a language. */ struct LanguageStrings { - const char *language; ///< Name of the language (base filename). - StringList lines; ///< The lines of the file to pass into the parser/encoder. + std::string language; ///< Name of the language (base filename). Empty string if invalid. + StringList lines; ///< The lines of the file to pass into the parser/encoder. - LanguageStrings(const char *language, const char *end = nullptr); - ~LanguageStrings(); + LanguageStrings() {} + LanguageStrings(const std::string &lang) : language(lang) {} + LanguageStrings(const LanguageStrings &other) : language(other.language), lines(other.lines) {} + LanguageStrings(LanguageStrings &&other) : language(std::move(other.language)), lines(std::move(other.lines)) {} + + bool IsValid() const { return !this->language.empty(); } }; /** Container for all the game strings. */ struct GameStrings { - uint version; ///< The version of the language strings. - std::shared_ptr<LanguageStrings> cur_language; ///< The current (compiled) language. + uint version; ///< The version of the language strings. + LanguageStrings *cur_language; ///< The current (compiled) language. - std::vector<std::unique_ptr<LanguageStrings>> raw_strings; ///< The raw strings per language, first must be English/the master language!. - std::vector<std::shared_ptr<LanguageStrings>> compiled_strings; ///< The compiled strings per language, first must be English/the master language!. - StringList string_names; ///< The names of the compiled strings. + std::vector<LanguageStrings> raw_strings; ///< The raw strings per language, first must be English/the master language!. + std::vector<LanguageStrings> compiled_strings; ///< The compiled strings per language, first must be English/the master language!. + StringList string_names; ///< The names of the compiled strings. void Compile(); + + GameStrings() = default; + + GameStrings(const GameStrings &) = delete; + GameStrings(GameStrings &&) = delete; + GameStrings &operator=(const GameStrings &) = delete; + GameStrings &operator=(GameStrings &&) = delete; }; #endif /* GAME_TEXT_HPP */ |