# HG changeset patch # User rubidium # Date 2010-11-13 11:11:02 # Node ID 88fcbcadb08e0e2e4f82ef3b677cdec851a82ccb # Parent 9149b1d03a2a8855329251167cc315c2f02a0323 (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 diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -453,6 +453,7 @@ + @@ -551,7 +552,6 @@ - diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -579,6 +579,9 @@ Header Files + + Header Files + Header Files @@ -873,9 +876,6 @@ Header Files - - Header Files - Header Files diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1087,6 +1087,10 @@ > + + @@ -1479,10 +1483,6 @@ > - - diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1084,6 +1084,10 @@ > + + @@ -1476,10 +1480,6 @@ > - - diff --git a/source.list b/source.list --- a/source.list +++ b/source.list @@ -186,6 +186,7 @@ industrytype.h ini_type.h landscape.h landscape_type.h +language.h livery.h map_func.h map_type.h @@ -284,7 +285,6 @@ station_gui.h station_type.h statusbar_gui.h stdafx.h -strgen/strgen.h string_func.h string_type.h strings_func.h diff --git a/src/language.h b/src/language.h new file mode 100644 --- /dev/null +++ b/src/language.h @@ -0,0 +1,59 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * 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 . + */ + +/** @file language.h Information about languages and their files. */ + +#ifndef LANGUAGE_H +#define LANGUAGE_H + +/** Header of a language file. */ +struct LanguagePackHeader { + static const uint32 IDENT = 0x474E414C; ///< Identifier for OpenTTD language files, big endian for "LANG" + + uint32 ident; ///< 32-bits identifier + uint32 version; ///< 32-bits of auto generated version info which is basically a hash of strings.h + char name[32]; ///< the international name of this language + char own_name[32]; ///< the localized name of this language + char isocode[16]; ///< the ISO code for the language (not country code) + uint16 offsets[32]; ///< the offsets + + /** Thousand separator used for anything not currencies */ + char digit_group_separator[8]; + /** Thousand separator used for currencies */ + char digit_group_separator_currency[8]; + /** Decimal separator */ + char digit_decimal_separator[8]; + byte plural_form; ///< plural form index + byte text_dir; ///< default direction of the text + /** + * Windows language ID: + * Windows cannot and will not convert isocodes to something it can use to + * determine whether a font can be used for the language or not. As a result + * of that we need to pass the language id via strgen to OpenTTD to tell + * what language it is in "Windows". The ID is the 'locale identifier' on: + * http://msdn.microsoft.com/en-us/library/ms776294.aspx + */ + uint16 winlangid; ///< windows language id + uint8 newgrflangid; ///< newgrf language id + byte pad[3]; ///< pad header to be a multiple of 4 + + /** + * Check whether the header is a valid header for OpenTTD. + * @return true iff the header is deemed valid. + */ + bool IsValid() const; +}; +assert_compile(sizeof(LanguagePackHeader) % 4 == 0); + +/** 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 */ diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -16,7 +16,7 @@ #include "../core/mem_func.hpp" #include "../string_func.h" #include "../strings_type.h" -#include "strgen.h" +#include "../language.h" #include "../table/control_codes.h" #include diff --git a/src/strgen/strgen.h b/src/strgen/strgen.h deleted file mode 100644 --- a/src/strgen/strgen.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id$ */ - -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * 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 . - */ - -/** @file strgen.h Language pack header for strgen (needs to match). */ - -#ifndef STRGEN_H -#define STRGEN_H - -/** Header of a language file. */ -struct LanguagePackHeader { - static const uint32 IDENT = 0x474E414C; ///< Identifier for OpenTTD language files, big endian for "LANG" - - uint32 ident; ///< 32-bits identifier - uint32 version; ///< 32-bits of auto generated version info which is basically a hash of strings.h - char name[32]; ///< the international name of this language - char own_name[32]; ///< the localized name of this language - char isocode[16]; ///< the ISO code for the language (not country code) - uint16 offsets[32]; ///< the offsets - - /** Thousand separator used for anything not currencies */ - char digit_group_separator[8]; - /** Thousand separator used for currencies */ - char digit_group_separator_currency[8]; - /** Decimal separator */ - char digit_decimal_separator[8]; - byte plural_form; ///< plural form index - byte text_dir; ///< default direction of the text - /** - * Windows language ID: - * Windows cannot and will not convert isocodes to something it can use to - * determine whether a font can be used for the language or not. As a result - * of that we need to pass the language id via strgen to OpenTTD to tell - * what language it is in "Windows". The ID is the 'locale identifier' on: - * http://msdn.microsoft.com/en-us/library/ms776294.aspx - */ - uint16 winlangid; ///< windows language id - uint8 newgrflangid; ///< newgrf language id - byte pad[3]; ///< pad header to be a multiple of 4 - - /** - * Check whether the header is a valid header for OpenTTD. - * @return true iff the header is deemed valid. - */ - bool IsValid() const; -}; - -assert_compile(sizeof(LanguagePackHeader) % 4 == 0); - -#endif /* STRGEN_H */ diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -30,7 +30,7 @@ #include "date_func.h" #include "vehicle_base.h" #include "engine_base.h" -#include "strgen/strgen.h" +#include "language.h" #include "townname_func.h" #include "string_func.h" #include "company_base.h" @@ -1439,12 +1439,12 @@ int CDECL StringIDSorter(const StringID /** * 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 language name of the language to check * @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++) { const char *f_name = strrchr(langs[i].file, PATHSEPCHAR) + 1; @@ -1460,7 +1460,7 @@ static bool UniqueLanguageFile(const Lan * @param hdr the place to write the header information to * @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"); if (f == NULL) return false; @@ -1483,7 +1483,7 @@ static bool GetLanguageFileHeader(const * @param path the base directory to search in * @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; @@ -1500,13 +1500,11 @@ static int GetLanguageList(Language *lan /* Filter any duplicate language-files, first-come first-serve */ 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 */ - LanguagePack hdr; - if (!GetLanguageFileHeader(langs[i].file, &hdr)) { + if (!GetLanguageFileHeader(langs[i].file, &langs[i])) { DEBUG(misc, 3, "%s is not a valid language file", langs[i].file); - free(langs[i].file); continue; } @@ -1524,13 +1522,12 @@ static int GetLanguageList(Language *lan void InitializeLanguagePacks() { Searchpath sp; - Language files[MAX_LANG]; uint language_count = 0; FOR_ALL_SEARCHPATHS(sp) { char path[MAX_PATH]; 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?)"); @@ -1542,41 +1539,29 @@ void InitializeLanguagePacks() 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 - DynamicLanguages *dl = &_dynlang; - dl->num = 0; + _dynlang.num = language_count; /* Fill the dynamic languages structures */ 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 * configuration file, local environment and last, if nothing found, * english. If def equals -1, we have not picked a default language */ - const char *lang_file = strrchr(dl->ent[dl->num].file, PATHSEPCHAR) + 1; - if (strcmp(lang_file, dl->curr_file) == 0) chosen_language = dl->num; + const char *lang_file = strrchr(_dynlang.ent[i].file, PATHSEPCHAR) + 1; + if (strcmp(lang_file, _dynlang.curr_file) == 0) chosen_language = i; if (chosen_language == -1) { - if (strcmp (hdr.isocode, "en_GB") == 0) en_GB_fallback = dl->num; - if (strncmp(hdr.isocode, lang, 5) == 0) chosen_language = dl->num; - if (strncmp(hdr.isocode, lang, 2) == 0) language_fallback = dl->num; + if (strcmp (_dynlang.ent[i].isocode, "en_GB") == 0) en_GB_fallback = i; + if (strncmp(_dynlang.ent[i].isocode, lang, 5) == 0) chosen_language = i; + 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. * Now we set it to one of the fallback languages */ if (chosen_language == -1) { 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); } /** diff --git a/src/strings_type.h b/src/strings_type.h --- a/src/strings_type.h +++ b/src/strings_type.h @@ -12,6 +12,8 @@ #ifndef STRINGS_TYPE_H #define STRINGS_TYPE_H +#include "language.h" + /** * 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 }; -/** 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 */ struct DynamicLanguages { int num; ///< Number of languages 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). - Language ent[MAX_LANG]; ///< Information about the languages + LanguageMetadata ent[MAX_LANG]; ///< Information about the languages }; /** Special string constants */