daily update
[deliverable/binutils-gdb.git] / gas / macro.c
index fbe266612c30036434e397a36d636bbbca3ce22a..d7d470b764eb31355e0a3b6173848a8c7e57d69e 100644 (file)
@@ -1,6 +1,6 @@
 /* macro.c - macro support for gas
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005 Free Software Foundation, Inc.
+   2004, 2005, 2006 Free Software Foundation, Inc.
 
    Written by Steve and Judy Chamberlain of Cygnus Support,
       sac@cygnus.com
    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
-#include "config.h"
-
-#ifndef __GNUC__
-# if HAVE_ALLOCA_H
-#  include <alloca.h>
-# else
-#  ifdef _AIX
-/* Indented so that pre-ansi C compilers will ignore it, rather than
-   choke on it.  Some versions of AIX require this to be the first
-   thing in the file.  */
- #pragma alloca
-#  else
-#   ifndef alloca /* predefined by HP cc +Olibcalls */
-#    if !defined (__STDC__) && !defined (__hpux)
-extern char *alloca ();
-#    else
-extern void *alloca ();
-#    endif /* __STDC__, __hpux */
-#   endif /* alloca */
-#  endif /* _AIX */
-# endif /* HAVE_ALLOCA_H */
-#endif /* __GNUC__ */
-
-#include <stdio.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
 #include "as.h"
-#include "libiberty.h"
 #include "safe-ctype.h"
 #include "sb.h"
-#include "hash.h"
 #include "macro.h"
 
-#include "asintl.h"
-
 /* The routines in this file handle macro definition and expansion.
    They are called by gas.  */
 
