1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2019 RackTop Systems. 26 */ 27 28 /* 29 * read.c 30 * 31 * This file contains the makefile reader. 32 */ 33 34 /* 35 * Included files 36 */ 37 #include <alloca.h> /* alloca() */ 38 #include <errno.h> /* errno */ 39 #include <fcntl.h> /* fcntl() */ 40 #include <mk/defs.h> 41 #include <mksh/macro.h> /* expand_value(), expand_macro() */ 42 #include <mksh/misc.h> /* getmem() */ 43 #include <mksh/read.h> /* get_next_block_fn() */ 44 #include <sys/uio.h> /* read() */ 45 #include <unistd.h> /* read(), unlink() */ 46 #include <libintl.h> 47 48 49 /* 50 * typedefs & structs 51 */ 52 53 /* 54 * Static variables 55 */ 56 57 static int line_started_with_space=0; // Used to diagnose spaces instead of tabs 58 59 /* 60 * File table of contents 61 */ 62 static void parse_makefile(register Name true_makefile_name, register Source source); 63 static Source push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source); 64 extern void enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen); 65 extern Name normalize_name(register wchar_t *name_string, register int length); 66 67 /* 68 * read_simple_file(makefile_name, chase_path, doname_it, 69 * complain, must_exist, report_file, lock_makefile) 70 * 71 * Make the makefile and setup to read it. Actually read it if it is stdio 72 * 73 * Return value: 74 * false if the read failed 75 * 76 * Parameters: 77 * makefile_name Name of the file to read 78 * chase_path Use the makefile path when opening file 79 * doname_it Call doname() to build the file first 80 * complain Print message if doname/open fails 81 * must_exist Generate fatal if file is missing 82 * report_file Report file when running -P 83 * lock_makefile Lock the makefile when reading 84 * 85 * Static variables used: 86 * 87 * Global variables used: 88 * do_not_exec_rule Is -n on? 89 * file_being_read Set to the name of the new file 90 * line_number The number of the current makefile line 91 * makefiles_used A list of all makefiles used, appended to 92 */ 93 94 95 Boolean 96 read_simple_file(register Name makefile_name, register Boolean chase_path, register Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile) 97 { 98 static short max_include_depth; 99 register Property makefile = maybe_append_prop(makefile_name, 100 makefile_prop); 101 Boolean forget_after_parse = false; 102 static pathpt makefile_path; 103 register int n; 104 char *path; 105 register Source source = ALLOC(Source); 106 Property orig_makefile = makefile; 107 Dependency *dpp; 108 Dependency dp; 109 register int length; 110 wchar_t *previous_file_being_read = file_being_read; 111 int previous_line_number = line_number; 112 wchar_t previous_current_makefile[MAXPATHLEN]; 113 Makefile_type save_makefile_type; 114 Name normalized_makefile_name; 115 register wchar_t *string_start; 116 register wchar_t *string_end; 117 118 119 120 wchar_t * wcb = get_wstring(makefile_name->string_mb); 121 122 if (max_include_depth++ >= 40) { 123 fatal(gettext("Too many nested include statements")); 124 } 125 if (makefile->body.makefile.contents != NULL) { 126 retmem(makefile->body.makefile.contents); 127 } 128 source->inp_buf = 129 source->inp_buf_ptr = 130 source->inp_buf_end = NULL; 131 source->error_converting = false; 132 makefile->body.makefile.contents = NULL; 133 makefile->body.makefile.size = 0; 134 if ((makefile_name->hash.length != 1) || 135 (wcb[0] != (int) hyphen_char)) { 136 if ((makefile->body.makefile.contents == NULL) && 137 (doname_it)) { 138 if (makefile_path == NULL) { 139 char *pfx = make_install_prefix(); 140 char *path; 141 142 add_dir_to_path(".", 143 &makefile_path, 144 -1); 145 146 // As regularly installed 147 asprintf(&path, "%s/../share/lib/make", pfx); 148 add_dir_to_path(path, &makefile_path, -1); 149 free(path); 150 151 // Tools build 152 asprintf(&path, "%s/../../share/", pfx); 153 add_dir_to_path(path, &makefile_path, -1); 154 free(path); 155 156 add_dir_to_path("/usr/share/lib/make", 157 &makefile_path, 158 -1); 159 add_dir_to_path("/etc/default", 160 &makefile_path, 161 -1); 162 163 free(pfx); 164 } 165 save_makefile_type = makefile_type; 166 makefile_type = reading_nothing; 167 if (doname(makefile_name, true, false) == build_dont_know) { 168 /* Try normalized filename */ 169 string_start=get_wstring(makefile_name->string_mb); 170 for (string_end=string_start+1; *string_end != L'\0'; string_end++); 171 normalized_makefile_name=normalize_name(string_start, string_end - string_start); 172 if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) || 173 (doname(normalized_makefile_name, true, false) == build_dont_know)) { 174 n = access_vroot(makefile_name->string_mb, 175 4, 176 chase_path ? 177 makefile_path : NULL, 178 VROOT_DEFAULT); 179 if (n == 0) { 180 get_vroot_path((char **) NULL, 181 &path, 182 (char **) NULL); 183 if ((path[0] == (int) period_char) && 184 (path[1] == (int) slash_char)) { 185 path += 2; 186 } 187 MBSTOWCS(wcs_buffer, path); 188 makefile_name = GETNAME(wcs_buffer, 189 FIND_LENGTH); 190 } 191 } 192 retmem(string_start); 193 /* 194 * Commented out: retmem_mb(normalized_makefile_name->string_mb); 195 * We have to return this memory, but it seems to trigger a bug 196 * in dmake or in Sun C++ 5.7 compiler (it works ok if this code 197 * is compiled using Sun C++ 5.6). 198 */ 199 // retmem_mb(normalized_makefile_name->string_mb); 200 } 201 makefile_type = save_makefile_type; 202 } 203 source->string.free_after_use = false; 204 source->previous = NULL; 205 source->already_expanded = false; 206 /* Lock the file for read, but not when -n. */ 207 if (lock_makefile && 208 !do_not_exec_rule) { 209 210 make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1); 211 (void) sprintf(make_state_lockfile, 212 "%s.lock", 213 make_state->string_mb); 214 (void) file_lock(make_state->string_mb, 215 make_state_lockfile, 216 (int *) &make_state_locked, 217 0); 218 if(!make_state_locked) { 219 printf("-- NO LOCKING for read\n"); 220 retmem_mb(make_state_lockfile); 221 make_state_lockfile = 0; 222 return failed; 223 } 224 } 225 if (makefile->body.makefile.contents == NULL) { 226 save_makefile_type = makefile_type; 227 makefile_type = reading_nothing; 228 if ((doname_it) && 229 (doname(makefile_name, true, false) == build_failed)) { 230 if (complain) { 231 (void) fprintf(stderr, 232 gettext("%s: Couldn't make `%s'\n"), 233 getprogname(), 234 makefile_name->string_mb); 235 } 236 max_include_depth--; 237 makefile_type = save_makefile_type; 238 return failed; 239 } 240 makefile_type = save_makefile_type; 241 // 242 // Before calling exists() make sure that we have the right timestamp 243 // 244 makefile_name->stat.time = file_no_time; 245 246 if (exists(makefile_name) == file_doesnt_exist) { 247 if (complain || 248 (makefile_name->stat.stat_errno != ENOENT)) { 249 if (must_exist) { 250 fatal(gettext("Can't find `%s': %s"), 251 makefile_name->string_mb, 252 errmsg(makefile_name-> 253 stat.stat_errno)); 254 } else { 255 warning(gettext("Can't find `%s': %s"), 256 makefile_name->string_mb, 257 errmsg(makefile_name-> 258 stat.stat_errno)); 259 } 260 } 261 max_include_depth--; 262 if(make_state_locked && (make_state_lockfile != NULL)) { 263 (void) unlink(make_state_lockfile); 264 retmem_mb(make_state_lockfile); 265 make_state_lockfile = NULL; 266 make_state_locked = false; 267 } 268 retmem(wcb); 269 retmem_mb((char *)source); 270 return failed; 271 } 272 /* 273 * These values are the size and bytes of 274 * the MULTI-BYTE makefile. 275 */ 276 orig_makefile->body.makefile.size = 277 makefile->body.makefile.size = 278 source->bytes_left_in_file = 279 makefile_name->stat.size; 280 if (report_file) { 281 for (dpp = &makefiles_used; 282 *dpp != NULL; 283 dpp = &(*dpp)->next); 284 dp = ALLOC(Dependency); 285 dp->next = NULL; 286 dp->name = makefile_name; 287 dp->automatic = false; 288 dp->stale = false; 289 dp->built = false; 290 *dpp = dp; 291 } 292 source->fd = open_vroot(makefile_name->string_mb, 293 O_RDONLY, 294 0, 295 NULL, 296 VROOT_DEFAULT); 297 if (source->fd < 0) { 298 if (complain || (errno != ENOENT)) { 299 if (must_exist) { 300 fatal(gettext("Can't open `%s': %s"), 301 makefile_name->string_mb, 302 errmsg(errno)); 303 } else { 304 warning(gettext("Can't open `%s': %s"), 305 makefile_name->string_mb, 306 errmsg(errno)); 307 } 308 } 309 max_include_depth--; 310 return failed; 311 } 312 (void) fcntl(source->fd, F_SETFD, 1); 313 orig_makefile->body.makefile.contents = 314 makefile->body.makefile.contents = 315 source->string.text.p = 316 source->string.buffer.start = 317 ALLOC_WC((int) (makefile_name->stat.size + 2)); 318 if (makefile_type == reading_cpp_file) { 319 forget_after_parse = true; 320 } 321 source->string.text.end = source->string.text.p; 322 source->string.buffer.end = 323 source->string.text.p + makefile_name->stat.size; 324 } else { 325 /* Do we ever reach here? */ 326 source->fd = -1; 327 source->string.text.p = 328 source->string.buffer.start = 329 makefile->body.makefile.contents; 330 source->string.text.end = 331 source->string.buffer.end = 332 source->string.text.p + makefile->body.makefile.size; 333 source->bytes_left_in_file = 334 makefile->body.makefile.size; 335 } 336 file_being_read = wcb; 337 } else { 338 char *stdin_text_p; 339 char *stdin_text_end; 340 char *stdin_buffer_start; 341 char *stdin_buffer_end; 342 char *p_mb; 343 int num_mb_chars; 344 size_t num_wc_chars; 345 346 MBSTOWCS(wcs_buffer, "Standard in"); 347 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH); 348 /* 349 * Memory to read standard in, then convert it 350 * to wide char strings. 351 */ 352 stdin_buffer_start = 353 stdin_text_p = getmem(length = 1024); 354 stdin_buffer_end = stdin_text_p + length; 355 MBSTOWCS(wcs_buffer, "standard input"); 356 file_being_read = (wchar_t *) wcsdup(wcs_buffer); 357 line_number = 0; 358 while ((n = read(fileno(stdin), 359 stdin_text_p, 360 length)) > 0) { 361 length -= n; 362 stdin_text_p += n; 363 if (length == 0) { 364 p_mb = getmem(length = 1024 + 365 (stdin_buffer_end - 366 stdin_buffer_start)); 367 (void) strncpy(p_mb, 368 stdin_buffer_start, 369 (stdin_buffer_end - 370 stdin_buffer_start)); 371 retmem_mb(stdin_buffer_start); 372 stdin_text_p = p_mb + 373 (stdin_buffer_end - stdin_buffer_start); 374 stdin_buffer_start = p_mb; 375 stdin_buffer_end = 376 stdin_buffer_start + length; 377 length = 1024; 378 } 379 } 380 if (n < 0) { 381 fatal(gettext("Error reading standard input: %s"), 382 errmsg(errno)); 383 } 384 stdin_text_p = stdin_buffer_start; 385 stdin_text_end = stdin_buffer_end - length; 386 num_mb_chars = stdin_text_end - stdin_text_p; 387 388 /* 389 * Now, convert the sequence of multibyte chars into 390 * a sequence of corresponding wide character codes. 391 */ 392 source->string.free_after_use = false; 393 source->previous = NULL; 394 source->bytes_left_in_file = 0; 395 source->fd = -1; 396 source->already_expanded = false; 397 source->string.buffer.start = 398 source->string.text.p = ALLOC_WC(num_mb_chars + 1); 399 source->string.buffer.end = 400 source->string.text.p + num_mb_chars; 401 num_wc_chars = mbstowcs(source->string.text.p, 402 stdin_text_p, 403 num_mb_chars); 404 if ((int) num_wc_chars >= 0) { 405 source->string.text.end = 406 source->string.text.p + num_wc_chars; 407 } 408 (void) retmem_mb(stdin_text_p); 409 } 410 line_number = 1; 411 if (trace_reader) { 412 (void) printf(gettext(">>>>>>>>>>>>>>>> Reading makefile %s\n"), 413 makefile_name->string_mb); 414 } 415 parse_makefile(makefile_name, source); 416 if (trace_reader) { 417 (void) printf(gettext(">>>>>>>>>>>>>>>> End of makefile %s\n"), 418 makefile_name->string_mb); 419 } 420 if(file_being_read) { 421 retmem(file_being_read); 422 } 423 file_being_read = previous_file_being_read; 424 line_number = previous_line_number; 425 makefile_type = reading_nothing; 426 max_include_depth--; 427 if (make_state_locked) { 428 /* Unlock .make.state. */ 429 unlink(make_state_lockfile); 430 make_state_locked = false; 431 retmem_mb(make_state_lockfile); 432 } 433 if (forget_after_parse) { 434 retmem(makefile->body.makefile.contents); 435 makefile->body.makefile.contents = NULL; 436 } 437 retmem_mb((char *)source); 438 return succeeded; 439 } 440 441 /* 442 * parse_makefile(true_makefile_name, source) 443 * 444 * Strings are read from Sources. 445 * When macros are found, their values are represented by a 446 * Source that is pushed on a stack. At end of string 447 * (that is returned from GET_CHAR() as 0), the block is popped. 448 * 449 * Parameters: 450 * true_makefile_name The name of makefile we are parsing 451 * source The source block to read from 452 * 453 * Global variables used: 454 * do_not_exec_rule Is -n on? 455 * line_number The number of the current makefile line 456 * makefile_type What kind of makefile are we reading? 457 * empty_name The Name "" 458 */ 459 static void 460 parse_makefile(register Name true_makefile_name, register Source source) 461 { 462 /* 463 char mb_buffer[MB_LEN_MAX]; 464 */ 465 register wchar_t *source_p; 466 register wchar_t *source_end; 467 register wchar_t *string_start; 468 wchar_t *string_end; 469 register Boolean macro_seen_in_string; 470 Boolean append; 471 String_rec name_string; 472 wchar_t name_buffer[STRING_BUFFER_LENGTH]; 473 register int distance; 474 register int paren_count; 475 int brace_count; 476 int char_number; 477 Cmd_line command; 478 Cmd_line command_tail; 479 Name macro_value; 480 481 Name_vector_rec target; 482 Name_vector_rec depes; 483 Name_vector_rec extra_name_vector; 484 Name_vector current_names; 485 Name_vector extra_names = &extra_name_vector; 486 Name_vector nvp; 487 Boolean target_group_seen; 488 489 register Reader_state state; 490 register Reader_state on_eoln_state; 491 register Separator separator; 492 493 wchar_t buffer[4 * STRING_BUFFER_LENGTH]; 494 Source extrap; 495 496 Boolean save_do_not_exec_rule = do_not_exec_rule; 497 Name makefile_name; 498 499 static Name sh_name; 500 static Name shell_name; 501 int i; 502 503 static wchar_t include_space[10]; 504 static wchar_t include_tab[10]; 505 int tmp_bytes_left_in_string; 506 Boolean tmp_maybe_include = false; 507 int emptycount = 0; 508 Boolean first_target; 509 510 String_rec include_name; 511 wchar_t include_buffer[STRING_BUFFER_LENGTH]; 512 513 target.next = depes.next = NULL; 514 /* Move some values from their struct to register declared locals */ 515 CACHE_SOURCE(0); 516 517 start_new_line: 518 /* 519 * Read whitespace on old line. Leave pointer on first char on 520 * next line. 521 */ 522 first_target = true; 523 on_eoln_state = exit_state; 524 /* 525 for (WCTOMB(mb_buffer, GET_CHAR()); 526 1; 527 source_p++, WCTOMB(mb_buffer, GET_CHAR())) 528 switch (mb_buffer[0]) { 529 */ 530 for (char_number=0; 1; source_p++,char_number++) switch (GET_CHAR()) { 531 case nul_char: 532 /* End of this string. Pop it and return to the previous one */ 533 GET_NEXT_BLOCK(source); 534 source_p--; 535 if (source == NULL) { 536 GOTO_STATE(on_eoln_state); 537 } 538 break; 539 case newline_char: 540 end_of_line: 541 source_p++; 542 if (source->fd >= 0) { 543 line_number++; 544 } 545 switch (GET_CHAR()) { 546 case nul_char: 547 GET_NEXT_BLOCK(source); 548 if (source == NULL) { 549 GOTO_STATE(on_eoln_state); 550 } 551 /* Go back to the top of this loop */ 552 goto start_new_line; 553 case newline_char: 554 case numbersign_char: 555 case dollar_char: 556 case space_char: 557 case tab_char: 558 /* 559 * Go back to the top of this loop since the 560 * new line does not start with a regular char. 561 */ 562 goto start_new_line; 563 default: 564 /* We found the first proper char on the new line */ 565 goto start_new_line_no_skip; 566 } 567 case space_char: 568 if (char_number == 0) 569 line_started_with_space=line_number; 570 case tab_char: 571 /* Whitespace. Just keep going in this loop */ 572 break; 573 case numbersign_char: 574 /* Comment. Skip over it */ 575 for (; 1; source_p++) { 576 switch (GET_CHAR()) { 577 case nul_char: 578 GET_NEXT_BLOCK_NOCHK(source); 579 if (source == NULL) { 580 GOTO_STATE(on_eoln_state); 581 } 582 if (source->error_converting) { 583 // Illegal byte sequence - skip its first byte 584 source->inp_buf_ptr++; 585 } 586 source_p--; 587 break; 588 case backslash_char: 589 /* Comments can be continued */ 590 if (*++source_p == (int) nul_char) { 591 GET_NEXT_BLOCK_NOCHK(source); 592 if (source == NULL) { 593 GOTO_STATE(on_eoln_state); 594 } 595 if (source->error_converting) { 596 // Illegal byte sequence - skip its first byte 597 source->inp_buf_ptr++; 598 source_p--; 599 break; 600 } 601 } 602 if(*source_p == (int) newline_char) { 603 if (source->fd >= 0) { 604 line_number++; 605 } 606 } 607 break; 608 case newline_char: 609 /* 610 * After we skip the comment we go to 611 * the end of line handler since end of 612 * line terminates comments. 613 */ 614 goto end_of_line; 615 } 616 } 617 case dollar_char: 618 /* Macro reference */ 619 if (source->already_expanded) { 620 /* 621 * If we are reading from the expansion of a 622 * macro we already expanded everything enough. 623 */ 624 goto start_new_line_no_skip; 625 } 626 /* 627 * Expand the value and push the Source on the stack of 628 * things being read. 629 */ 630 source_p++; 631 UNCACHE_SOURCE(); 632 { 633 Source t = (Source) alloca((int) sizeof (Source_rec)); 634 source = push_macro_value(t, 635 buffer, 636 sizeof buffer, 637 source); 638 } 639 CACHE_SOURCE(1); 640 break; 641 default: 642 /* We found the first proper char on the new line */ 643 goto start_new_line_no_skip; 644 } 645 646 /* 647 * We found the first normal char (one that starts an identifier) 648 * on the newline. 649 */ 650 start_new_line_no_skip: 651 /* Inspect that first char to see if it maybe is special anyway */ 652 switch (GET_CHAR()) { 653 case nul_char: 654 GET_NEXT_BLOCK(source); 655 if (source == NULL) { 656 GOTO_STATE(on_eoln_state); 657 } 658 goto start_new_line_no_skip; 659 case newline_char: 660 /* Just in case */ 661 goto start_new_line; 662 case exclam_char: 663 /* Evaluate the line before it is read */ 664 string_start = source_p + 1; 665 macro_seen_in_string = false; 666 /* Stuff the line in a string so we can eval it. */ 667 for (; 1; source_p++) { 668 switch (GET_CHAR()) { 669 case newline_char: 670 goto eoln_1; 671 case nul_char: 672 if (source->fd > 0) { 673 if (!macro_seen_in_string) { 674 macro_seen_in_string = true; 675 INIT_STRING_FROM_STACK( 676 name_string, name_buffer); 677 } 678 append_string(string_start, 679 &name_string, 680 source_p - string_start); 681 GET_NEXT_BLOCK(source); 682 string_start = source_p; 683 source_p--; 684 break; 685 } 686 eoln_1: 687 if (!macro_seen_in_string) { 688 INIT_STRING_FROM_STACK(name_string, 689 name_buffer); 690 } 691 append_string(string_start, 692 &name_string, 693 source_p - string_start); 694 extrap = (Source) 695 alloca((int) sizeof (Source_rec)); 696 extrap->string.buffer.start = NULL; 697 extrap->inp_buf = 698 extrap->inp_buf_ptr = 699 extrap->inp_buf_end = NULL; 700 extrap->error_converting = false; 701 if (*source_p == (int) nul_char) { 702 source_p++; 703 } 704 /* Eval the macro */ 705 expand_value(GETNAME(name_string.buffer.start, 706 FIND_LENGTH), 707 &extrap->string, 708 false); 709 if (name_string.free_after_use) { 710 retmem(name_string.buffer.start); 711 } 712 UNCACHE_SOURCE(); 713 extrap->string.text.p = 714 extrap->string.buffer.start; 715 extrap->fd = -1; 716 /* And push the value */ 717 extrap->previous = source; 718 source = extrap; 719 CACHE_SOURCE(0); 720 goto line_evald; 721 } 722 } 723 default: 724 goto line_evald; 725 } 726 727 /* We now have a line we can start reading */ 728 line_evald: 729 if (source == NULL) { 730 GOTO_STATE(exit_state); 731 } 732 /* Check if this is an include command */ 733 if ((makefile_type == reading_makefile) && 734 !source->already_expanded) { 735 if (include_space[0] == (int) nul_char) { 736 MBSTOWCS(include_space, "include "); 737 MBSTOWCS(include_tab, "include\t"); 738 } 739 if ((IS_WEQUALN(source_p, include_space, 8)) || 740 (IS_WEQUALN(source_p, include_tab, 8))) { 741 source_p += 7; 742 if (iswspace(*source_p)) { 743 Makefile_type save_makefile_type; 744 wchar_t *name_start; 745 int name_length; 746 747 /* 748 * Yes, this is an include. 749 * Skip spaces to get to the filename. 750 */ 751 while (iswspace(*source_p) || 752 (*source_p == (int) nul_char)) { 753 switch (GET_CHAR()) { 754 case nul_char: 755 GET_NEXT_BLOCK(source); 756 if (source == NULL) { 757 GOTO_STATE(on_eoln_state); 758 } 759 break; 760 761 default: 762 source_p++; 763 break; 764 } 765 } 766 767 string_start = source_p; 768 /* Find the end of the filename */ 769 macro_seen_in_string = false; 770 while (!iswspace(*source_p) || 771 (*source_p == (int) nul_char)) { 772 switch (GET_CHAR()) { 773 case nul_char: 774 if (!macro_seen_in_string) { 775 INIT_STRING_FROM_STACK(name_string, 776 name_buffer); 777 } 778 append_string(string_start, 779 &name_string, 780 source_p - string_start); 781 macro_seen_in_string = true; 782 GET_NEXT_BLOCK(source); 783 string_start = source_p; 784 if (source == NULL) { 785 GOTO_STATE(on_eoln_state); 786 } 787 break; 788 789 default: 790 source_p++; 791 break; 792 } 793 } 794 795 source->string.text.p = source_p; 796 if (macro_seen_in_string) { 797 append_string(string_start, 798 &name_string, 799 source_p - string_start); 800 name_start = name_string.buffer.start; 801 name_length = name_string.text.p - name_start; 802 } else { 803 name_start = string_start; 804 name_length = source_p - string_start; 805 } 806 807 /* Strip "./" from the head of the name */ 808 if ((name_start[0] == (int) period_char) && 809 (name_start[1] == (int) slash_char)) { 810 name_start += 2; 811 name_length -= 2; 812 } 813 /* if include file name is surrounded by double quotes */ 814 if ((name_start[0] == (int) doublequote_char) && 815 (name_start[name_length - 1] == (int) doublequote_char)) { 816 name_start += 1; 817 name_length -= 2; 818 819 /* if name does not begin with a slash char */ 820 if (name_start[0] != (int) slash_char) { 821 if ((name_start[0] == (int) period_char) && 822 (name_start[1] == (int) slash_char)) { 823 name_start += 2; 824 name_length -= 2; 825 } 826 827 INIT_STRING_FROM_STACK(include_name, include_buffer); 828 APPEND_NAME(true_makefile_name, 829 &include_name, 830 true_makefile_name->hash.length); 831 832 wchar_t *slash = wcsrchr(include_name.buffer.start, (int) slash_char); 833 if (slash != NULL) { 834 include_name.text.p = slash + 1; 835 append_string(name_start, 836 &include_name, 837 name_length); 838 839 name_start = include_name.buffer.start; 840 name_length = include_name.text.p - name_start; 841 } 842 } 843 } 844 845 /* Even when we run -n we want to create makefiles */ 846 do_not_exec_rule = false; 847 makefile_name = GETNAME(name_start, name_length); 848 if (makefile_name->dollar) { 849 String_rec destination; 850 wchar_t buffer[STRING_BUFFER_LENGTH]; 851 wchar_t *p; 852 wchar_t *q; 853 854 INIT_STRING_FROM_STACK(destination, buffer); 855 expand_value(makefile_name, 856 &destination, 857 false); 858 for (p = destination.buffer.start; 859 (*p != (int) nul_char) && iswspace(*p); 860 p++); 861 for (q = p; 862 (*q != (int) nul_char) && !iswspace(*q); 863 q++); 864 makefile_name = GETNAME(p, q-p); 865 if (destination.free_after_use) { 866 retmem(destination.buffer.start); 867 } 868 } 869 source_p++; 870 UNCACHE_SOURCE(); 871 /* Read the file */ 872 save_makefile_type = makefile_type; 873 if (read_simple_file(makefile_name, 874 true, 875 true, 876 true, 877 false, 878 true, 879 false) == failed) { 880 fatal_reader(gettext("Read of include file `%s' failed"), 881 makefile_name->string_mb); 882 } 883 makefile_type = save_makefile_type; 884 do_not_exec_rule = save_do_not_exec_rule; 885 CACHE_SOURCE(0); 886 goto start_new_line; 887 } else { 888 source_p -= 7; 889 } 890 } else { 891 /* Check if the word include was split across 8K boundary. */ 892 893 tmp_bytes_left_in_string = source->string.text.end - source_p; 894 if (tmp_bytes_left_in_string < 8) { 895 tmp_maybe_include = false; 896 if (IS_WEQUALN(source_p, 897 include_space, 898 tmp_bytes_left_in_string)) { 899 tmp_maybe_include = true; 900 } 901 if (tmp_maybe_include) { 902 GET_NEXT_BLOCK(source); 903 tmp_maybe_include = false; 904 goto line_evald; 905 } 906 } 907 } 908 } 909 910 /* Reset the status in preparation for the new line */ 911 for (nvp = ⌖ nvp != NULL; nvp = nvp->next) { 912 nvp->used = 0; 913 } 914 for (nvp = &depes; nvp != NULL; nvp = nvp->next) { 915 nvp->used = 0; 916 } 917 target_group_seen = false; 918 command = command_tail = NULL; 919 macro_value = NULL; 920 append = false; 921 current_names = ⌖ 922 SET_STATE(scan_name_state); 923 on_eoln_state = illegal_eoln_state; 924 separator = none_seen; 925 926 /* The state machine starts here */ 927 enter_state: 928 while (1) switch (state) { 929 930 /**************************************************************** 931 * Scan name state 932 */ 933 case scan_name_state: 934 /* Scan an identifier. We skip over chars until we find a break char */ 935 /* First skip white space. */ 936 for (; 1; source_p++) switch (GET_CHAR()) { 937 case nul_char: 938 GET_NEXT_BLOCK(source); 939 source_p--; 940 if (source == NULL) { 941 GOTO_STATE(on_eoln_state); 942 } 943 break; 944 case newline_char: 945 /* We found the end of the line. */ 946 /* Do postprocessing or return error */ 947 source_p++; 948 if (source->fd >= 0) { 949 line_number++; 950 } 951 GOTO_STATE(on_eoln_state); 952 case backslash_char: 953 /* Continuation */ 954 if (*++source_p == (int) nul_char) { 955 GET_NEXT_BLOCK(source); 956 if (source == NULL) { 957 GOTO_STATE(on_eoln_state); 958 } 959 } 960 if (*source_p == (int) newline_char) { 961 if (source->fd >= 0) { 962 line_number++; 963 } 964 } else { 965 source_p--; 966 } 967 break; 968 case tab_char: 969 case space_char: 970 /* Whitespace is skipped */ 971 break; 972 case numbersign_char: 973 /* Comment. Skip over it */ 974 for (; 1; source_p++) { 975 switch (GET_CHAR()) { 976 case nul_char: 977 GET_NEXT_BLOCK_NOCHK(source); 978 if (source == NULL) { 979 GOTO_STATE(on_eoln_state); 980 } 981 if (source->error_converting) { 982 // Illegal byte sequence - skip its first byte 983 source->inp_buf_ptr++; 984 } 985 source_p--; 986 break; 987 case backslash_char: 988 if (*++source_p == (int) nul_char) { 989 GET_NEXT_BLOCK_NOCHK(source); 990 if (source == NULL) { 991 GOTO_STATE(on_eoln_state); 992 } 993 if (source->error_converting) { 994 // Illegal byte sequence - skip its first byte 995 source->inp_buf_ptr++; 996 source_p--; 997 break; 998 } 999 } 1000 if(*source_p == (int) newline_char) { 1001 if (source->fd >= 0) { 1002 line_number++; 1003 } 1004 } 1005 break; 1006 case newline_char: 1007 source_p++; 1008 if (source->fd >= 0) { 1009 line_number++; 1010 } 1011 GOTO_STATE(on_eoln_state); 1012 } 1013 } 1014 case dollar_char: 1015 /* Macro reference. Expand and push value */ 1016 if (source->already_expanded) { 1017 goto scan_name; 1018 } 1019 source_p++; 1020 UNCACHE_SOURCE(); 1021 { 1022 Source t = (Source) alloca((int) sizeof (Source_rec)); 1023 source = push_macro_value(t, 1024 buffer, 1025 sizeof buffer, 1026 source); 1027 } 1028 CACHE_SOURCE(1); 1029 break; 1030 default: 1031 /* End of white space */ 1032 goto scan_name; 1033 } 1034 1035 /* First proper identifier character */ 1036 scan_name: 1037 1038 string_start = source_p; 1039 paren_count = brace_count = 0; 1040 macro_seen_in_string = false; 1041 resume_name_scan: 1042 for (; 1; source_p++) { 1043 switch (GET_CHAR()) { 1044 case nul_char: 1045 /* Save what we have seen so far of the identifier */ 1046 if (source_p != string_start) { 1047 if (!macro_seen_in_string) { 1048 INIT_STRING_FROM_STACK(name_string, 1049 name_buffer); 1050 } 1051 append_string(string_start, 1052 &name_string, 1053 source_p - string_start); 1054 macro_seen_in_string = true; 1055 } 1056 /* Get more text to read */ 1057 GET_NEXT_BLOCK(source); 1058 string_start = source_p; 1059 source_p--; 1060 if (source == NULL) { 1061 GOTO_STATE(on_eoln_state); 1062 } 1063 break; 1064 case newline_char: 1065 if (paren_count > 0) { 1066 fatal_reader(gettext("Unmatched `(' on line")); 1067 } 1068 if (brace_count > 0) { 1069 fatal_reader(gettext("Unmatched `{' on line")); 1070 } 1071 source_p++; 1072 /* Enter name */ 1073 current_names = enter_name(&name_string, 1074 macro_seen_in_string, 1075 string_start, 1076 source_p - 1, 1077 current_names, 1078 &extra_names, 1079 &target_group_seen); 1080 first_target = false; 1081 if (extra_names == NULL) { 1082 extra_names = (Name_vector) 1083 alloca((int) sizeof (Name_vector_rec)); 1084 } 1085 /* Do postprocessing or return error */ 1086 if (source->fd >= 0) { 1087 line_number++; 1088 } 1089 GOTO_STATE(on_eoln_state); 1090 case backslash_char: 1091 /* Check if this is a quoting backslash */ 1092 if (!macro_seen_in_string) { 1093 INIT_STRING_FROM_STACK(name_string, 1094 name_buffer); 1095 macro_seen_in_string = true; 1096 } 1097 append_string(string_start, 1098 &name_string, 1099 source_p - string_start); 1100 if (*++source_p == (int) nul_char) { 1101 GET_NEXT_BLOCK(source); 1102 if (source == NULL) { 1103 GOTO_STATE(on_eoln_state); 1104 } 1105 } 1106 if (*source_p == (int) newline_char) { 1107 if (source->fd >= 0) { 1108 line_number++; 1109 } 1110 *source_p = (int) space_char; 1111 string_start = source_p; 1112 goto resume_name_scan; 1113 } else { 1114 string_start = source_p; 1115 break; 1116 } 1117 break; 1118 case numbersign_char: 1119 if (paren_count + brace_count > 0) { 1120 break; 1121 } 1122 fatal_reader(gettext("Unexpected comment seen")); 1123 case dollar_char: 1124 if (source->already_expanded) { 1125 break; 1126 } 1127 /* Save the identifier so far */ 1128 if (source_p != string_start) { 1129 if (!macro_seen_in_string) { 1130 INIT_STRING_FROM_STACK(name_string, 1131 name_buffer); 1132 } 1133 append_string(string_start, 1134 &name_string, 1135 source_p - string_start); 1136 macro_seen_in_string = true; 1137 } 1138 /* Eval and push the macro */ 1139 source_p++; 1140 UNCACHE_SOURCE(); 1141 { 1142 Source t = 1143 (Source) alloca((int) sizeof (Source_rec)); 1144 source = push_macro_value(t, 1145 buffer, 1146 sizeof buffer, 1147 source); 1148 } 1149 CACHE_SOURCE(1); 1150 string_start = source_p + 1; 1151 break; 1152 case parenleft_char: 1153 paren_count++; 1154 break; 1155 case parenright_char: 1156 if (--paren_count < 0) { 1157 fatal_reader(gettext("Unmatched `)' on line")); 1158 } 1159 break; 1160 case braceleft_char: 1161 brace_count++; 1162 break; 1163 case braceright_char: 1164 if (--brace_count < 0) { 1165 fatal_reader(gettext("Unmatched `}' on line")); 1166 } 1167 break; 1168 case ampersand_char: 1169 case greater_char: 1170 case bar_char: 1171 if (paren_count + brace_count == 0) { 1172 source_p++; 1173 } 1174 /* FALLTHROUGH */ 1175 case tab_char: 1176 case space_char: 1177 if (paren_count + brace_count > 0) { 1178 break; 1179 } 1180 current_names = enter_name(&name_string, 1181 macro_seen_in_string, 1182 string_start, 1183 source_p, 1184 current_names, 1185 &extra_names, 1186 &target_group_seen); 1187 first_target = false; 1188 if (extra_names == NULL) { 1189 extra_names = (Name_vector) 1190 alloca((int) sizeof (Name_vector_rec)); 1191 } 1192 goto enter_state; 1193 case colon_char: 1194 if (paren_count + brace_count > 0) { 1195 break; 1196 } 1197 if (separator == conditional_seen) { 1198 break; 1199 } 1200 /** POSIX **/ 1201 #if 0 1202 if(posix) { 1203 emptycount = 0; 1204 } 1205 #endif 1206 /** END POSIX **/ 1207 /* End of the target list. We now start reading */ 1208 /* dependencies or a conditional assignment */ 1209 if (separator != none_seen) { 1210 fatal_reader(gettext("Extra `:', `::', or `:=' on dependency line")); 1211 } 1212 /* Enter the last target */ 1213 if ((string_start != source_p) || 1214 macro_seen_in_string) { 1215 current_names = 1216 enter_name(&name_string, 1217 macro_seen_in_string, 1218 string_start, 1219 source_p, 1220 current_names, 1221 &extra_names, 1222 &target_group_seen); 1223 first_target = false; 1224 if (extra_names == NULL) { 1225 extra_names = (Name_vector) 1226 alloca((int) 1227 sizeof (Name_vector_rec)); 1228 } 1229 } 1230 /* Check if it is ":" "::" or ":=" */ 1231 scan_colon_label: 1232 switch (*++source_p) { 1233 case nul_char: 1234 GET_NEXT_BLOCK(source); 1235 source_p--; 1236 if (source == NULL) { 1237 GOTO_STATE(enter_dependencies_state); 1238 } 1239 goto scan_colon_label; 1240 case equal_char: 1241 if(svr4) { 1242 fatal_reader(gettext("syntax error")); 1243 } 1244 separator = conditional_seen; 1245 source_p++; 1246 current_names = &depes; 1247 GOTO_STATE(scan_name_state); 1248 case colon_char: 1249 separator = two_colon; 1250 source_p++; 1251 break; 1252 default: 1253 separator = one_colon; 1254 } 1255 current_names = &depes; 1256 on_eoln_state = enter_dependencies_state; 1257 GOTO_STATE(scan_name_state); 1258 case semicolon_char: 1259 if (paren_count + brace_count > 0) { 1260 break; 1261 } 1262 /* End of reading names. Start reading the rule */ 1263 if ((separator != one_colon) && 1264 (separator != two_colon)) { 1265 fatal_reader(gettext("Unexpected command seen")); 1266 } 1267 /* Enter the last dependency */ 1268 if ((string_start != source_p) || 1269 macro_seen_in_string) { 1270 current_names = 1271 enter_name(&name_string, 1272 macro_seen_in_string, 1273 string_start, 1274 source_p, 1275 current_names, 1276 &extra_names, 1277 &target_group_seen); 1278 first_target = false; 1279 if (extra_names == NULL) { 1280 extra_names = (Name_vector) 1281 alloca((int) 1282 sizeof (Name_vector_rec)); 1283 } 1284 } 1285 source_p++; 1286 /* Make sure to enter a rule even if the is */ 1287 /* no text here */ 1288 command = command_tail = ALLOC(Cmd_line); 1289 command->next = NULL; 1290 command->command_line = empty_name; 1291 command->make_refd = false; 1292 command->ignore_command_dependency = false; 1293 command->assign = false; 1294 command->ignore_error = false; 1295 command->silent = false; 1296 1297 GOTO_STATE(scan_command_state); 1298 case plus_char: 1299 /* 1300 ** following code drops the target separator plus char if it starts 1301 ** a line. 1302 */ 1303 if(first_target && !macro_seen_in_string && 1304 source_p == string_start) { 1305 for (; 1; source_p++) 1306 switch (GET_CHAR()) { 1307 case nul_char: 1308 if (source_p != string_start) { 1309 if (!macro_seen_in_string) { 1310 INIT_STRING_FROM_STACK(name_string, 1311 name_buffer); 1312 } 1313 append_string(string_start, 1314 &name_string, 1315 source_p - string_start); 1316 macro_seen_in_string = true; 1317 } 1318 GET_NEXT_BLOCK(source); 1319 string_start = source_p; 1320 source_p--; 1321 if (source == NULL) { 1322 GOTO_STATE(on_eoln_state); 1323 } 1324 break; 1325 case plus_char: 1326 source_p++; 1327 while (*source_p == (int) nul_char) { 1328 if (source_p != string_start) { 1329 if (!macro_seen_in_string) { 1330 INIT_STRING_FROM_STACK(name_string, 1331 name_buffer); 1332 } 1333 append_string(string_start, 1334 &name_string, 1335 source_p - string_start); 1336 macro_seen_in_string = true; 1337 } 1338 GET_NEXT_BLOCK(source); 1339 string_start = source_p; 1340 if (source == NULL) { 1341 GOTO_STATE(on_eoln_state); 1342 } 1343 } 1344 if (*source_p == (int) tab_char || 1345 *source_p == (int) space_char) { 1346 macro_seen_in_string = false; 1347 string_start = source_p + 1; 1348 } else { 1349 goto resume_name_scan; 1350 } 1351 break; 1352 case tab_char: 1353 case space_char: 1354 string_start = source_p + 1; 1355 break; 1356 default: 1357 goto resume_name_scan; 1358 } 1359 } 1360 if (paren_count + brace_count > 0) { 1361 break; 1362 } 1363 /* We found "+=" construct */ 1364 if (source_p != string_start) { 1365 /* "+" is not a break char. */ 1366 /* Ignore it if it is part of an identifier */ 1367 source_p++; 1368 goto resume_name_scan; 1369 } 1370 /* Make sure the "+" is followed by a "=" */ 1371 scan_append: 1372 switch (*++source_p) { 1373 case nul_char: 1374 if (!macro_seen_in_string) { 1375 INIT_STRING_FROM_STACK(name_string, 1376 name_buffer); 1377 } 1378 append_string(string_start, 1379 &name_string, 1380 source_p - string_start); 1381 GET_NEXT_BLOCK(source); 1382 source_p--; 1383 string_start = source_p; 1384 if (source == NULL) { 1385 GOTO_STATE(illegal_eoln_state); 1386 } 1387 goto scan_append; 1388 case equal_char: 1389 if(!svr4) { 1390 append = true; 1391 } else { 1392 fatal_reader(gettext("Must be a separator on rules")); 1393 } 1394 break; 1395 default: 1396 /* The "+" just starts a regular name. */ 1397 /* Start reading that name */ 1398 goto resume_name_scan; 1399 } 1400 /* FALLTHROUGH */ 1401 case equal_char: 1402 if (paren_count + brace_count > 0) { 1403 break; 1404 } 1405 /* We found macro assignment. */ 1406 /* Check if it is legal and if it is appending */ 1407 switch (separator) { 1408 case none_seen: 1409 separator = equal_seen; 1410 on_eoln_state = enter_equal_state; 1411 break; 1412 case conditional_seen: 1413 on_eoln_state = enter_conditional_state; 1414 break; 1415 default: 1416 /* Reader must special check for "MACRO:sh=" */ 1417 /* notation */ 1418 if (sh_name == NULL) { 1419 MBSTOWCS(wcs_buffer, "sh"); 1420 sh_name = GETNAME(wcs_buffer, FIND_LENGTH); 1421 MBSTOWCS(wcs_buffer, "shell"); 1422 shell_name = GETNAME(wcs_buffer, FIND_LENGTH); 1423 } 1424 1425 if (!macro_seen_in_string) { 1426 INIT_STRING_FROM_STACK(name_string, 1427 name_buffer); 1428 } 1429 append_string(string_start, 1430 &name_string, 1431 source_p - string_start 1432 ); 1433 1434 if ( (((target.used == 1) && 1435 (depes.used == 1) && 1436 (depes.names[0] == sh_name)) || 1437 ((target.used == 1) && 1438 (depes.used == 0) && 1439 (separator == one_colon) && 1440 (GETNAME(name_string.buffer.start,FIND_LENGTH) == sh_name))) && 1441 (!svr4)) { 1442 String_rec macro_name; 1443 wchar_t buffer[100]; 1444 1445 INIT_STRING_FROM_STACK(macro_name, 1446 buffer); 1447 APPEND_NAME(target.names[0], 1448 ¯o_name, 1449 FIND_LENGTH); 1450 append_char((int) colon_char, 1451 ¯o_name); 1452 APPEND_NAME(sh_name, 1453 ¯o_name, 1454 FIND_LENGTH); 1455 target.names[0] = 1456 GETNAME(macro_name.buffer.start, 1457 FIND_LENGTH); 1458 separator = equal_seen; 1459 on_eoln_state = enter_equal_state; 1460 break; 1461 } else if ( (((target.used == 1) && 1462 (depes.used == 1) && 1463 (depes.names[0] == shell_name)) || 1464 ((target.used == 1) && 1465 (depes.used == 0) && 1466 (separator == one_colon) && 1467 (GETNAME(name_string.buffer.start,FIND_LENGTH) == shell_name))) && 1468 (!svr4)) { 1469 String_rec macro_name; 1470 wchar_t buffer[100]; 1471 1472 INIT_STRING_FROM_STACK(macro_name, 1473 buffer); 1474 APPEND_NAME(target.names[0], 1475 ¯o_name, 1476 FIND_LENGTH); 1477 append_char((int) colon_char, 1478 ¯o_name); 1479 APPEND_NAME(shell_name, 1480 ¯o_name, 1481 FIND_LENGTH); 1482 target.names[0] = 1483 GETNAME(macro_name.buffer.start, 1484 FIND_LENGTH); 1485 separator = equal_seen; 1486 on_eoln_state = enter_equal_state; 1487 break; 1488 } 1489 if(svr4) { 1490 fatal_reader(gettext("syntax error")); 1491 } 1492 else { 1493 fatal_reader(gettext("Macro assignment on dependency line")); 1494 } 1495 } 1496 if (append) { 1497 source_p--; 1498 } 1499 /* Enter the macro name */ 1500 if ((string_start != source_p) || 1501 macro_seen_in_string) { 1502 current_names = 1503 enter_name(&name_string, 1504 macro_seen_in_string, 1505 string_start, 1506 source_p, 1507 current_names, 1508 &extra_names, 1509 &target_group_seen); 1510 first_target = false; 1511 if (extra_names == NULL) { 1512 extra_names = (Name_vector) 1513 alloca((int) 1514 sizeof (Name_vector_rec)); 1515 } 1516 } 1517 if (append) { 1518 source_p++; 1519 } 1520 macro_value = NULL; 1521 source_p++; 1522 distance = 0; 1523 /* Skip whitespace to the start of the value */ 1524 macro_seen_in_string = false; 1525 for (; 1; source_p++) { 1526 switch (GET_CHAR()) { 1527 case nul_char: 1528 GET_NEXT_BLOCK(source); 1529 source_p--; 1530 if (source == NULL) { 1531 GOTO_STATE(on_eoln_state); 1532 } 1533 break; 1534 case backslash_char: 1535 if (*++source_p == (int) nul_char) { 1536 GET_NEXT_BLOCK(source); 1537 if (source == NULL) { 1538 GOTO_STATE(on_eoln_state); 1539 } 1540 } 1541 if (*source_p != (int) newline_char) { 1542 if (!macro_seen_in_string) { 1543 macro_seen_in_string = 1544 true; 1545 INIT_STRING_FROM_STACK(name_string, 1546 name_buffer); 1547 } 1548 append_char((int) 1549 backslash_char, 1550 &name_string); 1551 append_char(*source_p, 1552 &name_string); 1553 string_start = source_p+1; 1554 goto macro_value_start; 1555 } else { 1556 if (source->fd >= 0) { 1557 line_number++; 1558 } 1559 } 1560 break; 1561 case newline_char: 1562 case numbersign_char: 1563 string_start = source_p; 1564 goto macro_value_end; 1565 case tab_char: 1566 case space_char: 1567 break; 1568 default: 1569 string_start = source_p; 1570 goto macro_value_start; 1571 } 1572 } 1573 macro_value_start: 1574 /* Find the end of the value */ 1575 for (; 1; source_p++) { 1576 if (distance != 0) { 1577 *source_p = *(source_p + distance); 1578 } 1579 switch (GET_CHAR()) { 1580 case nul_char: 1581 if (!macro_seen_in_string) { 1582 macro_seen_in_string = true; 1583 INIT_STRING_FROM_STACK(name_string, 1584 name_buffer); 1585 } 1586 append_string(string_start, 1587 &name_string, 1588 source_p - string_start); 1589 GET_NEXT_BLOCK(source); 1590 string_start = source_p; 1591 source_p--; 1592 if (source == NULL) { 1593 GOTO_STATE(on_eoln_state); 1594 } 1595 break; 1596 case backslash_char: 1597 source_p++; 1598 if (distance != 0) { 1599 *source_p = 1600 *(source_p + distance); 1601 } 1602 if (*source_p == (int) nul_char) { 1603 if (!macro_seen_in_string) { 1604 macro_seen_in_string = 1605 true; 1606 INIT_STRING_FROM_STACK(name_string, 1607 name_buffer); 1608 } 1609 1610 /* BID_1225561 */ 1611 *(source_p - 1) = (int) space_char; 1612 append_string(string_start, 1613 &name_string, 1614 source_p - 1615 string_start - 1); 1616 GET_NEXT_BLOCK(source); 1617 string_start = source_p; 1618 if (source == NULL) { 1619 GOTO_STATE(on_eoln_state); 1620 } 1621 if (distance != 0) { 1622 *source_p = 1623 *(source_p + 1624 distance); 1625 } 1626 if (*source_p == (int) newline_char) { 1627 append_char((int) space_char, &name_string); 1628 } else { 1629 append_char((int) backslash_char, &name_string); 1630 } 1631 /****************/ 1632 } 1633 if (*source_p == (int) newline_char) { 1634 source_p--; 1635 line_number++; 1636 distance++; 1637 *source_p = (int) space_char; 1638 while ((*(source_p + 1639 distance + 1) == 1640 (int) tab_char) || 1641 (*(source_p + 1642 distance + 1) == 1643 (int) space_char)) { 1644 distance++; 1645 } 1646 } 1647 break; 1648 case newline_char: 1649 case numbersign_char: 1650 goto macro_value_end; 1651 } 1652 } 1653 macro_value_end: 1654 /* Complete the value in the string */ 1655 if (!macro_seen_in_string) { 1656 macro_seen_in_string = true; 1657 INIT_STRING_FROM_STACK(name_string, 1658 name_buffer); 1659 } 1660 append_string(string_start, 1661 &name_string, 1662 source_p - string_start); 1663 if (name_string.buffer.start != name_string.text.p) { 1664 macro_value = 1665 GETNAME(name_string.buffer.start, 1666 FIND_LENGTH); 1667 } 1668 if (name_string.free_after_use) { 1669 retmem(name_string.buffer.start); 1670 } 1671 for (; distance > 0; distance--) { 1672 *source_p++ = (int) space_char; 1673 } 1674 GOTO_STATE(on_eoln_state); 1675 } 1676 } 1677 1678 /**************************************************************** 1679 * enter dependencies state 1680 */ 1681 case enter_dependencies_state: 1682 enter_dependencies_label: 1683 /* Expects pointer on first non whitespace char after last dependency. (On */ 1684 /* next line.) We end up here after having read a "targets : dependencies" */ 1685 /* line. The state checks if there is a rule to read and if so dispatches */ 1686 /* to scan_command_state scan_command_state reads one rule line and the */ 1687 /* returns here */ 1688 1689 /* First check if the first char on the next line is special */ 1690 switch (GET_CHAR()) { 1691 case nul_char: 1692 GET_NEXT_BLOCK(source); 1693 if (source == NULL) { 1694 break; 1695 } 1696 goto enter_dependencies_label; 1697 case exclam_char: 1698 /* The line should be evaluate before it is read */ 1699 macro_seen_in_string = false; 1700 string_start = source_p + 1; 1701 for (; 1; source_p++) { 1702 switch (GET_CHAR()) { 1703 case newline_char: 1704 goto eoln_2; 1705 case nul_char: 1706 if (source->fd > 0) { 1707 if (!macro_seen_in_string) { 1708 macro_seen_in_string = true; 1709 INIT_STRING_FROM_STACK(name_string, 1710 name_buffer); 1711 } 1712 append_string(string_start, 1713 &name_string, 1714 source_p - string_start); 1715 GET_NEXT_BLOCK(source); 1716 string_start = source_p; 1717 source_p--; 1718 break; 1719 } 1720 eoln_2: 1721 if (!macro_seen_in_string) { 1722 INIT_STRING_FROM_STACK(name_string, 1723 name_buffer); 1724 } 1725 append_string(string_start, 1726 &name_string, 1727 source_p - string_start); 1728 extrap = (Source) 1729 alloca((int) sizeof (Source_rec)); 1730 extrap->string.buffer.start = NULL; 1731 extrap->inp_buf = 1732 extrap->inp_buf_ptr = 1733 extrap->inp_buf_end = NULL; 1734 extrap->error_converting = false; 1735 expand_value(GETNAME(name_string.buffer.start, 1736 FIND_LENGTH), 1737 &extrap->string, 1738 false); 1739 if (name_string.free_after_use) { 1740 retmem(name_string.buffer.start); 1741 } 1742 UNCACHE_SOURCE(); 1743 extrap->string.text.p = 1744 extrap->string.buffer.start; 1745 extrap->fd = -1; 1746 extrap->previous = source; 1747 source = extrap; 1748 CACHE_SOURCE(0); 1749 goto enter_dependencies_label; 1750 } 1751 } 1752 case dollar_char: 1753 if (source->already_expanded) { 1754 break; 1755 } 1756 source_p++; 1757 UNCACHE_SOURCE(); 1758 { 1759 Source t = (Source) alloca((int) sizeof (Source_rec)); 1760 source = push_macro_value(t, 1761 buffer, 1762 sizeof buffer, 1763 source); 1764 } 1765 CACHE_SOURCE(0); 1766 goto enter_dependencies_label; 1767 case numbersign_char: 1768 if (makefile_type != reading_makefile) { 1769 source_p++; 1770 GOTO_STATE(scan_command_state); 1771 } 1772 for (; 1; source_p++) { 1773 switch (GET_CHAR()) { 1774 case nul_char: 1775 GET_NEXT_BLOCK_NOCHK(source); 1776 if (source == NULL) { 1777 GOTO_STATE(on_eoln_state); 1778 } 1779 if (source->error_converting) { 1780 // Illegal byte sequence - skip its first byte 1781 source->inp_buf_ptr++; 1782 } 1783 source_p--; 1784 break; 1785 case backslash_char: 1786 if (*++source_p == (int) nul_char) { 1787 GET_NEXT_BLOCK_NOCHK(source); 1788 if (source == NULL) { 1789 GOTO_STATE(on_eoln_state); 1790 } 1791 if (source->error_converting) { 1792 // Illegal byte sequence - skip its first byte 1793 source->inp_buf_ptr++; 1794 source_p--; 1795 break; 1796 } 1797 } 1798 if(*source_p == (int) newline_char) { 1799 if (source->fd >= 0) { 1800 line_number++; 1801 } 1802 } 1803 break; 1804 case newline_char: 1805 source_p++; 1806 if (source->fd >= 0) { 1807 line_number++; 1808 } 1809 goto enter_dependencies_label; 1810 } 1811 } 1812 1813 case tab_char: 1814 GOTO_STATE(scan_command_state); 1815 } 1816 1817 /* We read all the command lines for the target/dependency line. */ 1818 /* Enter the stuff */ 1819 enter_target_groups_and_dependencies( &target, &depes, command, 1820 separator, target_group_seen); 1821 1822 goto start_new_line; 1823 1824 /**************************************************************** 1825 * scan command state 1826 */ 1827 case scan_command_state: 1828 /* We need to read one rule line. Do that and return to */ 1829 /* the enter dependencies state */ 1830 string_start = source_p; 1831 macro_seen_in_string = false; 1832 for (; 1; source_p++) { 1833 switch (GET_CHAR()) { 1834 case backslash_char: 1835 if (!macro_seen_in_string) { 1836 INIT_STRING_FROM_STACK(name_string, 1837 name_buffer); 1838 } 1839 append_string(string_start, 1840 &name_string, 1841 source_p - string_start); 1842 macro_seen_in_string = true; 1843 if (*++source_p == (int) nul_char) { 1844 GET_NEXT_BLOCK(source); 1845 if (source == NULL) { 1846 string_start = source_p; 1847 goto command_newline; 1848 } 1849 } 1850 append_char((int) backslash_char, &name_string); 1851 append_char(*source_p, &name_string); 1852 if (*source_p == (int) newline_char) { 1853 if (source->fd >= 0) { 1854 line_number++; 1855 } 1856 if (*++source_p == (int) nul_char) { 1857 GET_NEXT_BLOCK(source); 1858 if (source == NULL) { 1859 string_start = source_p; 1860 goto command_newline; 1861 } 1862 } 1863 if (*source_p == (int) tab_char) { 1864 source_p++; 1865 } 1866 } else { 1867 if (*++source_p == (int) nul_char) { 1868 GET_NEXT_BLOCK(source); 1869 if (source == NULL) { 1870 string_start = source_p; 1871 goto command_newline; 1872 } 1873 } 1874 } 1875 string_start = source_p; 1876 if ((*source_p == (int) newline_char) || 1877 (*source_p == (int) backslash_char) || 1878 (*source_p == (int) nul_char)) { 1879 source_p--; 1880 } 1881 break; 1882 case newline_char: 1883 command_newline: 1884 if ((string_start != source_p) || 1885 macro_seen_in_string) { 1886 if (macro_seen_in_string) { 1887 append_string(string_start, 1888 &name_string, 1889 source_p - string_start); 1890 string_start = 1891 name_string.buffer.start; 1892 string_end = name_string.text.p; 1893 } else { 1894 string_end = source_p; 1895 } 1896 while ((*string_start != (int) newline_char) && 1897 iswspace(*string_start)){ 1898 string_start++; 1899 } 1900 if ((string_end > string_start) || 1901 (makefile_type == reading_statefile)) { 1902 if (command_tail == NULL) { 1903 command = 1904 command_tail = 1905 ALLOC(Cmd_line); 1906 } else { 1907 command_tail->next = 1908 ALLOC(Cmd_line); 1909 command_tail = 1910 command_tail->next; 1911 } 1912 command_tail->next = NULL; 1913 command_tail->make_refd = false; 1914 command_tail->ignore_command_dependency = false; 1915 command_tail->assign = false; 1916 command_tail->ignore_error = false; 1917 command_tail->silent = false; 1918 command_tail->command_line = 1919 GETNAME(string_start, 1920 string_end - string_start); 1921 if (macro_seen_in_string && 1922 name_string.free_after_use) { 1923 retmem(name_string. 1924 buffer.start); 1925 } 1926 } 1927 } 1928 do { 1929 if ((source != NULL) && (source->fd >= 0)) { 1930 line_number++; 1931 } 1932 if ((source != NULL) && 1933 (*++source_p == (int) nul_char)) { 1934 GET_NEXT_BLOCK(source); 1935 if (source == NULL) { 1936 GOTO_STATE(on_eoln_state); 1937 } 1938 } 1939 } while (*source_p == (int) newline_char); 1940 1941 GOTO_STATE(enter_dependencies_state); 1942 case nul_char: 1943 if (!macro_seen_in_string) { 1944 INIT_STRING_FROM_STACK(name_string, 1945 name_buffer); 1946 } 1947 append_string(string_start, 1948 &name_string, 1949 source_p - string_start); 1950 macro_seen_in_string = true; 1951 GET_NEXT_BLOCK(source); 1952 string_start = source_p; 1953 source_p--; 1954 if (source == NULL) { 1955 GOTO_STATE(enter_dependencies_state); 1956 } 1957 break; 1958 } 1959 } 1960 1961 /**************************************************************** 1962 * enter equal state 1963 */ 1964 case enter_equal_state: 1965 if (target.used != 1) { 1966 GOTO_STATE(poorly_formed_macro_state); 1967 } 1968 enter_equal(target.names[0], macro_value, append); 1969 goto start_new_line; 1970 1971 /**************************************************************** 1972 * enter conditional state 1973 */ 1974 case enter_conditional_state: 1975 if (depes.used != 1) { 1976 GOTO_STATE(poorly_formed_macro_state); 1977 } 1978 for (nvp = ⌖ nvp != NULL; nvp = nvp->next) { 1979 for (i = 0; i < nvp->used; i++) { 1980 enter_conditional(nvp->names[i], 1981 depes.names[0], 1982 macro_value, 1983 append); 1984 } 1985 } 1986 goto start_new_line; 1987 1988 /**************************************************************** 1989 * Error states 1990 */ 1991 case illegal_bytes_state: 1992 fatal_reader(gettext("Invalid byte sequence")); 1993 case illegal_eoln_state: 1994 if (line_number > 1) { 1995 if (line_started_with_space == (line_number - 1)) { 1996 line_number--; 1997 fatal_reader(gettext("Unexpected end of line seen\n\t*** missing separator (did you mean TAB instead of 8 spaces?)")); 1998 } 1999 } 2000 fatal_reader(gettext("Unexpected end of line seen")); 2001 case poorly_formed_macro_state: 2002 fatal_reader(gettext("Badly formed macro assignment")); 2003 case exit_state: 2004 return; 2005 default: 2006 fatal_reader(gettext("Internal error. Unknown reader state")); 2007 } 2008 } 2009 2010 /* 2011 * push_macro_value(bp, buffer, size, source) 2012 * 2013 * Macro and function that evaluates one macro 2014 * and makes the reader read from the value of it 2015 * 2016 * Return value: 2017 * The source block to read the macro from 2018 * 2019 * Parameters: 2020 * bp The new source block to fill in 2021 * buffer Buffer to read from 2022 * size size of the buffer 2023 * source The old source block 2024 * 2025 * Global variables used: 2026 */ 2027 static Source 2028 push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source) 2029 { 2030 bp->string.buffer.start = bp->string.text.p = buffer; 2031 bp->string.text.end = NULL; 2032 bp->string.buffer.end = buffer + (size/SIZEOFWCHAR_T); 2033 bp->string.free_after_use = false; 2034 bp->inp_buf = 2035 bp->inp_buf_ptr = 2036 bp->inp_buf_end = NULL; 2037 bp->error_converting = false; 2038 expand_macro(source, &bp->string, (wchar_t *) NULL, false); 2039 bp->string.text.p = bp->string.buffer.start; 2040 2041 /* 4209588: 'make' doesn't understand a macro with whitespaces in the head as target. 2042 * strip whitespace from the begining of the macro value 2043 */ 2044 while (iswspace(*bp->string.text.p)) { 2045 bp->string.text.p++; 2046 } 2047 2048 bp->fd = -1; 2049 bp->already_expanded = true; 2050 bp->previous = source; 2051 return bp; 2052 } 2053 2054 /* 2055 * enter_target_groups_and_dependencies(target, depes, command, separator, 2056 * target_group_seen) 2057 * 2058 * Parameters: 2059 * target Structure that shows the target(s) on the line 2060 * we are currently parsing. This can looks like 2061 * target1 .. targetN : dependencies 2062 * commands 2063 * or 2064 * target1 + .. + targetN : dependencies 2065 * commands 2066 * depes Dependencies 2067 * command Points to the command(s) to be executed for 2068 * this target. 2069 * separator : or :: or := 2070 * target_group_seen Set if we have target1 + .. + targetN 2071 * 2072 * 2073 * After reading the command lines for a target, this routine 2074 * is called to setup the dependencies and the commands for it. 2075 * If the target is a % pattern or part of a target group, then 2076 * the appropriate routines are called. 2077 */ 2078 2079 void 2080 enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen) 2081 { 2082 int i; 2083 Boolean reset= true; 2084 Chain target_group_member; 2085 Percent percent_ptr; 2086 2087 for (; target != NULL; target = target->next) { 2088 for (i = 0; i < target->used; i++) { 2089 if (target->names[i] != NULL) { 2090 if (target_group_seen) { 2091 target_group_member = 2092 find_target_groups(target, i, reset); 2093 if(target_group_member == NULL) { 2094 fatal_reader(gettext("Unexpected '+' on dependency line")); 2095 } 2096 } 2097 reset = false; 2098 2099 /* If we saw it in the makefile it must be 2100 * a file */ 2101 target->names[i]->stat.is_file = true; 2102 /* Make sure that we use dependencies 2103 * entered for makefiles */ 2104 target->names[i]->state = build_dont_know; 2105 2106 /* If the target is special we delegate 2107 * the processing */ 2108 if (target->names[i]->special_reader 2109 != no_special) { 2110 special_reader(target->names[i], 2111 depes, 2112 command); 2113 } 2114 /* Check if this is a "a%b : x%y" type rule */ 2115 else if (target->names[i]->percent) { 2116 percent_ptr = 2117 enter_percent(target->names[i], 2118 target->target_group[i], 2119 depes, command); 2120 if (target_group_seen) { 2121 target_group_member->percent_member = 2122 percent_ptr; 2123 } 2124 } else if (target->names[i]->dollar) { 2125 enter_dyntarget(target->names[i]); 2126 enter_dependencies 2127 (target->names[i], 2128 target->target_group[i], 2129 depes, 2130 command, 2131 separator); 2132 } else { 2133 if (target_group_seen) { 2134 target_group_member->percent_member = 2135 NULL; 2136 } 2137 2138 enter_dependencies 2139 (target->names[i], 2140 target->target_group[i], 2141 depes, 2142 command, 2143 separator); 2144 } 2145 } 2146 } 2147 } 2148 } 2149