mirror of https://github.com/OpenTTD/OpenTTD
(svn r21160) -Codechange: reuse the strgen LanguageHeader to store some metadata about a language, and keep the language metadata in memory instead of loading it several times from disk
parent
239fcc8ccd
commit
f195920695
|
@ -453,6 +453,7 @@
|
||||||
<ClInclude Include="..\src\ini_type.h" />
|
<ClInclude Include="..\src\ini_type.h" />
|
||||||
<ClInclude Include="..\src\landscape.h" />
|
<ClInclude Include="..\src\landscape.h" />
|
||||||
<ClInclude Include="..\src\landscape_type.h" />
|
<ClInclude Include="..\src\landscape_type.h" />
|
||||||
|
<ClInclude Include="..\src\language.h" />
|
||||||
<ClInclude Include="..\src\livery.h" />
|
<ClInclude Include="..\src\livery.h" />
|
||||||
<ClInclude Include="..\src\map_func.h" />
|
<ClInclude Include="..\src\map_func.h" />
|
||||||
<ClInclude Include="..\src\map_type.h" />
|
<ClInclude Include="..\src\map_type.h" />
|
||||||
|
@ -551,7 +552,6 @@
|
||||||
<ClInclude Include="..\src\station_type.h" />
|
<ClInclude Include="..\src\station_type.h" />
|
||||||
<ClInclude Include="..\src\statusbar_gui.h" />
|
<ClInclude Include="..\src\statusbar_gui.h" />
|
||||||
<ClInclude Include="..\src\stdafx.h" />
|
<ClInclude Include="..\src\stdafx.h" />
|
||||||
<ClInclude Include="..\src\strgen\strgen.h" />
|
|
||||||
<ClInclude Include="..\src\string_func.h" />
|
<ClInclude Include="..\src\string_func.h" />
|
||||||
<ClInclude Include="..\src\string_type.h" />
|
<ClInclude Include="..\src\string_type.h" />
|
||||||
<ClInclude Include="..\src\strings_func.h" />
|
<ClInclude Include="..\src\strings_func.h" />
|
||||||
|
|
|
@ -579,6 +579,9 @@
|
||||||
<ClInclude Include="..\src\landscape_type.h">
|
<ClInclude Include="..\src\landscape_type.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\language.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\src\livery.h">
|
<ClInclude Include="..\src\livery.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -873,9 +876,6 @@
|
||||||
<ClInclude Include="..\src\stdafx.h">
|
<ClInclude Include="..\src\stdafx.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\src\strgen\strgen.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\src\string_func.h">
|
<ClInclude Include="..\src\string_func.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -1086,6 +1086,10 @@
|
||||||
RelativePath=".\..\src\landscape_type.h"
|
RelativePath=".\..\src\landscape_type.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\language.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\livery.h"
|
RelativePath=".\..\src\livery.h"
|
||||||
>
|
>
|
||||||
|
@ -1478,10 +1482,6 @@
|
||||||
RelativePath=".\..\src\stdafx.h"
|
RelativePath=".\..\src\stdafx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\..\src\strgen\strgen.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\string_func.h"
|
RelativePath=".\..\src\string_func.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1083,6 +1083,10 @@
|
||||||
RelativePath=".\..\src\landscape_type.h"
|
RelativePath=".\..\src\landscape_type.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\language.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\livery.h"
|
RelativePath=".\..\src\livery.h"
|
||||||
>
|
>
|
||||||
|
@ -1475,10 +1479,6 @@
|
||||||
RelativePath=".\..\src\stdafx.h"
|
RelativePath=".\..\src\stdafx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\..\src\strgen\strgen.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\string_func.h"
|
RelativePath=".\..\src\string_func.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -186,6 +186,7 @@ industrytype.h
|
||||||
ini_type.h
|
ini_type.h
|
||||||
landscape.h
|
landscape.h
|
||||||
landscape_type.h
|
landscape_type.h
|
||||||
|
language.h
|
||||||
livery.h
|
livery.h
|
||||||
map_func.h
|
map_func.h
|
||||||
map_type.h
|
map_type.h
|
||||||
|
@ -284,7 +285,6 @@ station_gui.h
|
||||||
station_type.h
|
station_type.h
|
||||||
statusbar_gui.h
|
statusbar_gui.h
|
||||||
stdafx.h
|
stdafx.h
|
||||||
strgen/strgen.h
|
|
||||||
string_func.h
|
string_func.h
|
||||||
string_type.h
|
string_type.h
|
||||||
strings_func.h
|
strings_func.h
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file strgen.h Language pack header for strgen (needs to match). */
|
/** @file language.h Information about languages and their files. */
|
||||||
|
|
||||||
#ifndef STRGEN_H
|
#ifndef LANGUAGE_H
|
||||||
#define STRGEN_H
|
#define LANGUAGE_H
|
||||||
|
|
||||||
/** Header of a language file. */
|
/** Header of a language file. */
|
||||||
struct LanguagePackHeader {
|
struct LanguagePackHeader {
|
||||||
|
@ -49,7 +49,11 @@ struct LanguagePackHeader {
|
||||||
*/
|
*/
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_compile(sizeof(LanguagePackHeader) % 4 == 0);
|
assert_compile(sizeof(LanguagePackHeader) % 4 == 0);
|
||||||
|
|
||||||
#endif /* STRGEN_H */
|
/** Metadata about a single language. */
|
||||||
|
struct LanguageMetadata : public LanguagePackHeader {
|
||||||
|
char file[MAX_PATH]; ///< Name of the file we read this data from.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LANGUAGE_H */
|
|
@ -16,7 +16,7 @@
|
||||||
#include "../core/mem_func.hpp"
|
#include "../core/mem_func.hpp"
|
||||||
#include "../string_func.h"
|
#include "../string_func.h"
|
||||||
#include "../strings_type.h"
|
#include "../strings_type.h"
|
||||||
#include "strgen.h"
|
#include "../language.h"
|
||||||
#include "../table/control_codes.h"
|
#include "../table/control_codes.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
#include "vehicle_base.h"
|
#include "vehicle_base.h"
|
||||||
#include "engine_base.h"
|
#include "engine_base.h"
|
||||||
#include "strgen/strgen.h"
|
#include "language.h"
|
||||||
#include "townname_func.h"
|
#include "townname_func.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
|
@ -1439,12 +1439,12 @@ int CDECL StringIDSorter(const StringID *a, const StringID *b)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given language is already found.
|
* Checks whether the given language is already found.
|
||||||
* @param langs languages we've found so fa
|
* @param langs languages we've found so far
|
||||||
* @param max the length of the language list
|
* @param max the length of the language list
|
||||||
* @param language name of the language to check
|
* @param language name of the language to check
|
||||||
* @return true if and only if a language file with the same name has not been found
|
* @return true if and only if a language file with the same name has not been found
|
||||||
*/
|
*/
|
||||||
static bool UniqueLanguageFile(const Language *langs, uint max, const char *language)
|
static bool UniqueLanguageFile(const LanguageMetadata *langs, uint max, const char *language)
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < max; i++) {
|
for (uint i = 0; i < max; i++) {
|
||||||
const char *f_name = strrchr(langs[i].file, PATHSEPCHAR) + 1;
|
const char *f_name = strrchr(langs[i].file, PATHSEPCHAR) + 1;
|
||||||
|
@ -1460,7 +1460,7 @@ static bool UniqueLanguageFile(const Language *langs, uint max, const char *lang
|
||||||
* @param hdr the place to write the header information to
|
* @param hdr the place to write the header information to
|
||||||
* @return true if and only if the language file is of a compatible version
|
* @return true if and only if the language file is of a compatible version
|
||||||
*/
|
*/
|
||||||
static bool GetLanguageFileHeader(const char *file, LanguagePack *hdr)
|
static bool GetLanguageFileHeader(const char *file, LanguagePackHeader *hdr)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(file, "rb");
|
FILE *f = fopen(file, "rb");
|
||||||
if (f == NULL) return false;
|
if (f == NULL) return false;
|
||||||
|
@ -1483,7 +1483,7 @@ static bool GetLanguageFileHeader(const char *file, LanguagePack *hdr)
|
||||||
* @param path the base directory to search in
|
* @param path the base directory to search in
|
||||||
* @return the number of added languages
|
* @return the number of added languages
|
||||||
*/
|
*/
|
||||||
static int GetLanguageList(Language *langs, int start, int max, const char *path)
|
static int GetLanguageList(LanguageMetadata *langs, int start, int max, const char *path)
|
||||||
{
|
{
|
||||||
int i = start;
|
int i = start;
|
||||||
|
|
||||||
|
@ -1500,13 +1500,11 @@ static int GetLanguageList(Language *langs, int start, int max, const char *path
|
||||||
/* Filter any duplicate language-files, first-come first-serve */
|
/* Filter any duplicate language-files, first-come first-serve */
|
||||||
if (!UniqueLanguageFile(langs, i, d_name)) continue;
|
if (!UniqueLanguageFile(langs, i, d_name)) continue;
|
||||||
|
|
||||||
langs[i].file = str_fmt("%s%s", path, d_name);
|
seprintf(langs[i].file, lastof(langs[i].file), "%s%s", path, d_name);
|
||||||
|
|
||||||
/* Check whether the file is of the correct version */
|
/* Check whether the file is of the correct version */
|
||||||
LanguagePack hdr;
|
if (!GetLanguageFileHeader(langs[i].file, &langs[i])) {
|
||||||
if (!GetLanguageFileHeader(langs[i].file, &hdr)) {
|
|
||||||
DEBUG(misc, 3, "%s is not a valid language file", langs[i].file);
|
DEBUG(misc, 3, "%s is not a valid language file", langs[i].file);
|
||||||
free(langs[i].file);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,13 +1522,12 @@ static int GetLanguageList(Language *langs, int start, int max, const char *path
|
||||||
void InitializeLanguagePacks()
|
void InitializeLanguagePacks()
|
||||||
{
|
{
|
||||||
Searchpath sp;
|
Searchpath sp;
|
||||||
Language files[MAX_LANG];
|
|
||||||
uint language_count = 0;
|
uint language_count = 0;
|
||||||
|
|
||||||
FOR_ALL_SEARCHPATHS(sp) {
|
FOR_ALL_SEARCHPATHS(sp) {
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
FioAppendDirectory(path, lengthof(path), sp, LANG_DIR);
|
FioAppendDirectory(path, lengthof(path), sp, LANG_DIR);
|
||||||
language_count += GetLanguageList(files, language_count, lengthof(files), path);
|
language_count += GetLanguageList(_dynlang.ent, language_count, lengthof(_dynlang.ent), path);
|
||||||
}
|
}
|
||||||
if (language_count == 0) usererror("No available language packs (invalid versions?)");
|
if (language_count == 0) usererror("No available language packs (invalid versions?)");
|
||||||
|
|
||||||
|
@ -1542,41 +1539,29 @@ void InitializeLanguagePacks()
|
||||||
int language_fallback = -1; ///< Using pt_PT for pt_BR locale when pt_BR is not available
|
int language_fallback = -1; ///< Using pt_PT for pt_BR locale when pt_BR is not available
|
||||||
int en_GB_fallback = 0; ///< Fallback when no locale-matching language has been found
|
int en_GB_fallback = 0; ///< Fallback when no locale-matching language has been found
|
||||||
|
|
||||||
DynamicLanguages *dl = &_dynlang;
|
_dynlang.num = language_count;
|
||||||
dl->num = 0;
|
|
||||||
/* Fill the dynamic languages structures */
|
/* Fill the dynamic languages structures */
|
||||||
for (uint i = 0; i < language_count; i++) {
|
for (uint i = 0; i < language_count; i++) {
|
||||||
/* File read the language header */
|
|
||||||
LanguagePack hdr;
|
|
||||||
if (!GetLanguageFileHeader(files[i].file, &hdr)) continue;
|
|
||||||
|
|
||||||
dl->ent[dl->num].file = files[i].file;
|
|
||||||
dl->ent[dl->num].name = strdup(hdr.name);
|
|
||||||
|
|
||||||
/* We are trying to find a default language. The priority is by
|
/* We are trying to find a default language. The priority is by
|
||||||
* configuration file, local environment and last, if nothing found,
|
* configuration file, local environment and last, if nothing found,
|
||||||
* english. If def equals -1, we have not picked a default language */
|
* english. If def equals -1, we have not picked a default language */
|
||||||
const char *lang_file = strrchr(dl->ent[dl->num].file, PATHSEPCHAR) + 1;
|
const char *lang_file = strrchr(_dynlang.ent[i].file, PATHSEPCHAR) + 1;
|
||||||
if (strcmp(lang_file, dl->curr_file) == 0) chosen_language = dl->num;
|
if (strcmp(lang_file, _dynlang.curr_file) == 0) chosen_language = i;
|
||||||
|
|
||||||
if (chosen_language == -1) {
|
if (chosen_language == -1) {
|
||||||
if (strcmp (hdr.isocode, "en_GB") == 0) en_GB_fallback = dl->num;
|
if (strcmp (_dynlang.ent[i].isocode, "en_GB") == 0) en_GB_fallback = i;
|
||||||
if (strncmp(hdr.isocode, lang, 5) == 0) chosen_language = dl->num;
|
if (strncmp(_dynlang.ent[i].isocode, lang, 5) == 0) chosen_language = i;
|
||||||
if (strncmp(hdr.isocode, lang, 2) == 0) language_fallback = dl->num;
|
if (strncmp(_dynlang.ent[i].isocode, lang, 2) == 0) language_fallback = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
dl->num++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dl->num == 0) usererror("Invalid version of language packs");
|
|
||||||
|
|
||||||
/* We haven't found the language in the config nor the one in the locale.
|
/* We haven't found the language in the config nor the one in the locale.
|
||||||
* Now we set it to one of the fallback languages */
|
* Now we set it to one of the fallback languages */
|
||||||
if (chosen_language == -1) {
|
if (chosen_language == -1) {
|
||||||
chosen_language = (language_fallback != -1) ? language_fallback : en_GB_fallback;
|
chosen_language = (language_fallback != -1) ? language_fallback : en_GB_fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReadLanguagePack(chosen_language)) usererror("Can't read language pack '%s'", dl->ent[chosen_language].file);
|
if (!ReadLanguagePack(chosen_language)) usererror("Can't read language pack '%s'", _dynlang.ent[chosen_language].file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef STRINGS_TYPE_H
|
#ifndef STRINGS_TYPE_H
|
||||||
#define STRINGS_TYPE_H
|
#define STRINGS_TYPE_H
|
||||||
|
|
||||||
|
#include "language.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numeric value that represents a string, independent of the selected language.
|
* Numeric value that represents a string, independent of the selected language.
|
||||||
*/
|
*/
|
||||||
|
@ -26,18 +28,12 @@ enum TextDirection {
|
||||||
TD_RTL, ///< Text is written right-to-left by default
|
TD_RTL, ///< Text is written right-to-left by default
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Information about a language */
|
|
||||||
struct Language {
|
|
||||||
char *name; ///< The internal name of the language
|
|
||||||
char *file; ///< The name of the language as it appears on disk
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Used for dynamic language support */
|
/** Used for dynamic language support */
|
||||||
struct DynamicLanguages {
|
struct DynamicLanguages {
|
||||||
int num; ///< Number of languages
|
int num; ///< Number of languages
|
||||||
int curr; ///< Currently selected language index
|
int curr; ///< Currently selected language index
|
||||||
char curr_file[MAX_PATH]; ///< Currently selected language file name without path (needed for saving the filename of the loaded language).
|
char curr_file[MAX_PATH]; ///< Currently selected language file name without path (needed for saving the filename of the loaded language).
|
||||||
Language ent[MAX_LANG]; ///< Information about the languages
|
LanguageMetadata ent[MAX_LANG]; ///< Information about the languages
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Special string constants */
|
/** Special string constants */
|
||||||
|
|
Loading…
Reference in New Issue