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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gas/] [macro.c] - Blame information for rev 866

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

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

powered by: WebSVN 2.1.0

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