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