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