diff options
author | Egbert Eich <eich@suse.de> | 2004-03-14 08:27:26 +0000 |
---|---|---|
committer | Egbert Eich <eich@suse.de> | 2004-03-14 08:27:26 +0000 |
commit | 97527faa1b2b9f66be7171454161f273b986ee46 (patch) | |
tree | 95026cce9aa4a1973ba0fd7fe3c8acf277c11ed9 /ifparser.c | |
parent | cc985b59a40838d617ec2c5b03771620e56fe461 (diff) |
Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004xf86-4_4_99_1
Diffstat (limited to 'ifparser.c')
-rw-r--r-- | ifparser.c | 144 |
1 files changed, 85 insertions, 59 deletions
@@ -2,7 +2,7 @@ * $Xorg: ifparser.c,v 1.3 2000/08/17 19:41:50 cpqbld Exp $ * * Copyright 1992 Network Computing Devices, Inc. - * + * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that @@ -12,7 +12,7 @@ * without specific, written prior permission. Network Computing Devices makes * no representations about the suitability of this software for any purpose. * It is provided ``as is'' without express or implied warranty. - * + * * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, @@ -20,46 +20,47 @@ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. - * + * * Author: Jim Fulton * Network Computing Devices, Inc. - * + * * Simple if statement processor * * This module can be used to evaluate string representations of C language * if constructs. It accepts the following grammar: - * + * * EXPRESSION := VALUE - * | VALUE BINOP EXPRESSION + * | VALUE BINOP EXPRESSION * | VALUE '?' EXPRESSION ':' EXPRESSION - * + * * VALUE := '(' EXPRESSION ')' - * | '!' VALUE - * | '-' VALUE - * | '+' VALUE + * | '!' VALUE + * | '-' VALUE + * | '+' VALUE * | '~' VALUE - * | 'defined' '(' variable ')' - * | 'defined' variable + * | 'defined' '(' variable_name ')' + * | 'defined' variable_name * | # variable '(' variable-list ')' - * | variable - * | number - * + * | variable(arglist) + * | variable + * | number + * * BINOP := '*' | '/' | '%' - * | '+' | '-' - * | '<<' | '>>' - * | '<' | '>' | '<=' | '>=' - * | '==' | '!=' - * | '&' | '^' | '|' - * | '&&' | '||' - * + * | '+' | '-' + * | '<<' | '>>' + * | '<' | '>' | '<=' | '>=' + * | '==' | '!=' + * | '&' | '^' | '|' + * | '&&' | '||' + * * The normal C order of precedence is supported. - * - * + * + * * External Entry Points: - * + * * ParseIfExpression parse a string for #if */ -/* $XFree86: xc/config/makedepend/ifparser.c,v 3.10tsi Exp $ */ +/* $XFree86: xc/config/makedepend/ifparser.c,v 3.12 2004/03/05 16:02:58 tsi Exp $ */ #include "ifparser.h" #include <ctype.h> @@ -77,16 +78,53 @@ static const char * -parse_variable (IfParser *g, const char *cp, const char **varp) +parse_variable_name (IfParser *g, const char *cp, const char **varp, int *varlenp) +{ + *varlenp = 0; + + SKIPSPACE (cp); + + if (!isvarfirstletter(*cp)) + return CALLFUNC(g, handle_error) (g, cp, "variable name"); + + *varp = cp; + for (cp++; isalnum(*cp) || *cp == '_'; cp++) /* EMPTY */; + *varlenp = cp - *varp; + + return cp; +} + + +static const char * +parse_variable (IfParser *g, const char *cp, const char **varp, int *varlenp, const char **argsp) { + *argsp = NULL; + *varlenp = 0; + SKIPSPACE (cp); + /* this error handling call might prevent us from merging with above code */ if (!isvarfirstletter (*cp)) return CALLFUNC(g, handle_error) (g, cp, "variable name"); *varp = cp; - /* EMPTY */ - for (cp++; isalnum(*cp) || *cp == '_'; cp++) ; + for (cp++; isalnum(*cp) || *cp == '_'; cp++) /* EMPTY */; + *varlenp = cp - *varp; + + if (variable_has_args(g, *varp, *varlenp)) + { + SKIPSPACE (cp); + if (*cp != '(') + { + return CALLFUNC(g, handle_error) (g, cp, "argument list"); + } + cp++; + + *argsp = cp; + for (cp++; *cp != ')'; cp++) /* EMPTY */; + cp++; + } + return cp; } @@ -171,7 +209,8 @@ parse_character (IfParser *g, const char *cp, long *valp) static const char * parse_value (IfParser *g, const char *cp, long *valp) { - const char *var, *varend; + const char *var, *args; + int varlen; *valp = 0; @@ -183,7 +222,7 @@ parse_value (IfParser *g, const char *cp, long *valp) case '(': DO (cp = ParseIfExpression (g, cp + 1, valp)); SKIPSPACE (cp); - if (*cp != ')') + if (*cp != ')') return CALLFUNC(g, handle_error) (g, cp, ")"); return cp + 1; /* skip the right paren */ @@ -208,12 +247,12 @@ parse_value (IfParser *g, const char *cp, long *valp) return cp; case '#': - DO (cp = parse_variable (g, cp + 1, &var)); + DO (cp = parse_variable (g, cp + 1, &var, &varlen, &args)); SKIPSPACE (cp); if (*cp != '(') return CALLFUNC(g, handle_error) (g, cp, "("); do { - DO (cp = parse_variable (g, cp + 1, &var)); + DO (cp = parse_variable (g, cp + 1, &var, &varlen, &args)); SKIPSPACE (cp); } while (*cp && *cp != ')'); if (*cp != ')') @@ -230,7 +269,6 @@ parse_value (IfParser *g, const char *cp, long *valp) case 'd': if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) { int paren = 0; - int len; cp += 7; SKIPSPACE (cp); @@ -238,43 +276,31 @@ parse_value (IfParser *g, const char *cp, long *valp) paren = 1; cp++; } - DO (cp = parse_variable (g, cp, &var)); - len = cp - var; + DO (cp = parse_variable_name (g, cp, &var, &varlen)); SKIPSPACE (cp); if (paren && *cp != ')') return CALLFUNC(g, handle_error) (g, cp, ")"); - *valp = (*(g->funcs.eval_defined)) (g, var, len); + *valp = (*(g->funcs.eval_defined)) (g, var, varlen); return cp + paren; /* skip the right paren */ } /* fall out */ } if (isdigit(*cp)) { + /* determine the numeric value */ DO (cp = parse_number (g, cp, valp)); - } else if (!isvarfirstletter(*cp)) - return CALLFUNC(g, handle_error) (g, cp, "variable or number"); + } else if (isvarfirstletter(*cp)) { + /* resolve the value of this macro. + * (macro argument substitution will take place + * and recursive macro resolvement will apply) */ + DO (cp = parse_variable (g, cp, &var, &varlen, &args)); + *valp = (*(g->funcs.eval_variable)) (g, var, varlen, args); + } else { - DO (cp = parse_variable (g, cp, &var)); - varend = cp; - SKIPSPACE(cp); - if (*cp != '(') { - *valp = (*(g->funcs.eval_variable)) (g, var, varend - var); - } else { - do { - long dummy; - DO (cp = ParseIfExpression (g, cp + 1, &dummy)); - SKIPSPACE(cp); - if (*cp == ')') - break; - if (*cp != ',') - return CALLFUNC(g, handle_error) (g, cp, ","); - } while (1); - - *valp = 1; /* XXX */ - cp++; - } + /* we finally got something that does not fit the syntax rules */ + return CALLFUNC(g, handle_error) (g, cp, "variable or number"); } - + return cp; } |