]> Git Repo - binutils.git/blobdiff - gas/app.c
Warn rather than cause an error if the reloc is not compatible with -mrelocatable.
[binutils.git] / gas / app.c
index 1983c3ca6a88bfafcb2ca6941d7f6847ecec5b95..9ed97ebdca28777ebd4e2ec11de3f8042f1dddfd 100644 (file)
--- a/gas/app.c
+++ b/gas/app.c
@@ -1,9 +1,5 @@
-/* Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
-
-   Modified by Allen Wirfs-Brock, Instantiations Inc 2/90
-   */
 /* This is the Assembler Pre-Processor
-   Copyright (C) 1987 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    along with GAS; see the file COPYING.  If not, write to
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90 */
 /* App, the assembler pre-processor.  This pre-processor strips out excess
    spaces, turns single-quoted characters into a decimal constant, and turns
-   # <number> <filename> <garbage> into a .line <number>\n.app-file <filename>
+   # <number> <filename> <garbage> into a .line <number>\n.file <filename>
    pair.  This needs better error-handling.
    */
 
 #include <stdio.h>
 #include "as.h"                        /* For BAD_CASE() only */
 
-#if (__STDC__ != 1) && !defined(const)
-#define const                  /* Nothing */
+#if (__STDC__ != 1)
+#ifndef const
+#define const  /* empty */
+#endif
 #endif
 
 static char lex[256];
@@ -56,6 +55,8 @@ static const char symbol_chars[] =
 #define IS_LINE_COMMENT(c)             (lex[c] == LEX_IS_LINE_COMMENT_START)
 #define        IS_NEWLINE(c)                   (lex[c] == LEX_IS_NEWLINE)
 
+static int process_escape PARAMS ((int));
+
 /* FIXME-soon: The entire lexer/parser thingy should be
    built statically at compile time rather than dynamically
    each and every time the assembler is run.  xoxorich. */
@@ -70,7 +71,9 @@ do_scrub_begin ()
   lex['\n'] = LEX_IS_NEWLINE;
   lex[';'] = LEX_IS_LINE_SEPARATOR;
   lex['"'] = LEX_IS_STRINGQUOTE;
+#ifndef TC_HPPA
   lex['\''] = LEX_IS_ONECHAR_QUOTE;
+#endif
   lex[':'] = LEX_IS_COLON;
 
 
@@ -84,22 +87,22 @@ do_scrub_begin ()
           is a comment char, then it isn't a line separator.  */
   for (p = symbol_chars; *p; ++p)
     {
-      lex[*p] = LEX_IS_SYMBOL_COMPONENT;
+      lex[(unsigned char) *p] = LEX_IS_SYMBOL_COMPONENT;
     }                          /* declare symbol characters */
 
-  for (p = line_comment_chars; *p; p++)
-    {
-      lex[*p] = LEX_IS_LINE_COMMENT_START;
-    }                          /* declare line comment chars */
-
   for (p = comment_chars; *p; p++)
     {
-      lex[*p] = LEX_IS_COMMENT_START;
+      lex[(unsigned char) *p] = LEX_IS_COMMENT_START;
     }                          /* declare comment chars */
 
+  for (p = line_comment_chars; *p; p++)
+    {
+      lex[(unsigned char) *p] = LEX_IS_LINE_COMMENT_START;
+    }                          /* declare line comment chars */
+
   for (p = line_separator_chars; *p; p++)
     {
-      lex[*p] = LEX_IS_LINE_SEPARATOR;
+      lex[(unsigned char) *p] = LEX_IS_LINE_SEPARATOR;
     }                          /* declare line separators */
 
   /* Only allow slash-star comments if slash is not in use */
@@ -180,7 +183,7 @@ app_push ()
   saved->state = state;
   saved->old_state = old_state;
   saved->out_string = out_string;
-  memcpy (out_buf, saved->out_buf, sizeof (out_buf));
+  memcpy (saved->out_buf, out_buf, sizeof (out_buf));
   saved->add_newlines = add_newlines;
   saved->scrub_string = scrub_string;
   saved->scrub_last_string = scrub_last_string;
@@ -200,7 +203,7 @@ app_pop (arg)
   state = saved->state;
   old_state = saved->old_state;
   out_string = saved->out_string;
-  memcpy (saved->out_buf, out_buf, sizeof (out_buf));
+  memcpy (out_buf, saved->out_buf, sizeof (out_buf));
   add_newlines = saved->add_newlines;
   scrub_string = saved->scrub_string;
   scrub_last_string = saved->scrub_last_string;
@@ -211,9 +214,9 @@ app_pop (arg)
 
 /* @@ This assumes that \n &c are the same on host and target.  This is not
    necessarily true.  */
-int 
+static int 
 process_escape (ch)
