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