makedepend: remove register keyword
[oweals/cde.git] / cde / config / makedepend / ifparser.c
index 44f54f48682c833a7dca338e887adc0b4a856284..b06a4fd17f14b9acabc477386f14aeb35e73d3d2 100644 (file)
@@ -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 <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
 
 /****************************************************************************
                   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] != '|') {