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