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