include/
[external/binutils.git] / gas / app.c
index e6b39d6..56a0e12 100644 (file)
--- a/gas/app.c
+++ b/gas/app.c
@@ -1,19 +1,19 @@
 /* This is the Assembler Pre-Processor
    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2006, 2007
+   1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS 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 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
-   GAS is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   GAS is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
 #endif
 #endif
 
+#ifdef H_TICK_HEX
+int enable_h_tick_hex = 0;
+#endif
+
 #ifdef TC_M68K
 /* Whether we are scrubbing in m68k MRI mode.  This is different from
    flag_m68k_mri, because the two flags will be affected by the .mri
@@ -78,6 +82,9 @@ static const char symbol_chars[] =
 #define LEX_IS_DOUBLEBAR_1ST           13
 #endif
 #define LEX_IS_PARALLEL_SEPARATOR      14
+#ifdef H_TICK_HEX
+#define LEX_IS_H                       15
+#endif
 #define IS_SYMBOL_COMPONENT(c)         (lex[c] == LEX_IS_SYMBOL_COMPONENT)
 #define IS_WHITESPACE(c)               (lex[c] == LEX_IS_WHITESPACE)
 #define IS_LINE_SEPARATOR(c)           (lex[c] == LEX_IS_LINE_SEPARATOR)
@@ -190,6 +197,14 @@ do_scrub_begin (int m68k_mri ATTRIBUTE_UNUSED)
   /* Must do this is we want VLIW instruction with "->" or "<-".  */
   lex['-'] = LEX_IS_SYMBOL_COMPONENT;
 #endif
+
+#ifdef H_TICK_HEX
+  if (enable_h_tick_hex)
+    {
+      lex['h'] = LEX_IS_H;
+      lex['H'] = LEX_IS_H;
+    }
+#endif
 }
 
 /* Saved state of the scrubber.  */
@@ -243,7 +258,7 @@ app_push (void)
     saved->saved_input = NULL;
   else
     {
-      saved->saved_input = xmalloc (saved_input_len);
+      saved->saved_input = (char *) xmalloc (saved_input_len);
       memcpy (saved->saved_input, saved_input, saved_input_len);
       saved->saved_input_len = saved_input_len;
     }
@@ -279,7 +294,7 @@ app_pop (char *arg)
     saved_input = NULL;
   else
     {
-      assert (saved->saved_input_len <= (int) (sizeof input_buffer));
+      gas_assert (saved->saved_input_len <= (int) (sizeof input_buffer));
       memcpy (input_buffer, saved->saved_input, saved->saved_input_len);
       saved_input = input_buffer;
       saved_input_len = saved->saved_input_len;
@@ -355,7 +370,7 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          5: parsing a string, then go to old-state
          6: putting out \ escape in a "d string.
          7: no longer used
-         8: After putting out a .appfile string, flush until newline.
+         8: no longer used
          9: After seeing symbol char in state 3 (keep 1white after symchar)
         10: After seeing whitespace in state 9 (keep white before symchar)
         11: After seeing a symbol character in state 0 (eg a label definition)
@@ -510,11 +525,10 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
                ch = GET ();
              if (ch == '"')
                {
-                 PUT (' ');
-                 PUT (ch);
                  quotechar = ch;
                  state = 5;
-                 old_state = 8;
+                 old_state = 3;
+                 PUT (ch);
                }
              else
                {
@@ -551,14 +565,22 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
                memcpy (to, from, len);
                to += len;
                from += len;
+               if (to >= toend)
+                 goto tofull;
              }
          }
 
          ch = GET ();
          if (ch == EOF)
            {
+             /* This buffer is here specifically so
+                that the UNGET below will work.  */
+             static char one_char_buf[1];
+
              as_warn (_("end of file in string; '%c' inserted"), quotechar);
              state = old_state;
+             from = fromend = one_char_buf + 1;
+             fromlen = 1;
              UNGET ('\n');
              PUT (quotechar);
            }
@@ -635,16 +657,6 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          PUT (ch);
          continue;
 
