fix: %if parsing skipped 3 chars too many.

CVS patchset: 3177
CVS date: 1999/07/19 13:22:21
This commit is contained in:
jbj 1999-07-19 13:22:21 +00:00
parent 78808908b4
commit 902cdf4c1b
4 changed files with 130 additions and 66 deletions

View File

@ -7,6 +7,7 @@
- move checksig/resign major modes into rpmlib.
- add python bindings to rpm-devel (linux only).
- make query (rpm -qvl) behave like (POSIX?) ls for older files (#4050).
- fix: %if parsing skipped 3 chars too many.
3.0.1 -> 3.0.2
- eliminate armv4 entries from rpmrc (Andrew E. Mileski).

View File

@ -16,7 +16,7 @@
#include "rpmbuild.h"
#include "rpmlib.h"
/* #define DEBUG_PARSER */
/* #define DEBUG_PARSER 1 */
#ifdef DEBUG_PARSER
#include <stdio.h>
@ -68,8 +68,10 @@ static void valueFree(Value v)
}
#ifdef DEBUG_PARSER
static void valueDump(Value v, FILE *fp)
static void valueDump(const char *msg, Value v, FILE *fp)
{
if (msg)
fprintf(fp, "%s ", msg);
if (v) {
if (v->type == VALUE_TYPE_INTEGER)
fprintf(fp, "INTEGER %d\n", v->data.i);
@ -103,29 +105,68 @@ typedef struct _parseState
* Token parser.
*/
#define TOK_EOF 0
#define TOK_INTEGER 1
#define TOK_STRING 2
#define TOK_IDENTIFIER 3
#define TOK_ADD 4
#define TOK_MINUS 5
#define TOK_MULTIPLY 6
#define TOK_DIVIDE 7
#define TOK_OPEN_P 8
#define TOK_CLOSE_P 9
#define TOK_EQ 10
#define TOK_NEQ 11
#define TOK_LT 12
#define TOK_LE 13
#define TOK_GT 14
#define TOK_GE 15
#define TOK_NOT 16
#define TOK_LOGICAL_AND 17
#define TOK_LOGICAL_OR 18
#define TOK_EOF 1
#define TOK_INTEGER 2
#define TOK_STRING 3
#define TOK_IDENTIFIER 4
#define TOK_ADD 5
#define TOK_MINUS 6
#define TOK_MULTIPLY 7
#define TOK_DIVIDE 8
#define TOK_OPEN_P 9
#define TOK_CLOSE_P 10
#define TOK_EQ 11
#define TOK_NEQ 12
#define TOK_LT 13
#define TOK_LE 14
#define TOK_GT 15
#define TOK_GE 16
#define TOK_NOT 17
#define TOK_LOGICAL_AND 18
#define TOK_LOGICAL_OR 19
#define EXPRBUFSIZ BUFSIZ
static int readToken(ParseState state)
typedef struct exprTokTableEntry {
const char *name;
int val;
} ETTE_t;
ETTE_t exprTokTable[] = {
{ "EOF", TOK_EOF },
{ "I", TOK_INTEGER },
{ "S", TOK_STRING },
{ "ID", TOK_IDENTIFIER },
{ "+", TOK_ADD },
{ "-", TOK_MINUS },
{ "*", TOK_MULTIPLY },
{ "/", TOK_DIVIDE },
{ "( ", TOK_OPEN_P },
{ " )", TOK_CLOSE_P },
{ "==", TOK_EQ },
{ "!=", TOK_NEQ },
{ "<", TOK_LT },
{ "<=", TOK_LE },
{ ">", TOK_GT },
{ ">=", TOK_GE },
{ "!", TOK_NOT },
{ "&&", TOK_LOGICAL_AND },
{ "||", TOK_LOGICAL_OR },
{ NULL, 0 }
};
static const char *prToken(int val)
{
ETTE_t *et;
for (et = exprTokTable; et->name != NULL; et++) {
if (val == et->val)
return et->name;
}
return "???";
}
static int rdToken(ParseState state)
{
int token;
Value v = NULL;
@ -158,7 +199,13 @@ static int readToken(ParseState state)
token = TOK_CLOSE_P;
break;
case '=':
token = TOK_EQ;
if (p[1] == '=') {
token = TOK_EQ;
p++;
} else {
rpmError(RPMERR_BADSPEC, _("syntax error while parsing =="));
return -1;
}
break;
case '!':
if (p[1] == '=') {
@ -186,7 +233,7 @@ static int readToken(ParseState state)
token = TOK_LOGICAL_AND;
p++;
} else {
rpmError(RPMERR_BADSPEC, _("parse error in tokenizer"));
rpmError(RPMERR_BADSPEC, _("syntax error while parsing &&"));
return -1;
}
break;
@ -195,7 +242,7 @@ static int readToken(ParseState state)
token = TOK_LOGICAL_OR;
p++;
} else {
rpmError(RPMERR_BADSPEC, _("parse error in tokenizer"));
rpmError(RPMERR_BADSPEC, _("syntax error while parsing ||"));
return -1;
}
break;
@ -246,8 +293,8 @@ static int readToken(ParseState state)
state->nextToken = token;
state->tokenValue = v;
DEBUG(printf("readToken: token=%d\n", token));
DEBUG(valueDump(state->tokenValue, stdout));
DEBUG(printf("rdToken: \"%s\" (%d)\n", prToken(token), token));
DEBUG(valueDump("rdToken:", state->tokenValue, stdout));
return 0;
}
@ -263,7 +310,7 @@ static Value doPrimary(ParseState state)
switch (state->nextToken) {
case TOK_OPEN_P:
if (readToken(state))
if (rdToken(state))
return NULL;
v = doLogical(state);
if (state->nextToken != TOK_CLOSE_P) {
@ -275,7 +322,7 @@ static Value doPrimary(ParseState state)
case TOK_INTEGER:
case TOK_STRING:
v = state->tokenValue;
if (readToken(state))
if (rdToken(state))
return NULL;
break;
@ -290,13 +337,13 @@ static Value doPrimary(ParseState state)
}
v = valueMakeString(body);
if (readToken(state))
if (rdToken(state))
return NULL;
break;
}
case TOK_MINUS:
if (readToken(state))
if (rdToken(state))
return NULL;
v = doPrimary(state);
@ -312,7 +359,7 @@ static Value doPrimary(ParseState state)
break;
case TOK_NOT:
if (readToken(state))
if (rdToken(state))
return NULL;
v = doPrimary(state);
@ -331,7 +378,7 @@ static Value doPrimary(ParseState state)
break;
}
DEBUG(valueDump(v, stdout));
DEBUG(valueDump("doPrimary:", v, stdout));
return v;
}
@ -349,7 +396,7 @@ static Value doMultiplyDivide(ParseState state)
|| state->nextToken == TOK_DIVIDE) {
int op = state->nextToken;
if (readToken(state))
if (rdToken(state))
return NULL;
if (v2) valueFree(v2);
@ -394,7 +441,7 @@ static Value doAddSubtract(ParseState state)
while (state->nextToken == TOK_ADD || state->nextToken == TOK_MINUS) {
int op = state->nextToken;
if (readToken(state))
if (rdToken(state))
return NULL;
if (v2) valueFree(v2);
@ -451,7 +498,7 @@ static Value doRelational(ParseState state)
while (state->nextToken >= TOK_EQ && state->nextToken <= TOK_GE) {
int op = state->nextToken;
if (readToken(state))
if (rdToken(state))
return NULL;
if (v2) valueFree(v2);
@ -538,7 +585,7 @@ static Value doLogical(ParseState state)
|| state->nextToken == TOK_LOGICAL_OR) {
int op = state->nextToken;
if (readToken(state))
if (rdToken(state))
return NULL;
if (v2) valueFree(v2);
@ -581,7 +628,7 @@ int parseExpressionBoolean(Spec spec, char *expr)
/* Initialize the expression parser state. */
state.str = state.p = strdup(expr);
state.spec = spec;
readToken(&state);
rdToken(&state);
/* Parse the expression. */
v = doLogical(&state);
@ -597,7 +644,7 @@ int parseExpressionBoolean(Spec spec, char *expr)
return -1;
}
DEBUG(valueDump(v, stdout));
DEBUG(valueDump("parseExprBoolean:", v, stdout));
switch (v->type) {
case VALUE_TYPE_INTEGER:
@ -621,12 +668,12 @@ char * parseExpressionString(Spec spec, char *expr)
char *result = NULL;
Value v;
DEBUG(printf("parseExprBoolean(?, '%s')\n", expr));
DEBUG(printf("parseExprString(?, '%s')\n", expr));
/* Initialize the expression parser state. */
state.str = state.p = strdup(expr);
state.spec = spec;
readToken(&state);
rdToken(&state);
/* Parse the expression. */
v = doLogical(&state);
@ -642,15 +689,14 @@ char * parseExpressionString(Spec spec, char *expr)
return NULL;
}
DEBUG(valueDump(v, stdout));
DEBUG(valueDump("parseExprString:", v, stdout));
switch (v->type) {
case VALUE_TYPE_INTEGER: {
char buf[128];
sprintf(buf, "%d", v->data.i);
result = strdup(buf);
break;
}
} break;
case VALUE_TYPE_STRING:
result = strdup(v->data.s);
break;

View File

@ -209,8 +209,12 @@ retry:
match = !matchTok(os, s);
} else if (! strncmp("%if", s, 3)) {
s += 3;
match = parseExpressionBoolean(spec, s + 3);
if (match < 0) return RPMERR_BADSPEC;
match = parseExpressionBoolean(spec, s);
if (match < 0) {
rpmError(RPMERR_UNMATCHEDIF, _("%s:%d: parseExpressionBoolean returns %d"),
ofi->fileName, ofi->lineNum, match);
return RPMERR_BADSPEC;
}
} else if (! strncmp("%else", s, 5)) {
s += 5;
if (! spec->readStack->next) {

View File

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 1999-07-17 14:56-0400\n"
"POT-Creation-Date: 1999-07-19 08:32-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1248,48 +1248,56 @@ msgstr ""
msgid "Bad exit status from %s (%s)"
msgstr ""
#: ../build/expression.c:189 ../build/expression.c:198
msgid "parse error in tokenizer"
#: ../build/expression.c:206
msgid "syntax error while parsing =="
msgstr ""
#: ../build/expression.c:240
#: ../build/expression.c:236
msgid "syntax error while parsing &&"
msgstr ""
#: ../build/expression.c:245
msgid "syntax error while parsing ||"
msgstr ""
#: ../build/expression.c:287
msgid "parse error in expression"
msgstr ""
#: ../build/expression.c:270
#: ../build/expression.c:317
msgid "unmatched ("
msgstr ""
#: ../build/expression.c:288
#: ../build/expression.c:335
msgid "undefined identifier"
msgstr ""
#: ../build/expression.c:307
#: ../build/expression.c:354
msgid "- only on numbers"
msgstr ""
#: ../build/expression.c:323
#: ../build/expression.c:370
msgid "! only on numbers"
msgstr ""
#: ../build/expression.c:362 ../build/expression.c:407
#: ../build/expression.c:464 ../build/expression.c:551
#: ../build/expression.c:409 ../build/expression.c:454
#: ../build/expression.c:511 ../build/expression.c:598
msgid "types must match"
msgstr ""
#: ../build/expression.c:375
#: ../build/expression.c:422
msgid "* / not suported for strings"
msgstr ""
#: ../build/expression.c:423
#: ../build/expression.c:470
msgid "- not suported for strings"
msgstr ""
#: ../build/expression.c:564
#: ../build/expression.c:611
msgid "&& and || not suported for strings"
msgstr ""
#: ../build/expression.c:595 ../build/expression.c:640
#: ../build/expression.c:642 ../build/expression.c:687
msgid "syntax error in expression"
msgstr ""
@ -1867,30 +1875,35 @@ msgstr ""
msgid "line %d: %s"
msgstr ""
#: ../build/parseSpec.c:214
#, c-format
msgid "%s:%d: parseExpressionBoolean returns %d"
msgstr ""
#. Got an else with no %if !
#: ../build/parseSpec.c:218
#: ../build/parseSpec.c:222
msgid "%s:%d: Got a %%else with no if"
msgstr ""
#. Got an end with no %if !
#: ../build/parseSpec.c:229
#: ../build/parseSpec.c:233
msgid "%s:%d: Got a %%endif with no if"
msgstr ""
#: ../build/parseSpec.c:243 ../build/parseSpec.c:252
#: ../build/parseSpec.c:247 ../build/parseSpec.c:256
msgid "malformed %%include statement"
msgstr ""
#: ../build/parseSpec.c:333
#: ../build/parseSpec.c:337
#, c-format
msgid "Timecheck value must be an integer: %s"
msgstr ""
#: ../build/parseSpec.c:416
#: ../build/parseSpec.c:420
msgid "No buildable architectures"
msgstr ""
#: ../build/parseSpec.c:461
#: ../build/parseSpec.c:465
msgid "Package has no %%description: %s"
msgstr ""