(root)/
binutils-2.41/
gas/
macro.c
       1  /* macro.c - macro support for gas
       2     Copyright (C) 1994-2023 Free Software Foundation, Inc.
       3  
       4     Written by Steve and Judy Chamberlain of Cygnus Support,
       5        sac@cygnus.com
       6  
       7     This file is part of GAS, the GNU Assembler.
       8  
       9     GAS is free software; you can redistribute it and/or modify
      10     it under the terms of the GNU General Public License as published by
      11     the Free Software Foundation; either version 3, or (at your option)
      12     any later version.
      13  
      14     GAS is distributed in the hope that it will be useful,
      15     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17     GNU General Public License for more details.
      18  
      19     You should have received a copy of the GNU General Public License
      20     along with GAS; see the file COPYING.  If not, write to the Free
      21     Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
      22     02110-1301, USA.  */
      23  
      24  #include "as.h"
      25  #include "safe-ctype.h"
      26  #include "sb.h"
      27  #include "macro.h"
      28  
      29  /* The routines in this file handle macro definition and expansion.
      30     They are called by gas.  */
      31  
      32  #define ISWHITE(x) ((x) == ' ' || (x) == '\t')
      33  
      34  #define ISSEP(x) \
      35   ((x) == ' ' || (x) == '\t' || (x) == ',' || (x) == '"' || (x) == ';' \
      36    || (x) == ')' || (x) == '(' \
      37    || ((flag_macro_alternate || flag_mri) && ((x) == '<' || (x) == '>')))
      38  
      39  #define ISBASE(x) \
      40    ((x) == 'b' || (x) == 'B' \
      41     || (x) == 'q' || (x) == 'Q' \
      42     || (x) == 'h' || (x) == 'H' \
      43     || (x) == 'd' || (x) == 'D')
      44  
      45  /* The macro hash table.  */
      46  
      47  htab_t macro_hash;
      48  
      49  /* Whether any macros have been defined.  */
      50  
      51  int macro_defined;
      52  
      53  /* Whether we should strip '@' characters.  */
      54  
      55  #define macro_strip_at false
      56  
      57  /* Number of macro expansions that have been done.  */
      58  
      59  static int macro_number;
      60  
      61  static void free_macro (macro_entry *);
      62  
      63  static void
      64  macro_del_f (void *ent)
      65  {
      66    string_tuple_t *tuple = ent;
      67    free_macro ((macro_entry *) tuple->value);
      68  }
      69  
      70  /* Initialize macro processing.  */
      71  
      72  void
      73  macro_init (void)
      74  {
      75    macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
      76  				  macro_del_f, notes_calloc, NULL);
      77    macro_defined = 0;
      78  }
      79  
      80  void
      81  macro_end (void)
      82  {
      83    htab_delete (macro_hash);
      84  }
      85  
      86  /* Read input lines till we get to a TO string.
      87     Increase nesting depth if we get a FROM string.
      88     Put the results into sb at PTR.
      89     FROM may be NULL (or will be ignored) if TO is "ENDR".
      90     Add a new input line to an sb using GET_LINE.
      91     Return 1 on success, 0 on unexpected EOF.  */
      92  
      93  int
      94  buffer_and_nest (const char *from, const char *to, sb *ptr,
      95  		 size_t (*get_line) (sb *))
      96  {
      97    size_t from_len;
      98    size_t to_len = strlen (to);
      99    int depth = 1;
     100    size_t line_start, more;
     101  
     102    if (to_len == 4 && strcasecmp (to, "ENDR") == 0)
     103      {
     104        from = NULL;
     105        from_len = 0;
     106      }
     107    else
     108      from_len = strlen (from);
     109  
     110    /* Record the present source position, such that diagnostics and debug info
     111       can be properly associated with the respective original lines, rather
     112       than with the line of the ending directive (TO).  */
     113    {
     114      unsigned int line;
     115      char *linefile;
     116  
     117      as_where_top (&line);
     118      if (!flag_m68k_mri)
     119        linefile = xasprintf ("\t.linefile %u .", line + 1);
     120      else
     121        linefile = xasprintf ("\tlinefile %u .", line + 1);
     122      sb_add_string (ptr, linefile);
     123      xfree (linefile);
     124    }
     125  
     126    line_start = ptr->len;
     127    more = get_line (ptr);
     128    while (more)
     129      {
     130        /* Try to find the first pseudo op on the line.  */
     131        size_t i = line_start;
     132        bool had_colon = false;
     133  
     134        /* With normal syntax we can suck what we want till we get
     135  	 to the dot.  With the alternate, labels have to start in
     136  	 the first column, since we can't tell what's a label and
     137  	 what's a pseudoop.  */
     138  
     139        if (! LABELS_WITHOUT_COLONS)
     140  	{
     141  	  /* Skip leading whitespace.  */
     142  	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
     143  	    i++;
     144  	}
     145  
     146        for (;;)
     147  	{
     148  	  /* Skip over a label, if any.  */
     149  	  if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
     150  	    break;
     151  	  i++;
     152  	  while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
     153  	    i++;
     154  	  if (i < ptr->len && is_name_ender (ptr->ptr[i]))
     155  	    i++;
     156  	  /* Skip whitespace.  */
     157  	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
     158  	    i++;
     159  	  /* Check for the colon.  */
     160  	  if (i >= ptr->len || ptr->ptr[i] != ':')
     161  	    {
     162  	      /* LABELS_WITHOUT_COLONS doesn't mean we cannot have a
     163  		 colon after a label.  If we do have a colon on the
     164  		 first label then handle more than one label on the
     165  		 line, assuming that each label has a colon.  */
     166  	      if (LABELS_WITHOUT_COLONS && !had_colon)
     167  		break;
     168  	      i = line_start;
     169  	      break;
     170  	    }
     171  	  i++;
     172  	  line_start = i;
     173  	  had_colon = true;
     174  	}
     175  
     176        /* Skip trailing whitespace.  */
     177        while (i < ptr->len && ISWHITE (ptr->ptr[i]))
     178  	i++;
     179  
     180        if (i < ptr->len && (ptr->ptr[i] == '.'
     181  			   || NO_PSEUDO_DOT
     182  			   || flag_mri))
     183  	{
     184  	  if (! flag_m68k_mri && ptr->ptr[i] == '.')
     185  	    i++;
     186  	  size_t len = ptr->len - i;
     187  	  if (from == NULL)
     188  	    {
     189  	      if (len >= 5 && strncasecmp (ptr->ptr + i, "IREPC", 5) == 0)
     190  		from_len = 5;
     191  	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "IREP", 4) == 0)
     192  		from_len = 4;
     193  	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "IRPC", 4) == 0)
     194  		from_len = 4;
     195  	      else if (len >= 4 && strncasecmp (ptr->ptr + i, "REPT", 4) == 0)
     196  		from_len = 4;
     197  	      else if (len >= 3 && strncasecmp (ptr->ptr + i, "IRP", 3) == 0)
     198  		from_len = 3;
     199  	      else if (len >= 3 && strncasecmp (ptr->ptr + i, "REP", 3) == 0)
     200  		from_len = 3;
     201  	      else
     202  		from_len = 0;
     203  	    }
     204  	  if ((from != NULL
     205  	       ? (len >= from_len
     206  		  && strncasecmp (ptr->ptr + i, from, from_len) == 0)
     207  	       : from_len > 0)
     208  	      && (len == from_len
     209  		  || ! (is_part_of_name (ptr->ptr[i + from_len])
     210  			|| is_name_ender (ptr->ptr[i + from_len]))))
     211  	    depth++;
     212  	  if (len >= to_len
     213  	      && strncasecmp (ptr->ptr + i, to, to_len) == 0
     214  	      && (len == to_len
     215  		  || ! (is_part_of_name (ptr->ptr[i + to_len])
     216  			|| is_name_ender (ptr->ptr[i + to_len]))))
     217  	    {
     218  	      depth--;
     219  	      if (depth == 0)
     220  		{
     221  		  /* Reset the string to not include the ending rune.  */
     222  		  ptr->len = line_start;
     223  		  break;
     224  		}
     225  	    }
     226  
     227  	  /* PR gas/16908
     228  	     Apply .linefile directives that appear within the macro, alongside
     229  	     keeping them for later expansion of the macro.  */
     230  	  if (from != NULL && strcasecmp (from, "MACRO") == 0
     231  	      && len >= 8 && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
     232  	    {
     233  	      sb_add_char (ptr, more);
     234  	      temp_ilp (sb_terminate (ptr) + i + 8);
     235  	      s_linefile (0);
     236  	      restore_ilp ();
     237  	      line_start = ptr->len;
     238  	      more = get_line (ptr);
     239  	      continue;
     240  	    }
     241  	}
     242  
     243        /* Add the original end-of-line char to the end and keep running.  */
     244        sb_add_char (ptr, more);
     245        line_start = ptr->len;
     246        more = get_line (ptr);
     247      }
     248  
     249    /* Return 1 on success, 0 on unexpected EOF.  */
     250    return depth == 0;
     251  }
     252  
     253  /* Pick up a token.  */
     254  
     255  static size_t
     256  get_token (size_t idx, sb *in, sb *name)
     257  {
     258    if (idx < in->len
     259        && is_name_beginner (in->ptr[idx]))
     260      {
     261        sb_add_char (name, in->ptr[idx++]);
     262        while (idx < in->len
     263  	     && is_part_of_name (in->ptr[idx]))
     264  	{
     265  	  sb_add_char (name, in->ptr[idx++]);
     266  	}
     267        if (idx < in->len
     268  	     && is_name_ender (in->ptr[idx]))
     269  	{
     270  	  sb_add_char (name, in->ptr[idx++]);
     271  	}
     272      }
     273    /* Ignore trailing &.  */
     274    if (flag_macro_alternate && idx < in->len && in->ptr[idx] == '&')
     275      idx++;
     276    return idx;
     277  }
     278  
     279  /* Pick up a string.  */
     280  
     281  static size_t
     282  getstring (size_t idx, sb *in, sb *acc)
     283  {
     284    while (idx < in->len
     285  	 && (in->ptr[idx] == '"'
     286  	     || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
     287  	     || (in->ptr[idx] == '\'' && flag_macro_alternate)))
     288      {
     289        if (in->ptr[idx] == '<')
     290  	{
     291  	  int nest = 0;
     292  	  idx++;
     293  	  while (idx < in->len
     294  		 && (in->ptr[idx] != '>' || nest))
     295  	    {
     296  	      if (in->ptr[idx] == '!')
     297  		{
     298  		  idx++;
     299  		  sb_add_char (acc, in->ptr[idx++]);
     300  		}
     301  	      else
     302  		{
     303  		  if (in->ptr[idx] == '>')
     304  		    nest--;
     305  		  if (in->ptr[idx] == '<')
     306  		    nest++;
     307  		  sb_add_char (acc, in->ptr[idx++]);
     308  		}
     309  	    }
     310  	  idx++;
     311  	}
     312        else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
     313  	{
     314  	  char tchar = in->ptr[idx];
     315  	  int escaped = 0;
     316  
     317  	  idx++;
     318  
     319  	  while (idx < in->len)
     320  	    {
     321  	      if (in->ptr[idx - 1] == '\\')
     322  		escaped ^= 1;
     323  	      else
     324  		escaped = 0;
     325  
     326  	      if (flag_macro_alternate && in->ptr[idx] == '!')
     327  		{
     328  		  idx ++;
     329  
     330  		  sb_add_char (acc, in->ptr[idx]);
     331  
     332  		  idx ++;
     333  		}
     334  	      else if (escaped && in->ptr[idx] == tchar)
     335  		{
     336  		  sb_add_char (acc, tchar);
     337  		  idx ++;
     338  		}
     339  	      else
     340  		{
     341  		  if (in->ptr[idx] == tchar)
     342  		    {
     343  		      idx ++;
     344  
     345  		      if (idx >= in->len || in->ptr[idx] != tchar)
     346  			break;
     347  		    }
     348  
     349  		  sb_add_char (acc, in->ptr[idx]);
     350  		  idx ++;
     351  		}
     352  	    }
     353  	}
     354      }
     355  
     356    return idx;
     357  }
     358  
     359  /* Fetch string from the input stream,
     360     rules:
     361      'Bxyx<whitespace>  	-> return 'Bxyza
     362      %<expr>		-> return string of decimal value of <expr>
     363      "string"		-> return string
     364      (string)		-> return (string-including-whitespaces)
     365      xyx<whitespace>     -> return xyz.  */
     366  
     367  static size_t
     368  get_any_string (size_t idx, sb *in, sb *out)
     369  {
     370    sb_reset (out);
     371    idx = sb_skip_white (idx, in);
     372  
     373    if (idx < in->len)
     374      {
     375        if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
     376  	{
     377  	  while (idx < in->len && !ISSEP (in->ptr[idx]))
     378  	    sb_add_char (out, in->ptr[idx++]);
     379  	}
     380        else if (in->ptr[idx] == '%' && flag_macro_alternate)
     381  	{
     382  	  /* Turn the following expression into a string.  */
     383  	  expressionS ex;
     384  	  char buf[64];
     385  
     386  	  sb_terminate (in);
     387  
     388  	  temp_ilp (in->ptr + idx + 1);
     389  	  expression_and_evaluate (&ex);
     390  	  idx = input_line_pointer - in->ptr;
     391  	  restore_ilp ();
     392  
     393  	  if (ex.X_op != O_constant)
     394  	    as_bad (_("%% operator needs absolute expression"));
     395  
     396  	  sprintf (buf, "%" PRId64, (int64_t) ex.X_add_number);
     397  	  sb_add_string (out, buf);
     398  	}
     399        else if (in->ptr[idx] == '"'
     400  	       || (in->ptr[idx] == '<' && (flag_macro_alternate || flag_mri))
     401  	       || (flag_macro_alternate && in->ptr[idx] == '\''))
     402  	{
     403  	  if (flag_macro_alternate && ! macro_strip_at && in->ptr[idx] != '<')
     404  	    {
     405  	      /* Keep the quotes.  */
     406  	      sb_add_char (out, '"');
     407  	      idx = getstring (idx, in, out);
     408  	      sb_add_char (out, '"');
     409  	    }
     410  	  else
     411  	    {
     412  	      idx = getstring (idx, in, out);
     413  	    }
     414  	}
     415        else
     416  	{
     417  	  char *br_buf = XNEWVEC (char, 1);
     418  	  char *in_br = br_buf;
     419  
     420  	  *in_br = '\0';
     421  	  while (idx < in->len
     422  		 && (*in_br
     423  		     || (in->ptr[idx] != ' '
     424  			 && in->ptr[idx] != '\t'))
     425  		 && in->ptr[idx] != ','
     426  		 && (in->ptr[idx] != '<'
     427  		     || (! flag_macro_alternate && ! flag_mri)))
     428  	    {
     429  	      char tchar = in->ptr[idx];
     430  
     431  	      switch (tchar)
     432  		{
     433  		case '"':
     434  		case '\'':
     435  		  sb_add_char (out, in->ptr[idx++]);
     436  		  while (idx < in->len
     437  			 && in->ptr[idx] != tchar)
     438  		    sb_add_char (out, in->ptr[idx++]);
     439  		  if (idx == in->len)
     440  		    {
     441  		      free (br_buf);
     442  		      return idx;
     443  		    }
     444  		  break;
     445  		case '(':
     446  		case '[':
     447  		  if (in_br > br_buf)
     448  		    --in_br;
     449  		  else
     450  		    {
     451  		      br_buf = XNEWVEC (char, strlen (in_br) + 2);
     452  		      strcpy (br_buf + 1, in_br);
     453  		      free (in_br);
     454  		      in_br = br_buf;
     455  		    }
     456  		  *in_br = tchar;
     457  		  break;
     458  		case ')':
     459  		  if (*in_br == '(')
     460  		    ++in_br;
     461  		  break;
     462  		case ']':
     463  		  if (*in_br == '[')
     464  		    ++in_br;
     465  		  break;
     466  		}
     467  	      sb_add_char (out, tchar);
     468  	      ++idx;
     469  	    }
     470  	  free (br_buf);
     471  	}
     472      }
     473  
     474    return idx;
     475  }
     476  
     477  /* Allocate a new formal.  */
     478  
     479  static formal_entry *
     480  new_formal (void)
     481  {
     482    formal_entry *formal;
     483  
     484    formal = XNEW (formal_entry);
     485  
     486    sb_new (&formal->name);
     487    sb_new (&formal->def);
     488    sb_new (&formal->actual);
     489    formal->next = NULL;
     490    formal->type = FORMAL_OPTIONAL;
     491    return formal;
     492  }
     493  
     494  /* Free a formal.  */
     495  
     496  static void
     497  del_formal (formal_entry *formal)
     498  {
     499    sb_kill (&formal->actual);
     500    sb_kill (&formal->def);
     501    sb_kill (&formal->name);
     502    free (formal);
     503  }
     504  
     505  /* Pick up the formal parameters of a macro definition.  */
     506  
     507  static size_t
     508  do_formals (macro_entry *macro, size_t idx, sb *in)
     509  {
     510    formal_entry **p = &macro->formals;
     511    const char *name;
     512  
     513    idx = sb_skip_white (idx, in);
     514    while (idx < in->len)
     515      {
     516        formal_entry *formal = new_formal ();
     517        size_t cidx;
     518  
     519        idx = get_token (idx, in, &formal->name);
     520        if (formal->name.len == 0)
     521  	{
     522  	  if (macro->formal_count)
     523  	    --idx;
     524  	  del_formal (formal);	/* 'formal' goes out of scope.  */
     525  	  break;
     526  	}
     527        idx = sb_skip_white (idx, in);
     528        /* This is a formal.  */
     529        name = sb_terminate (&formal->name);
     530        if (! flag_mri
     531  	  && idx < in->len
     532  	  && in->ptr[idx] == ':'
     533  	  && (! is_name_beginner (':')
     534  	      || idx + 1 >= in->len
     535  	      || ! is_part_of_name (in->ptr[idx + 1])))
     536  	{
     537  	  /* Got a qualifier.  */
     538  	  sb qual;
     539  
     540  	  sb_new (&qual);
     541  	  idx = get_token (sb_skip_white (idx + 1, in), in, &qual);
     542  	  sb_terminate (&qual);
     543  	  if (qual.len == 0)
     544  	    as_bad_where (macro->file,
     545  			  macro->line,
     546  			  _("Missing parameter qualifier for `%s' in macro `%s'"),
     547  			  name,
     548  			  macro->name);
     549  	  else if (strcmp (qual.ptr, "req") == 0)
     550  	    formal->type = FORMAL_REQUIRED;
     551  	  else if (strcmp (qual.ptr, "vararg") == 0)
     552  	    formal->type = FORMAL_VARARG;
     553  	  else
     554  	    as_bad_where (macro->file,
     555  			  macro->line,
     556  			  _("`%s' is not a valid parameter qualifier for `%s' in macro `%s'"),
     557  			  qual.ptr,
     558  			  name,
     559  			  macro->name);
     560  	  sb_kill (&qual);
     561  	  idx = sb_skip_white (idx, in);
     562  	}
     563        if (idx < in->len && in->ptr[idx] == '=')
     564  	{
     565  	  /* Got a default.  */
     566  	  idx = get_any_string (idx + 1, in, &formal->def);
     567  	  idx = sb_skip_white (idx, in);
     568  	  if (formal->type == FORMAL_REQUIRED)
     569  	    {
     570  	      sb_reset (&formal->def);
     571  	      as_warn_where (macro->file,
     572  			    macro->line,
     573  			    _("Pointless default value for required parameter `%s' in macro `%s'"),
     574  			    name,
     575  			    macro->name);
     576  	    }
     577  	}
     578  
     579        /* Add to macro's hash table.  */
     580        if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
     581  	{
     582  	  as_bad_where (macro->file, macro->line,
     583  			_("A parameter named `%s' "
     584  			  "already exists for macro `%s'"),
     585  			name, macro->name);
     586  	}
     587  
     588        formal->index = macro->formal_count++;
     589        *p = formal;
     590        p = &formal->next;
     591        if (formal->type == FORMAL_VARARG)
     592  	break;
     593        cidx = idx;
     594        idx = sb_skip_comma (idx, in);
     595        if (idx != cidx && idx >= in->len)
     596  	{
     597  	  idx = cidx;
     598  	  break;
     599  	}
     600      }
     601  
     602    if (flag_mri)
     603      {
     604        formal_entry *formal = new_formal ();
     605  
     606        /* Add a special NARG formal, which macro_expand will set to the
     607  	 number of arguments.  */
     608        /* The same MRI assemblers which treat '@' characters also use
     609  	 the name $NARG.  At least until we find an exception.  */
     610        if (macro_strip_at)
     611  	name = "$NARG";
     612        else
     613  	name = "NARG";
     614  
     615        sb_add_string (&formal->name, name);
     616  
     617        /* Add to macro's hash table.  */
     618        if (str_hash_insert (macro->formal_hash, name, formal, 0) != NULL)
     619  	{
     620  	  as_bad_where (macro->file, macro->line,
     621  			_("Reserved word `%s' used as parameter in macro `%s'"),
     622  			name, macro->name);
     623  	}
     624  
     625        formal->index = NARG_INDEX;
     626        *p = formal;
     627      }
     628  
     629    return idx;
     630  }
     631  
     632  /* Free the memory allocated to a macro.  */
     633  
     634  static void
     635  free_macro (macro_entry *macro)
     636  {
     637    formal_entry *formal;
     638  
     639    for (formal = macro->formals; formal; )
     640      {
     641        formal_entry *f;
     642  
     643        f = formal;
     644        formal = formal->next;
     645        del_formal (f);
     646      }
     647    htab_delete (macro->formal_hash);
     648    sb_kill (&macro->sub);
     649    free ((char *) macro->name);
     650    free (macro);
     651  }
     652  
     653  /* Define a new macro.  */
     654  
     655  macro_entry *
     656  define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
     657  {
     658    macro_entry *macro;
     659    sb name;
     660    size_t idx;
     661    const char *error = NULL;
     662  
     663    macro = XNEW (macro_entry);
     664    sb_new (&macro->sub);
     665    sb_new (&name);
     666    macro->file = as_where (&macro->line);
     667  
     668    macro->formal_count = 0;
     669    macro->formals = 0;
     670    macro->formal_hash = str_htab_create ();
     671  
     672    idx = sb_skip_white (0, in);
     673    if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
     674      error = _("unexpected end of file in macro `%s' definition");
     675    if (label != NULL && label->len != 0)
     676      {
     677        sb_add_sb (&name, label);
     678        macro->name = sb_terminate (&name);
     679        if (idx < in->len && in->ptr[idx] == '(')
     680  	{
     681  	  /* It's the label: MACRO (formals,...)  sort  */
     682  	  idx = do_formals (macro, idx + 1, in);
     683  	  if (idx < in->len && in->ptr[idx] == ')')
     684  	    idx = sb_skip_white (idx + 1, in);
     685  	  else if (!error)
     686  	    error = _("missing `)' after formals in macro definition `%s'");
     687  	}
     688        else
     689  	{
     690  	  /* It's the label: MACRO formals,...  sort  */
     691  	  idx = do_formals (macro, idx, in);
     692  	}
     693      }
     694    else
     695      {
     696        size_t cidx;
     697  
     698        idx = get_token (idx, in, &name);
     699        macro->name = sb_terminate (&name);
     700        if (name.len == 0)
     701  	error = _("Missing macro name");
     702        cidx = sb_skip_white (idx, in);
     703        idx = sb_skip_comma (cidx, in);
     704        if (idx == cidx || idx < in->len)
     705  	idx = do_formals (macro, idx, in);
     706        else
     707  	idx = cidx;
     708      }
     709    if (!error && idx < in->len)
     710      error = _("Bad parameter list for macro `%s'");
     711  
     712    /* And stick it in the macro hash table.  */
     713    for (idx = 0; idx < name.len; idx++)
     714      name.ptr[idx] = TOLOWER (name.ptr[idx]);
     715    if (!error)
     716      {
     717        if (str_hash_insert (macro_hash, macro->name, macro, 0) != NULL)
     718  	error = _("Macro `%s' was already defined");
     719      }
     720  
     721    if (!error)
     722      macro_defined = 1;
     723    else
     724      {
     725        as_bad_where (macro->file, macro->line, error, macro->name);
     726        free_macro (macro);
     727        macro = NULL;
     728      }
     729  
     730    return macro;
     731  }
     732  
     733  /* Scan a token, and then skip KIND.  */
     734  
     735  static size_t
     736  get_apost_token (size_t idx, sb *in, sb *name, int kind)
     737  {
     738    idx = get_token (idx, in, name);
     739    if (idx < in->len
     740        && in->ptr[idx] == kind
     741        && (! flag_mri || macro_strip_at)
     742        && (! macro_strip_at || kind == '@'))
     743      idx++;
     744    return idx;
     745  }
     746  
     747  /* Substitute the actual value for a formal parameter.  */
     748  
     749  static size_t
     750  sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
     751  	    int kind, sb *out, int copyifnotthere)
     752  {
     753    size_t src;
     754    formal_entry *ptr;
     755  
     756    src = get_apost_token (start, in, t, kind);
     757    /* See if it's in the macro's hash table, unless this is
     758       macro_strip_at and kind is '@' and the token did not end in '@'.  */
     759    if (macro_strip_at
     760        && kind == '@'
     761        && (src == start || in->ptr[src - 1] != '@'))
     762      ptr = NULL;
     763    else
     764      ptr = str_hash_find (formal_hash, sb_terminate (t));
     765    if (ptr)
     766      {
     767        if (ptr->actual.len)
     768  	{
     769  	  sb_add_sb (out, &ptr->actual);
     770  	}
     771        else
     772  	{
     773  	  sb_add_sb (out, &ptr->def);
     774  	}
     775      }
     776    else if (kind == '&')
     777      {
     778        /* Doing this permits people to use & in macro bodies.  */
     779        sb_add_char (out, '&');
     780        sb_add_sb (out, t);
     781        if (src != start && in->ptr[src - 1] == '&')
     782  	sb_add_char (out, '&');
     783      }
     784    else if (copyifnotthere)
     785      {
     786        sb_add_sb (out, t);
     787      }
     788    else
     789      {
     790        sb_add_char (out, '\\');
     791        sb_add_sb (out, t);
     792      }
     793    return src;
     794  }
     795  
     796  /* Expand the body of a macro.  */
     797  
     798  static const char *
     799  macro_expand_body (sb *in, sb *out, formal_entry *formals,
     800  		   struct htab *formal_hash, const macro_entry *macro)
     801  {
     802    sb t;
     803    size_t src = 0;
     804    int inquote = 0, macro_line = 0;
     805    formal_entry *loclist = NULL;
     806    const char *err = NULL;
     807  
     808    sb_new (&t);
     809  
     810    while (src < in->len && !err)
     811      {
     812        if (in->ptr[src] == '&')
     813  	{
     814  	  sb_reset (&t);
     815  	  if (flag_mri)
     816  	    {
     817  	      if (src + 1 < in->len && in->ptr[src + 1] == '&')
     818  		src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
     819  	      else
     820  		sb_add_char (out, in->ptr[src++]);
     821  	    }
     822  	  else
     823  	    {
     824  	      /* Permit macro parameter substitution delineated with
     825  		 an '&' prefix and optional '&' suffix.  */
     826  	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
     827  	    }
     828  	}
     829        else if (in->ptr[src] == '\\')
     830  	{
     831  	  src++;
     832  	  if (src < in->len && in->ptr[src] == '(')
     833  	    {
     834  	      /* Sub in till the next ')' literally.  */
     835  	      src++;
     836  	      while (src < in->len && in->ptr[src] != ')')
     837  		{
     838  		  sb_add_char (out, in->ptr[src++]);
     839  		}
     840  	      if (src < in->len)
     841  		src++;
     842  	      else if (!macro)
     843  		err = _("missing `)'");
     844  	      else
     845  		as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
     846  	    }
     847  	  else if (src < in->len && in->ptr[src] == '@')
     848  	    {
     849  	      /* Sub in the macro invocation number.  */
     850  
     851  	      char buffer[12];
     852  	      src++;
     853  	      sprintf (buffer, "%d", macro_number);
     854  	      sb_add_string (out, buffer);
     855  	    }
     856  	  else if (src < in->len && in->ptr[src] == '&')
     857  	    {
     858  	      /* This is a preprocessor variable name, we don't do them
     859  		 here.  */
     860  	      sb_add_char (out, '\\');
     861  	      sb_add_char (out, '&');
     862  	      src++;
     863  	    }
     864  	  else if (flag_mri && src < in->len && ISALNUM (in->ptr[src]))
     865  	    {
     866  	      int ind;
     867  	      formal_entry *f;
     868  
     869  	      if (ISDIGIT (in->ptr[src]))
     870  		ind = in->ptr[src] - '0';
     871  	      else if (ISUPPER (in->ptr[src]))
     872  		ind = in->ptr[src] - 'A' + 10;
     873  	      else
     874  		ind = in->ptr[src] - 'a' + 10;
     875  	      ++src;
     876  	      for (f = formals; f != NULL; f = f->next)
     877  		{
     878  		  if (f->index == ind - 1)
     879  		    {
     880  		      if (f->actual.len != 0)
     881  			sb_add_sb (out, &f->actual);
     882  		      else
     883  			sb_add_sb (out, &f->def);
     884  		      break;
     885  		    }
     886  		}
     887  	    }
     888  	  else
     889  	    {
     890  	      sb_reset (&t);
     891  	      src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
     892  	    }
     893  	}
     894        else if ((flag_macro_alternate || flag_mri)
     895  	       && is_name_beginner (in->ptr[src])
     896  	       && (! inquote
     897  		   || ! macro_strip_at
     898  		   || (src > 0 && in->ptr[src - 1] == '@')))
     899  	{
     900  	  if (! macro
     901  	      || src + 5 >= in->len
     902  	      || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
     903  	      || ! ISWHITE (in->ptr[src + 5])
     904  	      /* PR 11507: Skip keyword LOCAL if it is found inside a quoted string.  */
     905  	      || inquote)
     906  	    {
     907  	      sb_reset (&t);
     908  	      src = sub_actual (src, in, &t, formal_hash,
     909  				(macro_strip_at && inquote) ? '@' : '\'',
     910  				out, 1);
     911  	    }
     912  	  else
     913  	    {
     914  	      src = sb_skip_white (src + 5, in);
     915  	      while (in->ptr[src] != '\n')
     916  		{
     917  		  const char *name;
     918  		  formal_entry *f = new_formal ();
     919  
     920  		  src = get_token (src, in, &f->name);
     921  		  name = sb_terminate (&f->name);
     922  		  if (str_hash_insert (formal_hash, name, f, 0) != NULL)
     923  		    {
     924  		      as_bad_where (macro->file, macro->line + macro_line,
     925  				    _("`%s' was already used as parameter "
     926  				      "(or another local) name"), name);
     927  		      del_formal (f);
     928  		    }
     929  		  else
     930  		    {
     931  		      static int loccnt;
     932  		      char buf[20];
     933  
     934  		      f->index = LOCAL_INDEX;
     935  		      f->next = loclist;
     936  		      loclist = f;
     937  
     938  		      sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
     939  		      sb_add_string (&f->actual, buf);
     940  		    }
     941  
     942  		  src = sb_skip_comma (src, in);
     943  		}
     944  	    }
     945  	}
     946        else if (in->ptr[src] == '"'
     947  	       || (flag_mri && in->ptr[src] == '\''))
     948  	{
     949  	  inquote = !inquote;
     950  	  sb_add_char (out, in->ptr[src++]);
     951  	}
     952        else if (in->ptr[src] == '@' && macro_strip_at)
     953  	{
     954  	  ++src;
     955  	  if (src < in->len
     956  	      && in->ptr[src] == '@')
     957  	    {
     958  	      sb_add_char (out, '@');
     959  	      ++src;
     960  	    }
     961  	}
     962        else if (flag_mri
     963  	       && in->ptr[src] == '='
     964  	       && src + 1 < in->len
     965  	       && in->ptr[src + 1] == '=')
     966  	{
     967  	  formal_entry *ptr;
     968  
     969  	  sb_reset (&t);
     970  	  src = get_token (src + 2, in, &t);
     971  	  ptr = str_hash_find (formal_hash, sb_terminate (&t));
     972  	  if (ptr == NULL)
     973  	    {
     974  	      /* FIXME: We should really return a warning string here,
     975  		 but we can't, because the == might be in the MRI
     976  		 comment field, and, since the nature of the MRI
     977  		 comment field depends upon the exact instruction
     978  		 being used, we don't have enough information here to
     979  		 figure out whether it is or not.  Instead, we leave
     980  		 the == in place, which should cause a syntax error if
     981  		 it is not in a comment.  */
     982  	      sb_add_char (out, '=');
     983  	      sb_add_char (out, '=');
     984  	      sb_add_sb (out, &t);
     985  	    }
     986  	  else
     987  	    {
     988  	      if (ptr->actual.len)
     989  		{
     990  		  sb_add_string (out, "-1");
     991  		}
     992  	      else
     993  		{
     994  		  sb_add_char (out, '0');
     995  		}
     996  	    }
     997  	}
     998        else
     999  	{
    1000  	  if (in->ptr[src] == '\n')
    1001  	    ++macro_line;
    1002  	  sb_add_char (out, in->ptr[src++]);
    1003  	}
    1004      }
    1005  
    1006    sb_kill (&t);
    1007  
    1008    while (loclist != NULL)
    1009      {
    1010        formal_entry *f;
    1011        const char *name;
    1012  
    1013        f = loclist->next;
    1014        name = sb_terminate (&loclist->name);
    1015        str_hash_delete (formal_hash, name);
    1016        del_formal (loclist);
    1017        loclist = f;
    1018      }
    1019  
    1020    if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
    1021      sb_add_char (out, '\n');
    1022    return err;
    1023  }
    1024  
    1025  /* Assign values to the formal parameters of a macro, and expand the
    1026     body.  */
    1027  
    1028  static const char *
    1029  macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
    1030  {
    1031    sb t;
    1032    formal_entry *ptr;
    1033    formal_entry *f;
    1034    int is_keyword = 0;
    1035    int narg = 0;
    1036    const char *err = NULL;
    1037  
    1038    sb_new (&t);
    1039  
    1040    /* Reset any old value the actuals may have.  */
    1041    for (f = m->formals; f; f = f->next)
    1042      sb_reset (&f->actual);
    1043    f = m->formals;
    1044    while (f != NULL && f->index < 0)
    1045      f = f->next;
    1046  
    1047    if (flag_mri)
    1048      {
    1049        /* The macro may be called with an optional qualifier, which may
    1050  	 be referred to in the macro body as \0.  */
    1051        if (idx < in->len && in->ptr[idx] == '.')
    1052  	{
    1053  	  /* The Microtec assembler ignores this if followed by a white space.
    1054  	     (Macro invocation with empty extension) */
    1055  	  idx++;
    1056  	  if (    idx < in->len
    1057  		  && in->ptr[idx] != ' '
    1058  		  && in->ptr[idx] != '\t')
    1059  	    {
    1060  	      formal_entry *n = new_formal ();
    1061  
    1062  	      n->index = QUAL_INDEX;
    1063  
    1064  	      n->next = m->formals;
    1065  	      m->formals = n;
    1066  
    1067  	      idx = get_any_string (idx, in, &n->actual);
    1068  	    }
    1069  	}
    1070      }
    1071  
    1072    /* Peel off the actuals and store them away in the hash tables' actuals.  */
    1073    idx = sb_skip_white (idx, in);
    1074    while (idx < in->len)
    1075      {
    1076        size_t scan;
    1077  
    1078        /* Look and see if it's a positional or keyword arg.  */
    1079        scan = idx;
    1080        while (scan < in->len
    1081  	     && !ISSEP (in->ptr[scan])
    1082  	     && !(flag_mri && in->ptr[scan] == '\'')
    1083  	     && (!flag_macro_alternate && in->ptr[scan] != '='))
    1084  	scan++;
    1085        if (scan < in->len && !flag_macro_alternate && in->ptr[scan] == '=')
    1086  	{
    1087  	  is_keyword = 1;
    1088  
    1089  	  /* It's OK to go from positional to keyword.  */
    1090  
    1091  	  /* This is a keyword arg, fetch the formal name and
    1092  	     then the actual stuff.  */
    1093  	  sb_reset (&t);
    1094  	  idx = get_token (idx, in, &t);
    1095  	  if (idx >= in->len || in->ptr[idx] != '=')
    1096  	    {
    1097  	      err = _("confusion in formal parameters");
    1098  	      break;
    1099  	    }
    1100  
    1101  	  /* Lookup the formal in the macro's list.  */
    1102  	  ptr = str_hash_find (m->formal_hash, sb_terminate (&t));
    1103  	  if (!ptr)
    1104  	    {
    1105  	      as_bad (_("Parameter named `%s' does not exist for macro `%s'"),
    1106  		      t.ptr,
    1107  		      m->name);
    1108  	      sb_reset (&t);
    1109  	      idx = get_any_string (idx + 1, in, &t);
    1110  	    }
    1111  	  else
    1112  	    {
    1113  	      /* Insert this value into the right place.  */
    1114  	      if (ptr->actual.len)
    1115  		{
    1116  		  as_warn (_("Value for parameter `%s' of macro `%s' was already specified"),
    1117  			   ptr->name.ptr,
    1118  			   m->name);
    1119  		  sb_reset (&ptr->actual);
    1120  		}
    1121  	      idx = get_any_string (idx + 1, in, &ptr->actual);
    1122  	      if (ptr->actual.len > 0)
    1123  		++narg;
    1124  	    }
    1125  	}
    1126        else
    1127  	{
    1128  	  if (is_keyword)
    1129  	    {
    1130  	      err = _("can't mix positional and keyword arguments");
    1131  	      break;
    1132  	    }
    1133  
    1134  	  if (!f)
    1135  	    {
    1136  	      formal_entry **pf;
    1137  	      int c;
    1138  
    1139  	      if (!flag_mri)
    1140  		{
    1141  		  err = _("too many positional arguments");
    1142  		  break;
    1143  		}
    1144  
    1145  	      f = new_formal ();
    1146  
    1147  	      c = -1;
    1148  	      for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
    1149  		if ((*pf)->index >= c)
    1150  		  c = (*pf)->index + 1;
    1151  	      if (c == -1)
    1152  		c = 0;
    1153  	      *pf = f;
    1154  	      f->index = c;
    1155  	    }
    1156  
    1157  	  if (f->type != FORMAL_VARARG)
    1158  	    idx = get_any_string (idx, in, &f->actual);
    1159  	  else if (idx < in->len)
    1160  	    {
    1161  	      sb_add_buffer (&f->actual, in->ptr + idx, in->len - idx);
    1162  	      idx = in->len;
    1163  	    }
    1164  	  if (f->actual.len > 0)
    1165  	    ++narg;
    1166  	  do
    1167  	    {
    1168  	      f = f->next;
    1169  	    }
    1170  	  while (f != NULL && f->index < 0);
    1171  	}
    1172  
    1173        if (! flag_mri)
    1174  	idx = sb_skip_comma (idx, in);
    1175        else
    1176  	{
    1177  	  if (idx < in->len && in->ptr[idx] == ',')
    1178  	    ++idx;
    1179  	  if (idx < in->len && ISWHITE (in->ptr[idx]))
    1180  	    break;
    1181  	}
    1182      }
    1183  
    1184    if (! err)
    1185      {
    1186        for (ptr = m->formals; ptr; ptr = ptr->next)
    1187  	{
    1188  	  if (ptr->type == FORMAL_REQUIRED && ptr->actual.len == 0)
    1189  	    as_bad (_("Missing value for required parameter `%s' of macro `%s'"),
    1190  		    ptr->name.ptr,
    1191  		    m->name);
    1192  	}
    1193  
    1194        if (flag_mri)
    1195  	{
    1196  	  ptr = str_hash_find (m->formal_hash,
    1197  			       macro_strip_at ? "$NARG" : "NARG");
    1198  	  if (ptr)
    1199  	    {
    1200  	      char buffer[20];
    1201  	      sprintf (buffer, "%d", narg);
    1202  	      sb_add_string (&ptr->actual, buffer);
    1203  	    }
    1204  	}
    1205  
    1206        err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
    1207      }
    1208  
    1209    /* Discard any unnamed formal arguments.  */
    1210    if (flag_mri)
    1211      {
    1212        formal_entry **pf;
    1213  
    1214        pf = &m->formals;
    1215        while (*pf != NULL)
    1216  	{
    1217  	  if ((*pf)->name.len != 0)
    1218  	    pf = &(*pf)->next;
    1219  	  else
    1220  	    {
    1221  	      f = (*pf)->next;
    1222  	      del_formal (*pf);
    1223  	      *pf = f;
    1224  	    }
    1225  	}
    1226      }
    1227  
    1228    sb_kill (&t);
    1229    if (!err)
    1230      macro_number++;
    1231  
    1232    return err;
    1233  }
    1234  
    1235  /* Check for a macro.  If one is found, put the expansion into
    1236     *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
    1237  
    1238  int
    1239  check_macro (const char *line, sb *expand,
    1240  	     const char **error, macro_entry **info)
    1241  {
    1242    const char *s;
    1243    char *copy, *cls;
    1244    macro_entry *macro;
    1245    sb line_sb;
    1246  
    1247    if (! is_name_beginner (*line)
    1248        && (! flag_mri || *line != '.'))
    1249      return 0;
    1250  
    1251    s = line + 1;
    1252    while (is_part_of_name (*s))
    1253      ++s;
    1254    if (is_name_ender (*s))
    1255      ++s;
    1256  
    1257    copy = xmemdup0 (line, s - line);
    1258    for (cls = copy; *cls != '\0'; cls ++)
    1259      *cls = TOLOWER (*cls);
    1260  
    1261    macro = str_hash_find (macro_hash, copy);
    1262    free (copy);
    1263  
    1264    if (macro == NULL)
    1265      return 0;
    1266  
    1267    /* Wrap the line up in an sb.  */
    1268    sb_new (&line_sb);
    1269    while (*s != '\0' && *s != '\n' && *s != '\r')
    1270      sb_add_char (&line_sb, *s++);
    1271  
    1272    sb_new (expand);
    1273    *error = macro_expand (0, &line_sb, macro, expand);
    1274  
    1275    sb_kill (&line_sb);
    1276  
    1277    /* Export the macro information if requested.  */
    1278    if (info)
    1279      *info = macro;
    1280  
    1281    return 1;
    1282  }
    1283  
    1284  /* Delete a macro.  */
    1285  
    1286  void
    1287  delete_macro (const char *name)
    1288  {
    1289    char *copy;
    1290    size_t i, len;
    1291    macro_entry *macro;
    1292  
    1293    len = strlen (name);
    1294    copy = XNEWVEC (char, len + 1);
    1295    for (i = 0; i < len; ++i)
    1296      copy[i] = TOLOWER (name[i]);
    1297    copy[i] = '\0';
    1298  
    1299    macro = str_hash_find (macro_hash, copy);
    1300    if (macro != NULL)
    1301      str_hash_delete (macro_hash, copy);
    1302    else
    1303      as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
    1304    free (copy);
    1305  }
    1306  
    1307  /* Handle the MRI IRP and IRPC pseudo-ops.  These are handled as a
    1308     combined macro definition and execution.  This returns NULL on
    1309     success, or an error message otherwise.  */
    1310  
    1311  const char *
    1312  expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
    1313  {
    1314    sb sub;
    1315    formal_entry f;
    1316    struct htab *h;
    1317    const char *err = NULL;
    1318  
    1319    idx = sb_skip_white (idx, in);
    1320  
    1321    sb_new (&sub);
    1322    if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
    1323      {
    1324        err = _("unexpected end of file in irp or irpc");
    1325        goto out2;
    1326      }
    1327  
    1328    sb_new (&f.name);
    1329    sb_new (&f.def);
    1330    sb_new (&f.actual);
    1331  
    1332    idx = get_token (idx, in, &f.name);
    1333    if (f.name.len == 0)
    1334      {
    1335        err = _("missing model parameter");
    1336        goto out1;
    1337      }
    1338  
    1339    h = str_htab_create ();
    1340  
    1341    str_hash_insert (h, sb_terminate (&f.name), &f, 0);
    1342  
    1343    f.index = 1;
    1344    f.next = NULL;
    1345    f.type = FORMAL_OPTIONAL;
    1346  
    1347    sb_reset (out);
    1348  
    1349    idx = sb_skip_comma (idx, in);
    1350    if (idx >= in->len)
    1351      {
    1352        /* Expand once with a null string.  */
    1353        err = macro_expand_body (&sub, out, &f, h, 0);
    1354      }
    1355    else
    1356      {
    1357        bool in_quotes = false;
    1358  
    1359        if (irpc && in->ptr[idx] == '"')
    1360  	{
    1361  	  in_quotes = true;
    1362  	  ++idx;
    1363  	}
    1364  
    1365        while (idx < in->len)
    1366  	{
    1367  	  if (!irpc)
    1368  	    idx = get_any_string (idx, in, &f.actual);
    1369  	  else
    1370  	    {
    1371  	      if (in->ptr[idx] == '"')
    1372  		{
    1373  		  size_t nxt;
    1374  
    1375  		  if (irpc)
    1376  		    in_quotes = ! in_quotes;
    1377  
    1378  		  nxt = sb_skip_white (idx + 1, in);
    1379  		  if (nxt >= in->len)
    1380  		    {
    1381  		      idx = nxt;
    1382  		      break;
    1383  		    }
    1384  		}
    1385  	      sb_reset (&f.actual);
    1386  	      sb_add_char (&f.actual, in->ptr[idx]);
    1387  	      ++idx;
    1388  	    }
    1389  
    1390  	  err = macro_expand_body (&sub, out, &f, h, 0);
    1391  	  if (err != NULL)
    1392  	    break;
    1393  	  if (!irpc)
    1394  	    idx = sb_skip_comma (idx, in);
    1395  	  else if (! in_quotes)
    1396  	    idx = sb_skip_white (idx, in);
    1397  	}
    1398      }
    1399  
    1400    htab_delete (h);
    1401   out1:
    1402    sb_kill (&f.actual);
    1403    sb_kill (&f.def);
    1404    sb_kill (&f.name);
    1405   out2:
    1406    sb_kill (&sub);
    1407  
    1408    return err;
    1409  }