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