X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cde%2Fconfig%2Fmakedepend%2Fifparser.c;h=b06a4fd17f14b9acabc477386f14aeb35e73d3d2;hb=29ea5f794d20264c545a0e641835cbbd6821d46f;hp=44f54f48682c833a7dca338e887adc0b4a856284;hpb=c884521619ded86baea5e0a74c8d0d2234c232fe;p=oweals%2Fcde.git diff --git a/cde/config/makedepend/ifparser.c b/cde/config/makedepend/ifparser.c index 44f54f48..b06a4fd1 100644 --- a/cde/config/makedepend/ifparser.c +++ b/cde/config/makedepend/ifparser.c @@ -16,7 +16,7 @@ * details. * * You should have received a copy of the GNU Lesser General Public - * License along with these librararies and programs; if not, write + * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ @@ -81,6 +81,9 @@ #include "ifparser.h" #include +#include +#include +#include /**************************************************************************** Internal Macros and Utilities for Parser @@ -88,8 +91,8 @@ #define DO(val) if (!(val)) return NULL #define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff)) -#define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++ -#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') +#define SKIPSPACE(ccc) while (isspace((int)*ccc)) ccc++ +#define isvarfirstletter(ccc) (isalpha((int)ccc) || (ccc) == '_') static const char * @@ -105,7 +108,7 @@ parse_variable (g, cp, varp) *varp = cp; /* EMPTY */ - for (cp++; isalnum(*cp) || *cp == '_'; cp++) ; + for (cp++; isalnum((int)*cp) || *cp == '_'; cp++) ; return cp; } @@ -116,19 +119,48 @@ parse_number (g, cp, valp) const char *cp; long *valp; { + long base = 10; SKIPSPACE (cp); - if (!isdigit(*cp)) + if (!isdigit((int)*cp)) return CALLFUNC(g, handle_error) (g, cp, "number"); - *valp = strtol(cp, &cp, 0); - /* skip trailing qualifiers */ + *valp = 0; + + if (*cp == '0') { + cp++; + if ((*cp == 'x') || (*cp == 'X')) { + base = 16; + cp++; + } else { + base = 8; + } + } + + /* Ignore overflows and assume ASCII, what source is usually written in */ + while (1) { + int increment = -1; + if (base == 8) { + if ((*cp >= '0') && (*cp <= '7')) + increment = *cp++ - '0'; + } else if (base == 16) { + if ((*cp >= '0') && (*cp <= '9')) + increment = *cp++ - '0'; + else if ((*cp >= 'A') && (*cp <= 'F')) + increment = *cp++ - ('A' - 10); + else if ((*cp >= 'a') && (*cp <= 'f')) + increment = *cp++ - ('a' - 10); + } else { /* Decimal */ + if ((*cp >= '0') && (*cp <= '9')) + increment = *cp++ - '0'; + } + if (increment < 0) + break; + *valp = (*valp * base) + increment; + } + + /* Skip trailing qualifiers */ while (*cp == 'U' || *cp == 'u' || *cp == 'L' || *cp == 'l') cp++; -#if 0 - *valp = atoi (cp); - /* EMPTY */ - for (cp++; isdigit(*cp); cp++) ; -#endif return cp; } @@ -170,7 +202,7 @@ parse_value (g, cp, valp) const char *cp; long *valp; { - const char *var; + const char *var, *varend; *valp = 0; @@ -197,6 +229,16 @@ parse_value (g, cp, valp) *valp = -(*valp); return cp; + case '+': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = +(*valp); + return cp; + + case '~': + DO (cp = parse_value (g, cp + 1, valp)); + *valp = ~(*valp); + return cp; + case '#': DO (cp = parse_variable (g, cp + 1, &var)); SKIPSPACE (cp); @@ -218,7 +260,7 @@ parse_value (g, cp, valp) return cp + 1; case 'd': - if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) { + if (strncmp (cp, "defined", 7) == 0 && !isalnum((int)cp[7])) { int paren = 0; int len; @@ -239,13 +281,30 @@ parse_value (g, cp, valp) /* fall out */ } - if (isdigit(*cp)) { + if (isdigit((int)*cp)) { DO (cp = parse_number (g, cp, valp)); } else if (!isvarfirstletter(*cp)) return CALLFUNC(g, handle_error) (g, cp, "variable or number"); else { DO (cp = parse_variable (g, cp, &var)); - *valp = (*(g->funcs.eval_variable)) (g, var, 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++; + } } return cp; @@ -272,7 +331,10 @@ parse_product (g, cp, valp) case '/': DO (cp = parse_product (g, cp + 1, &rightval)); - *valp = (*valp / rightval); + if (rightval) + *valp = (*valp / rightval); + else + *valp = LONG_MAX; break; case '%': @@ -430,7 +492,7 @@ parse_band (g, cp, valp) static const char * -parse_bor (g, cp, valp) +parse_bxor (g, cp, valp) IfParser *g; const char *cp; long *valp; @@ -440,6 +502,27 @@ parse_bor (g, cp, valp) DO (cp = parse_band (g, cp, valp)); SKIPSPACE (cp); + switch (*cp) { + case '^': + DO (cp = parse_bxor (g, cp + 1, &rightval)); + *valp = (*valp ^ rightval); + break; + } + return cp; +} + + +static const char * +parse_bor (g, cp, valp) + IfParser *g; + const char *cp; + long *valp; +{ + long rightval; + + DO (cp = parse_bxor (g, cp, valp)); + SKIPSPACE (cp); + switch (*cp) { case '|': if (cp[1] != '|') {