(svn r18444) -Feature: allow G and P to 'select' substrings of STRINGn for getting their gender

This commit is contained in:
rubidium 2009-12-09 11:41:27 +00:00
parent 7ec7cf2435
commit 64b727b03c

View File

@ -245,7 +245,7 @@ static void EmitSingleChar(char *buf, int value)
/* This is encoded like /* This is encoded like
* CommandByte <ARG#> <NUM> {Length of each string} {each string} */ * 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; const char *s = *buf;
char *end; char *end;
@ -263,6 +263,12 @@ bool ParseRelNum(char **buf, int *value)
} else { } else {
*value = v; *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; *buf = end;
return true; return true;
} }
@ -303,7 +309,7 @@ char *ParseWord(char **buf)
} }
/* Forward declaration */ /* Forward declaration */
static int TranslateArgumentIdx(int arg); static int TranslateArgumentIdx(int arg, int offset = 0);
static void EmitWordList(const char * const *words, uint nw) static void EmitWordList(const char * const *words, uint nw)
{ {
@ -318,11 +324,12 @@ static void EmitWordList(const char * const *words, uint nw)
static void EmitPlural(char *buf, int value) static void EmitPlural(char *buf, int value)
{ {
int argidx = _cur_argidx; int argidx = _cur_argidx;
int offset = 0;
const char *words[5]; const char *words[5];
int nw = 0; int nw = 0;
/* Parse out the number, if one exists. Otherwise default to prev arg. */ /* 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 */ /* Parse each string */
for (nw = 0; nw < 5; nw++) { for (nw = 0; nw < 5; nw++) {
@ -351,7 +358,7 @@ static void EmitPlural(char *buf, int value)
} }
PutUtf8(SCC_PLURAL_LIST); PutUtf8(SCC_PLURAL_LIST);
PutByte(TranslateArgumentIdx(argidx)); PutByte(TranslateArgumentIdx(argidx, offset));
EmitWordList(words, nw); EmitWordList(words, nw);
} }
@ -359,6 +366,7 @@ static void EmitPlural(char *buf, int value)
static void EmitGender(char *buf, int value) static void EmitGender(char *buf, int value)
{ {
int argidx = _cur_argidx; int argidx = _cur_argidx;
int offset = 0;
uint nw; uint nw;
if (buf[0] == '=') { if (buf[0] == '=') {
@ -377,7 +385,7 @@ static void EmitGender(char *buf, int value)
/* This is a {G 0 foo bar two} command. /* This is a {G 0 foo bar two} command.
* If no relative number exists, default to +0 */ * 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++) { for (nw = 0; nw < MAX_NUM_GENDER; nw++) {
words[nw] = ParseWord(&buf); words[nw] = ParseWord(&buf);
@ -385,7 +393,7 @@ static void EmitGender(char *buf, int value)
} }
if (nw != _numgenders) error("Bad # of arguments for gender command"); if (nw != _numgenders) error("Bad # of arguments for gender command");
PutUtf8(SCC_GENDER_LIST); PutUtf8(SCC_GENDER_LIST);
PutByte(TranslateArgumentIdx(argidx)); PutByte(TranslateArgumentIdx(argidx, offset));
EmitWordList(words, nw); EmitWordList(words, nw);
} }
} }
@ -948,20 +956,25 @@ static void WriteStringsH(const char *filename)
} }
} }
static int TranslateArgumentIdx(int argidx) static int TranslateArgumentIdx(int argidx, int offset)
{ {
int sum; int sum;
if (argidx < 0 || (uint)argidx >= lengthof(_cur_pcs.cmd)) { if (argidx < 0 || (uint)argidx >= lengthof(_cur_pcs.cmd)) {
error("invalid argidx %d", argidx); 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++) { for (int i = sum = 0; i < argidx; i++) {
const CmdStruct *cs = _cur_pcs.cmd[i]; const CmdStruct *cs = _cur_pcs.cmd[i];
sum += (cs != NULL) ? cs->consumes : 1; sum += (cs != NULL) ? cs->consumes : 1;
} }
return sum; return sum + offset;
} }
static void PutArgidxCommand() static void PutArgidxCommand()