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