* gas/all/assign.s: New.
[deliverable/binutils-gdb.git] / gas / macro.c
index 2173d00a17cb5ad19691666df49a526775fd2cd6..4f934ae52de73d540fdb48f42b033b12df55a163 100644 (file)
@@ -1,6 +1,6 @@
 /* macro.c - macro support for gas
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005 Free Software Foundation, Inc.
 
    Written by Steve and Judy Chamberlain of Cygnus Support,
       sac@cygnus.com
@@ -152,6 +152,7 @@ macro_mri_mode (int mri)
 /* Read input lines till we get to a TO string.
    Increase nesting depth if we get a FROM string.
    Put the results into sb at PTR.
+   FROM may be NULL (or will be ignored) if TO is "ENDR".
    Add a new input line to an sb using GET_LINE.
    Return 1 on success, 0 on unexpected EOF.  */
 
@@ -159,40 +160,64 @@ int
 buffer_and_nest (const char *from, const char *to, sb *ptr,
                 int (*get_line) (sb *))
 {
-  int from_len = strlen (from);
+  int from_len;
   int to_len = strlen (to);
   int depth = 1;
   int line_start = ptr->len;
 
   int more = get_line (ptr);
 
+  if (to_len == 4 && strcasecmp(to, "ENDR") == 0)
+    {
+      from = NULL;
+      from_len = 0;
+    }
+  else
+    from_len = strlen (from);
+
   while (more)
     {
       /* Try and find the first pseudo op on the line.  */
       int i = line_start;
 
-      if (! macro_alternate && ! macro_mri)
+      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 cant tell what's a label and
+            the first column, since we can't tell what's a label and
             whats a pseudoop.  */
 
-         /* Skip leading whitespace.  */
-         while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-           i++;
-
-         /* Skip over a label.  */
-         while (i < ptr->len
-                && (ISALNUM (ptr->ptr[i])
-                    || ptr->ptr[i] == '_'
-                    || ptr->ptr[i] == '$'))
-           i++;
+         if (! LABELS_WITHOUT_COLONS)
+           {
+             /* Skip leading whitespace.  */
+             while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+               i++;
+           }
 
-         /* And a colon.  */
-         if (i < ptr->len
-             && ptr->ptr[i] == ':')
-           i++;
+         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] != ':')
+               {
+                 i = line_start;
+                 break;
+               }
+             i++;
+             line_start = i;
+           }
 
        }
       /* Skip trailing whitespace.  */
@@ -200,18 +225,30 @@ buffer_and_nest (const char *from, const char *to, sb *ptr,
        i++;
 
       if (i < ptr->len && (ptr->ptr[i] == '.'
-                          || macro_alternate
+                          || NO_PSEUDO_DOT
                           || macro_mri))
        {
-         if (ptr->ptr[i] == '.')
+         if (! flag_m68k_mri && ptr->ptr[i] == '.')
            i++;
-         if (strncasecmp (ptr->ptr + i, from, from_len) == 0
+         if (from == NULL
+            && strncasecmp (ptr->ptr + i, "IRPC", from_len = 4) != 0
+            && strncasecmp (ptr->ptr + i, "IRP", from_len = 3) != 0
+            && strncasecmp (ptr->ptr + i, "IREPC", from_len = 5) != 0
+            && strncasecmp (ptr->ptr + i, "IREP", from_len = 4) != 0
+            && strncasecmp (ptr->ptr + i, "REPT", from_len = 4) != 0
+            && strncasecmp (ptr->ptr + i, "REP", from_len = 3) != 0)
+           from_len = 0;
+         if ((from != NULL
+              ? strncasecmp (ptr->ptr + i, from, from_len) == 0
+              : from_len > 0)
              && (ptr->len == (i + from_len)
-                 || ! ISALNUM (ptr->ptr[i + from_len])))
+                 || ! (is_part_of_name (ptr->ptr[i + from_len])
+                       || is_name_ender (ptr->ptr[i + from_len]))))
            depth++;
          if (strncasecmp (ptr->ptr + i, to, to_len) == 0
              && (ptr->len == (i + to_len)
-                 || ! ISALNUM (ptr->ptr[i + to_len])))
+                 || ! (is_part_of_name (ptr->ptr[i + to_len])
+                       || is_name_ender (ptr->ptr[i + to_len]))))
            {
              depth--;
              if (depth == 0)
@@ -239,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-         || in->ptr[idx] == '_'
-         || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-            && (ISALNUM (in->ptr[idx])
-                || in->ptr[idx] == '_'
-                || in->ptr[idx] == '$'))
+            && is_part_of_name (in->ptr[idx]))
+       {
+         sb_add_char (name, in->ptr[idx++]);
+       }
+      if (idx < in->len
+            && is_name_ender (in->ptr[idx]))
        {
          sb_add_char (name, in->ptr[idx++]);
        }
@@ -673,13 +711,14 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
          else
            {
              /* FIXME: Why do we do this?  */
+             /* At least in alternate mode this seems correct.  */
              src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
            }
        }
       else if (in->ptr[src] == '\\')
        {
          src++;
-         if (in->ptr[src] == '(')
+         if (src < in->len && in->ptr[src] == '(')
            {
              /* Sub in till the next ')' literally.  */
              src++;
@@ -690,9 +729,9 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              if (in->ptr[src] == ')')
                src++;
              else
-               return _("missplaced )");
+               return _("misplaced `)'");
            }
-         else if (in->ptr[src] == '@')
+         else if (src < in->len && in->ptr[src] == '@')
            {
              /* Sub in the macro invocation number.  */
 
@@ -701,7 +740,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              sprintf (buffer, "%d", macro_number);
              sb_add_string (out, buffer);
            }
-         else if (in->ptr[src] == '&')
+         else if (src < in->len && in->ptr[src] == '&')
            {
              /* This is a preprocessor variable name, we don't do them
                 here.  */
@@ -709,7 +748,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              sb_add_char (out, '&');
              src++;
            }
-         else if (macro_mri && ISALNUM (in->ptr[src]))
+         else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
            {
              int ind;
              formal_entry *f;
@@ -740,9 +779,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
            }
        }
       else if ((macro_alternate || macro_mri)
-              && (ISALPHA (in->ptr[src])
-                  || in->ptr[src] == '_'
-                  || in->ptr[src] == '$')
+              && is_name_beginner (in->ptr[src])
               && (! inquote
                   || ! macro_strip_at
                   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1067,16 +1104,14 @@ check_macro (const char *line, sb *expand,
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-        || *s == '_'
-        || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
@@ -1122,21 +1157,15 @@ delete_macro (const char *name)
 const char *
 expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
 {
-  const char *mn;
   sb sub;
   formal_entry f;
   struct hash_control *h;
   const char *err;
 
-  if (irpc)
-    mn = "IRPC";
-  else
-    mn = "IRP";
-
   idx = sb_skip_white (idx, in);
 
   sb_new (&sub);
-  if (! buffer_and_nest (mn, "ENDR", &sub, get_line))
+  if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
     return _("unexpected end of file in irp or irpc");
 
   sb_new (&f.name);
This page took 0.028105 seconds and 4 git commands to generate.