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