-       case 8:
-         do
-           if ((ch = GET ()) == EOF)
-             goto fromeof;
-           else
-             PUT (ch);
-         while (ch != '\n');
-         state = 0;
-         continue;
-
 #ifdef DOUBLEBAR_PARALLEL
        case 13:
          ch = GET ();
@@ -679,7 +691,7 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          if (ch == '\'')
            /* Change to avoid warning about unclosed string.  */
            PUT ('`');
-         else
+         else if (ch != EOF)
            UNGET (ch);
          break;
 #endif
@@ -835,7 +847,8 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
              /* Only keep this white if there's no white *after* the
                 colon.  */
              ch2 = GET ();
-             UNGET (ch2);
+             if (ch2 != EOF)
+               UNGET (ch2);
              if (!IS_WHITESPACE (ch2))
                {
                  state = 9;
@@ -1011,6 +1024,16 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
 
 #ifndef IEEE_STYLE
        case LEX_IS_ONECHAR_QUOTE:
+#ifdef H_TICK_HEX
+         if (state == 9 && enable_h_tick_hex)
+           {
+             char c;
+
+             c = GET ();
+             as_warn ("'%c found after symbol", c);
+             UNGET (c);
+           }
+#endif
          if (state == 10)
            {
              /* Preserve the whitespace in foo 'b'.  */
@@ -1099,7 +1122,8 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          ch2 = GET ();
          if (ch2 != '-')
            {
-             UNGET (ch2);
+             if (ch2 != EOF)
+               UNGET (ch2);
              goto de_fault;
            }
          /* Read and skip to end of line.  */
@@ -1119,7 +1143,8 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
 #ifdef DOUBLEBAR_PARALLEL
        case LEX_IS_DOUBLEBAR_1ST:
          ch2 = GET ();
-         UNGET (ch2);
+         if (ch2 != EOF)
+           UNGET (ch2);
          if (ch2 != '|')
            goto de_fault;
 
@@ -1230,6 +1255,15 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          if ((symver_state != NULL) && (*symver_state == 0))
            goto de_fault;
 #endif
+
+#ifdef TC_ARM
+         /* For the ARM, care is needed not to damage occurrences of \@
+            by stripping the @ onwards.  Yuck.  */
+         if (to > tostart && *(to - 1) == '\\')
+           /* Do not treat the @ as a start-of-comment.  */
+           goto de_fault;
+#endif
+
 #ifdef WARN_COMMENTS
          if (!found_comment)
            as_where (&found_comment_file, &found_comment);
@@ -1245,6 +1279,26 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
          PUT ('\n');
          break;
 
+#ifdef H_TICK_HEX
+       case LEX_IS_H:
+         /* Look for strings like H'[0-9A-Fa-f] and if found, replace
+            the H' with 0x to make them gas-style hex characters.  */
+         if (enable_h_tick_hex)
+           {
+             char quot;
+
+             quot = GET ();
+             if (quot == '\'')
+               {
+                 UNGET ('x');
+                 ch = '0';
+               }
+             else
+               UNGET (quot);
+           }
+         /* FALL THROUGH */
+#endif
+
        case LEX_IS_SYMBOL_COMPONENT:
          if (state == 10)
            {
@@ -1275,7 +1329,8 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
                  state = 9;
                  if (!IS_SYMBOL_COMPONENT (ch)) 
                    {
-                     UNGET (ch);
+                     if (ch != EOF)
+                       UNGET (ch);
                      break;
                    }
                }
@@ -1362,7 +1417,15 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
                     the space.  We don't have enough information to
                     make the right choice, so here we are making the
                     choice which is more likely to be correct.  */
-                 PUT (' ');
+                 if (to + 1 >= toend)
+                   {
+                     /* If we're near the end of the buffer, save the
+                        character for the next time round.  Otherwise
+                        we'll lose our state.  */
+                     UNGET (ch);
+                     goto tofull;
+                   }
+                 *to++ = ' ';
                }
 
              state = 3;
@@ -1391,4 +1454,3 @@ do_scrub_chars (int (*get) (char *, int), char *tostart, int tolen)
 
   return to - tostart;
 }
-