* support/cpp2/cpphash.h, support/cpp2/cpplex.c,
authorborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Dec 2006 19:46:24 +0000 (19:46 +0000)
committerborutr <borutr@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Dec 2006 19:46:24 +0000 (19:46 +0000)
  support/cpp2/cpplib.[ch], support/cpp2/sdcppinit.c, doc/sdccman.lyx:
  an other try to fix bug #982435: introduced -pedantic-parse-number
  command line option and pedantic_parse_number pragma

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4522 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
doc/sdccman.lyx
support/cpp2/cpphash.h
support/cpp2/cpplex.c
support/cpp2/cpplib.c
support/cpp2/cpplib.h
support/cpp2/sdcppinit.c

index 6649830a59faa1fc088918d5ee07403f51bab0d3..de6c3a6e1378ee05fe1603f7ca9730e658b5dcc7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-12-23 Borut Razem <borut.razem AT siol.net>
+
+       * support/cpp2/cpphash.h, support/cpp2/cpplex.c,
+         support/cpp2/cpplib.[ch], support/cpp2/sdcppinit.c, doc/sdccman.lyx:
+         an other try to fix bug #982435: introduced -pedantic-parse-number
+         command line option and pedantic_parse_number pragma
+
 2006-12-21 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * as/link/mcs51/lkarea.c (lnkarea2): handle absolute areas, restructured
index 6aa3baa8e174dc0f03181e0175a2a143ccfc1d9c..86817c15dfbaaa6884ab018ba571741d414e4eb1 100644 (file)
@@ -6121,6 +6121,34 @@ file"'.
 \bar default 
 Like `-dD' except that the macro arguments and contents are omitted.
  Only `#define name' is included in the output.
+\layout List
+\labelwidthstring 00.00.0000
+
+
+\series bold 
+-pedantic-parse-number
+\begin_inset LatexCommand \index{-pedantic-parse-number}
+
+\end_inset 
+
+
+\size large 
+\bar under 
+\series default 
+\size default 
+\bar default 
+Pedentic parse numbers so that situations like 0xfe-LO_B(3) are parsed properly
+ and the macro LO_B(3) gets expanded.
+ See also #pragma pedantic_parse_number in section
+\begin_inset LatexCommand \ref{sec:Pragmas}
+
+\end_inset 
+
+\emph on
+Note: this functionality is not in conformance with standard!
+
 \layout List
 \added_space_bottom bigskip \labelwidthstring 00.00.0000
 
@@ -16958,6 +16986,57 @@ void foo (void)
 } 
 \newline 
 
+\layout Itemize
+
+
+\series bold
+pedantic_parse_number
+\series default
+
+\begin_inset LatexCommand \index{\#pragma pedantic\_parse\_number}
+
+\end_inset
+
+ (+ | -) - Pedantic parse numbers so that situations like 0xfe-LO_B(3) are
+ parsed properly and the macro LO_B(3) gets expanded.
+ Default is off.
+ Below is an example on how to use this pragma.
+
+\emph on
+ Note: this functionality is not in conformance with standard!
+
+\layout Verse
+
+
+\family typewriter
+#pragma pedantic_parse_number +
+\begin_inset LatexCommand \index{\#pragma pedantic\_parse\_number}
+
+\end_inset
+
+
+\newline 
+\newline
+#define LO_B(x) ((x) & 0xff)
+\newline
+\newline
+unsigned char foo(void)
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+unsigned char c=0xfe-LO_B(3);
+\newline
+\newline
+\InsetSpace ~
+\InsetSpace ~
+\InsetSpace ~
+
+return c;
+\newline
+}
+\newline
+
 \layout Standard
 
 The pragma's are intended to be used to turn-on or off certain optimizations
index d619fcbf02faff64d3cb5ef4319cc1fcc354c941..0643f93bd7a138f51b21c21757ff01faca9e56da 100644 (file)
@@ -43,10 +43,6 @@ typedef unsigned char uchar;
     || (((prevc) == 'p' || (prevc) == 'P') \
         && CPP_OPTION (pfile, extended_numbers))))
 
-/* Test if a X or x is valid within a preprocessing number.  */
-#define VALID_HEX(c, prevc) \
-  (((c) == 'X' || (c) == 'x') && (prevc) == '0')
-
 #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
 #define CPP_BUFFER(PFILE) ((PFILE)->buffer)
 #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
index b802ed60cf4bcf52b76fe7363ffcb1afd84cebd5..a24b68d3959096b7a70d528fae2155cb6b40233c 100644 (file)
@@ -74,6 +74,7 @@ static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
 static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
 static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int,
                                  unsigned int *));
+static void pedantic_parse_number PARAMS ((cpp_reader *, cpp_string *, int));
 static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
 static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *));
 static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
