]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/macro.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / macro.c
index 119b1bfa3971b7302746a3d9a1a82a7ece621f73..9aa2ebfc7a02eff6e9e24e73430657127800da48 100644 (file)
@@ -1,5 +1,5 @@
 /* macro.c - macro support for gas
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
    Written by Steve and Judy Chamberlain of Cygnus Support,
       sac@cygnus.com
@@ -44,7 +44,7 @@
 
 /* The macro hash table.  */
 
-struct hash_control *macro_hash;
+struct htab *macro_hash;
 
 /* Whether any macros have been defined.  */
 
@@ -76,7 +76,8 @@ void
 macro_init (int alternate, int mri, int strip_at,
            size_t (*exp) (const char *, size_t, sb *, offsetT *))
 {
-  macro_hash = hash_new ();
+  macro_hash = htab_create_alloc (16, hash_macro_entry, eq_macro_entry,
+                                 NULL, xcalloc, free);
   macro_defined = 0;
   macro_alternate = alternate;
   macro_mri = mri;
@@ -223,14 +224,13 @@ buffer_and_nest (const char *from, const char *to, sb *ptr,
             anyway, there's not an obviously better fix here.  */
          if (strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
            {
-             char *saved_input_line_pointer = input_line_pointer;
              char saved_eol_char = ptr->ptr[ptr->len];
 
              ptr->ptr[ptr->len] = '\0';
-             input_line_pointer = ptr->ptr + i + 8;
+             temp_ilp (ptr->ptr + i + 8);
              s_app_line (0);
+             restore_ilp ();
              ptr->ptr[ptr->len] = saved_eol_char;
-             input_line_pointer = saved_input_line_pointer;
              ptr->len = line_start;
            }
        }
@@ -285,8 +285,8 @@ getstring (size_t idx, sb *in, sb *acc)
        {
          int nest = 0;
          idx++;
-         while ((in->ptr[idx] != '>' || nest)
-                && idx < in->len)
+         while (idx < in->len
+                && (in->ptr[idx] != '>' || nest))
            {
              if (in->ptr[idx] == '!')
                {
@@ -369,13 +369,13 @@ get_any_string (size_t idx, sb *in, sb *out)
     {
       if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
        {
-         while (!ISSEP (in->ptr[idx]))
+         while (idx < in->len && !ISSEP (in->ptr[idx]))
            sb_add_char (out, in->ptr[idx++]);
        }
       else if (in->ptr[idx] == '%' && macro_alternate)
        {
          offsetT val;
-         char buf[20];
+         char buf[64];
 
          /* Turns the next expression into a string.  */
          /* xgettext: no-c-format */
@@ -404,7 +404,7 @@ get_any_string (size_t idx, sb *in, sb *out)
        }
       else
        {
-         char *br_buf = (char *) xmalloc (1);
+         char *br_buf = XNEWVEC (char, 1);
          char *in_br = br_buf;
 
          *in_br = '\0';
@@ -438,7 +438,7 @@ get_any_string (size_t idx, sb *in, sb *out)
                    --in_br;
                  else
                    {
-                     br_buf = (char *) xmalloc (strlen (in_br) + 2);
+                     br_buf = XNEWVEC (char, strlen (in_br) + 2);
                      strcpy (br_buf + 1, in_br);
                      free (in_br);
                      in_br = br_buf;
@@ -471,7 +471,7 @@ new_formal (void)
 {
   formal_entry *formal;
 
-  formal = (formal_entry *) xmalloc (sizeof (formal_entry));
+  formal = XNEW (formal_entry);
 
   sb_new (&formal->name);
   sb_new (&formal->def);
@@ -505,6 +505,7 @@ do_formals (macro_entry *macro, size_t idx, sb *in)
     {
       formal_entry *formal = new_formal ();
       size_t cidx;
+      formal_hash_entry_t *elt;
 
       idx = get_token (idx, in, &formal->name);
       if (formal->name.len == 0)
@@ -567,14 +568,15 @@ do_formals (macro_entry *macro, size_t idx, sb *in)
        }
 
       /* Add to macro's hash table.  */
-      if (! hash_find (macro->formal_hash, name))
-       hash_jam (macro->formal_hash, name, formal);
-      else
-       as_bad_where (macro->file,
-                     macro->line,
-                     _("A parameter named `%s' already exists for macro `%s'"),
-                     name,
-                     macro->name);
+      elt = formal_entry_alloc (name, formal);
+      if (htab_insert (macro->formal_hash, elt, 0) != NULL)
+       {
+         free (elt);
+         as_bad_where (macro->file, macro->line,
+                       _("A parameter named `%s' "
+                         "already exists for macro `%s'"),
+                       name, macro->name);
+       }
 
       formal->index = macro->formal_count++;
       *p = formal;
@@ -593,6 +595,7 @@ do_formals (macro_entry *macro, size_t idx, sb *in)
   if (macro_mri)
     {
       formal_entry *formal = new_formal ();
+      formal_hash_entry_t *elt;
 
       /* Add a special NARG formal, which macro_expand will set to the
         number of arguments.  */
@@ -606,13 +609,14 @@ do_formals (macro_entry *macro, size_t idx, sb *in)
       sb_add_string (&formal->name, name);
 
       /* Add to macro's hash table.  */
-      if (hash_find (macro->formal_hash, name))
-       as_bad_where (macro->file,
-                     macro->line,
-                     _("Reserved word `%s' used as parameter in macro `%s'"),
-                     name,
-                     macro->name);
-      hash_jam (macro->formal_hash, name, formal);
+      elt = formal_entry_alloc (name, formal);
+      if (htab_insert (macro->formal_hash, elt, 0) != NULL)
+       {
+         free (elt);
+         as_bad_where (macro->file, macro->line,
+                       _("Reserved word `%s' used as parameter in macro `%s'"),
+                       name, macro->name);
+       }
 
       formal->index = NARG_INDEX;
       *p = formal;
@@ -636,7 +640,7 @@ free_macro (macro_entry *macro)
       formal = formal->next;
       del_formal (f);
     }
-  hash_die (macro->formal_hash);
+  htab_delete (macro->formal_hash);
   sb_kill (&macro->sub);
   free (macro);
 }
@@ -648,14 +652,14 @@ free_macro (macro_entry *macro)
 const char *
 define_macro (size_t idx, sb *in, sb *label,
              size_t (*get_line) (sb *),
-             char *file, unsigned int line,
+             const char *file, unsigned int line,
              const char **namep)
 {
   macro_entry *macro;
   sb name;
   const char *error = NULL;
 
-  macro = (macro_entry *) xmalloc (sizeof (macro_entry));
+  macro = XNEW (macro_entry);
   sb_new (&macro->sub);
   sb_new (&name);
   macro->file = file;
@@ -663,7 +667,8 @@ define_macro (size_t idx, sb *in, sb *label,
 
   macro->formal_count = 0;
   macro->formals = 0;
-  macro->formal_hash = hash_new_sized (7);
+  macro->formal_hash = htab_create_alloc (7, hash_formal_entry, eq_formal_entry,
+                                         NULL, xcalloc, free);
 
   idx = sb_skip_white (idx, in);
   if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
@@ -708,10 +713,15 @@ define_macro (size_t idx, sb *in, sb *label,
   /* And stick it in the macro hash table.  */
   for (idx = 0; idx < name.len; idx++)
     name.ptr[idx] = TOLOWER (name.ptr[idx]);
-  if (hash_find (macro_hash, macro->name))
-    error = _("Macro `%s' was already defined");
   if (!error)
-    error = hash_jam (macro_hash, macro->name, (void *) macro);
+    {
+      macro_hash_entry_t *elt = macro_entry_alloc (macro->name, macro);
+      if (htab_insert (macro_hash, elt, 0) != NULL)
+       {
+         free (elt);
+         error = _("Macro `%s' was already defined");
+       }
+    }
 
   if (namep != NULL)
     *namep = macro->name;
@@ -741,7 +751,7 @@ get_apost_token (size_t idx, sb *in, sb *name, int kind)
 /* Substitute the actual value for a formal parameter.  */
 
 static size_t
-sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash,
+sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
            int kind, sb *out, int copyifnotthere)
 {
   size_t src;
@@ -755,7 +765,7 @@ sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash,
       && (src == start || in->ptr[src - 1] != '@'))
     ptr = NULL;
   else
-    ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
+    ptr = formal_entry_find (formal_hash, sb_terminate (t));
   if (ptr)
     {
       if (ptr->actual.len)
@@ -791,7 +801,7 @@ sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash,
 
 static const char *
 macro_expand_body (sb *in, sb *out, formal_entry *formals,
-                  struct hash_control *formal_hash, const macro_entry *macro)
+                  struct htab *formal_hash, const macro_entry *macro)
 {
   sb t;
   size_t src = 0;
@@ -815,7 +825,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
            }
          else
            {
-             /* Permit macro parameter substition delineated with
+             /* Permit macro parameter substitution delineated with
                 an '&' prefix and optional '&' suffix.  */
              src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
            }
@@ -842,7 +852,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
            {
              /* Sub in the macro invocation number.  */
 
-             char buffer[10];
+             char buffer[12];
              src++;
              sprintf (buffer, "%d", macro_number);
              sb_add_string (out, buffer);
@@ -910,10 +920,20 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
                {
                  const char *name;
                  formal_entry *f = new_formal ();
+                 formal_hash_entry_t *elt;
 
                  src = get_token (src, in, &f->name);
                  name = sb_terminate (&f->name);
-                 if (! hash_find (formal_hash, name))
+                 elt = formal_entry_alloc (name, f);
+                 if (htab_insert (formal_hash, elt, 0) != NULL)
+                   {
+                     free (elt);
+                     as_bad_where (macro->file, macro->line + macro_line,
+                                   _("`%s' was already used as parameter "
+                                     "(or another local) name"), name);
+                     del_formal (f);
+                   }
+                 else
                    {
                      static int loccnt;
                      char buf[20];
@@ -924,18 +944,6 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
 
                      sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
                      sb_add_string (&f->actual, buf);
-
-                     err = hash_jam (formal_hash, name, f);
-                     if (err != NULL)
-                       break;
-                   }
-                 else
-                   {
-                     as_bad_where (macro->file,
-                                   macro->line + macro_line,
-                                   _("`%s' was already used as parameter (or another local) name"),
-                                   name);
-                     del_formal (f);
                    }
 
                  src = sb_skip_comma (src, in);
@@ -967,7 +975,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
 
          sb_reset (&t);
          src = get_token (src + 2, in, &t);
-         ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
+         ptr = formal_entry_find (formal_hash, sb_terminate (&t));
          if (ptr == NULL)
            {
              /* FIXME: We should really return a warning string here,
@@ -1011,7 +1019,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
 
       f = loclist->next;
       name = sb_terminate (&loclist->name);
-      hash_delete (formal_hash, name, f == NULL);
+      formal_hash_entry_t needle = { name, NULL };
+      htab_remove_elt (formal_hash, &needle);
       del_formal (loclist);
       loclist = f;
     }
@@ -1096,7 +1105,7 @@ macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
            }
 
          /* Lookup the formal in the macro's list.  */
-         ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+         ptr = formal_entry_find (m->formal_hash, sb_terminate (&t));
          if (!ptr)
            {
              as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
@@ -1194,7 +1203,7 @@ macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
 
          sb_reset (&t);
          sb_add_string (&t, macro_strip_at ? "$NARG" : "NARG");
-         ptr = (formal_entry *) hash_find (m->formal_hash, sb_terminate (&t));
+         ptr = formal_entry_find (m->formal_hash, sb_terminate (&t));
          sprintf (buffer, "%d", narg);
          sb_add_string (&ptr->actual, buffer);
        }
@@ -1250,13 +1259,12 @@ check_macro (const char *line, sb *expand,
   if (is_name_ender (*s))
     ++s;
 
-  copy = (char *) alloca (s - line + 1);
-  memcpy (copy, line, s - line);
-  copy[s - line] = '\0';
+  copy = xmemdup0 (line, s - line);
   for (cls = copy; *cls != '\0'; cls ++)
     *cls = TOLOWER (*cls);
 
-  macro = (macro_entry *) hash_find (macro_hash, copy);
+  macro = macro_entry_find (macro_hash, copy);
+  free (copy);
 
   if (macro == NULL)
     return 0;
@@ -1285,24 +1293,26 @@ delete_macro (const char *name)
 {
   char *copy;
   size_t i, len;
-  macro_entry *macro;
+  void **slot;
+  macro_hash_entry_t needle;
 
   len = strlen (name);
-  copy = (char *) alloca (len + 1);
+  copy = XNEWVEC (char, len + 1);
   for (i = 0; i < len; ++i)
     copy[i] = TOLOWER (name[i]);
   copy[i] = '\0';
 
-  /* We can only ask hash_delete to free memory if we are deleting
-     macros in reverse order to their definition.
-     So just clear out the entry.  */
-  if ((macro = (macro_entry *) hash_find (macro_hash, copy)) != NULL)
+  needle.name = copy;
+  needle.macro = NULL;
+  slot = htab_find_slot (macro_hash, &needle, NO_INSERT);
+  if (slot)
     {
-      hash_jam (macro_hash, copy, NULL);
-      free_macro (macro);
+      free_macro (((macro_hash_entry_t *) *slot)->macro);
+      htab_clear_slot (macro_hash, slot);
     }
   else
-    as_warn (_("Attempt to purge non-existant macro `%s'"), copy);
+    as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
+  free (copy);
 }
 
 /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
@@ -1314,8 +1324,8 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
 {
   sb sub;
   formal_entry f;
-  struct hash_control *h;
-  const char *err;
+  struct htab *h;
+  const char *err = NULL;
 
   idx = sb_skip_white (idx, in);
 
@@ -1331,10 +1341,10 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
   if (f.name.len == 0)
     return _("missing model parameter");
 
-  h = hash_new ();
-  err = hash_jam (h, sb_terminate (&f.name), &f);
-  if (err != NULL)
-    return err;
+  h = htab_create_alloc (16, hash_formal_entry, eq_formal_entry,
+                        NULL, xcalloc, free);
+
+  htab_insert (h, formal_entry_alloc (sb_terminate (&f.name), &f), 0);
 
   f.index = 1;
   f.next = NULL;
@@ -1393,7 +1403,7 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
        }
     }
 
-  hash_die (h);
+  htab_delete (h);
   sb_kill (&f.actual);
   sb_kill (&f.def);
   sb_kill (&f.name);