strgen/strgen.c
changeset 2765 8fa792b6e525
parent 2586 1c0f0b67a70d
child 2904 1075bac76b72
equal deleted inserted replaced
2764:f819d0b46f5f 2765:8fa792b6e525
   330 	}
   330 	}
   331 
   331 
   332 	if (nw == 0)
   332 	if (nw == 0)
   333 		Fatal("%s: No plural words", _cur_ident);
   333 		Fatal("%s: No plural words", _cur_ident);
   334 
   334 
   335 	if (_plural_form_counts[_lang_pluralform] != nw)
   335 	if (_plural_form_counts[_lang_pluralform] != nw) {
   336 		if (_translated) {
   336 		if (_translated) {
   337 			Fatal("%s: Invalid number of plural forms. Expecting %d, found %d.", _cur_ident,
   337 			Fatal("%s: Invalid number of plural forms. Expecting %d, found %d.", _cur_ident,
   338 				_plural_form_counts[_lang_pluralform], nw);
   338 				_plural_form_counts[_lang_pluralform], nw);
   339 		} else {
   339 		} else {
   340 			Warning("'%s' is untranslated. Tweaking english string to allow compilation for plural forms", _cur_ident);
   340 			Warning("'%s' is untranslated. Tweaking english string to allow compilation for plural forms", _cur_ident);
   344 				for(; nw < _plural_form_counts[_lang_pluralform]; nw++) {
   344 				for(; nw < _plural_form_counts[_lang_pluralform]; nw++) {
   345 					words[nw] = words[nw - 1];
   345 					words[nw] = words[nw - 1];
   346 				}
   346 				}
   347 			}
   347 			}
   348 		}
   348 		}
       
   349 	}
   349 
   350 
   350 	PutByte(0x8D);
   351 	PutByte(0x8D);
   351 	PutByte(TranslateArgumentIdx(argidx));
   352 	PutByte(TranslateArgumentIdx(argidx));
   352 	EmitWordList(words, nw);
   353 	EmitWordList(words, nw);
   353 }
   354 }
   392 }
   393 }
   393 
   394 
   394 
   395 
   395 static const CmdStruct _cmd_structs[] = {
   396 static const CmdStruct _cmd_structs[] = {
   396 	// Update position
   397 	// Update position
   397 	{"SETX", EmitSetX, 1, 0},
   398 	{"SETX",  EmitSetX,  1, 0, 0},
   398 	{"SETXY", EmitSetXY, 2, 0},
   399 	{"SETXY", EmitSetXY, 2, 0, 0},
   399 
   400 
   400 	// Font size
   401 	// Font size
   401 	{"TINYFONT", EmitSingleByte, 8, 0},
   402 	{"TINYFONT", EmitSingleByte, 8, 0, 0},
   402 	{"BIGFONT", EmitSingleByte, 9, 0},
   403 	{"BIGFONT",  EmitSingleByte, 9, 0, 0},
   403 
   404 
   404 	// New line
   405 	// New line
   405 	{"", EmitSingleByte, 10, 0, C_DONTCOUNT},
   406 	{"", EmitSingleByte, 10, 0, C_DONTCOUNT},
   406 
   407 
   407 	{"{", EmitSingleByte, '{', 0, C_DONTCOUNT},
   408 	{"{", EmitSingleByte, '{', 0, C_DONTCOUNT},
   408 
   409 
   409 	// Colors
   410 	// Colors
   410 	{"BLUE", EmitSingleByte,    15, 0},
   411 	{"BLUE",    EmitSingleByte, 15, 0, 0},
   411 	{"SILVER", EmitSingleByte,  16, 0},
   412 	{"SILVER",  EmitSingleByte, 16, 0, 0},
   412 	{"GOLD", EmitSingleByte,    17, 0},
   413 	{"GOLD",    EmitSingleByte, 17, 0, 0},
   413 	{"RED", EmitSingleByte,     18, 0},
   414 	{"RED",     EmitSingleByte, 18, 0, 0},
   414 	{"PURPLE", EmitSingleByte,  19, 0},
   415 	{"PURPLE",  EmitSingleByte, 19, 0, 0},
   415 	{"LTBROWN", EmitSingleByte, 20, 0},
   416 	{"LTBROWN", EmitSingleByte, 20, 0, 0},
   416 	{"ORANGE", EmitSingleByte,  21, 0},
   417 	{"ORANGE",  EmitSingleByte, 21, 0, 0},
   417 	{"GREEN", EmitSingleByte,   22, 0},
   418 	{"GREEN",   EmitSingleByte, 22, 0, 0},
   418 	{"YELLOW", EmitSingleByte,  23, 0},
   419 	{"YELLOW",  EmitSingleByte, 23, 0, 0},
   419 	{"DKGREEN", EmitSingleByte, 24, 0},
   420 	{"DKGREEN", EmitSingleByte, 24, 0, 0},
   420 	{"CREAM", EmitSingleByte,   25, 0},
   421 	{"CREAM",   EmitSingleByte, 25, 0, 0},
   421 	{"BROWN", EmitSingleByte,   26, 0},
   422 	{"BROWN",   EmitSingleByte, 26, 0, 0},
   422 	{"WHITE", EmitSingleByte,   27, 0},
   423 	{"WHITE",   EmitSingleByte, 27, 0, 0},
   423 	{"LTBLUE", EmitSingleByte,  28, 0},
   424 	{"LTBLUE",  EmitSingleByte, 28, 0, 0},
   424 	{"GRAY", EmitSingleByte,    29, 0},
   425 	{"GRAY",    EmitSingleByte, 29, 0, 0},
   425 	{"DKBLUE", EmitSingleByte,  30, 0},
   426 	{"DKBLUE",  EmitSingleByte, 30, 0, 0},
   426 	{"BLACK", EmitSingleByte,   31, 0},
   427 	{"BLACK",   EmitSingleByte, 31, 0, 0},
   427 
   428 
   428 	// 0x85
   429 	// 0x85
   429 	{"CURRCOMPACT", EmitEscapedByte, 0, 1},		// compact currency (32 bits)
   430 	{"CURRCOMPACT",   EmitEscapedByte, 0, 1, 0}, // compact currency (32 bits)
   430 	{"REV", EmitEscapedByte, 2, 0},						// openttd revision string
   431 	{"REV",           EmitEscapedByte, 2, 0, 0}, // openttd revision string
   431 	{"SHORTCARGO", EmitEscapedByte, 3, 2},		// short cargo description, only ### tons, or ### litres
   432 	{"SHORTCARGO",    EmitEscapedByte, 3, 2, 0}, // short cargo description, only ### tons, or ### litres
   432 	{"CURRCOMPACT64", EmitEscapedByte, 4, 2},	// compact currency 64 bits
   433 	{"CURRCOMPACT64", EmitEscapedByte, 4, 2, 0}, // compact currency 64 bits
   433 
   434 
   434 	{"COMPANY", EmitEscapedByte, 5, 1},				// company string. This is actually a {STRING1}
   435 	{"COMPANY", EmitEscapedByte, 5, 1, 0},				// company string. This is actually a {STRING1}
   435 																						// The first string includes the second string.
   436 																						// The first string includes the second string.
   436 
   437 
   437 	{"PLAYERNAME", EmitEscapedByte, 5, 1},		// playername string. This is actually a {STRING1}
   438 	{"PLAYERNAME", EmitEscapedByte, 5, 1, 0},		// playername string. This is actually a {STRING1}
   438 																						// The first string includes the second string.
   439 																						// The first string includes the second string.
   439 
   440 
   440 	{"VEHICLE", EmitEscapedByte, 5, 1},		// playername string. This is actually a {STRING1}
   441 	{"VEHICLE", EmitEscapedByte, 5, 1, 0},		// playername string. This is actually a {STRING1}
   441 																						// The first string includes the second string.
   442 																						// The first string includes the second string.
   442 
   443 
   443 
   444 
   444 	{"STRING1", EmitEscapedByte, 5, 1, C_CASE},				// included string that consumes ONE argument
   445 	{"STRING1", EmitEscapedByte, 5, 1, C_CASE},				// included string that consumes ONE argument
   445 	{"STRING2", EmitEscapedByte, 6, 2, C_CASE},				// included string that consumes TWO arguments
   446 	{"STRING2", EmitEscapedByte, 6, 2, C_CASE},				// included string that consumes TWO arguments
   446 	{"STRING3", EmitEscapedByte, 7, 3, C_CASE},				// included string that consumes THREE arguments
   447 	{"STRING3", EmitEscapedByte, 7, 3, C_CASE},				// included string that consumes THREE arguments
   447 	{"STRING4", EmitEscapedByte, 8, 4, C_CASE},				// included string that consumes FOUR arguments
   448 	{"STRING4", EmitEscapedByte, 8, 4, C_CASE},				// included string that consumes FOUR arguments
   448 	{"STRING5", EmitEscapedByte, 9, 5, C_CASE},				// included string that consumes FIVE arguments
   449 	{"STRING5", EmitEscapedByte, 9, 5, C_CASE},				// included string that consumes FIVE arguments
   449 
   450 
   450 	{"STATIONFEATURES", EmitEscapedByte, 10, 1},				// station features string, icons of the features
   451 	{"STATIONFEATURES", EmitEscapedByte, 10, 1, 0}, // station features string, icons of the features
   451 	{"INDUSTRY", EmitEscapedByte, 11, 1},			// industry, takes an industry #
   452 	{"INDUSTRY",        EmitEscapedByte, 11, 1, 0}, // industry, takes an industry #
   452 	{"VOLUME", EmitEscapedByte, 12, 1},
   453 	{"VOLUME",          EmitEscapedByte, 12, 1, 0},
   453 	{"DATE_TINY", EmitEscapedByte, 14, 1},
   454 	{"DATE_TINY",       EmitEscapedByte, 14, 1, 0},
   454 	{"CARGO", EmitEscapedByte, 15, 2},
   455 	{"CARGO",           EmitEscapedByte, 15, 2, 0},
   455 
   456 
   456 	{"P", EmitPlural, 0, 0, C_DONTCOUNT},					// plural specifier
   457 	{"P", EmitPlural, 0, 0, C_DONTCOUNT},					// plural specifier
   457 	{"G", EmitGender, 0, 0, C_DONTCOUNT},					// gender specifier
   458 	{"G", EmitGender, 0, 0, C_DONTCOUNT},					// gender specifier
   458 
   459 
   459 	{"DATE_LONG", EmitSingleByte, 0x82, 1},
   460 	{"DATE_LONG",  EmitSingleByte, 0x82, 1, 0},
   460 	{"DATE_SHORT", EmitSingleByte, 0x83, 1},
   461 	{"DATE_SHORT", EmitSingleByte, 0x83, 1, 0},
   461 
   462 
   462 	{"VELOCITY", EmitSingleByte, 0x84, 1},
   463 	{"VELOCITY", EmitSingleByte, 0x84, 1, 0},
   463 
   464 
   464 	{"SKIP", EmitSingleByte, 0x86, 1},
   465 	{"SKIP", EmitSingleByte, 0x86, 1, 0},
   465 
   466 
   466 	{"STRING", EmitSingleByte, 0x88, 1, C_CASE},
   467 	{"STRING", EmitSingleByte, 0x88, 1, C_CASE},
   467 
   468 
   468 	// Numbers
   469 	// Numbers
   469 	{"COMMA", EmitSingleByte, 0x8B, 1}, // Number with comma
   470 	{"COMMA", EmitSingleByte, 0x8B, 1, 0}, // Number with comma
   470 	{"NUM",   EmitSingleByte, 0x8E, 1}, // Signed number
   471 	{"NUM",   EmitSingleByte, 0x8E, 1, 0}, // Signed number
   471 
   472 
   472 	{"CURRENCY", EmitSingleByte, 0x8F, 1},
   473 	{"CURRENCY", EmitSingleByte, 0x8F, 1, 0},
   473 
   474 
   474 	{"WAYPOINT", EmitSingleByte, 0x99, 1}, // waypoint name
   475 	{"WAYPOINT",   EmitSingleByte, 0x99, 1, 0}, // waypoint name
   475 	{"STATION", EmitSingleByte, 0x9A, 1},
   476 	{"STATION",    EmitSingleByte, 0x9A, 1, 0},
   476 	{"TOWN", EmitSingleByte, 0x9B, 1},
   477 	{"TOWN",       EmitSingleByte, 0x9B, 1, 0},
   477 	{"CURRENCY64", EmitSingleByte, 0x9C, 2},
   478 	{"CURRENCY64", EmitSingleByte, 0x9C, 2, 0},
   478 	// 0x9D is used for the pseudo command SETCASE
   479 	// 0x9D is used for the pseudo command SETCASE
   479 	// 0x9E is used for case switching
   480 	// 0x9E is used for case switching
   480 
   481 
   481 	// 0x9E=158 is the LAST special character we may use.
   482 	// 0x9E=158 is the LAST special character we may use.
   482 
   483 
   483 	{"UPARROW", EmitSingleByte, 0x80, 0},
   484 	{"UPARROW", EmitSingleByte, 0x80, 0, 0},
   484 
   485 
   485 	{"NBSP", EmitSingleByte, 0xA0, 0, C_DONTCOUNT},
   486 	{"NBSP",       EmitSingleByte, 0xA0, 0, C_DONTCOUNT},
   486 	{"POUNDSIGN", EmitSingleByte, 0xA3, 0},
   487 	{"POUNDSIGN",  EmitSingleByte, 0xA3, 0, 0},
   487 	{"YENSIGN", EmitSingleByte, 0xA5, 0},
   488 	{"YENSIGN",    EmitSingleByte, 0xA5, 0, 0},
   488 	{"COPYRIGHT", EmitSingleByte, 0xA9, 0},
   489 	{"COPYRIGHT",  EmitSingleByte, 0xA9, 0, 0},
   489 	{"DOWNARROW", EmitSingleByte, 0xAA, 0},
   490 	{"DOWNARROW",  EmitSingleByte, 0xAA, 0, 0},
   490 	{"CHECKMARK", EmitSingleByte, 0xAC, 0},
   491 	{"CHECKMARK",  EmitSingleByte, 0xAC, 0, 0},
   491 	{"CROSS", EmitSingleByte, 0xAD, 0},
   492 	{"CROSS",      EmitSingleByte, 0xAD, 0, 0},
   492 	{"RIGHTARROW", EmitSingleByte, 0xAF, 0},
   493 	{"RIGHTARROW", EmitSingleByte, 0xAF, 0, 0},
   493 
   494 
   494 	{"TRAIN", EmitSingleByte, 0x94, 0},
   495 	{"TRAIN", EmitSingleByte, 0x94, 0, 0},
   495 	{"LORRY", EmitSingleByte, 0x95, 0},
   496 	{"LORRY", EmitSingleByte, 0x95, 0, 0},
   496 	{"BUS",   EmitSingleByte, 0x96, 0},
   497 	{"BUS",   EmitSingleByte, 0x96, 0, 0},
   497 	{"PLANE", EmitSingleByte, 0x97, 0},
   498 	{"PLANE", EmitSingleByte, 0x97, 0, 0},
   498 	{"SHIP",  EmitSingleByte, 0x98, 0},
   499 	{"SHIP",  EmitSingleByte, 0x98, 0, 0},
   499 
   500 
   500 	{"SMALLUPARROW", EmitSingleByte, 0x90, 0},
   501 	{"SMALLUPARROW",   EmitSingleByte, 0x90, 0, 0},
   501 	{"SMALLDOWNARROW", EmitSingleByte, 0x91, 0},
   502 	{"SMALLDOWNARROW", EmitSingleByte, 0x91, 0, 0}
   502 };
   503 };
   503 
   504 
   504 
   505 
   505 static const CmdStruct *FindCmd(const char *s, int len)
   506 static const CmdStruct *FindCmd(const char *s, int len)
   506 {
   507 {
   527 // else returns command struct
   528 // else returns command struct
   528 static const CmdStruct *ParseCommandString(const char **str, char *param, int *argno, int *casei)
   529 static const CmdStruct *ParseCommandString(const char **str, char *param, int *argno, int *casei)
   529 {
   530 {
   530 	const char *s = *str, *start;
   531 	const char *s = *str, *start;
   531 	const CmdStruct *cmd;
   532 	const CmdStruct *cmd;
   532 	int plen = 0;
       
   533 	byte c;
   533 	byte c;
   534 
   534 
   535 	*argno = -1;
   535 	*argno = -1;
   536 	*casei = -1;
   536 	*casei = -1;
   537 
   537 
   891 	return hash;
   891 	return hash;
   892 }
   892 }
   893 
   893 
   894 
   894 
   895 // make a hash of the file to get a unique "version number"
   895 // make a hash of the file to get a unique "version number"
   896 static void MakeHashOfStrings()
   896 static void MakeHashOfStrings(void)
   897 {
   897 {
   898 	uint32 hash = 0;
   898 	uint32 hash = 0;
   899 	LangString *ls;
   899 	LangString *ls;
   900 	char *s;
   900 	char *s;
   901 	const CmdStruct *cs;
   901 	const CmdStruct *cs;