@@ -180,49 +144,46 @@ buffer_and_nest (const char *from, const char *to, sb *ptr,
 
   while (more)
     {
-      /* Try and find the first pseudo op on the line.  */
+      /* Try to find the first pseudo op on the line.  */
       int i = line_start;
 
-      if (! NO_PSEUDO_DOT && ! flag_m68k_mri)
-       {
-         /* With normal syntax we can suck what we want till we get
-            to the dot.  With the alternate, labels have to start in
-            the first column, since we can't tell what's a label and
-            whats a pseudoop.  */
+      /* With normal syntax we can suck what we want till we get
+        to the dot.  With the alternate, labels have to start in
+        the first column, since we can't tell what's a label and
+        what's a pseudoop.  */
 
-         if (! LABELS_WITHOUT_COLONS)
-           {
-             /* Skip leading whitespace.  */
-             while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-               i++;
-           }
+      if (! LABELS_WITHOUT_COLONS)
+       {
+         /* Skip leading whitespace.  */
+         while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+           i++;
+       }
 
-         for (;;)
+      for (;;)
+       {
+         /* Skip over a label, if any.  */
+         if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+           break;
+         i++;
+         while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+           i++;
+         if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+           i++;
+         if (LABELS_WITHOUT_COLONS)
+           break;
+         /* Skip whitespace.  */
+         while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+           i++;
+         /* Check for the colon.  */
+         if (i >= ptr->len || ptr->ptr[i] != ':')
            {
-             /* Skip over a label, if any.  */
-             if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
-               break;
-             i++;
-             while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
-               i++;
-             if (i < ptr->len && is_name_ender (ptr->ptr[i]))
-               i++;
-             if (LABELS_WITHOUT_COLONS)
-               break;
-             /* Skip whitespace.  */
-             while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-               i++;
-             /* Check for the colon.  */
-             if (i >= ptr->len || ptr->ptr[i] != ':')
-               {
-                 i = line_start;
-                 break;
-               }
-             i++;
-             line_start = i;
+             i = line_start;
+             break;
            }
-
+         i++;
+         line_start = i;
        }
+
       /* Skip trailing whitespace.  */
       while (i < ptr->len && ISWHITE (ptr->ptr[i]))
        i++;
@@ -306,19 +267,14 @@ getstring (int idx, sb *in, sb *acc)
 {
   while (idx < in->len
         && (in->ptr[idx] == '"'
-            || in->ptr[idx] == '('
             || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
             || (in->ptr[idx] == '\'' && macro_alternate)))
     {
-      if (in->ptr[idx] == '<'
-         || in->ptr[idx] == '(')
+      if (in->ptr[idx] == '<')
        {
          int nest = 0;
-         char start_char = in->ptr[idx];
-         char end_char = in->ptr[idx] == '<' ? '>' : ')';
-
          idx++;
-         while ((in->ptr[idx] != end_char || nest)
+         while ((in->ptr[idx] != '>' || nest)
                 && idx < in->len)
            {
              if (in->ptr[idx] == '!')
@@ -328,9 +284,9 @@ getstring (int idx, sb *in, sb *acc)
                }
              else
                {
-                 if (in->ptr[idx] == end_char)
+                 if (in->ptr[idx] == '>')
                    nest--;
-                 if (in->ptr[idx] == start_char)
+                 if (in->ptr[idx] == '<')
                    nest++;
                  sb_add_char (acc, in->ptr[idx++]);
                }
@@ -389,7 +345,7 @@ getstring (int idx, sb *in, sb *acc)
     'Bxyx<whitespace>          -> return 'Bxyza
     %<expr>            -> return string of decimal value of <expr>
     "string"           -> return string
-    (string)           -> return string
+    (string)           -> return (string-including-whitespaces)
     xyx<whitespace>     -> return xyz.  */
 
 static int
@@ -420,17 +376,15 @@ get_any_string (int idx, sb *in, sb *out)
          sb_add_string (out, buf);
        }
       else if (in->ptr[idx] == '"'
-              || in->ptr[idx] == '('
               || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
               || (macro_alternate && in->ptr[idx] == '\''))
        {
-         if (macro_alternate && ! macro_strip_at)
+         if (macro_alternate && ! macro_strip_at && in->ptr[idx] != '<')
            {
              /* Keep the quotes.  */
-             sb_add_char (out, '\"');
-
+             sb_add_char (out, '"');
              idx = getstring (idx, in, out);
-             sb_add_char (out, '\"');
+             sb_add_char (out, '"');
            }
          else
            {
@@ -439,27 +393,57 @@ get_any_string (int idx, sb *in, sb *out)
        }
       else
        {
+         char *br_buf = xmalloc(1);
+         char *in_br = br_buf;
+
+         *in_br = '\0';
          while (idx < in->len
-                && in->ptr[idx] != ' '
-                && in->ptr[idx] != '\t'
+                && (*in_br
+                    || (in->ptr[idx] != ' '
+                        && in->ptr[idx] != '\t'))
                 && in->ptr[idx] != ','
                 && (in->ptr[idx] != '<'
                     || (! macro_alternate && ! macro_mri)))
            {
-             if (in->ptr[idx] == '"'
-                 || in->ptr[idx] == '\'')
-               {
-                 char tchar = in->ptr[idx];
+             char tchar = in->ptr[idx];
 
+             switch (tchar)
+               {
+               case '"':
+               case '\'':
                  sb_add_char (out, in->ptr[idx++]);
                  while (idx < in->len
                         && in->ptr[idx] != tchar)
                    sb_add_char (out, in->ptr[idx++]);
                  if (idx == in->len)
                    return idx;
+                 break;
+               case '(':
+               case '[':
+                 if (in_br > br_buf)
+                   --in_br;
+                 else
+                   {
+                     br_buf = xmalloc(strlen(in_br) + 2);
+                     strcpy(br_buf + 1, in_br);
+                     free(in_br);
+                     in_br = br_buf;
+                   }
+                 *in_br = tchar;
+                 break;
+               case ')':
+                 if (*in_br == '(')
+                   ++in_br;
+                 break;
+               case ']':
+                 if (*in_br == '[')
+                   ++in_br;
+                 break;
                }
-             sb_add_char (out, in->ptr[idx++]);
+             sb_add_char (out, tchar);
+             ++idx;
            }
+         free(br_buf);
        }
     }
 
@@ -1005,7 +989,6 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out)
   sb t;
   formal_entry *ptr;
   formal_entry *f;
-  int is_positional = 0;
   int is_keyword = 0;
   int narg = 0;
   const char *err = NULL;
@@ -1096,8 +1079,6 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out)
        }
       else
        {
-         /* This is a positional arg.  */
-         is_positional = 1;
          if (is_keyword)
            {
              err = _("can't mix positional and keyword arguments");
@@ -1344,8 +1325,14 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
     }
   else
     {
+      bfd_boolean in_quotes = FALSE;
+
       if (irpc && in->ptr[idx] == '"')
-       ++idx;
+       {
+         in_quotes = TRUE;
+         ++idx;
+       }
+
       while (idx < in->len)
        {
          if (!irpc)
@@ -1356,6 +1343,9 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
                {
                  int nxt;
 
+                 if (irpc)
+                   in_quotes = ! in_quotes;
+         
                  nxt = sb_skip_white (idx + 1, in);
                  if (nxt >= in->len)
                    {
@@ -1367,12 +1357,13 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
              sb_add_char (&f.actual, in->ptr[idx]);
              ++idx;
            }
+
          err = macro_expand_body (&sub, out, &f, h, 0);
          if (err != NULL)
            break;
          if (!irpc)
            idx = sb_skip_comma (idx, in);
-         else
+         else if (! in_quotes)
            idx = sb_skip_white (idx, in);
        }
     }
This page took 0.145962 seconds and 4 git commands to generate.