@@ -577,42 +578,26 @@ parse_slow (pfile, cur, number_p, plen)
       if (c == '?' || c == '\\')
        c = skip_escaped_newlines (pfile);
 
-      if (number_p)
-        {
-          if (!ISXDIGIT (c) && c != '.' && !VALID_SIGN (c, prevc) && !VALID_HEX (c, prevc))
+      if (!is_idchar (c))
+       {
+         if (!number_p)
            break;
+         if (c != '.' && !VALID_SIGN (c, prevc))
+           break;
+       }
 
-            obstack_1grow (stack, c);
-
-            base = cur = buffer->cur;
-            while (ISXDIGIT (*cur))
-              ++cur;
-
-            if (cur != base)
-              obstack_grow (stack, base, cur - base);
-
-            prevc = cur[-1];
-            c = *cur++;
-            buffer->cur = cur;
-        }
-      else
-        {
-          if (!is_idchar (c))
-            break;
-
-          /* Handle normal identifier characters in this loop.  */
-          do
-           {
-             prevc = c;
-             obstack_1grow (stack, c);
+      /* Handle normal identifier characters in this loop.  */
+      do
+       {
+         prevc = c;
+         obstack_1grow (stack, c);
 
-             if (c == '$')
-               saw_dollar++;
+         if (c == '$')
+           saw_dollar++;
 
-             c = *buffer->cur++;
-           }
-          while (is_idchar (c));
-        }
+         c = *buffer->cur++;
+       }
+      while (is_idchar (c));
     }
 
   /* Step back over the unwanted char.  */
@@ -630,6 +615,249 @@ parse_slow (pfile, cur, number_p, plen)
   return obstack_finish (stack);
 }
 
+/* SDCC specific */
+/* Pedantic parse a number, beginning with character C, skipping embedded
+   backslash-newlines.  LEADING_PERIOD is nonzero if there was a "."
+   before C.  Place the result in NUMBER.  */
+static void
+pedantic_parse_number (pfile, number, leading_period)
+     cpp_reader *pfile;
+     cpp_string *number;
+     int leading_period;
+{
+  enum num_type_e { NT_DEC, NT_HEX } num_type = NT_DEC;
+  enum num_part_e { NP_WHOLE, NP_FRACT, NP_EXP, NP_INT_SUFFIX, NP_FLOAT_SUFFIX } num_part = NP_WHOLE;
+
+  uchar c = *(pfile->buffer->cur - 1);
+  struct obstack *stack = &pfile->hash_table->stack;
+  cpp_buffer *buffer = pfile->buffer;
+  int len = 0;
+  int has_whole = 0;
+  int has_fract = 0;
+
+  if (leading_period)
+    {
+      num_part = NP_FRACT;
+      ++len;
+      obstack_1grow (stack, '.');
+      c = get_effective_char(pfile);
+    }
+  else
+    {
+      if ('0' == c)  
+        {
+          has_whole = 1;
+          ++len;
+          obstack_1grow (stack, c);
+          c = get_effective_char(pfile);
+
+          switch (c)
+            {
+            case 'X':
+            case 'x':
+              num_type = NT_HEX;
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+              break;
+
+            case '.':
+              num_part = NP_FRACT;
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+              break;
+            }
+        }
+    }
+
+  for (; ; )
+    {
+      switch (num_part)
+        {
+        case NP_WHOLE:
+          if (NT_DEC == num_type)
+            {
+              while (ISDIGIT (c))
+                {
+                  has_whole = 1;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                }
+
+              if ('.' == c)
+                {
+                  num_part = NP_FRACT;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                  continue;
+                }
+              else if ('E' == c || 'e' == c)
+                {
+                  if (has_whole || has_fract)
+                  {
+                    num_part = NP_EXP;
+                    ++len;
+                    obstack_1grow (stack, c);
+                    c = get_effective_char(pfile);
+                    continue;
+                  }
+                  else
+                    break;
+                }
+            }
+          else
+            {
+              while (ISXDIGIT (c))
+                {
+                  has_whole = 1;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                }
+
+              if ('.' == c)
+                {
+                  num_part = NP_FRACT;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                  continue;
+                }
+              else if ('P' == c || 'p' == c)
+                {
+                  if (has_whole || has_fract)
+                    {
+                      num_part = NP_EXP;
+                      ++len;
+                      obstack_1grow (stack, c);
+                      c = get_effective_char(pfile);
+                      continue;
+                    }
+                  else
+                    break;
+                }
+            }
+          num_part = NP_INT_SUFFIX;
+          continue;
+
+        case NP_FRACT:
+          if (NT_DEC == num_type)
+            {
+              while (ISDIGIT (c))
+                {
+                  has_fract = 1;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                }
+
+              if ('E' == c || 'e' == c)
+                {
+                  if (has_whole || has_fract)
+                    {
+                      num_part = NP_EXP;
+                      ++len;
+                      obstack_1grow (stack, c);
+                      c = get_effective_char(pfile);
+                      continue;
+                    }
+                }
+            }
+          else
+            {
+              while (ISXDIGIT (c))
+                {
+                  has_fract = 1;
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                }
+
+              if ('P' == c || 'p' == c)
+                {
+                  if (has_whole || has_fract)
+                    {
+                      num_part = NP_EXP;
+                      ++len;
+                      obstack_1grow (stack, c);
+                      c = get_effective_char(pfile);
+                      continue;
+                    }
+                }
+            }
+          num_part = NP_FLOAT_SUFFIX;
+          continue;
+            
+        case NP_EXP:
+          if ('+' == c || '-' == c)
+            {
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+            }
+
+          while (ISDIGIT (c))
+            {
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+            }
+
+          num_part = NP_FLOAT_SUFFIX;
+          continue;
+
+        case NP_INT_SUFFIX:
+           if ('L' == c || 'l' == c)
+            {
+              uchar prevc = c;
+
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+
+              if (c == prevc)
+                {
+                  ++len;
+                  obstack_1grow (stack, c);
+                  c = get_effective_char(pfile);
+                }
+            }
+          else if ('U' == c || 'u' == c)
+            {
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+            }
+          break;
+
+        case NP_FLOAT_SUFFIX:
+           if ('F' == c || 'f' == c)
+            {
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+            }
+          else if ('L' == c || 'l' == c)
+            {
+              ++len;
+              obstack_1grow (stack, c);
+              c = get_effective_char(pfile);
+            }
+          break;
+        }
+      break;
+    }
+
+  /* Step back over the unwanted char.  */
+  BACKUP ();
+
+  number->text = obstack_finish (stack);
+  number->len = len;
+}
+
 /* Parse a number, beginning with character C, skipping embedded
    backslash-newlines.  LEADING_PERIOD is nonzero if there was a "."
    before C.  Place the result in NUMBER.  */
