version 1.15, 2003/04/17 15:57:52 |
version 1.25, 2005/02/16 15:11:52 |
|
|
|
|
/* |
/* |
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
|
* All rights reserved. |
|
* |
|
* This code is derived from software contributed to Berkeley by |
|
* Adam de Boor. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* 3. Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
|
*/ |
|
|
|
/* |
* Copyright (c) 1988, 1989 by Adam de Boor |
* Copyright (c) 1988, 1989 by Adam de Boor |
* Copyright (c) 1989 by Berkeley Softworks |
* Copyright (c) 1989 by Berkeley Softworks |
* All rights reserved. |
* All rights reserved. |
|
|
* SUCH DAMAGE. |
* SUCH DAMAGE. |
*/ |
*/ |
|
|
#ifdef MAKE_BOOTSTRAP |
#ifndef MAKE_NATIVE |
static char rcsid[] = "$NetBSD$"; |
static char rcsid[] = "$NetBSD$"; |
#else |
#else |
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
Line 83 __RCSID("$NetBSD$"); |
|
Line 114 __RCSID("$NetBSD$"); |
|
* T -> $(varspec) op value |
* T -> $(varspec) op value |
* T -> $(varspec) == "string" |
* T -> $(varspec) == "string" |
* T -> $(varspec) != "string" |
* T -> $(varspec) != "string" |
|
* T -> "string" |
* T -> ( E ) |
* T -> ( E ) |
* T -> ! T |
* T -> ! T |
* op -> == | != | > | < | >= | <= |
* op -> == | != | > | < | >= | <= |
|
|
* last two fields are stored in condInvert and condDefProc, respectively. |
* last two fields are stored in condInvert and condDefProc, respectively. |
*/ |
*/ |
static void CondPushBack(Token); |
static void CondPushBack(Token); |
static int CondGetArg(char **, char **, char *, Boolean); |
static int CondGetArg(char **, char **, const char *, Boolean); |
static Boolean CondDoDefined(int, char *); |
static Boolean CondDoDefined(int, char *); |
static int CondStrMatch(ClientData, ClientData); |
static int CondStrMatch(ClientData, ClientData); |
static Boolean CondDoMake(int, char *); |
static Boolean CondDoMake(int, char *); |
static Boolean CondDoExists(int, char *); |
static Boolean CondDoExists(int, char *); |
static Boolean CondDoTarget(int, char *); |
static Boolean CondDoTarget(int, char *); |
static Boolean CondDoCommands(int, char *); |
static Boolean CondDoCommands(int, char *); |
static Boolean CondCvtArg(char *, double *); |
static char * CondCvtArg(char *, double *); |
static Token CondToken(Boolean); |
static Token CondToken(Boolean); |
static Token CondT(Boolean); |
static Token CondT(Boolean); |
static Token CondF(Boolean); |
static Token CondF(Boolean); |
static Token CondE(Boolean); |
static Token CondE(Boolean); |
|
|
static struct If { |
static struct If { |
char *form; /* Form of if */ |
const char *form; /* Form of if */ |
int formlen; /* Length of form */ |
int formlen; /* Length of form */ |
Boolean doNot; /* TRUE if default function should be negated */ |
Boolean doNot; /* TRUE if default function should be negated */ |
Boolean (*defProc)(int, char *); /* Default function to apply */ |
Boolean (*defProc)(int, char *); /* Default function to apply */ |
Line 140 static char *condExpr; /* The ex |
|
Line 172 static char *condExpr; /* The ex |
|
static Token condPushBack=None; /* Single push-back token used in |
static Token condPushBack=None; /* Single push-back token used in |
* parsing */ |
* parsing */ |
|
|
#define MAXIF 30 /* greatest depth of #if'ing */ |
#define MAXIF 64 /* greatest depth of #if'ing */ |
|
|
|
static Boolean finalElse[MAXIF+1][MAXIF+1]; /* Seen final else (stack) */ |
static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ |
static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ |
static int condTop = MAXIF; /* Top-most conditional */ |
static int condTop = MAXIF; /* Top-most conditional */ |
static int skipIfLevel=0; /* Depth of skipped conditionals */ |
static int skipIfLevel=0; /* Depth of skipped conditionals */ |
Line 189 CondPushBack(Token t) |
|
Line 222 CondPushBack(Token t) |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
CondGetArg(char **linePtr, char **argPtr, char *func, Boolean parens) |
CondGetArg(char **linePtr, char **argPtr, const char *func, Boolean parens) |
{ |
{ |
char *cp; |
char *cp; |
int argLen; |
int argLen; |
Line 259 CondGetArg(char **linePtr, char **argPtr |
|
Line 292 CondGetArg(char **linePtr, char **argPtr |
|
cp++; |
cp++; |
} |
} |
if (parens && *cp != ')') { |
if (parens && *cp != ')') { |
Parse_Error (PARSE_WARNING, "Missing closing parenthesis for %s()", |
Parse_Error(PARSE_WARNING, "Missing closing parenthesis for %s()", |
func); |
func); |
return (0); |
return (0); |
} else if (parens) { |
} else if (parens) { |
Line 294 CondDoDefined(int argLen, char *arg) |
|
Line 327 CondDoDefined(int argLen, char *arg) |
|
Boolean result; |
Boolean result; |
|
|
arg[argLen] = '\0'; |
arg[argLen] = '\0'; |
if (Var_Value (arg, VAR_CMD, &p1) != (char *)NULL) { |
if (Var_Value(arg, VAR_CMD, &p1) != (char *)NULL) { |
result = TRUE; |
result = TRUE; |
} else { |
} else { |
result = FALSE; |
result = FALSE; |
Line 345 CondDoMake(int argLen, char *arg) |
|
Line 378 CondDoMake(int argLen, char *arg) |
|
Boolean result; |
Boolean result; |
|
|
arg[argLen] = '\0'; |
arg[argLen] = '\0'; |
if (Lst_Find (create, (ClientData)arg, CondStrMatch) == NILLNODE) { |
if (Lst_Find(create, (ClientData)arg, CondStrMatch) == NILLNODE) { |
result = FALSE; |
result = FALSE; |
} else { |
} else { |
result = TRUE; |
result = TRUE; |
Line 460 CondDoCommands(int argLen, char *arg) |
|
Line 493 CondDoCommands(int argLen, char *arg) |
|
* |
* |
* Results: |
* Results: |
* Sets 'value' to double value of string. |
* Sets 'value' to double value of string. |
* Returns true if the string was a valid number, false o.w. |
* Returns NULL if string was fully consumed, |
|
* else returns remaining input. |
* |
* |
* Side Effects: |
* Side Effects: |
* Can change 'value' even if string is not a valid number. |
* Can change 'value' even if string is not a valid number. |
Line 468 CondDoCommands(int argLen, char *arg) |
|
Line 502 CondDoCommands(int argLen, char *arg) |
|
* |
* |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static char * |
CondCvtArg(char *str, double *value) |
CondCvtArg(char *str, double *value) |
{ |
{ |
if ((*str == '0') && (str[1] == 'x')) { |
if ((*str == '0') && (str[1] == 'x')) { |
Line 481 CondCvtArg(char *str, double *value) |
|
Line 515 CondCvtArg(char *str, double *value) |
|
else if (isxdigit((unsigned char) *str)) |
else if (isxdigit((unsigned char) *str)) |
x = 10 + *str - isupper((unsigned char) *str) ? 'A' : 'a'; |
x = 10 + *str - isupper((unsigned char) *str) ? 'A' : 'a'; |
else |
else |
return FALSE; |
break; |
i = (i << 4) + x; |
i = (i << 4) + x; |
} |
} |
*value = (double) i; |
*value = (double) i; |
return TRUE; |
return *str ? str : NULL; |
} |
} else { |
else { |
|
char *eptr; |
char *eptr; |
*value = strtod(str, &eptr); |
*value = strtod(str, &eptr); |
return *eptr == '\0'; |
return *eptr ? eptr : NULL; |
|
} |
|
} |
|
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* CondGetString -- |
|
* Get a string from a variable reference or an optionally quoted |
|
* string. This is called for the lhs and rhs of string compares. |
|
* |
|
* Results: |
|
* Sets doFree if needed, |
|
* Sets quoted if string was quoted, |
|
* Returns NULL on error, |
|
* else returns string - absent any quotes. |
|
* |
|
* Side Effects: |
|
* Moves condExpr to end of this token. |
|
* |
|
* |
|
*----------------------------------------------------------------------- |
|
*/ |
|
static char * |
|
CondGetString(Boolean doEval, Boolean *quoted, Boolean *doFree) |
|
{ |
|
Buffer buf; |
|
char *cp; |
|
char *str; |
|
int len; |
|
int qt; |
|
char *start; |
|
|
|
buf = Buf_Init(0); |
|
str = NULL; |
|
*quoted = qt = *condExpr == '"' ? 1 : 0; |
|
if (qt) |
|
condExpr++; |
|
for (start = condExpr; *condExpr && str == NULL; condExpr++) { |
|
switch (*condExpr) { |
|
case '\\': |
|
if (condExpr[1] != '\0') { |
|
condExpr++; |
|
Buf_AddByte(buf, (Byte)*condExpr); |
|
} |
|
break; |
|
case '"': |
|
if (qt) { |
|
condExpr++; /* we don't want the quotes */ |
|
goto got_str; |
|
} else |
|
Buf_AddByte(buf, (Byte)*condExpr); /* likely? */ |
|
break; |
|
case ')': |
|
case '!': |
|
case '=': |
|
case '>': |
|
case '<': |
|
case ' ': |
|
case '\t': |
|
if (!qt) |
|
goto got_str; |
|
else |
|
Buf_AddByte(buf, (Byte)*condExpr); |
|
break; |
|
case '$': |
|
/* if we are in quotes, then an undefined variable is ok */ |
|
str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval), |
|
&len, doFree); |
|
if (str == var_Error) { |
|
/* |
|
* Even if !doEval, we still report syntax errors, which |
|
* is what getting var_Error back with !doEval means. |
|
*/ |
|
str = NULL; |
|
goto cleanup; |
|
} |
|
condExpr += len; |
|
/* |
|
* If the '$' was first char (no quotes), and we are |
|
* followed by space, the operator or end of expression, |
|
* we are done. |
|
*/ |
|
if ((condExpr == start + len) && |
|
(*condExpr == '\0' || |
|
isspace((unsigned char) *condExpr) || |
|
strchr("!=><)", *condExpr))) { |
|
goto cleanup; |
|
} |
|
/* |
|
* Nope, we better copy str to buf |
|
*/ |
|
for (cp = str; *cp; cp++) { |
|
Buf_AddByte(buf, (Byte)*cp); |
|
} |
|
if (*doFree) |
|
free(str); |
|
*doFree = FALSE; |
|
str = NULL; /* not finished yet */ |
|
condExpr--; /* don't skip over next char */ |
|
break; |
|
default: |
|
Buf_AddByte(buf, (Byte)*condExpr); |
|
break; |
|
} |
} |
} |
|
got_str: |
|
Buf_AddByte(buf, (Byte)'\0'); |
|
str = (char *)Buf_GetAll(buf, NULL); |
|
*doFree = TRUE; |
|
cleanup: |
|
Buf_Destroy(buf, FALSE); |
|
return str; |
} |
} |
|
|
/*- |
/*- |
Line 548 CondToken(Boolean doEval) |
|
Line 691 CondToken(Boolean doEval) |
|
case '\0': |
case '\0': |
t = EndOfFile; |
t = EndOfFile; |
break; |
break; |
|
case '"': |
case '$': { |
case '$': { |
char *lhs; |
char *lhs; |
char *rhs; |
char *rhs; |
char *op; |
char *op; |
int varSpecLen; |
Boolean lhsFree; |
Boolean doFree; |
Boolean rhsFree; |
|
Boolean lhsQuoted; |
|
Boolean rhsQuoted; |
|
|
|
lhsFree = rhsFree = FALSE; |
|
lhsQuoted = rhsQuoted = FALSE; |
|
|
/* |
/* |
* Parse the variable spec and skip over it, saving its |
* Parse the variable spec and skip over it, saving its |
* value in lhs. |
* value in lhs. |
*/ |
*/ |
t = Err; |
t = Err; |
lhs = Var_Parse(condExpr, VAR_CMD, doEval,&varSpecLen,&doFree); |
lhs = CondGetString(doEval, &lhsQuoted, &lhsFree); |
if (lhs == var_Error) { |
if (!lhs) |
/* |
return Err; |
* Even if !doEval, we still report syntax errors, which |
|
* is what getting var_Error back with !doEval means. |
|
*/ |
|
return(Err); |
|
} |
|
condExpr += varSpecLen; |
|
|
|
if (!isspace((unsigned char) *condExpr) && |
|
strchr("!=><", *condExpr) == NULL) { |
|
Buffer buf; |
|
char *cp; |
|
|
|
buf = Buf_Init(0); |
|
|
|
for (cp = lhs; *cp; cp++) |
|
Buf_AddByte(buf, (Byte)*cp); |
|
|
|
if (doFree) |
|
free(lhs); |
|
|
|
for (;*condExpr && !isspace((unsigned char) *condExpr); |
|
condExpr++) |
|
Buf_AddByte(buf, (Byte)*condExpr); |
|
|
|
Buf_AddByte(buf, (Byte)'\0'); |
|
lhs = (char *)Buf_GetAll(buf, &varSpecLen); |
|
Buf_Destroy(buf, FALSE); |
|
|
|
doFree = TRUE; |
|
} |
|
|
|
/* |
/* |
* Skip whitespace to get to the operator |
* Skip whitespace to get to the operator |
*/ |
*/ |
Line 618 CondToken(Boolean doEval) |
|
Line 736 CondToken(Boolean doEval) |
|
} |
} |
break; |
break; |
default: |
default: |
op = "!="; |
op = UNCONST("!="); |
rhs = "0"; |
if (lhsQuoted) |
|
rhs = UNCONST(""); |
|
else |
|
rhs = UNCONST("0"); |
|
|
goto do_compare; |
goto do_compare; |
} |
} |
Line 631 CondToken(Boolean doEval) |
|
Line 752 CondToken(Boolean doEval) |
|
"Missing right-hand-side of operator"); |
"Missing right-hand-side of operator"); |
goto error; |
goto error; |
} |
} |
rhs = condExpr; |
rhs = CondGetString(doEval, &rhsQuoted, &rhsFree); |
|
if (!rhs) |
|
return Err; |
do_compare: |
do_compare: |
if (*rhs == '"') { |
if (rhsQuoted || lhsQuoted) { |
/* |
|
* Doing a string comparison. Only allow == and != for |
|
* operators. |
|
*/ |
|
char *string; |
|
char *cp, *cp2; |
|
int qt; |
|
Buffer buf; |
|
|
|
do_string_compare: |
do_string_compare: |
if (((*op != '!') && (*op != '=')) || (op[1] != '=')) { |
if (((*op != '!') && (*op != '=')) || (op[1] != '=')) { |
Parse_Error(PARSE_WARNING, |
Parse_Error(PARSE_WARNING, |
Line 650 do_string_compare: |
|
Line 764 do_string_compare: |
|
goto error; |
goto error; |
} |
} |
|
|
buf = Buf_Init(0); |
|
qt = *rhs == '"' ? 1 : 0; |
|
|
|
for (cp = &rhs[qt]; |
|
((qt && (*cp != '"')) || |
|
(!qt && strchr(" \t)", *cp) == NULL)) && |
|
(*cp != '\0'); cp++) { |
|
if ((*cp == '\\') && (cp[1] != '\0')) { |
|
/* |
|
* Backslash escapes things -- skip over next |
|
* character, if it exists. |
|
*/ |
|
cp++; |
|
Buf_AddByte(buf, (Byte)*cp); |
|
} else if (*cp == '$') { |
|
int len; |
|
Boolean freeIt; |
|
|
|
cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt); |
|
if (cp2 != var_Error) { |
|
Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2); |
|
if (freeIt) { |
|
free(cp2); |
|
} |
|
cp += len - 1; |
|
} else { |
|
Buf_AddByte(buf, (Byte)*cp); |
|
} |
|
} else { |
|
Buf_AddByte(buf, (Byte)*cp); |
|
} |
|
} |
|
|
|
Buf_AddByte(buf, (Byte)0); |
|
|
|
string = (char *)Buf_GetAll(buf, (int *)0); |
|
Buf_Destroy(buf, FALSE); |
|
|
|
if (DEBUG(COND)) { |
if (DEBUG(COND)) { |
printf("lhs = \"%s\", rhs = \"%s\", op = %.2s\n", |
printf("lhs = \"%s\", rhs = \"%s\", op = %.2s\n", |
lhs, string, op); |
lhs, rhs, op); |
} |
} |
/* |
/* |
* Null-terminate rhs and perform the comparison. |
* Null-terminate rhs and perform the comparison. |
* t is set to the result. |
* t is set to the result. |
*/ |
*/ |
if (*op == '=') { |
if (*op == '=') { |
t = strcmp(lhs, string) ? False : True; |
t = strcmp(lhs, rhs) ? False : True; |
} else { |
} else { |
t = strcmp(lhs, string) ? True : False; |
t = strcmp(lhs, rhs) ? True : False; |
} |
|
free(string); |
|
if (rhs == condExpr) { |
|
if (!qt && *cp == ')') |
|
condExpr = cp; |
|
else |
|
condExpr = cp + 1; |
|
} |
} |
} else { |
} else { |
/* |
/* |
Line 714 do_string_compare: |
|
Line 783 do_string_compare: |
|
* lhs and the rhs to a double and compare the two. |
* lhs and the rhs to a double and compare the two. |
*/ |
*/ |
double left, right; |
double left, right; |
char *string; |
char *cp; |
|
|
if (!CondCvtArg(lhs, &left)) |
if (CondCvtArg(lhs, &left)) |
|
goto do_string_compare; |
|
if ((cp = CondCvtArg(rhs, &right)) && |
|
cp == rhs) |
goto do_string_compare; |
goto do_string_compare; |
if (*rhs == '$') { |
|
int len; |
|
Boolean freeIt; |
|
|
|
string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt); |
|
if (string == var_Error) { |
|
right = 0.0; |
|
} else { |
|
if (!CondCvtArg(string, &right)) { |
|
if (freeIt) |
|
free(string); |
|
goto do_string_compare; |
|
} |
|
if (freeIt) |
|
free(string); |
|
if (rhs == condExpr) |
|
condExpr += len; |
|
} |
|
} else { |
|
if (!CondCvtArg(rhs, &right)) |
|
goto do_string_compare; |
|
if (rhs == condExpr) { |
|
/* |
|
* Skip over the right-hand side |
|
*/ |
|
while(!isspace((unsigned char) *condExpr) && |
|
(*condExpr != '\0')) { |
|
condExpr++; |
|
} |
|
} |
|
} |
|
|
|
if (DEBUG(COND)) { |
if (DEBUG(COND)) { |
printf("left = %f, right = %f, op = %.2s\n", left, |
printf("left = %f, right = %f, op = %.2s\n", left, |
Line 788 do_string_compare: |
|
Line 829 do_string_compare: |
|
} |
} |
} |
} |
error: |
error: |
if (doFree) |
if (lhsFree) |
free(lhs); |
free(lhs); |
|
if (rhsFree) |
|
free(rhs); |
break; |
break; |
} |
} |
default: { |
default: { |
|
|
*/ |
*/ |
evalProc = CondDoDefined; |
evalProc = CondDoDefined; |
condExpr += 7; |
condExpr += 7; |
arglen = CondGetArg (&condExpr, &arg, "defined", TRUE); |
arglen = CondGetArg(&condExpr, &arg, "defined", TRUE); |
if (arglen == 0) { |
if (arglen == 0) { |
condExpr -= 7; |
condExpr -= 7; |
goto use_default; |
goto use_default; |
|
|
*/ |
*/ |
evalProc = CondDoMake; |
evalProc = CondDoMake; |
condExpr += 4; |
condExpr += 4; |
arglen = CondGetArg (&condExpr, &arg, "make", TRUE); |
arglen = CondGetArg(&condExpr, &arg, "make", TRUE); |
if (arglen == 0) { |
if (arglen == 0) { |
condExpr -= 4; |
condExpr -= 4; |
goto use_default; |
goto use_default; |
|
|
|
|
if (condExpr[arglen] != '\0') { |
if (condExpr[arglen] != '\0') { |
val = Var_Parse(&condExpr[arglen - 1], VAR_CMD, |
val = Var_Parse(&condExpr[arglen - 1], VAR_CMD, |
doEval, &length, &doFree); |
FALSE, &length, &doFree); |
if (val == var_Error) { |
if (val == var_Error) { |
t = Err; |
t = Err; |
} else { |
} else { |
Line 1031 CondF(Boolean doEval) |
|
Line 1074 CondF(Boolean doEval) |
|
/* |
/* |
* F -> T |
* F -> T |
*/ |
*/ |
CondPushBack (o); |
CondPushBack(o); |
} |
} |
} |
} |
return (l); |
return (l); |
Line 1078 CondE(Boolean doEval) |
|
Line 1121 CondE(Boolean doEval) |
|
/* |
/* |
* E -> F |
* E -> F |
*/ |
*/ |
CondPushBack (o); |
CondPushBack(o); |
} |
} |
} |
} |
return (l); |
return (l); |
Line 1133 Cond_EvalExpression(int dosetup, char *l |
|
Line 1176 Cond_EvalExpression(int dosetup, char *l |
|
case Err: |
case Err: |
err: |
err: |
if (eprint) |
if (eprint) |
Parse_Error (PARSE_FATAL, "Malformed conditional (%s)", |
Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", |
line); |
line); |
return (COND_INVALID); |
return (COND_INVALID); |
default: |
default: |
Line 1198 Cond_Eval(char *line) |
|
Line 1241 Cond_Eval(char *line) |
|
* so we return COND_PARSE, unless this endif isn't paired with |
* so we return COND_PARSE, unless this endif isn't paired with |
* a decent if. |
* a decent if. |
*/ |
*/ |
|
finalElse[condTop][skipIfLevel] = FALSE; |
if (skipIfLevel != 0) { |
if (skipIfLevel != 0) { |
skipIfLevel -= 1; |
skipIfLevel -= 1; |
return (COND_SKIP); |
return (COND_SKIP); |
} else { |
} else { |
if (condTop == MAXIF) { |
if (condTop == MAXIF) { |
Parse_Error (level, "if-less endif"); |
Parse_Error(level, "if-less endif"); |
return (COND_INVALID); |
return (COND_INVALID); |
} else { |
} else { |
skipLine = FALSE; |
skipLine = FALSE; |
Line 1232 Cond_Eval(char *line) |
|
Line 1276 Cond_Eval(char *line) |
|
* of the previous if we parsed. |
* of the previous if we parsed. |
*/ |
*/ |
if (isElse && (line[0] == 's') && (line[1] == 'e')) { |
if (isElse && (line[0] == 's') && (line[1] == 'e')) { |
|
if (finalElse[condTop][skipIfLevel]) { |
|
Parse_Error(PARSE_WARNING, "extra else"); |
|
} else { |
|
finalElse[condTop][skipIfLevel] = TRUE; |
|
} |
if (condTop == MAXIF) { |
if (condTop == MAXIF) { |
Parse_Error (level, "if-less else"); |
Parse_Error(level, "if-less else"); |
return (COND_INVALID); |
return (COND_INVALID); |
} else if (skipIfLevel == 0) { |
} else if (skipIfLevel == 0) { |
value = !condStack[condTop]; |
value = !condStack[condTop]; |
Line 1249 Cond_Eval(char *line) |
|
Line 1298 Cond_Eval(char *line) |
|
} else { |
} else { |
if (isElse) { |
if (isElse) { |
if (condTop == MAXIF) { |
if (condTop == MAXIF) { |
Parse_Error (level, "if-less elif"); |
Parse_Error(level, "if-less elif"); |
return (COND_INVALID); |
return (COND_INVALID); |
} else if (skipIfLevel != 0) { |
} else if (skipIfLevel != 0) { |
/* |
/* |
Line 1266 Cond_Eval(char *line) |
|
Line 1315 Cond_Eval(char *line) |
|
* we're skipping things... |
* we're skipping things... |
*/ |
*/ |
skipIfLevel += 1; |
skipIfLevel += 1; |
|
if (skipIfLevel >= MAXIF) { |
|
Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF); |
|
return (COND_INVALID); |
|
} |
|
finalElse[condTop][skipIfLevel] = FALSE; |
return(COND_SKIP); |
return(COND_SKIP); |
} |
} |
|
|
Line 1281 Cond_Eval(char *line) |
|
Line 1335 Cond_Eval(char *line) |
|
} |
} |
if (!isElse) { |
if (!isElse) { |
condTop -= 1; |
condTop -= 1; |
|
finalElse[condTop][skipIfLevel] = FALSE; |
} else if ((skipIfLevel != 0) || condStack[condTop]) { |
} else if ((skipIfLevel != 0) || condStack[condTop]) { |
/* |
/* |
* If this is an else-type conditional, it should only take effect |
* If this is an else-type conditional, it should only take effect |
Line 1298 Cond_Eval(char *line) |
|
Line 1353 Cond_Eval(char *line) |
|
* This is the one case where we can definitely proclaim a fatal |
* This is the one case where we can definitely proclaim a fatal |
* error. If we don't, we're hosed. |
* error. If we don't, we're hosed. |
*/ |
*/ |
Parse_Error (PARSE_FATAL, "Too many nested if's. %d max.", MAXIF); |
Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF); |
return (COND_INVALID); |
return (COND_INVALID); |
} else { |
} else { |
condStack[condTop] = value; |
condStack[condTop] = value; |