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