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