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