OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

strgen_tables.h
Go to the documentation of this file.
1 /* $Id: strgen_tables.h 27295 2015-05-28 17:26:53Z frosch $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #include "../core/enum_type.hpp"
13
14 enum CmdFlags {
15 C_NONE = 0x0,
16 C_DONTCOUNT = 0x1,
17 C_CASE = 0x2,
18 C_GENDER = 0x4,
19 };
20 DECLARE_ENUM_AS_BIT_SET(CmdFlags)
21
22 struct Buffer;
23 typedef void (*ParseCmdProc)(Buffer *buffer, char *buf, int value);
24
25 struct CmdStruct {
26 const char *cmd;
27 ParseCmdProc proc;
28 long value;
29 uint8 consumes;
30 int8 default_plural_offset;
31 CmdFlags flags;
32 };
33
34 extern void EmitSingleChar(Buffer *buffer, char *buf, int value);
35 extern void EmitPlural(Buffer *buffer, char *buf, int value);
36 extern void EmitGender(Buffer *buffer, char *buf, int value);
37
38 static const CmdStruct _cmd_structs[] = {
39 /* Font size */
40 {"TINY_FONT", EmitSingleChar, SCC_TINYFONT, 0, -1, C_NONE},
41 {"BIG_FONT", EmitSingleChar, SCC_BIGFONT, 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
62 {"REV", EmitSingleChar, SCC_REVISION, 0, -1, C_NONE}, // openttd revision string
63
64 {"STRING1", EmitSingleChar, SCC_STRING1, 2, -1, C_CASE | C_GENDER}, // included string that consumes the string id and ONE argument
65 {"STRING2", EmitSingleChar, SCC_STRING2, 3, -1, C_CASE | C_GENDER}, // included string that consumes the string id and TWO arguments
66 {"STRING3", EmitSingleChar, SCC_STRING3, 4, -1, C_CASE | C_GENDER}, // included string that consumes the string id and THREE arguments
67 {"STRING4", EmitSingleChar, SCC_STRING4, 5, -1, C_CASE | C_GENDER}, // included string that consumes the string id and FOUR arguments
68 {"STRING5", EmitSingleChar, SCC_STRING5, 6, -1, C_CASE | C_GENDER}, // included string that consumes the string id and FIVE arguments
69 {"STRING6", EmitSingleChar, SCC_STRING6, 7, -1, C_CASE | C_GENDER}, // included string that consumes the string id and SIX arguments
70 {"STRING7", EmitSingleChar, SCC_STRING7, 8, -1, C_CASE | C_GENDER}, // included string that consumes the string id and SEVEN arguments
71
72 {"STATION_FEATURES", EmitSingleChar, SCC_STATION_FEATURES, 1, -1, C_NONE}, // station features string, icons of the features
73 {"INDUSTRY", EmitSingleChar, SCC_INDUSTRY_NAME, 1, -1, C_CASE | C_GENDER}, // industry, takes an industry #, can have cases
74 {"CARGO_LONG", EmitSingleChar, SCC_CARGO_LONG, 2, 1, C_NONE | C_GENDER},
75 {"CARGO_SHORT", EmitSingleChar, SCC_CARGO_SHORT, 2, 1, C_NONE}, // short cargo description, only ### tons, or ### litres
76 {"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
77 {"CARGO_LIST", EmitSingleChar, SCC_CARGO_LIST, 1, -1, C_CASE},
78 {"POWER", EmitSingleChar, SCC_POWER, 1, 0, C_NONE},
79 {"VOLUME_LONG", EmitSingleChar, SCC_VOLUME_LONG, 1, 0, C_NONE},
80 {"VOLUME_SHORT", EmitSingleChar, SCC_VOLUME_SHORT, 1, 0, C_NONE},
81 {"WEIGHT_LONG", EmitSingleChar, SCC_WEIGHT_LONG, 1, 0, C_NONE},
82 {"WEIGHT_SHORT", EmitSingleChar, SCC_WEIGHT_SHORT, 1, 0, C_NONE},
83 {"FORCE", EmitSingleChar, SCC_FORCE, 1, 0, C_NONE},
84 {"VELOCITY", EmitSingleChar, SCC_VELOCITY, 1, 0, C_NONE},
85 {"HEIGHT", EmitSingleChar, SCC_HEIGHT, 1, 0, C_NONE},
86
87 {"P", EmitPlural, 0, 0, -1, C_DONTCOUNT}, // plural specifier
88 {"G", EmitGender, 0, 0, -1, C_DONTCOUNT}, // gender specifier
89
90 {"DATE_TINY", EmitSingleChar, SCC_DATE_TINY, 1, -1, C_NONE},
91 {"DATE_SHORT", EmitSingleChar, SCC_DATE_SHORT, 1, -1, C_CASE},
92 {"DATE_LONG", EmitSingleChar, SCC_DATE_LONG, 1, -1, C_CASE},
93 {"DATE_ISO", EmitSingleChar, SCC_DATE_ISO, 1, -1, C_NONE},
94
95 {"STRING", EmitSingleChar, SCC_STRING, 1, -1, C_CASE | C_GENDER},
96 {"RAW_STRING", EmitSingleChar, SCC_RAW_STRING_POINTER, 1, -1, C_NONE | C_GENDER},
97
98 /* Numbers */
99 {"COMMA", EmitSingleChar, SCC_COMMA, 1, 0, C_NONE}, // Number with comma
100 {"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).
101 {"NUM", EmitSingleChar, SCC_NUM, 1, 0, C_NONE}, // Signed number
102 {"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
103 {"BYTES", EmitSingleChar, SCC_BYTES, 1, 0, C_NONE}, // Unsigned number with "bytes", i.e. "1.02 MiB or 123 KiB"
104 {"HEX", EmitSingleChar, SCC_HEX, 1, 0, C_NONE}, // Hexadecimally printed number
105
106 {"CURRENCY_LONG", EmitSingleChar, SCC_CURRENCY_LONG, 1, 0, C_NONE},
107 {"CURRENCY_SHORT", EmitSingleChar, SCC_CURRENCY_SHORT, 1, 0, C_NONE}, // compact currency
108
109 {"WAYPOINT", EmitSingleChar, SCC_WAYPOINT_NAME, 1, -1, C_NONE | C_GENDER}, // waypoint name
110 {"STATION", EmitSingleChar, SCC_STATION_NAME, 1, -1, C_NONE | C_GENDER},
111 {"DEPOT", EmitSingleChar, SCC_DEPOT_NAME, 2, -1, C_NONE | C_GENDER},
112 {"TOWN", EmitSingleChar, SCC_TOWN_NAME, 1, -1, C_NONE | C_GENDER},
113 {"GROUP", EmitSingleChar, SCC_GROUP_NAME, 1, -1, C_NONE | C_GENDER},
114 {"SIGN", EmitSingleChar, SCC_SIGN_NAME, 1, -1, C_NONE | C_GENDER},
115 {"ENGINE", EmitSingleChar, SCC_ENGINE_NAME, 1, -1, C_NONE | C_GENDER},
116 {"VEHICLE", EmitSingleChar, SCC_VEHICLE_NAME, 1, -1, C_NONE | C_GENDER},
117 {"COMPANY", EmitSingleChar, SCC_COMPANY_NAME, 1, -1, C_NONE | C_GENDER},
118 {"COMPANY_NUM", EmitSingleChar, SCC_COMPANY_NUM, 1, -1, C_NONE},
119 {"PRESIDENT_NAME", EmitSingleChar, SCC_PRESIDENT_NAME, 1, -1, C_NONE | C_GENDER},
120
121 {"", EmitSingleChar, '\n', 0, -1, C_DONTCOUNT},
122 {"{", EmitSingleChar, '{', 0, -1, C_DONTCOUNT},
123 {"UP_ARROW", EmitSingleChar, SCC_UP_ARROW, 0, -1, C_DONTCOUNT},
124 {"SMALL_UP_ARROW", EmitSingleChar, SCC_SMALL_UP_ARROW, 0, -1, C_DONTCOUNT},
125 {"SMALL_DOWN_ARROW", EmitSingleChar, SCC_SMALL_DOWN_ARROW, 0, -1, C_DONTCOUNT},
126 {"TRAIN", EmitSingleChar, SCC_TRAIN, 0, -1, C_DONTCOUNT},
127 {"LORRY", EmitSingleChar, SCC_LORRY, 0, -1, C_DONTCOUNT},
128 {"BUS", EmitSingleChar, SCC_BUS, 0, -1, C_DONTCOUNT},
129 {"PLANE", EmitSingleChar, SCC_PLANE, 0, -1, C_DONTCOUNT},
130 {"SHIP", EmitSingleChar, SCC_SHIP, 0, -1, C_DONTCOUNT},
131 {"NBSP", EmitSingleChar, 0xA0, 0, -1, C_DONTCOUNT},
132 {"COPYRIGHT", EmitSingleChar, 0xA9, 0, -1, C_DONTCOUNT},
133 {"DOWN_ARROW", EmitSingleChar, SCC_DOWN_ARROW, 0, -1, C_DONTCOUNT},
134 {"CHECKMARK", EmitSingleChar, SCC_CHECKMARK, 0, -1, C_DONTCOUNT},
135 {"CROSS", EmitSingleChar, SCC_CROSS, 0, -1, C_DONTCOUNT},
136 {"RIGHT_ARROW", EmitSingleChar, SCC_RIGHT_ARROW, 0, -1, C_DONTCOUNT},
137 {"SMALL_LEFT_ARROW", EmitSingleChar, SCC_LESS_THAN, 0, -1, C_DONTCOUNT},
138 {"SMALL_RIGHT_ARROW", EmitSingleChar, SCC_GREATER_THAN, 0, -1, C_DONTCOUNT},
139
140 /* The following are directional formatting codes used to get the RTL strings right:
141 * http://www.unicode.org/unicode/reports/tr9/#Directional_Formatting_Codes */
142 {"LRM", EmitSingleChar, CHAR_TD_LRM, 0, -1, C_DONTCOUNT},
143 {"RLM", EmitSingleChar, CHAR_TD_RLM, 0, -1, C_DONTCOUNT},
144 {"LRE", EmitSingleChar, CHAR_TD_LRE, 0, -1, C_DONTCOUNT},
145 {"RLE", EmitSingleChar, CHAR_TD_RLE, 0, -1, C_DONTCOUNT},
146 {"LRO", EmitSingleChar, CHAR_TD_LRO, 0, -1, C_DONTCOUNT},
147 {"RLO", EmitSingleChar, CHAR_TD_RLO, 0, -1, C_DONTCOUNT},
148 {"PDF", EmitSingleChar, CHAR_TD_PDF, 0, -1, C_DONTCOUNT},
149 };
150
152 struct PluralForm {
153 int plural_count;
154 const char *description;
155 const char *names;
156 };
157
159 static const int MAX_PLURALS = 5;
160
162 static const PluralForm _plural_forms[] = {
163 { 2, "Two forms: special case for 1.", "\"1\" \"other\"" },
164 { 1, "Only one form.", "\"other\"" },
165 { 2, "Two forms: special case for 0 to 1.", "\"0..1\" \"other\"" },
166 { 3, "Three forms: special cases for 0, and numbers ending in 1 except when ending in 11.", "\"1,21,31,...\" \"other\" \"0\"" },
167 { 5, "Five forms: special cases for 1, 2, 3 to 6, and 7 to 10.", "\"1\" \"2\" \"3..6\" \"7..10\" \"other\"" },
168 { 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\"" },
169 { 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\"" },
170 { 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\"" },
171 { 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\"" },
172 { 2, "Two forms: special case for numbers ending in 1 except when ending in 11.", "\"1,21,31,...\" \"other\"" },
173 { 3, "Three forms: special cases for 1, and 2 to 4.", "\"1\" \"2..4\" \"other\"" },
174 { 2, "Two forms: cases for numbers ending with a consonant, and with a vowel.", "\"yeong,il,sam,yuk,chil,pal\" \"i,sa,o,gu\"" },
175 { 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\"" },
176 { 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\"" },
177 };
178
179 /* Flags:
180 * 0 = nothing
181 * t = translator editable
182 * l = ltr/rtl choice
183 * p = plural choice
184 * d = separator char (replace spaces with {NBSP})
185 * x1 = hexadecimal number of 1 byte
186 * x2 = hexadecimal number of 2 bytes
187 * g = gender
188 * c = cases
189 * a = array, i.e. list of strings
190 */
192 static const char * const _pragmas[][4] = {
193 /* name flags default description */
194 { "name", "0", "", "English name for the language" },
195 { "ownname", "t", "", "Localised name for the language" },
196 { "isocode", "0", "", "ISO code for the language" },
197 { "plural", "tp", "0", "Plural form to use" },
198 { "textdir", "tl", "ltr", "Text direction. Either ltr (left-to-right) or rtl (right-to-left)" },
199 { "digitsep", "td", ",", "Digit grouping separator for non-currency numbers" },
200 { "digitsepcur", "td", ",", "Digit grouping separator for currency numbers" },
201 { "decimalsep", "td", ".", "Decimal separator" },
202 { "winlangid", "x2", "0x0000", "Language ID for Windows" },
203 { "grflangid", "x1", "0x00", "Language ID for NewGRFs" },
204 { "gender", "tag", "", "List of genders" },
205 { "case", "tac", "", "List of cases" },
206 };