changeset 13913:9ae8a0686e06 draft

(svn r18444) -Feature: allow G and P to 'select' substrings of STRINGn for getting their gender
author rubidium <rubidium@openttd.org>
date Wed, 09 Dec 2009 11:41:27 +0000
parents 3be57eaa986d
children f48ae1a0d976
files src/strgen/strgen.cpp
diffstat 1 files changed, 21 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/strgen/strgen.cpp
+++ b/src/strgen/strgen.cpp
@@ -245,7 +245,7 @@
 /* This is encoded like
  *  CommandByte <ARG#> <NUM> {Length of each string} {each string} */
 
-bool ParseRelNum(char **buf, int *value)
+bool ParseRelNum(char **buf, int *value, int *offset)
 {
 	const char *s = *buf;
 	char *end;
@@ -263,6 +263,12 @@
 	} else {
 		*value = v;
 	}
+	if (offset != NULL && *end == ':') {
+		/* Take the Nth within */
+		s = end + 1;
+		*offset = strtol(s, &end, 0);
+		if (end == s) return false;
+	}
 	*buf = end;
 	return true;
 }
@@ -303,7 +309,7 @@
 }
 
 /* Forward declaration */
-static int TranslateArgumentIdx(int arg);
+static int TranslateArgumentIdx(int arg, int offset = 0);
 
 static void EmitWordList(const char * const *words, uint nw)
 {
@@ -318,11 +324,12 @@
 static void EmitPlural(char *buf, int value)
 {
 	int argidx = _cur_argidx;
+	int offset = 0;
 	const char *words[5];
 	int nw = 0;
 
 	/* Parse out the number, if one exists. Otherwise default to prev arg. */
-	if (!ParseRelNum(&buf, &argidx)) argidx--;
+	if (!ParseRelNum(&buf, &argidx, &offset)) argidx--;
 
 	/* Parse each string */
 	for (nw = 0; nw < 5; nw++) {
@@ -351,7 +358,7 @@
 	}
 
 	PutUtf8(SCC_PLURAL_LIST);
-	PutByte(TranslateArgumentIdx(argidx));
+	PutByte(TranslateArgumentIdx(argidx, offset));
 	EmitWordList(words, nw);
 }
 
@@ -359,6 +366,7 @@
 static void EmitGender(char *buf, int value)
 {
 	int argidx = _cur_argidx;
+	int offset = 0;
 	uint nw;
 
 	if (buf[0] == '=') {
@@ -377,7 +385,7 @@
 
 		/* This is a {G 0 foo bar two} command.
 		 * If no relative number exists, default to +0 */
-		if (!ParseRelNum(&buf, &argidx)) {}
+		if (!ParseRelNum(&buf, &argidx, &offset)) {}
 
 		for (nw = 0; nw < MAX_NUM_GENDER; nw++) {
 			words[nw] = ParseWord(&buf);
@@ -385,7 +393,7 @@
 		}
 		if (nw != _numgenders) error("Bad # of arguments for gender command");
 		PutUtf8(SCC_GENDER_LIST);
-		PutByte(TranslateArgumentIdx(argidx));
+		PutByte(TranslateArgumentIdx(argidx, offset));
 		EmitWordList(words, nw);
 	}
 }
@@ -948,20 +956,25 @@
 	}
 }
 
-static int TranslateArgumentIdx(int argidx)
+static int TranslateArgumentIdx(int argidx, int offset)
 {
 	int sum;
 
 	if (argidx < 0 || (uint)argidx >= lengthof(_cur_pcs.cmd)) {
 		error("invalid argidx %d", argidx);
 	}
+	const CmdStruct *cs = _cur_pcs.cmd[argidx];
+	if (cs != NULL && cs->consumes <= offset) {
+		error("invalid argidx offset %d:%d\n", argidx, offset);
+	}
 
 	for (int i = sum = 0; i < argidx; i++) {
 		const CmdStruct *cs = _cur_pcs.cmd[i];
+
 		sum += (cs != NULL) ? cs->consumes : 1;
 	}
 
-	return sum;
+	return sum + offset;
 }
 
 static void PutArgidxCommand()