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