-     char ch;
+     int ch;
 {
   switch (ch)
     {
@@ -247,21 +250,22 @@ do_scrub_next_char (get, unget)
          4: after putting out a .line, put out digits
          5: parsing a string, then go to old-state
          6: putting out \ escape in a "d string.
-         7: After putting out a .app-file, put out string.
-         8: After putting out a .app-file string, flush until newline.
+         7: After putting out a .appfile, put out string.
+         8: After putting out a .appfile string, flush until newline.
          9: After seeing symbol char in state 3 (keep 1white after symchar)
+        10: After seeing whitespace in state 9 (keep white before symchar)
          -1: output string in out_string and go to the state in old_state
          -2: flush text until a '*' '/' is seen, then go to state old_state
          */
 
-  /* I added state 9 because the MIPS ECOFF assembler uses constructs
-     like ``.loc 1 20''.  This was turning into ``.loc 120''.  State 9
-     ensures that a space is never dropped immediately following a
-     character which could appear in a identifier.  It is still
-     dropped following a comma, so this has no effect for most
-     assemblers.  I hope.  Ian Taylor, [email protected].  */
+  /* I added states 9 and 10 because the MIPS ECOFF assembler uses
+     constructs like ``.loc 1 20''.  This was turning into ``.loc
+     120''.  States 9 and 10 ensure that a space is never dropped in
+     between characters which could appear in a identifier.  Ian
+     Taylor, [email protected].  */
 
   register int ch, ch2 = 0;
+  int not_cpp_line = 0;
 
   switch (state)
     {
@@ -308,7 +312,7 @@ do_scrub_next_char (get, unget)
          if (ch == '"')
            {
              (*unget) (ch);
-             out_string = "\n.app-file ";
+             out_string = "\n\t.appfile ";
              old_state = 7;
              state = -1;
              return *out_string++;
@@ -317,6 +321,7 @@ do_scrub_next_char (get, unget)
            {
              while (ch != EOF && ch != '\n')
                ch = (*get) ();
+             state = 0;
              return ch;
            }
        }
@@ -367,6 +372,8 @@ do_scrub_next_char (get, unget)
 #ifdef BACKSLASH_V
        case 'v':
 #endif /* BACKSLASH_V */
+       case 'x':
+       case 'X':
        case '0':
        case '1':
        case '2':
@@ -406,7 +413,7 @@ do_scrub_next_char (get, unget)
       return ch;
     }
 
-  /* OK, we are somewhere in states 0 through 4 or 9 */
+  /* OK, we are somewhere in states 0 through 4 or 9 through 10 */
 
   /* flushchar: */
   ch = (*get) ();
@@ -422,13 +429,24 @@ recycle:
     {
     case LEX_IS_WHITESPACE:
       do
-       ch = (*get) ();
+       /* Preserve a single whitespace character at the beginning of
+          a line.  */
+       if (state == 0)
+         {
+           state = 1;
+           return ch;
+         }
+       else
+         ch = (*get) ();
       while (ch != EOF && IS_WHITESPACE (ch));
       if (ch == EOF)
        return ch;
 
       if (IS_COMMENT (ch) || (state == 0 && IS_LINE_COMMENT (ch)) || ch == '/' || IS_LINE_SEPARATOR (ch))
        {
+         /* cpp never outputs a leading space before the #, so try to
+            avoid being confused.  */
+         not_cpp_line = 1;
          goto recycle;
        }
 #ifdef MRI
@@ -452,14 +470,19 @@ recycle:
          state++;
          goto recycle;         /* Punted leading sp */
        case 1:
-         BAD_CASE (state);     /* We can't get here */
+         /* We can arrive here if we leave a leading whitespace character
+            at the beginning of a line.  */
+         goto recycle;
        case 2:
-       case 9:
          state = 3;
          (*unget) (ch);
          return ' ';           /* Sp after opco */
        case 3:
          goto recycle;         /* Sp in operands */
+       case 9:
+       case 10:
+         state = 10;           /* Sp after symbol char */
+         goto recycle;
        default:
          BAD_CASE (state);
        }
@@ -501,12 +524,17 @@ recycle:
        {
          if (ch2 != EOF)
            (*unget) (ch2);
+         if (state == 9 || state == 10)
+           state = 3;
          return ch;
        }
       break;
 
     case LEX_IS_STRINGQUOTE:
-      old_state = state;
+      if (state == 9 || state == 10)
+       old_state = 3;
+      else
+       old_state = state;
       state = 5;
       return ch;
 #ifndef MRI
@@ -526,8 +554,7 @@ recycle:
       sprintf (out_buf, "%d", (int) (unsigned char) ch);
 
 
-      /* None of these 'x constants for us.  We want 'x'.
-                */
+      /* None of these 'x constants for us.  We want 'x'.  */
       if ((ch = (*get) ()) != '\'')
        {
 #ifdef REQUIRE_CHAR_CLOSE_QUOTE
@@ -540,14 +567,19 @@ recycle:
        {
          return out_buf[0];
        }
-      old_state = state;
+      if (state == 9 || state == 10)
+       old_state = 3;
+      else
+       old_state = state;
       state = -1;
       out_string = out_buf;
       return *out_string++;
 #endif
 #endif
     case LEX_IS_COLON:
-      if (state != 3)
+      if (state == 9 || state == 10)
+       state = 3;
+      else if (state != 3)
        state = 0;
       return ch;
 
@@ -565,53 +597,61 @@ recycle:
       return ch;
 
     case LEX_IS_LINE_COMMENT_START:
-      if (state != 0)          /* Not at start of line, act normal */
-       goto de_fault;
+      if (state == 0)          /* Only comment at start of line.  */
+       {
+         /* FIXME-someday: The two character comment stuff was badly
+            thought out.  On i386, we want '/' as line comment start
+            AND we want C style comments.  hence this hack.  The
+            whole lexical process should be reworked.  xoxorich.  */
+         if (ch == '/')
+           {
+             ch2 = (*get) ();
+             if (ch2 == '*')
+               {
+                 state = -2;
+                 return (do_scrub_next_char (get, unget));
+               }
+             else
+               {
+                 (*unget) (ch2);
+               }
+           }                   /* bad hack */
 
-      /* FIXME-someday: The two character comment stuff was badly
-        thought out.  On i386, we want '/' as line comment start AND
-        we want C style comments.  hence this hack.  The whole
-        lexical process should be reworked.  xoxorich.  */
+         if (ch != '#')
+           not_cpp_line = 1;
 
-      if (ch == '/')
-       {
-         ch2 = (*get) ();
-         if (ch2 == '*')
+         do
+           ch = (*get) ();
+         while (ch != EOF && IS_WHITESPACE (ch));
+         if (ch == EOF)
            {
-             state = -2;
-             return (do_scrub_next_char (get, unget));
+             as_warn ("EOF in comment:  Newline inserted");
+             return '\n';
            }
-         else
+         if (ch < '0' || ch > '9' || not_cpp_line)
            {
-             (*unget) (ch2);
+             /* Non-numerics:  Eat whole comment line */
+             while (ch != EOF && !IS_NEWLINE (ch))
+               ch = (*get) ();
+             if (ch == EOF)
+               as_warn ("EOF in Comment: Newline inserted");
+             state = 0;
+             return '\n';
            }
-       }                       /* bad hack */
-
-      do
-       ch = (*get) ();
-      while (ch != EOF && IS_WHITESPACE (ch));
-      if (ch == EOF)
-       {
-         as_warn ("EOF in comment:  Newline inserted");
-         return '\n';
-       }
-      if (ch < '0' || ch > '9')
-       {
-         /* Non-numerics:  Eat whole comment line */
-         while (ch != EOF && !IS_NEWLINE (ch))
-           ch = (*get) ();
-         if (ch == EOF)
-           as_warn ("EOF in Comment: Newline inserted");
-         state = 0;
-         return '\n';
+         /* Numerics begin comment.  Perhaps CPP `# 123 "filename"' */
+         (*unget) (ch);
+         old_state = 4;
+         state = -1;
+         out_string = "\t.appline ";
+         return *out_string++;
        }
-      /* Numerics begin comment.  Perhaps CPP `# 123 "filename"' */
-      (*unget) (ch);
-      old_state = 4;
-      state = -1;
-      out_string = ".line ";
-      return *out_string++;
 
+      /* We have a line comment character which is not at the start of
+        a line.  If this is also a normal comment character, fall
+        through.  Otherwise treat it as a default character.  */
+      if (strchr (comment_chars, ch) == NULL)
+       goto de_fault;
+      /* Fall through.  */
     case LEX_IS_COMMENT_START:
       do
        ch = (*get) ();
@@ -622,6 +662,15 @@ recycle:
       return '\n';
 
     case LEX_IS_SYMBOL_COMPONENT:
+      if (state == 10)
+       {
+         /* This is a symbol character following another symbol
+            character, with whitespace in between.  We skipped the
+            whitespace earlier, so output it now.  */
+         (*unget) (ch);
+         state = 3;
+         return ' ';
+       }
       if (state == 3)
        state = 9;
       /* Fall through.  */
@@ -644,6 +693,11 @@ recycle:
            state = 3;
          return ch;
        }
+      else if (state == 10)
+       {
+         state = 3;
+         return ch;
+       }
       else
        {
          return ch;            /* Opcode or operands already */
@@ -675,11 +729,4 @@ as_warn (str)
 
 #endif
 
-/*
- * Local Variables:
- * comment-column: 0
- * fill-column: 131
- * End:
- */
-
 /* end of app.c */
This page took 0.038796 seconds and 4 git commands to generate.