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