11#include "../strgen/strgen.h"
13#include "../fileio_func.h"
14#include "../tar_type.h"
15#include "../script/squirrel_class.hpp"
16#include "../strings_func.h"
21#include "table/strings.h"
24#include "../safeguards.h"
26void CDECL StrgenWarningI(
const std::string &msg)
32void CDECL StrgenErrorI(
const std::string &msg)
38void CDECL StrgenFatalI(
const std::string &msg)
41 throw std::exception();
55 auto pos = file.rfind(PATHSEPCHAR);
57 std::string langname = file.substr(pos + 1);
60 if (langname.empty() || langname.front() ==
'.')
return LanguageStrings();
65 while (to_read != 0 && fgets(buffer,
sizeof(buffer), *fh) !=
nullptr) {
66 size_t len = strlen(buffer);
70 while (i > 0 && (buffer[i - 1] ==
'\r' || buffer[i - 1] ==
'\n' || buffer[i - 1] ==
' ')) i--;
73 ret.
lines.emplace_back(buffer, i);
88 StringList::const_iterator
p;
89 StringList::const_iterator
end;
105 if (this->p == this->end)
return std::nullopt;
137 void Write(
const uint8_t *buffer,
size_t length)
override
139 this->strings.emplace_back((
const char *)buffer, length);
157 if (stringid == (
int)this->strings.size()) this->strings.emplace_back(name);
181 void Scan(
const std::string &directory)
186 bool AddFile(
const std::string &filename,
size_t,
const std::string &)
override
188 if (exclude == filename)
return true;
191 if (!ls.IsValid())
return false;
205 assert(info !=
nullptr);
207 auto e = basename.rfind(PATHSEPCHAR);
208 if (e == std::string::npos)
return nullptr;
209 basename.erase(e + 1);
211 std::string filename = basename +
"lang" PATHSEP
"english.txt";
215 if (!ls.IsValid())
return nullptr;
223 std::string ldir = basename +
"lang" PATHSEP;
225 const std::string tar_filename = info->
GetTarFile();
226 TarList::iterator iter;
227 if (!tar_filename.empty() && (iter = _tar_list[
GAME_DIR].find(tar_filename)) != _tar_list[
GAME_DIR].end()) {
230 for (
const auto &tar : _tar_filelist[
GAME_DIR]) {
232 if (tar.second.tar_filename != iter->first)
continue;
235 if (tar.first.size() <= ldir.size() || tar.first.compare(0, ldir.size(), ldir) != 0)
continue;
236 if (tar.first.compare(tar.first.size() - 4, 4,
".txt") != 0)
continue;
238 scanner.
AddFile(tar.first, 0, tar_filename);
253static StringParam::ParamType GetParamType(
const CmdStruct *cs)
255 if (cs->value == SCC_RAW_STRING_POINTER)
return StringParam::RAW_STRING;
256 if (cs->value == SCC_STRING || cs != TranslateCmdForCompare(cs))
return StringParam::STRING;
257 return StringParam::OTHER;
260static void ExtractStringParams(
const StringData &data, StringParamsList ¶ms)
266 StringParams ¶m = params.emplace_back();
269 for (
auto it = pcs.consuming_commands.begin(); it != pcs.consuming_commands.end(); it++) {
270 if (*it ==
nullptr) {
272 if (std::all_of(it, pcs.consuming_commands.end(), [](
auto cs) { return cs == nullptr; }))
break;
273 param.emplace_back(StringParam::UNUSED, 1,
nullptr);
277 param.emplace_back(GetParamType(cs), cs->consumes, cs->cmd);
289 if (_errors != 0)
throw std::exception();
300 StringListReader translation_reader(data, p,
false, p.language !=
"english");
302 if (_errors != 0)
throw std::exception();
332 static StringParams empty;
346 static const std::string undefined =
"STR_UNDEFINED";
362 HSQUIRRELVM vm = engine->
GetVM();
363 sq_pushroottable(vm);
364 sq_pushstring(vm,
"GSText", -1);
365 if (SQ_FAILED(sq_get(vm, -2)))
return;
369 sq_pushstring(vm, p, -1);
370 sq_pushinteger(vm, idx);
389 if (p.language == language) {
Helper for scanning for files with a given name.
uint Scan(std::string_view extension, Subdirectory sd, bool tars=true, bool recursive=true)
Scan for files with the given extension in the given search path.
All static information from an Game like name, version, etc.
static class GameInfo * GetInfo()
Get the current GameInfo.
Scanner to find language files in a GameScript directory.
void Scan(const std::string &directory)
Scan.
bool AddFile(const std::string &filename, size_t, const std::string &) override
Add a file with the given filename.
LanguageScanner(GameStrings *gs, const std::string &exclude)
Initialise.
const std::string & GetMainScript() const
Get the filename of the main.nut script.
const std::string & GetTarFile() const
Get the filename of the tar the script is in.
HSQUIRRELVM GetVM()
Get the squirrel VM.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
std::optional< FileHandle > FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
@ GAME_DIR
Subdirectory for all game scripts.
Base functions for all Games.
GameInfo keeps track of all information of an Game, like Author, Description, ...
void RegisterGameTranslation(Squirrel *engine)
Register the current translation to the Squirrel engine.
const std::string & GetGameStringName(uint id)
Get the name of a particular game string.
GameStrings * LoadTranslations()
Load all translations that we know of.
GameStrings * _current_data
The currently loaded game strings.
void ReconsiderGameScriptLanguage()
Reconsider the game script language, so we use the right one.
LanguageStrings ReadRawLanguageStrings(const std::string &file)
Read all the raw language strings from the given file.
const char * GetGameStringPtr(uint id)
Get the string pointer of a particular game string.
const StringParams & GetGameStringParams(uint id)
Get the string parameters of a particular game string.
Base functions regarding game texts.
const LanguageMetadata * _current_language
The currently loaded language.
int _cur_line
The current line we're parsing in the input file.
const char * _file
The filename of the input, so we can refer to it in errors/warnings.
Tables of commands for strgen.
std::vector< std::string > StringList
Type for a list of strings.
Container for all the game 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!.
uint version
The version of the language strings.
StringList string_names
The names of the compiled strings.
void Compile()
Compile the language.
StringParamsList string_params
The parameters for the strings.
LanguageStrings * cur_language
The current (compiled) language.
Information about a single string.
std::string english
English text.
Container for the raw (unencoded) language strings of a language.
StringList lines
The lines of the file to pass into the parser/encoder.
Base class for all language writers.
virtual void WriteLang(const StringData &data)
Actually write the language.
Information about the currently known strings.
std::vector< std::unique_ptr< LangString > > strings
List of all known strings.
size_t max_strings
The maximum number of strings.
uint Version() const
Make a hash of the file to get a unique "version number".
void FreeTranslation()
Free all data related to the translation.
A reader that simply reads using fopen.
StringList::const_iterator p
The current location of the iteration.
StringList::const_iterator end
The end of the iteration.
StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation)
Create the reader.
std::optional< std::string > ReadLine() override
Read a single line from the source of strings.
Class for writing the string IDs.
void Finalise(const StringData &) override
Finalise writing the file.
void WriteStringID(const std::string &name, int stringid) override
Write the string ID.
StringNameWriter(StringList &strings)
Writer for the string names.
StringList & strings
The string names.
Helper for reading strings.
StringData & data
The data to fill during reading.
virtual void ParseFile()
Start parsing the file.
bool translation
Are we reading a translation, implies !master. However, the base translation will have this false.
bool master
Are we reading the master file?
Class for writing an encoded language.
void WriteLength(uint) override
Write the length as a simple gamma.
StringList & strings
The encoded strings.
void WriteHeader(const LanguagePackHeader *) override
Write the header metadata.
TranslationWriter(StringList &strings)
Writer for the encoded data.
void Write(const uint8_t *buffer, size_t length) override
Write a number of bytes.
void Finalise() override
Finalise writing the file.
std::string FS2OTTD(const std::wstring &name)
Convert to OpenTTD's encoding from a wide string.