2000-06-13 Ulf Carlsson <ulfc@engr.sgi.com>
[binutils-gdb.git] / gas / macro.c
index 9d92ff4f1b15609762a58210e4a0ff35c923896a..3a0b6123062b8d5a951694485a9938ef028adcdf 100644 (file)
@@ -1,5 +1,5 @@
 /* macro.c - macro support for gas and gasp
-   Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
 
    Written by Steve and Judy Chamberlain of Cygnus Support,
       sac@cygnus.com
@@ -70,42 +70,6 @@ extern void *alloca ();
 /* The routines in this file handle macro definition and expansion.
    They are called by both gasp and gas.  */
 
-/* Structures used to store macros. 
-
-   Each macro knows its name and included text.  It gets built with a
-   list of formal arguments, and also keeps a hash table which points
-   into the list to speed up formal search.  Each formal knows its
-   name and its default value.  Each time the macro is expanded, the
-   formals get the actual values attatched to them. */
-
-/* describe the formal arguments to a macro */
-
-typedef struct formal_struct
-  {
-    struct formal_struct *next;        /* next formal in list */
-    sb name;                   /* name of the formal */
-    sb def;                    /* the default value */
-    sb actual;                 /* the actual argument (changed on each expansion) */
-    int index;                 /* the index of the formal 0..formal_count-1 */
-  }
-formal_entry;
-
-/* Other values found in the index field of a formal_entry.  */
-#define QUAL_INDEX (-1)
-#define NARG_INDEX (-2)
-#define LOCAL_INDEX (-3)
-
-/* describe the macro. */
-
-typedef struct macro_struct
-  {
-    sb sub;                    /* substitution text. */
-    int formal_count;          /* number of formal args. */
-    formal_entry *formals;     /* pointer to list of formal_structs */
-    struct hash_control *formal_hash; /* hash table of formals. */
-  }
-macro_entry;
-
 /* Internal functions.  */
 
 static int get_token PARAMS ((int, sb *, sb *));
@@ -245,9 +209,11 @@ buffer_and_nest (from, to, ptr, get_line)
        {
          if (ptr->ptr[i] == '.')
              i++;
-         if (strncasecmp (ptr->ptr + i, from, from_len) == 0)
+         if (strncasecmp (ptr->ptr + i, from, from_len) == 0
+             && (ptr->len == (i + from_len) || ! isalnum (ptr->ptr[i + from_len])))
            depth++;
-         if (strncasecmp (ptr->ptr + i, to, to_len) == 0)
+         if (strncasecmp (ptr->ptr + i, to, to_len) == 0
+             && (ptr->len == (i + to_len) || ! isalnum (ptr->ptr[i + to_len])))
            {
              depth--;
              if (depth == 0)
@@ -338,14 +304,25 @@ getstring (idx, in, acc)
       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
        {
          char tchar = in->ptr[idx];
+         int escaped = 0;
          idx++;
          while (idx < in->len)
            {
+             if (in->ptr[idx-1] == '\\')
+               escaped ^= 1;
+             else
+               escaped = 0;
+
              if (macro_alternate && in->ptr[idx] == '!')
                {
                  idx++  ;
                  sb_add_char (acc, in->ptr[idx++]);
                }
+             else if (escaped && in->ptr[idx] == tchar)
+               {
+                 sb_add_char (acc, tchar);
+                 idx++;
+               }
              else
                {
                  if (in->ptr[idx] == tchar)
@@ -734,7 +711,7 @@ macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
 
              char buffer[10];
              src++;
-             sprintf (buffer, "%05d", macro_number);
+             sprintf (buffer, "%d", macro_number);
              sb_add_string (out, buffer);
            }
          else if (in->ptr[src] == '&')
@@ -902,7 +879,9 @@ macro_expand_body (in, out, formals, formal_hash, comment_char, locals)
       formal_entry *f;
 
       f = loclist->next;
-      hash_delete (formal_hash, sb_terminate (&loclist->name));
+      /* Setting the value to NULL effectively deletes the entry.  We
+         avoid calling hash_delete because it doesn't reclaim memory.  */
+      hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
       sb_kill (&loclist->name);
       sb_kill (&loclist->def);
       sb_kill (&loclist->actual);
@@ -1104,11 +1083,12 @@ macro_expand (idx, in, m, out, comment_char)
    gasp.  Return 1 if a macro is found, 0 otherwise.  */
 
 int
-check_macro (line, expand, comment_char, error)
+check_macro (line, expand, comment_char, error, info)
      const char *line;
      sb *expand;
      int comment_char;
      const char **error;
+     macro_entry **info;
 {
   const char *s;
   char *copy, *cs;
@@ -1149,6 +1129,10 @@ check_macro (line, expand, comment_char, error)
 
   sb_kill (&line_sb);
 
+  /* export the macro information if requested */
+  if (info)
+    *info = macro;
+
   return 1;
 }