@@ -644,8 +872,7 @@ parse_number (pfile, number, leading_period)
   /* Fast-path loop.  Skim over a normal number.
      N.B. ISIDNUM does not include $.  */
   cur = pfile->buffer->cur;
-
-  while (ISXDIGIT (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]) || VALID_HEX (*cur, cur[-1]))
+  while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
     cur++;
 
   /* Check for slow-path cases.  */
@@ -1163,7 +1390,10 @@ _cpp_lex_direct (pfile)
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
       result->type = CPP_NUMBER;
-      parse_number (pfile, &result->val.str, 0);
+      if (CPP_OPTION(pfile, pedantic_parse_number))
+        pedantic_parse_number (pfile, &result->val.str, 0);
+      else
+        parse_number (pfile, &result->val.str, 0);
       break;
 
     case 'L':
@@ -1366,7 +1596,10 @@ _cpp_lex_direct (pfile)
       else if (ISDIGIT (c))
        {
          result->type = CPP_NUMBER;
-         parse_number (pfile, &result->val.str, 1);
+          if (CPP_OPTION(pfile, pedantic_parse_number))
+            pedantic_parse_number (pfile, &result->val.str, 1);
+          else
+           parse_number (pfile, &result->val.str, 1);
        }
       else if (c == '*' && CPP_OPTION (pfile, cplusplus))
        result->type = CPP_DOT_STAR;
index e903bca8c798e90062165d7dab1c2a2ab691dd54..6d2984a7202fe6d06aa2c2a7a0ebe3a910a159c7 100644 (file)
@@ -123,6 +123,7 @@ static void do_pragma_once  PARAMS ((cpp_reader *));
 static void do_pragma_poison   PARAMS ((cpp_reader *));
 static void do_pragma_sdcc_hash PARAMS ((cpp_reader *));
 static void do_pragma_preproc_asm      PARAMS ((cpp_reader *));
+static void do_pragma_pedantic_parse_number PARAMS ((cpp_reader *));
 static void do_pragma_system_header    PARAMS ((cpp_reader *));
 static void do_pragma_dependency       PARAMS ((cpp_reader *));
 static void do_linemarker              PARAMS ((cpp_reader *));
@@ -1089,6 +1090,8 @@ _cpp_init_internal_pragmas (pfile)
   cpp_register_pragma(pfile, 0, "sdcc_hash", do_pragma_sdcc_hash);
   /* SDCC _asm specific */
   cpp_register_pragma(pfile, 0, "preproc_asm", do_pragma_preproc_asm);
