strgen/strgen.c
changeset 2069 929b43e70be9
parent 2063 95259a31ceb5
child 2082 52fa58482eeb
equal deleted inserted replaced
2068:ffb18f5dbf38 2069:929b43e70be9
    87 	char buf[1024];
    87 	char buf[1024];
    88 	va_list va;
    88 	va_list va;
    89 	va_start(va, s);
    89 	va_start(va, s);
    90 	vsprintf(buf, s, va);
    90 	vsprintf(buf, s, va);
    91 	va_end(va);
    91 	va_end(va);
    92 	fprintf(stderr, "%d: Warning: %s\n", _cur_line, buf);
    92 	fprintf(stderr, "Warning:(%d): %s\n", _cur_line, buf);
    93 	_warnings++;
    93 	_warnings++;
    94 }
    94 }
    95 
    95 
    96 
    96 
    97 static void CDECL Error(const char *s, ...)
    97 static void CDECL Error(const char *s, ...)
    99 	char buf[1024];
    99 	char buf[1024];
   100 	va_list va;
   100 	va_list va;
   101 	va_start(va, s);
   101 	va_start(va, s);
   102 	vsprintf(buf, s, va);
   102 	vsprintf(buf, s, va);
   103 	va_end(va);
   103 	va_end(va);
   104 	fprintf(stderr, "%d: Error: %s\n", _cur_line, buf);
   104 	fprintf(stderr, "Error:(%d): %s\n", _cur_line, buf);
   105 	_errors++;
   105 	_errors++;
   106 }
   106 }
   107 
   107 
   108 
   108 
   109 static void NORETURN CDECL Fatal(const char *s, ...)
   109 static void NORETURN CDECL Fatal(const char *s, ...)
   239 	{"STRING3", EmitEscapedByte, 7, 3},				// included string that consumes THREE arguments
   239 	{"STRING3", EmitEscapedByte, 7, 3},				// included string that consumes THREE arguments
   240 	{"STRING4", EmitEscapedByte, 8, 4},				// included string that consumes FOUR arguments
   240 	{"STRING4", EmitEscapedByte, 8, 4},				// included string that consumes FOUR arguments
   241 	{"STRING5", EmitEscapedByte, 9, 5},				// included string that consumes FIVE arguments
   241 	{"STRING5", EmitEscapedByte, 9, 5},				// included string that consumes FIVE arguments
   242 
   242 
   243 	{"STATIONFEATURES", EmitEscapedByte, 10, 1},				// station features string, icons of the features
   243 	{"STATIONFEATURES", EmitEscapedByte, 10, 1},				// station features string, icons of the features
       
   244 	{"INDUSTRY", EmitEscapedByte, 11, 1},			// industry, takes an industry #
   244 
   245 
   245 	{"DATE_LONG", EmitSingleByte, 0x82, 1},
   246 	{"DATE_LONG", EmitSingleByte, 0x82, 1},
   246 	{"DATE_SHORT", EmitSingleByte, 0x83, 1},
   247 	{"DATE_SHORT", EmitSingleByte, 0x83, 1},
   247 
   248 
   248 	{"VELOCITY", EmitSingleByte, 0x84, 1},
   249 	{"VELOCITY", EmitSingleByte, 0x84, 1},
   439 
   440 
   440 	return a;
   441 	return a;
   441 }
   442 }
   442 
   443 
   443 
   444 
   444 static bool CheckCommandsMatch(char *a, char *b)
   445 static bool CheckCommandsMatch(char *a, char *b, const char *name)
   445 {
   446 {
   446 	ParsedCommandStruct templ;
   447 	ParsedCommandStruct templ;
   447 	ParsedCommandStruct lang;
   448 	ParsedCommandStruct lang;
   448 	int i,j;
   449 	int i,j;
   449 	bool result = true;
   450 	bool result = true;
   451 	ExtractCommandString(&templ, b, true);
   452 	ExtractCommandString(&templ, b, true);
   452 	ExtractCommandString(&lang, a, true);
   453 	ExtractCommandString(&lang, a, true);
   453 
   454 
   454 	// For each string in templ, see if we find it in lang
   455 	// For each string in templ, see if we find it in lang
   455 	if (templ.np != lang.np) {
   456 	if (templ.np != lang.np) {
   456 		Error("template string and language string have a different # of commands");
   457 		Warning("%s: template string and language string have a different # of commands", name);
   457 		result = false;
   458 		result = false;
   458 	}
   459 	}
   459 
   460 
   460 	for(i = 0; i < templ.np; i++) {
   461 	for(i = 0; i < templ.np; i++) {
   461 		// see if we find it in lang, and zero it out
   462 		// see if we find it in lang, and zero it out
   469 				break;
   470 				break;
   470 			}
   471 			}
   471 		}
   472 		}
   472 
   473 
   473 		if (!found) {
   474 		if (!found) {
   474 			Error("Command '%s' exists in template file but not in language file", templ.pairs[i].a->cmd);
   475 			Warning("%s: command '%s' exists in template file but not in language file", name, templ.pairs[i].a->cmd);
   475 			result = false;
   476 			result = false;
   476 		}
   477 		}
   477 	}
   478 	}
   478 
   479 
   479 	// if we reach here, all non consumer commands match up.
   480 	// if we reach here, all non consumer commands match up.
   480 	// Check if the non consumer commands match up also.
   481 	// Check if the non consumer commands match up also.
   481 	for(i = 0; i < lengthof(templ.cmd); i++) {
   482 	for(i = 0; i < lengthof(templ.cmd); i++) {
   482 		if (TranslateCmdForCompare(templ.cmd[i]) != TranslateCmdForCompare(lang.cmd[i])) {
   483 		if (TranslateCmdForCompare(templ.cmd[i]) != TranslateCmdForCompare(lang.cmd[i])) {
   483 			Error("Param idx #%d '%s' doesn't match with template command '%s'", i,
   484 			Warning("%s: Param idx #%d '%s' doesn't match with template command '%s'", name, i,
   484 				!lang.cmd[i] ? "<empty>" : lang.cmd[i]->cmd,
   485 				!lang.cmd[i] ? "<empty>" : lang.cmd[i]->cmd,
   485 				!templ.cmd[i] ? "<empty>" : templ.cmd[i]->cmd);
   486 				!templ.cmd[i] ? "<empty>" : templ.cmd[i]->cmd);
   486 			result = false;
   487 			result = false;
   487 		}
   488 		}
   488 	}
   489 	}
   537 
   538 
   538 		// add to hash table
   539 		// add to hash table
   539 		HashAdd(str, ent);
   540 		HashAdd(str, ent);
   540 	} else {
   541 	} else {
   541 		if (ent == -1) {
   542 		if (ent == -1) {
   542 			Error("String name '%s' does not exist in master file", str);
   543 			Warning("String name '%s' does not exist in master file", str);
   543 			return;
   544 			return;
   544 		}
   545 		}
   545 
   546 
   546 		if (_translated[ent]) {
   547 		if (_translated[ent]) {
   547 			Error("String name '%s' is used multiple times", str);
   548 			Error("String name '%s' is used multiple times", str);
   551 		if (s[0] == ':' && s[1] == '\0') {
   552 		if (s[0] == ':' && s[1] == '\0') {
   552 			// Special syntax :: means we should just inherit the master string
   553 			// Special syntax :: means we should just inherit the master string
   553 			_translated[ent] = strdup(_master[ent]);
   554 			_translated[ent] = strdup(_master[ent]);
   554 		} else {
   555 		} else {
   555 			// check that the commands match
   556 			// check that the commands match
   556 			if (!CheckCommandsMatch(s, _master[ent])) {
   557 			if (!CheckCommandsMatch(s, _master[ent], str)) {
   557 				Error("String name '%s' does not match the layout of the master string\n", str);
       
   558 				return;
   558 				return;
   559 			}
   559 			}
   560 			_translated[ent] = strdup(s);
   560 			_translated[ent] = strdup(s);
   561 		}
   561 		}
   562 	}
   562 	}