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