OSDN Git Service

* tradcif.y (parse_number): Use TOLOWER/ISXDIGIT/hex_value/hex_p.
[pf3gnuchains/gcc-fork.git] / gcc / tradcif.y
index 4a70bed..baafad1 100644 (file)
@@ -1,9 +1,13 @@
 /* Parse C expressions for CCCP.
-   Copyright (C) 1987 Free Software Foundation.
+   Copyright (C) 1987, 2000, 2001 Free Software Foundation.
+   Adapted from expread.y of GDB by Paul Rubin, July 1986.
+   Adapted to ANSI C, Richard Stallman, Jan 1987
+   Dusted off, polished, and adapted for use as traditional
+   preprocessor only, Zack Weinberg, Jul 2000
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 1, or (at your option) any
+Free Software Foundation; either version 2, or (at your option) any
 later version.
 
 This program is distributed in the hope that it will be useful,
@@ -13,40 +17,30 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them.   Help stamp out software-hoarding!
-
- Adapted from expread.y of GDB by Paul Rubin, July 1986.
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Parse a C expression from text in a string  */
    
 %{
 #include "config.h"
 #include "system.h"
+#include "intl.h"
+#include "tradcpp.h"
 #include <setjmp.h>
 
-  int yylex PARAMS ((void));
-  void yyerror PARAMS ((const char *msgid));
-  extern void error   PARAMS ((const char *msgid, ...));
-  extern void warning PARAMS ((const char *msgid, ...));
-  extern struct hashnode *lookup PARAMS ((const unsigned char *, int, int));
+  static int yylex PARAMS ((void));
+  static void yyerror PARAMS ((const char *msgid)) ATTRIBUTE_NORETURN;
 
-  int parse_number PARAMS ((int));
-  int parse_escape PARAMS ((char **));
-  int parse_c_expression PARAMS ((char *));
+  static int parse_number PARAMS ((int));
+  static int parse_escape PARAMS ((const char **));
 
-  int expression_value;
+  static int expression_value;
   static jmp_buf parse_return_error;
 
-  /* some external tables of character types */
-  extern unsigned char is_idstart[], is_idchar[];
+  /* During parsing of a C expression, the pointer to the next
+     character is in this variable.  */
 
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
+  static const char *lexptr;
 %}
 
 %union {
@@ -210,29 +204,26 @@ exp       :       exp '*' exp
        |       NAME
                        { $$.value = 0;
                          $$.unsignedp = 0; }
+       |       '#'     { $$.value =
+                           test_assertion ((unsigned char **) &lexptr); }
        ;
 %%
 \f
-/* During parsing of a C expression, the pointer to the next character
-   is in this variable.  */
-
-static char *lexptr;
-
 /* Take care of parsing a number (anything that starts with a digit).
    Set yylval and return the token type; update lexptr.
    LEN is the number of characters in it.  */
 
 /* maybe needs to actually deal with floating point numbers */
 
-int
+static int
 parse_number (olen)
      int olen;
 {
-  register char *p = lexptr;
-  register long n = 0;
-  register int c;
-  register int base = 10;
-  register int len = olen;
+  const char *p = lexptr;
+  long n = 0;
+  int c;
+  int base = 10;
+  int len = olen;
 
   for (c = 0; c < len; c++)
     if (p[c] == '.') {
@@ -241,6 +232,8 @@ parse_number (olen)
       return ERROR;
     }
 
+  /* Traditionally, all numbers are signed.  However, we make it
+     unsigned if requested with a suffix.  */
   yylval.integer.unsignedp = 0;
 
   if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
@@ -254,14 +247,12 @@ parse_number (olen)
   while (len > 0) {
     c = *p++;
     len--;
-    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
-
-    if (c >= '0' && c <= '9') {
-      n *= base;
-      n += c - '0';
-    } else if (base == 16 && c >= 'a' && c <= 'f') {
-      n *= base;
-      n += c - 'a' + 10;
+    if (ISUPPER (c))
+      c = TOLOWER (c);
+
+    if (ISDIGIT (c)
+       || (base == 16 && ISXDIGIT (c))) {
+      n = (n * base) + hex_value (c);
     } else {
       /* `l' means long, and `u' means unsigned.  */
       while (1) {
@@ -287,25 +278,21 @@ parse_number (olen)
     return ERROR;
   }
 
-  /* If too big to be signed, consider it unsigned.  */
-  if (n < 0)
-    yylval.integer.unsignedp = 1;
-
   lexptr = p;
   yylval.integer.value = n;
   return INT;
 }
 
 struct token {
-  const char *operator;
-  int token;
+  const char *const operator;
+  const int token;
 };
 
 #ifndef NULL
 #define NULL 0
 #endif
 
-static struct token tokentab2[] = {
+static const struct token tokentab2[] = {
   {"&&", AND},
   {"||", OR},
   {"<<", LSH},
@@ -319,13 +306,13 @@ static struct token tokentab2[] = {
 
 /* Read one token, getting characters through lexptr.  */
 
-int
+static int
 yylex ()
 {
-  register int c;
-  register int namelen;
-  register char *tokstart;
-  register struct token *toktab;
+  int c;
+  int namelen;
+  const char *tokstart;
+  const struct token *toktab;
 
  retry:
 
@@ -400,6 +387,7 @@ yylex ()
   case '{':
   case '}':
   case ',':
+  case '#':
     lexptr++;
     return c;
     
@@ -407,16 +395,16 @@ yylex ()
     yyerror ("double quoted strings not allowed in #if expressions");
     return ERROR;
   }
-  if (c >= '0' && c <= '9') {
+  if (ISDIGIT (c)) {
     /* It's a number */
     for (namelen = 0;
-        c = tokstart[namelen], is_idchar[c] || c == '.'; 
+        c = tokstart[namelen], is_idchar (c) || c == '.'; 
         namelen++)
       ;
     return parse_number (namelen);
   }
   
-  if (!is_idstart[c]) {
+  if (!is_idstart (c)) {
     yyerror ("Invalid token in expression");
     return ERROR;
   }
@@ -424,7 +412,7 @@ yylex ()
   /* It is a name.  See how long it is.  */
   
   for (namelen = 0;
-       is_idchar[(int)(unsigned char)tokstart[namelen]];
+       is_idchar (tokstart[namelen]);
        namelen++)
     ;
   
@@ -447,11 +435,11 @@ yylex ()
    If \ is followed by 000, we return 0 and leave the string pointer
    after the zeros.  A value of 0 does not mean end of string.  */
 
-int
+static int
 parse_escape (string_ptr)
-     char **string_ptr;
+     const char **string_ptr;
 {
-  register int c = *(*string_ptr)++;
+  int c = *(*string_ptr)++;
   switch (c)
     {
     case 'a':
@@ -492,8 +480,8 @@ parse_escape (string_ptr)
     case '6':
     case '7':
       {
-       register int i = c - '0';
-       register int count = 0;
+       int i = c - '0';
+       int count = 0;
        while (++count < 3)
          {
            c = *(*string_ptr)++;
@@ -514,16 +502,12 @@ parse_escape (string_ptr)
       }
     case 'x':
       {
-       register int i = 0;
+       int i = 0;
        for (;;)
          {
            c = *(*string_ptr)++;
-           if (c >= '0' && c <= '9')
-             i = (i << 4) + c - '0';
-           else if (c >= 'a' && c <= 'f')
-             i = (i << 4) + c - 'a' + 10;
-           else if (c >= 'A' && c <= 'F')
-             i = (i << 4) + c - 'A' + 10;
+           if (hex_p (c))
+             i = (i << 4) + hex_value (c);
            else
              {
                (*string_ptr)--;
@@ -542,11 +526,11 @@ parse_escape (string_ptr)
     }
 }
 
-void
-yyerror (s)
-     const char *s;
+static void
+yyerror (msgid)
+     const char *msgid;
 {
-  error (s);
+  error ("%s", _(msgid));
   longjmp (parse_return_error, 1);
 }
 \f
@@ -559,7 +543,7 @@ yyerror (s)
 
 int
 parse_c_expression (string)
-     char *string;
+     const char *string;
 {
   lexptr = string;