OpenTTD Source: src/table/strgen_tables.h Source File

OpenTTD Source 15.0-RC2

strgen_tables.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../core/enum_type.hpp"
11
12 enum class CmdFlag : uint8_t {
13 DontCount,
14 Case,
15 Gender,
16};
17using CmdFlags = EnumBitSet<CmdFlag, uint8_t>;
18
19class StringBuilder;
20typedef void (*ParseCmdProc)(StringBuilder &builder, std::string_view param, char32_t value);
21
22 struct CmdStruct {
23 std::string_view cmd;
24 ParseCmdProc proc;
25 char32_t value;
26 uint8_t consumes;
27 std::optional<size_t> default_plural_offset;
28 CmdFlags flags;
29};
30
31extern void EmitSingleChar(StringBuilder &builder, std::string_view param, char32_t value);
32extern void EmitPlural(StringBuilder &builder, std::string_view param, char32_t value);
33extern void EmitGender(StringBuilder &builder, std::string_view param, char32_t value);
34
35static const CmdStruct _cmd_structs[] = {
36 /* Font size */
37 {"NORMAL_FONT", EmitSingleChar, SCC_NORMALFONT, 0, std::nullopt, {}},
38 {"TINY_FONT", EmitSingleChar, SCC_TINYFONT, 0, std::nullopt, {}},
39 {"BIG_FONT", EmitSingleChar, SCC_BIGFONT, 0, std::nullopt, {}},
40 {"MONO_FONT", EmitSingleChar, SCC_MONOFONT, 0, std::nullopt, {}},
41
42 /* Colours */
43 {"BLUE", EmitSingleChar, SCC_BLUE, 0, std::nullopt, {CmdFlag::DontCount}},
44 {"SILVER", EmitSingleChar, SCC_SILVER, 0, std::nullopt, {CmdFlag::DontCount}},
45 {"GOLD", EmitSingleChar, SCC_GOLD, 0, std::nullopt, {CmdFlag::DontCount}},
46 {"RED", EmitSingleChar, SCC_RED, 0, std::nullopt, {CmdFlag::DontCount}},
47 {"PURPLE", EmitSingleChar, SCC_PURPLE, 0, std::nullopt, {CmdFlag::DontCount}},
48 {"LTBROWN", EmitSingleChar, SCC_LTBROWN, 0, std::nullopt, {CmdFlag::DontCount}},
49 {"ORANGE", EmitSingleChar, SCC_ORANGE, 0, std::nullopt, {CmdFlag::DontCount}},
50 {"GREEN", EmitSingleChar, SCC_GREEN, 0, std::nullopt, {CmdFlag::DontCount}},
51 {"YELLOW", EmitSingleChar, SCC_YELLOW, 0, std::nullopt, {CmdFlag::DontCount}},
52 {"DKGREEN", EmitSingleChar, SCC_DKGREEN, 0, std::nullopt, {CmdFlag::DontCount}},
53 {"CREAM", EmitSingleChar, SCC_CREAM, 0, std::nullopt, {CmdFlag::DontCount}},
54 {"BROWN", EmitSingleChar, SCC_BROWN, 0, std::nullopt, {CmdFlag::DontCount}},
55 {"WHITE", EmitSingleChar, SCC_WHITE, 0, std::nullopt, {CmdFlag::DontCount}},
56 {"LTBLUE", EmitSingleChar, SCC_LTBLUE, 0, std::nullopt, {CmdFlag::DontCount}},
57 {"GRAY", EmitSingleChar, SCC_GRAY, 0, std::nullopt, {CmdFlag::DontCount}},
58 {"DKBLUE", EmitSingleChar, SCC_DKBLUE, 0, std::nullopt, {CmdFlag::DontCount}},
59 {"BLACK", EmitSingleChar, SCC_BLACK, 0, std::nullopt, {CmdFlag::DontCount}},
60 {"COLOUR", EmitSingleChar, SCC_COLOUR, 1, std::nullopt, {}},
61 {"PUSH_COLOUR", EmitSingleChar, SCC_PUSH_COLOUR, 0, std::nullopt, {CmdFlag::DontCount}},
62 {"POP_COLOUR", EmitSingleChar, SCC_POP_COLOUR, 0, std::nullopt, {CmdFlag::DontCount}},
63
64 {"REV", EmitSingleChar, SCC_REVISION, 0, std::nullopt, {}}, // openttd revision string
65
66 {"STRING1", EmitSingleChar, SCC_STRING1, 2, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and ONE argument
67 {"STRING2", EmitSingleChar, SCC_STRING2, 3, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and TWO arguments
68 {"STRING3", EmitSingleChar, SCC_STRING3, 4, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and THREE arguments
69 {"STRING4", EmitSingleChar, SCC_STRING4, 5, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and FOUR arguments
70 {"STRING5", EmitSingleChar, SCC_STRING5, 6, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and FIVE arguments
71 {"STRING6", EmitSingleChar, SCC_STRING6, 7, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and SIX arguments
72 {"STRING7", EmitSingleChar, SCC_STRING7, 8, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // included string that consumes the string id and SEVEN arguments
73
74 {"STATION_FEATURES", EmitSingleChar, SCC_STATION_FEATURES, 1, std::nullopt, {}}, // station features string, icons of the features
75 {"INDUSTRY", EmitSingleChar, SCC_INDUSTRY_NAME, 1, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}}, // industry, takes an industry #, can have cases
76 {"CARGO_LONG", EmitSingleChar, SCC_CARGO_LONG, 2, 1, {CmdFlag::Gender}},
77 {"CARGO_SHORT", EmitSingleChar, SCC_CARGO_SHORT, 2, 1, {CmdFlag::Gender}}, // short cargo description, only ### tons, or ### litres
78 {"CARGO_TINY", EmitSingleChar, SCC_CARGO_TINY, 2, 1, {}}, // tiny cargo description with only the amount, not a specifier for the amount or the actual cargo name
79 {"CARGO_LIST", EmitSingleChar, SCC_CARGO_LIST, 1, std::nullopt, {CmdFlag::Case}},
80 {"POWER", EmitSingleChar, SCC_POWER, 1, 0, {}},
81 {"POWER_TO_WEIGHT", EmitSingleChar, SCC_POWER_TO_WEIGHT, 1, 0, {}},
82 {"VOLUME_LONG", EmitSingleChar, SCC_VOLUME_LONG, 1, 0, {}},
83 {"VOLUME_SHORT", EmitSingleChar, SCC_VOLUME_SHORT, 1, 0, {}},
84 {"WEIGHT_LONG", EmitSingleChar, SCC_WEIGHT_LONG, 1, 0, {}},
85 {"WEIGHT_SHORT", EmitSingleChar, SCC_WEIGHT_SHORT, 1, 0, {}},
86 {"FORCE", EmitSingleChar, SCC_FORCE, 1, 0, {}},
87 {"VELOCITY", EmitSingleChar, SCC_VELOCITY, 1, 0, {}},
88 {"HEIGHT", EmitSingleChar, SCC_HEIGHT, 1, 0, {}},
89
90 {"UNITS_DAYS_OR_SECONDS", EmitSingleChar, SCC_UNITS_DAYS_OR_SECONDS, 1, 0, {CmdFlag::Gender}},
91 {"UNITS_MONTHS_OR_MINUTES", EmitSingleChar, SCC_UNITS_MONTHS_OR_MINUTES, 1, 0, {CmdFlag::Gender}},
92 {"UNITS_YEARS_OR_PERIODS", EmitSingleChar, SCC_UNITS_YEARS_OR_PERIODS, 1, 0, {CmdFlag::Gender}},
93 {"UNITS_YEARS_OR_MINUTES", EmitSingleChar, SCC_UNITS_YEARS_OR_MINUTES, 1, 0, {CmdFlag::Gender}},
94
95 {"P", EmitPlural, 0, 0, std::nullopt, {CmdFlag::DontCount}}, // plural specifier
96 {"G", EmitGender, 0, 0, std::nullopt, {CmdFlag::DontCount}}, // gender specifier
97
98 {"DATE_TINY", EmitSingleChar, SCC_DATE_TINY, 1, std::nullopt, {}},
99 {"DATE_SHORT", EmitSingleChar, SCC_DATE_SHORT, 1, std::nullopt, {CmdFlag::Case}},
100 {"DATE_LONG", EmitSingleChar, SCC_DATE_LONG, 1, std::nullopt, {CmdFlag::Case}},
101 {"DATE_ISO", EmitSingleChar, SCC_DATE_ISO, 1, std::nullopt, {}},
102
103 {"STRING", EmitSingleChar, SCC_STRING, 1, std::nullopt, {CmdFlag::Case, CmdFlag::Gender}},
104 {"RAW_STRING", EmitSingleChar, SCC_RAW_STRING_POINTER, 1, std::nullopt, {CmdFlag::Gender}},
105
106 /* Numbers */
107 {"COMMA", EmitSingleChar, SCC_COMMA, 1, 0, {}}, // Number with comma
108 {"DECIMAL", EmitSingleChar, SCC_DECIMAL, 2, 0, {}}, // Number with comma and fractional part. Second parameter is number of fractional digits, first parameter is number times 10**(second parameter).
109 {"NUM", EmitSingleChar, SCC_NUM, 1, 0, {}}, // Signed number
110 {"ZEROFILL_NUM", EmitSingleChar, SCC_ZEROFILL_NUM, 2, 0, {}}, // Unsigned number with zero fill, e.g. "02". First parameter is number, second minimum length
111 {"BYTES", EmitSingleChar, SCC_BYTES, 1, 0, {}}, // Unsigned number with "bytes", i.e. "1.02 MiB or 123 KiB"
112 {"HEX", EmitSingleChar, SCC_HEX, 1, 0, {}}, // Hexadecimally printed number
113
114 {"CURRENCY_LONG", EmitSingleChar, SCC_CURRENCY_LONG, 1, 0, {}},
115 {"CURRENCY_SHORT", EmitSingleChar, SCC_CURRENCY_SHORT, 1, 0, {}}, // compact currency
116
117 {"WAYPOINT", EmitSingleChar, SCC_WAYPOINT_NAME, 1, std::nullopt, {CmdFlag::Gender}}, // waypoint name
118 {"STATION", EmitSingleChar, SCC_STATION_NAME, 1, std::nullopt, {CmdFlag::Gender}},
119 {"DEPOT", EmitSingleChar, SCC_DEPOT_NAME, 2, std::nullopt, {CmdFlag::Gender}},
120 {"TOWN", EmitSingleChar, SCC_TOWN_NAME, 1, std::nullopt, {CmdFlag::Gender}},
121 {"GROUP", EmitSingleChar, SCC_GROUP_NAME, 1, std::nullopt, {CmdFlag::Gender}},
122 {"SIGN", EmitSingleChar, SCC_SIGN_NAME, 1, std::nullopt, {CmdFlag::Gender}},
123 {"ENGINE", EmitSingleChar, SCC_ENGINE_NAME, 1, std::nullopt, {CmdFlag::Gender}},
124 {"VEHICLE", EmitSingleChar, SCC_VEHICLE_NAME, 1, std::nullopt, {CmdFlag::Gender}},
125 {"COMPANY", EmitSingleChar, SCC_COMPANY_NAME, 1, std::nullopt, {CmdFlag::Gender}},
126 {"COMPANY_NUM", EmitSingleChar, SCC_COMPANY_NUM, 1, std::nullopt, {}},
127 {"PRESIDENT_NAME", EmitSingleChar, SCC_PRESIDENT_NAME, 1, std::nullopt, {CmdFlag::Gender}},
128
129 {"SPACE", EmitSingleChar, ' ', 0, std::nullopt, {CmdFlag::DontCount}},
130 {"", EmitSingleChar, '\n', 0, std::nullopt, {CmdFlag::DontCount}},
131 {"{", EmitSingleChar, '{', 0, std::nullopt, {CmdFlag::DontCount}},
132 {"UP_ARROW", EmitSingleChar, SCC_UP_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
133 {"SMALL_UP_ARROW", EmitSingleChar, SCC_SMALL_UP_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
134 {"SMALL_DOWN_ARROW", EmitSingleChar, SCC_SMALL_DOWN_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
135 {"TRAIN", EmitSingleChar, SCC_TRAIN, 0, std::nullopt, {CmdFlag::DontCount}},
136 {"LORRY", EmitSingleChar, SCC_LORRY, 0, std::nullopt, {CmdFlag::DontCount}},
137 {"BUS", EmitSingleChar, SCC_BUS, 0, std::nullopt, {CmdFlag::DontCount}},
138 {"PLANE", EmitSingleChar, SCC_PLANE, 0, std::nullopt, {CmdFlag::DontCount}},
139 {"SHIP", EmitSingleChar, SCC_SHIP, 0, std::nullopt, {CmdFlag::DontCount}},
140 {"NBSP", EmitSingleChar, 0xA0, 0, std::nullopt, {CmdFlag::DontCount}},
141 {"COPYRIGHT", EmitSingleChar, 0xA9, 0, std::nullopt, {CmdFlag::DontCount}},
142 {"DOWN_ARROW", EmitSingleChar, SCC_DOWN_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
143 {"CHECKMARK", EmitSingleChar, SCC_CHECKMARK, 0, std::nullopt, {CmdFlag::DontCount}},
144 {"CROSS", EmitSingleChar, SCC_CROSS, 0, std::nullopt, {CmdFlag::DontCount}},
145 {"LEFT_ARROW", EmitSingleChar, SCC_LEFT_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
146 {"RIGHT_ARROW", EmitSingleChar, SCC_RIGHT_ARROW, 0, std::nullopt, {CmdFlag::DontCount}},
147 {"SMALL_LEFT_ARROW", EmitSingleChar, SCC_LESS_THAN, 0, std::nullopt, {CmdFlag::DontCount}},
148 {"SMALL_RIGHT_ARROW", EmitSingleChar, SCC_GREATER_THAN, 0, std::nullopt, {CmdFlag::DontCount}},
149 {"TOWN_ICON", EmitSingleChar, SCC_TOWN, 0, std::nullopt, {CmdFlag::DontCount}},
150 {"CITY_ICON", EmitSingleChar, SCC_CITY, 0, std::nullopt, {CmdFlag::DontCount}},
151
152 /* The following are directional formatting codes used to get the RTL strings right:
153 * http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */
154 {"LRM", EmitSingleChar, CHAR_TD_LRM, 0, std::nullopt, {CmdFlag::DontCount}},
155 {"RLM", EmitSingleChar, CHAR_TD_RLM, 0, std::nullopt, {CmdFlag::DontCount}},
156 {"LRE", EmitSingleChar, CHAR_TD_LRE, 0, std::nullopt, {CmdFlag::DontCount}},
157 {"RLE", EmitSingleChar, CHAR_TD_RLE, 0, std::nullopt, {CmdFlag::DontCount}},
158 {"LRO", EmitSingleChar, CHAR_TD_LRO, 0, std::nullopt, {CmdFlag::DontCount}},
159 {"RLO", EmitSingleChar, CHAR_TD_RLO, 0, std::nullopt, {CmdFlag::DontCount}},
160 {"PDF", EmitSingleChar, CHAR_TD_PDF, 0, std::nullopt, {CmdFlag::DontCount}},
161};
162
164 struct PluralForm {
165 size_t plural_count;
166 std::string_view description;
167 std::string_view names;
168};
169
171 static const size_t MAX_PLURALS = 5;
172
174 static const PluralForm _plural_forms[] = {
175 { 2, "Two forms: special case for 1.", "\"1\" \"other\"" },
176 { 1, "Only one form.", "\"other\"" },
177 { 2, "Two forms: special case for 0 to 1.", "\"0..1\" \"other\"" },
178 { 3, "Three forms: special cases for 0, and numbers ending in 1 except when ending in 11.", "\"1,21,31,...\" \"other\" \"0\"" },
179 { 5, "Five forms: special cases for 1, 2, 3 to 6, and 7 to 10.", "\"1\" \"2\" \"3..6\" \"7..10\" \"other\"" },
180 { 3, "Three forms: special cases for numbers ending in 1 except when ending in 11, and 2 to 9 except when ending in 12 to 19.", "\"1,21,31,...\" \"2..9,22..29,32..39,...\" \"other\"" },
181 { 3, "Three forms: special cases for numbers ending in 1 except when ending in 11, and 2 to 4 except when ending in 12 to 14.", "\"1,21,31,...\" \"2..4,22..24,32..34,...\" \"other\"" },
182 { 3, "Three forms: special cases for 1, and numbers ending in 2 to 4 except when ending in 12 to 14.", "\"1\" \"2..4,22..24,32..34,...\" \"other\"" },
183 { 4, "Four forms: special cases for numbers ending in 01, 02, and 03 to 04.", "\"1,101,201,...\" \"2,102,202,...\" \"3..4,103..104,203..204,...\" \"other\"" },
184 { 2, "Two forms: special case for numbers ending in 1 except when ending in 11.", "\"1,21,31,...\" \"other\"" },
185 { 3, "Three forms: special cases for 1, and 2 to 4.", "\"1\" \"2..4\" \"other\"" },
186 { 2, "Two forms: cases for numbers ending with a consonant, and with a vowel.", "\"yeong,il,sam,yuk,chil,pal\" \"i,sa,o,gu\"" },
187 { 4, "Four forms: special cases for 1, 0 and numbers ending in 02 to 10, and numbers ending in 11 to 19.", "\"1\" \"0,2..10,102..110,202..210,...\" \"11..19,111..119,211..219,...\" \"other\"" },
188 { 4, "Four forms: special cases for 1 and 11, 2 and 12, 3..10 and 13..19.", "\"1,11\" \"2,12\" \"3..10,13..19\" \"other\"" },
189 { 3, "Three forms: special cases for 1, 0 and numbers ending in 01 to 19.", "\"1\" \"0,2..19,101..119,201..219,...\" \"other\"" },
190};
191
192/* Flags:
193 * 0 = nothing
194 * t = translator editable
195 * l = ltr/rtl choice
196 * p = plural choice
197 * d = separator char (replace spaces with {NBSP})
198 * x1 = hexadecimal number of 1 byte
199 * x2 = hexadecimal number of 2 bytes
200 * g = gender
201 * c = cases
202 * a = array, i.e. list of strings
203 */
205 static const std::string_view _pragmas[][4] = {
206 /* name flags default description */
207 { "name", "0", "", "English name for the language" },
208 { "ownname", "t", "", "Localised name for the language" },
209 { "isocode", "0", "", "ISO code for the language" },
210 { "plural", "tp", "0", "Plural form to use" },
211 { "textdir", "tl", "ltr", "Text direction. Either ltr (left-to-right) or rtl (right-to-left)" },
212 { "digitsep", "td", ",", "Digit grouping separator for non-currency numbers" },
213 { "digitsepcur", "td", ",", "Digit grouping separator for currency numbers" },
214 { "decimalsep", "td", ".", "Decimal separator" },
215 { "winlangid", "x2", "0x0000", "Language ID for Windows" },
216 { "grflangid", "x1", "0x00", "Language ID for NewGRFs" },
217 { "gender", "tag", "", "List of genders" },
218 { "case", "tac", "", "List of cases" },
219};
EnumBitSet< CmdFlag, uint8_t >
StringBuilder
Compose data into a growing std::string.
Definition string_builder.hpp:65
SCC_TINYFONT
@ SCC_TINYFONT
Switch to small font.
Definition control_codes.h:35
SCC_NORMALFONT
@ SCC_NORMALFONT
Switch to normal size font.
Definition control_codes.h:34
SCC_BIGFONT
@ SCC_BIGFONT
Switch to large font.
Definition control_codes.h:36
SCC_MONOFONT
@ SCC_MONOFONT
Switch to monospaced font.
Definition control_codes.h:37
_pragmas
static const std::string_view _pragmas[][4]
All pragmas used.
Definition strgen_tables.h:205
_plural_forms
static const PluralForm _plural_forms[]
All plural forms used.
Definition strgen_tables.h:174
MAX_PLURALS
static const size_t MAX_PLURALS
The maximum number of plurals.
Definition strgen_tables.h:171
CmdFlag
CmdFlag
Definition strgen_tables.h:12
CmdFlag::Gender
@ Gender
These commands support genders.
CmdFlag::Case
@ Case
These commands support cases.
CmdFlag::DontCount
@ DontCount
These commands aren't counted for comparison.
CHAR_TD_RLE
static const char32_t CHAR_TD_RLE
The following text is embedded right-to-left.
Definition string_type.h:38
CHAR_TD_LRO
static const char32_t CHAR_TD_LRO
Force the following characters to be treated as left-to-right characters.
Definition string_type.h:39
CHAR_TD_LRM
static const char32_t CHAR_TD_LRM
The next character acts like a left-to-right character.
Definition string_type.h:35
CHAR_TD_RLO
static const char32_t CHAR_TD_RLO
Force the following characters to be treated as right-to-left characters.
Definition string_type.h:40
CHAR_TD_LRE
static const char32_t CHAR_TD_LRE
The following text is embedded left-to-right.
Definition string_type.h:37
CHAR_TD_RLM
static const char32_t CHAR_TD_RLM
The next character acts like a right-to-left character.
Definition string_type.h:36
CHAR_TD_PDF
static const char32_t CHAR_TD_PDF
Restore the text-direction state to before the last LRE, RLE, LRO or RLO.
Definition string_type.h:41
CmdStruct
Definition strgen_tables.h:22
PluralForm
Description of a plural form.
Definition strgen_tables.h:164
PluralForm::plural_count
size_t plural_count
The number of plural forms.
Definition strgen_tables.h:165
PluralForm::names
std::string_view names
Plural names.
Definition strgen_tables.h:167
PluralForm::description
std::string_view description
Human readable description of the form.
Definition strgen_tables.h:166