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