OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [macro.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.