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