+  /* SDCC specific */
+  cpp_register_pragma(pfile, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number);
 }
 
 /* Pragmata handling.  We handle some, and pass the rest on to the
@@ -1193,21 +1196,44 @@ do_pragma_poison (pfile)
 static void
 do_pragma_sdcc_hash (pfile)
      cpp_reader *pfile;
+{
+  const cpp_token *tok = _cpp_lex_token (pfile);
+
+  if (tok->type == CPP_PLUS)
+    {
+      CPP_OPTION(pfile, allow_naked_hash)++;
+    }
+  else if (tok->type == CPP_MINUS)
+    {
+      CPP_OPTION(pfile, allow_naked_hash)--;
+    }
+  else
+    {
+      cpp_error (pfile, DL_ERROR,
+                 "invalid #pragma sdcc_hash directive, need '+' or '-'");
+    }
+}
+
+/* SDCC specific
+   pedantic_parse_number pragma */
+static void
+do_pragma_pedantic_parse_number (pfile)
+     cpp_reader *pfile;
 {
     const cpp_token *tok = _cpp_lex_token (pfile);
 
-    if (tok->type == CPP_PLUS)
+  if (tok->type == CPP_PLUS)
     {
-       CPP_OPTION(pfile, allow_naked_hash)++;
+      CPP_OPTION(pfile, pedantic_parse_number)++;
     }
-    else if (tok->type == CPP_MINUS)
+  else if (tok->type == CPP_MINUS)
     {
-       CPP_OPTION(pfile, allow_naked_hash)--;
+      CPP_OPTION(pfile, pedantic_parse_number)--;
     }
-    else
+  else
     {
-       cpp_error (pfile, DL_ERROR,
-                  "invalid #pragma sdcc_hash directive, need '+' or '-'");
+      cpp_error (pfile, DL_ERROR,
+                 "invalid #pragma pedantic_parse_number directive, need '+' or '-'");
     }
 }
 
@@ -1230,7 +1256,7 @@ do_pragma_preproc_asm (pfile)
   else
     {
       cpp_error (pfile, DL_ERROR,
-                "invalid #pragma preproc_asm directive, need '+' or '-'");
+                 "invalid #pragma preproc_asm directive, need '+' or '-'");
     }
 }
 
index 8b788128362aa578b23fb7cb29b5826de6d40c60..7875af4b98abc84a36b1b696062e45ea400d75ec 100644 (file)
@@ -403,6 +403,10 @@ struct cpp_options
      object file exetnsion */
   const char *obj_ext;
 
+  /* SDCC specific
+     pedantic_parse_number */
+  unsigned char pedantic_parse_number;
+
   /* Dependency generation.  */
   struct
   {
index 1c96fddcccad430fc6d1fb57e0df9c8f8e0c83ee..6b5551f34de2feec1ba8e3266bd21ee7531e3b0b 100644 (file)
@@ -1245,6 +1245,8 @@ new_pending_directive (pend, text, handler)
   DEF_OPT("obj-ext=",                 no_arg, OPT_obj_ext)                    \
   DEF_OPT("pedantic",                 0,      OPT_pedantic)                   \
   DEF_OPT("pedantic-errors",          0,      OPT_pedantic_errors)            \
+  /* SDCC specific */                                                         \
+  DEF_OPT("pedantic-parse-number",    0,      OPT_pedantic_parse_number)      \
   DEF_OPT("remap",                    0,      OPT_remap)                      \
   DEF_OPT("std=c++98",                0,      OPT_std_cplusplus98)            \
   DEF_OPT("std=c89",                  0,      OPT_std_c89)                    \
@@ -1488,8 +1490,11 @@ cpp_handle_option (pfile, argc, argv)
        case OPT_pedantic:
          CPP_OPTION (pfile, pedantic) = 1;
          break;
+        case OPT_pedantic_parse_number:
+          CPP_OPTION (pfile, pedantic_parse_number) = 1;
+          break;
        case OPT_trigraphs:
-         CPP_OPTION (pfile, trigraphs) = 1;
+         CPP_OPTION (pfile, trigraphs) = 1;
          break;
        case OPT_plus:
          CPP_OPTION (pfile, cplusplus) = 1;
@@ -1850,6 +1855,10 @@ Switches:\n\
   -trigraphs                Support ISO C trigraphs\n\
   -lang-c                   Assume that the input sources are in C\n\
   -lang-c89                 Assume that the input sources are in C89\n\
+"), stdout);
+  /* SDCC specific */
+  fputs (_("\
+  -pedantic-parse-number    Pedantic parse number\n\
 "), stdout);
   fputs (_("\
   -lang-c++                 Assume that the input sources are in C++\n\
@@ -1890,7 +1899,7 @@ Switches:\n\
   -MG                       Treat missing header file as generated files\n\
 "), stdout);
   fputs (_("\
-  -MP                      Generate phony targets for all headers\n\
+  -MP                       Generate phony targets for all headers\n\
   -MQ <target>              Add a MAKE-quoted target\n\
   -MT <target>              Add an unquoted target\n\
 "), stdout);