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.
GameStrings * LoadTranslations()
Load all translations that we know of.
const std::string & GetGameStringName(StringIndexInTab id)
Get the name of a particular game string.
const StringParams & GetGameStringParams(StringIndexInTab id)
Get the string parameters of a particular game string.
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(StringIndexInTab id)
Get the string pointer 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?
Templated helper to make a type-safe 'typedef' representing a single POD value.
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.