1 /* MD reader for GCC. 2 Copyright (C) 1987-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 /* This file is compiled twice: once for the generator programs 21 once for the compiler. */ 22 #ifdef GENERATOR_FILE 23 #include "bconfig.h" 24 #else 25 #include "config.h" 26 #endif 27 #include "system.h" 28 #include "coretypes.h" 29 #ifdef GENERATOR_FILE 30 #include "errors.h" 31 #endif /* #ifdef GENERATOR_FILE */ 32 #include "statistics.h" 33 #include "vec.h" 34 #include "read-md.h" 35 36 #ifndef GENERATOR_FILE 37 38 /* Minimal reimplementation of errors.c for use by RTL frontend 39 within cc1. */ 40 41 int have_error = 0; 42 43 #endif /* #ifndef GENERATOR_FILE */ 44 45 46 /* Associates PTR (which can be a string, etc.) with the file location 47 specified by FILENAME and LINENO. */ 48 struct ptr_loc { 49 const void *ptr; 50 const char *filename; 51 int lineno; 52 }; 53 54 /* This callback will be invoked whenever an md include directive is 55 processed. To be used for creation of the dependency file. */ 56 void (*include_callback) (const char *); 57 58 /* Global singleton. */ 59 60 md_reader *md_reader_ptr; 61 62 /* Given an object that starts with a char * name field, return a hash 63 code for its name. */ 64 65 hashval_t 66 leading_string_hash (const void *def) 67 { 68 return htab_hash_string (*(const char *const *) def); 69 } 70 71 /* Given two objects that start with char * name fields, return true if 72 they have the same name. */ 73 74 int 75 leading_string_eq_p (const void *def1, const void *def2) 76 { 77 return strcmp (*(const char *const *) def1, 78 *(const char *const *) def2) == 0; 79 } 80 81 /* Return a hash value for the pointer pointed to by DEF. */ 82 83 static hashval_t 84 leading_ptr_hash (const void *def) 85 { 86 return htab_hash_pointer (*(const void *const *) def); 87 } 88 89 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */ 90 91 static int 92 leading_ptr_eq_p (const void *def1, const void *def2) 93 { 94 return *(const void *const *) def1 == *(const void *const *) def2; 95 } 96 97 /* Associate PTR with the file position given by FILENAME and LINENO. */ 98 99 void 100 md_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno) 101 { 102 struct ptr_loc *loc; 103 104 loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack, 105 sizeof (struct ptr_loc)); 106 loc->ptr = ptr; 107 loc->filename = filename; 108 loc->lineno = lineno; 109 *htab_find_slot (m_ptr_locs, loc, INSERT) = loc; 110 } 111 112 /* Return the position associated with pointer PTR. Return null if no 113 position was set. */ 114 115 const struct ptr_loc * 116 md_reader::get_md_ptr_loc (const void *ptr) 117 { 118 return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr); 119 } 120 121 /* Associate NEW_PTR with the same file position as OLD_PTR. */ 122 123 void 124 md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr) 125 { 126 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr); 127 if (loc != 0) 128 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno); 129 } 130 131 /* If PTR is associated with a known file position, print a #line 132 directive for it to OUTF. */ 133 134 void 135 md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr) 136 { 137 const struct ptr_loc *loc = get_md_ptr_loc (ptr); 138 if (loc != 0) 139 fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename); 140 } 141 142 /* Special fprint_md_ptr_loc for writing to STDOUT. */ 143 void 144 md_reader::print_md_ptr_loc (const void *ptr) 145 { 146 fprint_md_ptr_loc (stdout, ptr); 147 } 148 149 /* Return a condition that satisfies both COND1 and COND2. Either string 150 may be null or empty. */ 151 152 const char * 153 md_reader::join_c_conditions (const char *cond1, const char *cond2) 154 { 155 char *result; 156 const void **entry; 157 158 if (cond1 == 0 || cond1[0] == 0) 159 return cond2; 160 161 if (cond2 == 0 || cond2[0] == 0) 162 return cond1; 163 164 if (strcmp (cond1, cond2) == 0) 165 return cond1; 166 167 result = concat ("(", cond1, ") && (", cond2, ")", NULL); 168 obstack_ptr_grow (&m_joined_conditions_obstack, result); 169 obstack_ptr_grow (&m_joined_conditions_obstack, cond1); 170 obstack_ptr_grow (&m_joined_conditions_obstack, cond2); 171 entry = XOBFINISH (&m_joined_conditions_obstack, const void **); 172 *htab_find_slot (m_joined_conditions, entry, INSERT) = entry; 173 return result; 174 } 175 176 /* Print condition COND to OUTF, wrapped in brackets. If COND was created 177 by join_c_conditions, recursively invoke this function for the original 178 conditions and join the result with "&&". Otherwise print a #line 179 directive for COND if its original file position is known. */ 180 181 void 182 md_reader::fprint_c_condition (FILE *outf, const char *cond) 183 { 184 const char **halves = (const char **) htab_find (m_joined_conditions, &cond); 185 if (halves != 0) 186 { 187 fprintf (outf, "("); 188 fprint_c_condition (outf, halves[1]); 189 fprintf (outf, " && "); 190 fprint_c_condition (outf, halves[2]); 191 fprintf (outf, ")"); 192 } 193 else 194 { 195 fputc ('\n', outf); 196 fprint_md_ptr_loc (outf, cond); 197 fprintf (outf, "(%s)", cond); 198 } 199 } 200 201 /* Special fprint_c_condition for writing to STDOUT. */ 202 203 void 204 md_reader::print_c_condition (const char *cond) 205 { 206 fprint_c_condition (stdout, cond); 207 } 208 209 /* A vfprintf-like function for reporting an error against line LINENO 210 of the current MD file. */ 211 212 static void ATTRIBUTE_PRINTF(2,0) 213 message_at_1 (file_location loc, const char *msg, va_list ap) 214 { 215 fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno); 216 vfprintf (stderr, msg, ap); 217 fputc ('\n', stderr); 218 } 219 220 /* A printf-like function for reporting a message against location LOC. */ 221 222 void 223 message_at (file_location loc, const char *msg, ...) 224 { 225 va_list ap; 226 227 va_start (ap, msg); 228 message_at_1 (loc, msg, ap); 229 va_end (ap); 230 } 231 232 /* Like message_at, but treat the condition as an error. */ 233 234 void 235 error_at (file_location loc, const char *msg, ...) 236 { 237 va_list ap; 238 239 va_start (ap, msg); 240 message_at_1 (loc, msg, ap); 241 va_end (ap); 242 have_error = 1; 243 } 244 245 /* Like message_at, but treat the condition as a fatal error. */ 246 247 void 248 fatal_at (file_location loc, const char *msg, ...) 249 { 250 va_list ap; 251 252 va_start (ap, msg); 253 message_at_1 (loc, msg, ap); 254 va_end (ap); 255 exit (1); 256 } 257 258 /* A printf-like function for reporting an error against the current 259 position in the MD file. */ 260 261 void 262 fatal_with_file_and_line (const char *msg, ...) 263 { 264 char context[64]; 265 size_t i; 266 int c; 267 va_list ap; 268 269 va_start (ap, msg); 270 271 fprintf (stderr, "%s:%d:%d: error: ", md_reader_ptr->get_filename (), 272 md_reader_ptr->get_lineno (), 273 md_reader_ptr->get_colno ()); 274 vfprintf (stderr, msg, ap); 275 putc ('\n', stderr); 276 277 /* Gather some following context. */ 278 for (i = 0; i < sizeof (context)-1; ++i) 279 { 280 c = read_char (); 281 if (c == EOF) 282 break; 283 if (c == '\r' || c == '\n') 284 { 285 unread_char (c); 286 break; 287 } 288 context[i] = c; 289 } 290 context[i] = '\0'; 291 292 fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n", 293 md_reader_ptr->get_filename (), 294 md_reader_ptr->get_lineno (), 295 md_reader_ptr->get_colno (), context); 296 297 va_end (ap); 298 exit (1); 299 } 300 301 /* Report that we found character ACTUAL when we expected to find 302 character EXPECTED. */ 303 304 void 305 fatal_expected_char (int expected, int actual) 306 { 307 if (actual == EOF) 308 fatal_with_file_and_line ("expected character `%c', found EOF", 309 expected); 310 else 311 fatal_with_file_and_line ("expected character `%c', found `%c'", 312 expected, actual); 313 } 314 315 /* Read chars from the MD file until a non-whitespace char and return that. 316 Comments, both Lisp style and C style, are treated as whitespace. */ 317 318 int 319 read_skip_spaces (void) 320 { 321 int c; 322 323 while (1) 324 { 325 c = read_char (); 326 switch (c) 327 { 328 case ' ': case '\t': case '\f': case '\r': case '\n': 329 break; 330 331 case ';': 332 do 333 c = read_char (); 334 while (c != '\n' && c != EOF); 335 break; 336 337 case '/': 338 { 339 int prevc; 340 c = read_char (); 341 if (c != '*') 342 { 343 unread_char (c); 344 fatal_with_file_and_line ("stray '/' in file"); 345 } 346 347 prevc = 0; 348 while ((c = read_char ()) && c != EOF) 349 { 350 if (prevc == '*' && c == '/') 351 break; 352 prevc = c; 353 } 354 } 355 break; 356 357 default: 358 return c; 359 } 360 } 361 } 362 363 /* Consume the next character, issuing a fatal error if it is not 364 EXPECTED. */ 365 366 void 367 md_reader::require_char (char expected) 368 { 369 int ch = read_char (); 370 if (ch != expected) 371 fatal_expected_char (expected, ch); 372 } 373 374 /* Consume any whitespace, then consume the next non-whitespace 375 character, issuing a fatal error if it is not EXPECTED. */ 376 377 void 378 md_reader::require_char_ws (char expected) 379 { 380 int ch = read_skip_spaces (); 381 if (ch != expected) 382 fatal_expected_char (expected, ch); 383 } 384 385 /* Consume any whitespace, then consume the next word (as per read_name), 386 issuing a fatal error if it is not EXPECTED. */ 387 388 void 389 md_reader::require_word_ws (const char *expected) 390 { 391 struct md_name name; 392 read_name (&name); 393 if (strcmp (name.string, expected)) 394 fatal_with_file_and_line ("missing '%s'", expected); 395 } 396 397 /* Read the next character from the file. */ 398 399 int 400 md_reader::read_char (void) 401 { 402 int ch; 403 404 ch = getc (m_read_md_file); 405 if (ch == '\n') 406 { 407 m_read_md_lineno++; 408 m_last_line_colno = m_read_md_colno; 409 m_read_md_colno = 0; 410 } 411 else 412 m_read_md_colno++; 413 414 /* If we're filtering lines, treat everything before the range of 415 interest as a space, and as EOF for everything after. */ 416 if (m_first_line && m_last_line) 417 { 418 if (m_read_md_lineno < m_first_line) 419 return ' '; 420 if (m_read_md_lineno > m_last_line) 421 return EOF; 422 } 423 424 return ch; 425 } 426 427 /* Put back CH, which was the last character read from the file. */ 428 429 void 430 md_reader::unread_char (int ch) 431 { 432 if (ch == '\n') 433 { 434 m_read_md_lineno--; 435 m_read_md_colno = m_last_line_colno; 436 } 437 else 438 m_read_md_colno--; 439 ungetc (ch, m_read_md_file); 440 } 441 442 /* Peek at the next character from the file without consuming it. */ 443 444 int 445 md_reader::peek_char (void) 446 { 447 int ch = read_char (); 448 unread_char (ch); 449 return ch; 450 } 451 452 /* Read an rtx code name into NAME. It is terminated by any of the 453 punctuation chars of rtx printed syntax. */ 454 455 bool 456 md_reader::read_name_1 (struct md_name *name, file_location *out_loc) 457 { 458 int c; 459 size_t i; 460 int angle_bracket_depth; 461 462 c = read_skip_spaces (); 463 464 *out_loc = get_current_location (); 465 466 i = 0; 467 angle_bracket_depth = 0; 468 while (1) 469 { 470 if (c == '<') 471 angle_bracket_depth++; 472 473 if ((c == '>') && (angle_bracket_depth > 0)) 474 angle_bracket_depth--; 475 476 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' 477 || c == EOF) 478 break; 479 if (angle_bracket_depth == 0) 480 { 481 if (c == ':' || c == ')' || c == ']' 482 || c == '"' || c == '/' || c == '(' || c == '[') 483 { 484 unread_char (c); 485 break; 486 } 487 } 488 489 if (i == sizeof (name->buffer) - 1) 490 fatal_with_file_and_line ("name too long"); 491 name->buffer[i++] = c; 492 493 c = read_char (); 494 } 495 496 if (i == 0) 497 return false; 498 499 name->buffer[i] = 0; 500 name->string = name->buffer; 501 502 if (m_md_constants) 503 { 504 /* Do constant expansion. */ 505 struct md_constant *def; 506 507 do 508 { 509 struct md_constant tmp_def; 510 511 tmp_def.name = name->string; 512 def = (struct md_constant *) htab_find (m_md_constants, &tmp_def); 513 if (def) 514 name->string = def->value; 515 } 516 while (def); 517 } 518 519 return true; 520 } 521 522 /* Read an rtx code name into NAME. It is terminated by any of the 523 punctuation chars of rtx printed syntax. */ 524 525 file_location 526 md_reader::read_name (struct md_name *name) 527 { 528 file_location loc; 529 if (!read_name_1 (name, &loc)) 530 fatal_with_file_and_line ("missing name or number"); 531 return loc; 532 } 533 534 file_location 535 md_reader::read_name_or_nil (struct md_name *name) 536 { 537 file_location loc; 538 if (!read_name_1 (name, &loc)) 539 { 540 file_location loc = get_current_location (); 541 read_skip_construct (0, loc); 542 /* Skip the ')'. */ 543 read_char (); 544 name->buffer[0] = 0; 545 name->string = name->buffer; 546 } 547 return loc; 548 } 549 550 /* Subroutine of the string readers. Handles backslash escapes. 551 Caller has read the backslash, but not placed it into the obstack. */ 552 553 void 554 md_reader::read_escape () 555 { 556 int c = read_char (); 557 558 switch (c) 559 { 560 /* Backslash-newline is replaced by nothing, as in C. */ 561 case '\n': 562 return; 563 564 /* \" \' \\ are replaced by the second character. */ 565 case '\\': 566 case '"': 567 case '\'': 568 break; 569 570 /* Standard C string escapes: 571 \a \b \f \n \r \t \v 572 \[0-7] \x 573 all are passed through to the output string unmolested. 574 In normal use these wind up in a string constant processed 575 by the C compiler, which will translate them appropriately. 576 We do not bother checking that \[0-7] are followed by up to 577 two octal digits, or that \x is followed by N hex digits. 578 \? \u \U are left out because they are not in traditional C. */ 579 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v': 580 case '0': case '1': case '2': case '3': case '4': case '5': case '6': 581 case '7': case 'x': 582 obstack_1grow (&m_string_obstack, '\\'); 583 break; 584 585 /* \; makes stuff for a C string constant containing 586 newline and tab. */ 587 case ';': 588 obstack_grow (&m_string_obstack, "\\n\\t", 4); 589 return; 590 591 /* pass anything else through, but issue a warning. */ 592 default: 593 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n", 594 get_filename (), get_lineno (), 595 c); 596 obstack_1grow (&m_string_obstack, '\\'); 597 break; 598 } 599 600 obstack_1grow (&m_string_obstack, c); 601 } 602 603 /* Read a double-quoted string onto the obstack. Caller has scanned 604 the leading quote. */ 605 606 char * 607 md_reader::read_quoted_string () 608 { 609 int c; 610 611 while (1) 612 { 613 c = read_char (); /* Read the string */ 614 if (c == '\\') 615 { 616 read_escape (); 617 continue; 618 } 619 else if (c == '"' || c == EOF) 620 break; 621 622 obstack_1grow (&m_string_obstack, c); 623 } 624 625 obstack_1grow (&m_string_obstack, 0); 626 return XOBFINISH (&m_string_obstack, char *); 627 } 628 629 /* Read a braced string (a la Tcl) onto the string obstack. Caller 630 has scanned the leading brace. Note that unlike quoted strings, 631 the outermost braces _are_ included in the string constant. */ 632 633 char * 634 md_reader::read_braced_string () 635 { 636 int c; 637 int brace_depth = 1; /* caller-processed */ 638 unsigned long starting_read_md_lineno = get_lineno (); 639 640 obstack_1grow (&m_string_obstack, '{'); 641 while (brace_depth) 642 { 643 c = read_char (); /* Read the string */ 644 645 if (c == '{') 646 brace_depth++; 647 else if (c == '}') 648 brace_depth--; 649 else if (c == '\\') 650 { 651 read_escape (); 652 continue; 653 } 654 else if (c == EOF) 655 fatal_with_file_and_line 656 ("missing closing } for opening brace on line %lu", 657 starting_read_md_lineno); 658 659 obstack_1grow (&m_string_obstack, c); 660 } 661 662 obstack_1grow (&m_string_obstack, 0); 663 return XOBFINISH (&m_string_obstack, char *); 664 } 665 666 /* Read some kind of string constant. This is the high-level routine 667 used by read_rtx. It handles surrounding parentheses, leading star, 668 and dispatch to the appropriate string constant reader. */ 669 670 char * 671 md_reader::read_string (int star_if_braced) 672 { 673 char *stringbuf; 674 int saw_paren = 0; 675 int c, old_lineno; 676 677 c = read_skip_spaces (); 678 if (c == '(') 679 { 680 saw_paren = 1; 681 c = read_skip_spaces (); 682 } 683 684 old_lineno = get_lineno (); 685 if (c == '"') 686 stringbuf = read_quoted_string (); 687 else if (c == '{') 688 { 689 if (star_if_braced) 690 obstack_1grow (&m_string_obstack, '*'); 691 stringbuf = read_braced_string (); 692 } 693 else if (saw_paren && c == 'n') 694 { 695 /* Handle (nil) by returning NULL. */ 696 require_char ('i'); 697 require_char ('l'); 698 require_char_ws (')'); 699 return NULL; 700 } 701 else 702 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c); 703 704 if (saw_paren) 705 require_char_ws (')'); 706 707 set_md_ptr_loc (stringbuf, get_filename (), old_lineno); 708 return stringbuf; 709 } 710 711 /* Skip the rest of a construct that started at line LINENO and that 712 is currently nested by DEPTH levels of parentheses. */ 713 714 void 715 md_reader::read_skip_construct (int depth, file_location loc) 716 { 717 struct md_name name; 718 int c; 719 720 do 721 { 722 c = read_skip_spaces (); 723 if (c == EOF) 724 { 725 error_at (loc, "unterminated construct"); 726 exit (1); 727 } 728 switch (c) 729 { 730 case '(': 731 depth++; 732 break; 733 734 case ')': 735 depth--; 736 break; 737 738 case ':': 739 case '[': 740 case ']': 741 case '/': 742 break; 743 744 case '\"': 745 case '{': 746 unread_char (c); 747 read_string (false); 748 break; 749 750 default: 751 unread_char (c); 752 read_name (&name); 753 break; 754 } 755 } 756 while (depth > 0); 757 unread_char (c); 758 } 759 760 /* Given a string, return the number of comma-separated elements in it. 761 Return 0 for the null string. */ 762 763 int 764 n_comma_elts (const char *s) 765 { 766 int n; 767 768 if (*s == '\0') 769 return 0; 770 771 for (n = 1; *s; s++) 772 if (*s == ',') 773 n++; 774 775 return n; 776 } 777 778 /* Given a pointer to a (char *), return a pointer to the beginning of the 779 next comma-separated element in the string. Advance the pointer given 780 to the end of that element. Return NULL if at end of string. Caller 781 is responsible for copying the string if necessary. White space between 782 a comma and an element is ignored. */ 783 784 const char * 785 scan_comma_elt (const char **pstr) 786 { 787 const char *start; 788 const char *p = *pstr; 789 790 if (*p == ',') 791 p++; 792 while (ISSPACE (*p)) 793 p++; 794 795 if (*p == '\0') 796 return NULL; 797 798 start = p; 799 800 while (*p != ',' && *p != '\0') 801 p++; 802 803 *pstr = p; 804 return start; 805 } 806 807 /* Convert STRING to uppercase. */ 808 809 void 810 upcase_string (char *string) 811 { 812 int i; 813 814 for (i = 0; string[i]; i++) 815 string[i] = TOUPPER (string[i]); 816 } 817 818 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS, 819 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the 820 enum to which NAME belongs, or null if NAME is a stand-alone constant. */ 821 822 static struct md_constant * 823 add_constant (htab_t defs, char *name, char *value, 824 struct enum_type *parent_enum) 825 { 826 struct md_constant *def, tmp_def; 827 void **entry_ptr; 828 829 tmp_def.name = name; 830 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT); 831 if (*entry_ptr) 832 { 833 def = (struct md_constant *) *entry_ptr; 834 if (strcmp (def->value, value) != 0) 835 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'", 836 def->name, def->value, value); 837 else if (parent_enum || def->parent_enum) 838 fatal_with_file_and_line ("redefinition of `%s'", def->name); 839 free (name); 840 free (value); 841 } 842 else 843 { 844 def = XNEW (struct md_constant); 845 def->name = name; 846 def->value = value; 847 def->parent_enum = parent_enum; 848 *entry_ptr = def; 849 } 850 return def; 851 } 852 853 /* Process a define_constants directive, starting with the optional space 854 after the "define_constants". */ 855 856 void 857 md_reader::handle_constants () 858 { 859 int c; 860 htab_t defs; 861 862 require_char_ws ('['); 863 864 /* Disable constant expansion during definition processing. */ 865 defs = m_md_constants; 866 m_md_constants = 0; 867 while ( (c = read_skip_spaces ()) != ']') 868 { 869 struct md_name name, value; 870 871 if (c != '(') 872 fatal_expected_char ('(', c); 873 874 read_name (&name); 875 read_name (&value); 876 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0); 877 878 require_char_ws (')'); 879 } 880 m_md_constants = defs; 881 } 882 883 /* For every constant definition, call CALLBACK with two arguments: 884 a pointer a pointer to the constant definition and INFO. 885 Stop when CALLBACK returns zero. */ 886 887 void 888 md_reader::traverse_md_constants (htab_trav callback, void *info) 889 { 890 htab_traverse (get_md_constants (), callback, info); 891 } 892 893 /* Return a malloc()ed decimal string that represents number NUMBER. */ 894 895 static char * 896 md_decimal_string (int number) 897 { 898 /* A safe overestimate. +1 for sign, +1 for null terminator. */ 899 char buffer[sizeof (int) * CHAR_BIT + 1 + 1]; 900 901 sprintf (buffer, "%d", number); 902 return xstrdup (buffer); 903 } 904 905 /* Process a define_enum or define_c_enum directive, starting with 906 the optional space after the "define_enum". LINENO is the line 907 number on which the directive started and MD_P is true if the 908 directive is a define_enum rather than a define_c_enum. */ 909 910 void 911 md_reader::handle_enum (file_location loc, bool md_p) 912 { 913 char *enum_name, *value_name; 914 struct md_name name; 915 struct enum_type *def; 916 struct enum_value *ev; 917 void **slot; 918 int c; 919 920 enum_name = read_string (false); 921 slot = htab_find_slot (m_enum_types, &enum_name, INSERT); 922 if (*slot) 923 { 924 def = (struct enum_type *) *slot; 925 if (def->md_p != md_p) 926 error_at (loc, "redefining `%s' as a different type of enum", 927 enum_name); 928 } 929 else 930 { 931 def = XNEW (struct enum_type); 932 def->name = enum_name; 933 def->md_p = md_p; 934 def->values = 0; 935 def->tail_ptr = &def->values; 936 def->num_values = 0; 937 *slot = def; 938 } 939 940 require_char_ws ('['); 941 942 while ((c = read_skip_spaces ()) != ']') 943 { 944 if (c == EOF) 945 { 946 error_at (loc, "unterminated construct"); 947 exit (1); 948 } 949 unread_char (c); 950 read_name (&name); 951 952 ev = XNEW (struct enum_value); 953 ev->next = 0; 954 if (md_p) 955 { 956 value_name = concat (def->name, "_", name.string, NULL); 957 upcase_string (value_name); 958 ev->name = xstrdup (name.string); 959 } 960 else 961 { 962 value_name = xstrdup (name.string); 963 ev->name = value_name; 964 } 965 ev->def = add_constant (get_md_constants (), value_name, 966 md_decimal_string (def->num_values), def); 967 968 *def->tail_ptr = ev; 969 def->tail_ptr = &ev->next; 970 def->num_values++; 971 } 972 } 973 974 /* Try to find the definition of the given enum. Return null on failure. */ 975 976 struct enum_type * 977 md_reader::lookup_enum_type (const char *name) 978 { 979 return (struct enum_type *) htab_find (m_enum_types, &name); 980 } 981 982 /* For every enum definition, call CALLBACK with two arguments: 983 a pointer to the constant definition and INFO. Stop when CALLBACK 984 returns zero. */ 985 986 void 987 md_reader::traverse_enum_types (htab_trav callback, void *info) 988 { 989 htab_traverse (m_enum_types, callback, info); 990 } 991 992 993 /* Constructor for md_reader. */ 994 995 md_reader::md_reader (bool compact) 996 : m_compact (compact), 997 m_toplevel_fname (NULL), 998 m_base_dir (NULL), 999 m_read_md_file (NULL), 1000 m_read_md_filename (NULL), 1001 m_read_md_lineno (0), 1002 m_read_md_colno (0), 1003 m_first_dir_md_include (NULL), 1004 m_last_dir_md_include_ptr (&m_first_dir_md_include), 1005 m_first_line (0), 1006 m_last_line (0) 1007 { 1008 /* Set the global singleton pointer. */ 1009 md_reader_ptr = this; 1010 1011 obstack_init (&m_string_obstack); 1012 1013 m_ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); 1014 obstack_init (&m_ptr_loc_obstack); 1015 1016 m_joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0); 1017 obstack_init (&m_joined_conditions_obstack); 1018 1019 m_md_constants = htab_create (31, leading_string_hash, 1020 leading_string_eq_p, (htab_del) 0); 1021 1022 m_enum_types = htab_create (31, leading_string_hash, 1023 leading_string_eq_p, (htab_del) 0); 1024 1025 /* Unlock the stdio streams. */ 1026 unlock_std_streams (); 1027 } 1028 1029 /* md_reader's destructor. */ 1030 1031 md_reader::~md_reader () 1032 { 1033 free (m_base_dir); 1034 1035 htab_delete (m_enum_types); 1036 1037 htab_delete (m_md_constants); 1038 1039 obstack_free (&m_joined_conditions_obstack, NULL); 1040 htab_delete (m_joined_conditions); 1041 1042 obstack_free (&m_ptr_loc_obstack, NULL); 1043 htab_delete (m_ptr_locs); 1044 1045 obstack_free (&m_string_obstack, NULL); 1046 1047 /* Clear the global singleton pointer. */ 1048 md_reader_ptr = NULL; 1049 } 1050 1051 /* Process an "include" directive, starting with the optional space 1052 after the "include". Read in the file and use HANDLE_DIRECTIVE 1053 to process each unknown directive. LINENO is the line number on 1054 which the "include" occurred. */ 1055 1056 void 1057 md_reader::handle_include (file_location loc) 1058 { 1059 const char *filename; 1060 const char *old_filename; 1061 int old_lineno, old_colno; 1062 char *pathname; 1063 FILE *input_file, *old_file; 1064 1065 filename = read_string (false); 1066 input_file = NULL; 1067 1068 /* If the specified file name is absolute, skip the include stack. */ 1069 if (!IS_ABSOLUTE_PATH (filename)) 1070 { 1071 struct file_name_list *stackp; 1072 1073 /* Search the directory path, trying to open the file. */ 1074 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next) 1075 { 1076 static const char sep[2] = { DIR_SEPARATOR, '\0' }; 1077 1078 pathname = concat (stackp->fname, sep, filename, NULL); 1079 input_file = fopen (pathname, "r"); 1080 if (input_file != NULL) 1081 break; 1082 free (pathname); 1083 } 1084 } 1085 1086 /* If we haven't managed to open the file yet, try combining the 1087 filename with BASE_DIR. */ 1088 if (input_file == NULL) 1089 { 1090 if (m_base_dir) 1091 pathname = concat (m_base_dir, filename, NULL); 1092 else 1093 pathname = xstrdup (filename); 1094 input_file = fopen (pathname, "r"); 1095 } 1096 1097 if (input_file == NULL) 1098 { 1099 free (pathname); 1100 error_at (loc, "include file `%s' not found", filename); 1101 return; 1102 } 1103 1104 /* Save the old cursor. Note that the LINENO argument to this 1105 function is the beginning of the include statement, while 1106 read_md_lineno has already been advanced. */ 1107 old_file = m_read_md_file; 1108 old_filename = m_read_md_filename; 1109 old_lineno = m_read_md_lineno; 1110 old_colno = m_read_md_colno; 1111 1112 if (include_callback) 1113 include_callback (pathname); 1114 1115 m_read_md_file = input_file; 1116 m_read_md_filename = pathname; 1117 1118 handle_file (); 1119 1120 /* Restore the old cursor. */ 1121 m_read_md_file = old_file; 1122 m_read_md_filename = old_filename; 1123 m_read_md_lineno = old_lineno; 1124 m_read_md_colno = old_colno; 1125 1126 /* Do not free the pathname. It is attached to the various rtx 1127 queue elements. */ 1128 } 1129 1130 /* Process the current file, assuming that read_md_file and 1131 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle 1132 unknown directives. */ 1133 1134 void 1135 md_reader::handle_file () 1136 { 1137 struct md_name directive; 1138 int c; 1139 1140 m_read_md_lineno = 1; 1141 m_read_md_colno = 0; 1142 while ((c = read_skip_spaces ()) != EOF) 1143 { 1144 file_location loc = get_current_location (); 1145 if (c != '(') 1146 fatal_expected_char ('(', c); 1147 1148 read_name (&directive); 1149 if (strcmp (directive.string, "define_constants") == 0) 1150 handle_constants (); 1151 else if (strcmp (directive.string, "define_enum") == 0) 1152 handle_enum (loc, true); 1153 else if (strcmp (directive.string, "define_c_enum") == 0) 1154 handle_enum (loc, false); 1155 else if (strcmp (directive.string, "include") == 0) 1156 handle_include (loc); 1157 else 1158 handle_unknown_directive (loc, directive.string); 1159 1160 require_char_ws (')'); 1161 } 1162 fclose (m_read_md_file); 1163 } 1164 1165 /* Like handle_file, but for top-level files. Set up m_toplevel_fname 1166 and m_base_dir accordingly. */ 1167 1168 void 1169 md_reader::handle_toplevel_file () 1170 { 1171 const char *base; 1172 1173 m_toplevel_fname = m_read_md_filename; 1174 base = lbasename (m_toplevel_fname); 1175 if (base == m_toplevel_fname) 1176 m_base_dir = NULL; 1177 else 1178 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname); 1179 1180 handle_file (); 1181 } 1182 1183 file_location 1184 md_reader::get_current_location () const 1185 { 1186 return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno); 1187 } 1188 1189 /* Parse a -I option with argument ARG. */ 1190 1191 void 1192 md_reader::add_include_path (const char *arg) 1193 { 1194 struct file_name_list *dirtmp; 1195 1196 dirtmp = XNEW (struct file_name_list); 1197 dirtmp->next = 0; 1198 dirtmp->fname = arg; 1199 *m_last_dir_md_include_ptr = dirtmp; 1200 m_last_dir_md_include_ptr = &dirtmp->next; 1201 } 1202 1203 #ifdef GENERATOR_FILE 1204 1205 /* The main routine for reading .md files. Try to process all the .md 1206 files specified on the command line and return true if no error occurred. 1207 1208 ARGC and ARGV are the arguments to main. 1209 1210 PARSE_OPT, if nonnull, is passed all unknown command-line arguments. 1211 It should return true if it recognizes the argument or false if a 1212 generic error should be reported. */ 1213 1214 bool 1215 md_reader::read_md_files (int argc, const char **argv, 1216 bool (*parse_opt) (const char *)) 1217 { 1218 int i; 1219 bool no_more_options; 1220 bool already_read_stdin; 1221 int num_files; 1222 1223 /* First we loop over all the options. */ 1224 for (i = 1; i < argc; i++) 1225 if (argv[i][0] == '-') 1226 { 1227 /* An argument consisting of exactly one dash is a request to 1228 read stdin. This will be handled in the second loop. */ 1229 if (argv[i][1] == '\0') 1230 continue; 1231 1232 /* An argument consisting of just two dashes causes option 1233 parsing to cease. */ 1234 if (argv[i][1] == '-' && argv[i][2] == '\0') 1235 break; 1236 1237 if (argv[i][1] == 'I') 1238 { 1239 if (argv[i][2] != '\0') 1240 add_include_path (argv[i] + 2); 1241 else if (++i < argc) 1242 add_include_path (argv[i]); 1243 else 1244 fatal ("directory name missing after -I option"); 1245 continue; 1246 } 1247 1248 /* The program may have provided a callback so it can 1249 accept its own options. */ 1250 if (parse_opt && parse_opt (argv[i])) 1251 continue; 1252 1253 fatal ("invalid option `%s'", argv[i]); 1254 } 1255 1256 /* Now loop over all input files. */ 1257 num_files = 0; 1258 no_more_options = false; 1259 already_read_stdin = false; 1260 for (i = 1; i < argc; i++) 1261 { 1262 if (argv[i][0] == '-') 1263 { 1264 if (argv[i][1] == '\0') 1265 { 1266 /* Read stdin. */ 1267 if (already_read_stdin) 1268 fatal ("cannot read standard input twice"); 1269 1270 m_read_md_file = stdin; 1271 m_read_md_filename = "<stdin>"; 1272 handle_toplevel_file (); 1273 already_read_stdin = true; 1274 continue; 1275 } 1276 else if (argv[i][1] == '-' && argv[i][2] == '\0') 1277 { 1278 /* No further arguments are to be treated as options. */ 1279 no_more_options = true; 1280 continue; 1281 } 1282 else if (!no_more_options) 1283 continue; 1284 } 1285 1286 /* If we get here we are looking at a non-option argument, i.e. 1287 a file to be processed. */ 1288 m_read_md_filename = argv[i]; 1289 m_read_md_file = fopen (m_read_md_filename, "r"); 1290 if (m_read_md_file == 0) 1291 { 1292 perror (m_read_md_filename); 1293 return false; 1294 } 1295 handle_toplevel_file (); 1296 num_files++; 1297 } 1298 1299 /* If we get to this point without having seen any files to process, 1300 read the standard input now. */ 1301 if (num_files == 0 && !already_read_stdin) 1302 { 1303 m_read_md_file = stdin; 1304 m_read_md_filename = "<stdin>"; 1305 handle_toplevel_file (); 1306 } 1307 1308 return !have_error; 1309 } 1310 1311 #endif /* #ifdef GENERATOR_FILE */ 1312 1313 /* Read FILENAME. */ 1314 1315 bool 1316 md_reader::read_file (const char *filename) 1317 { 1318 m_read_md_filename = filename; 1319 m_read_md_file = fopen (m_read_md_filename, "r"); 1320 if (m_read_md_file == 0) 1321 { 1322 perror (m_read_md_filename); 1323 return false; 1324 } 1325 handle_toplevel_file (); 1326 return !have_error; 1327 } 1328 1329 /* Read FILENAME, filtering to just the given lines. */ 1330 1331 bool 1332 md_reader::read_file_fragment (const char *filename, 1333 int first_line, 1334 int last_line) 1335 { 1336 m_read_md_filename = filename; 1337 m_read_md_file = fopen (m_read_md_filename, "r"); 1338 if (m_read_md_file == 0) 1339 { 1340 perror (m_read_md_filename); 1341 return false; 1342 } 1343 m_first_line = first_line; 1344 m_last_line = last_line; 1345 handle_toplevel_file (); 1346 return !have_error; 1347 } 1348 1349 /* class noop_reader : public md_reader */ 1350 1351 /* A dummy implementation which skips unknown directives. */ 1352 void 1353 noop_reader::handle_unknown_directive (file_location loc, const char *) 1354 { 1355 read_skip_construct (1, loc); 1356 } 1357