8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / make / bin / read.cc
blob0d47f5b2f642f78369fed0e893827c848c59a409
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * read.c
29 * This file contains the makefile reader.
33 * Included files
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>
48 * typedefs & structs
52 * Static variables
55 static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
58 * File table of contents
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);
66 * read_simple_file(makefile_name, chase_path, doname_it,
67 * complain, must_exist, report_file, lock_makefile)
69 * Make the makefile and setup to read it. Actually read it if it is stdio
71 * Return value:
72 * false if the read failed
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
83 * Static variables used:
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
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)
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;
118 wchar_t * wcb = get_wstring(makefile_name->string_mb);
120 if (max_include_depth++ >= 40) {
121 fatal(gettext("Too many nested include statements"));
123 if (makefile->body.makefile.contents != NULL) {
124 retmem(makefile->body.makefile.contents);
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;
140 add_dir_to_path(".",
141 &makefile_path,
142 -1);
144 // As regularly installed
145 asprintf(&path, "%s/../share/lib/make", pfx);
146 add_dir_to_path(path, &makefile_path, -1);
147 free(path);
149 // Tools build
150 asprintf(&path, "%s/../../share/", pfx);
151 add_dir_to_path(path, &makefile_path, -1);
152 free(path);
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);
161 free(pfx);
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,
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;
185 MBSTOWCS(wcs_buffer, path);
186 makefile_name = GETNAME(wcs_buffer,
187 FIND_LENGTH);
190 retmem(string_start);
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).
197 // retmem_mb(normalized_makefile_name->string_mb);
199 makefile_type = save_makefile_type;
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) {
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,
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;
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);
234 max_include_depth--;
235 makefile_type = save_makefile_type;
236 return failed;
238 makefile_type = save_makefile_type;
240 // Before calling exists() make sure that we have the right timestamp
242 makefile_name->stat.time = file_no_time;
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));
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;
266 retmem(wcb);
267 retmem_mb((char *)source);
268 return failed;
271 * These values are the size and bytes of
272 * the MULTI-BYTE makefile.
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;
290 source->fd = open_vroot(makefile_name->string_mb,
291 O_RDONLY,
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));
307 max_include_depth--;
308 return failed;
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;
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;
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;
344 MBSTOWCS(wcs_buffer, "Standard in");
345 makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
347 * Memory to read standard in, then convert it
348 * to wide char strings.
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;
378 if (n < 0) {
379 fatal(gettext("Error reading standard input: %s"),
380 errmsg(errno));
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;
387 * Now, convert the sequence of multibyte chars into
388 * a sequence of corresponding wide character codes.
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;
406 (void) retmem_mb(stdin_text_p);
408 line_number = 1;
409 if (trace_reader) {
410 (void) printf(gettext(">>>>>>>>>>>>>>>> Reading makefile %s\n"),
411 makefile_name->string_mb);
413 parse_makefile(makefile_name, source);
414 if (trace_reader) {
415 (void) printf(gettext(">>>>>>>>>>>>>>>> End of makefile %s\n"),
416 makefile_name->string_mb);
418 if(file_being_read) {
419 retmem(file_being_read);
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);
431 if (forget_after_parse) {
432 retmem(makefile->body.makefile.contents);
433 makefile->body.makefile.contents = NULL;
435 retmem_mb((char *)source);
436 return succeeded;
440 * parse_makefile(true_makefile_name, source)
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.
447 * Parameters:
448 * true_makefile_name The name of makefile we are parsing
449 * source The source block to read from
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 ""
457 static void
458 parse_makefile(register Name true_makefile_name, register Source source)
461 char mb_buffer[MB_LEN_MAX];
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;
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;
487 register Reader_state state;
488 register Reader_state on_eoln_state;
489 register Separator separator;
491 wchar_t buffer[4 * STRING_BUFFER_LENGTH];
492 Source extrap;
494 Boolean save_do_not_exec_rule = do_not_exec_rule;
495 Name makefile_name;
497 static Name sh_name;
498 static Name shell_name;
499 int i;
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;
508 String_rec include_name;
509 wchar_t include_buffer[STRING_BUFFER_LENGTH];
511 target.next = depes.next = NULL;
512 /* Move some values from their struct to register declared locals */
513 CACHE_SOURCE(0);
515 start_new_line:
517 * Read whitespace on old line. Leave pointer on first char on
518 * next line.
520 first_target = true;
521 on_eoln_state = exit_state;
523 for (WCTOMB(mb_buffer, GET_CHAR());
525 source_p++, WCTOMB(mb_buffer, GET_CHAR()))
526 switch (mb_buffer[0]) {
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);
536 break;
537 case newline_char:
538 end_of_line:
539 source_p++;
540 if (source->fd >= 0) {
541 line_number++;
543 switch (GET_CHAR()) {
544 case nul_char:
545 GET_NEXT_BLOCK(source);
546 if (source == NULL) {
547 GOTO_STATE(on_eoln_state);
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:
557 * Go back to the top of this loop since the
558 * new line does not start with a regular char.
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;
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);
580 if (source->error_converting) {
581 // Illegal byte sequence - skip its first byte
582 source->inp_buf_ptr++;
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);
593 if (source->error_converting) {
594 // Illegal byte sequence - skip its first byte
595 source->inp_buf_ptr++;
596 source_p--;
597 break;
600 if(*source_p == (int) newline_char) {
601 if (source->fd >= 0) {
602 line_number++;
605 break;
606 case newline_char:
608 * After we skip the comment we go to
609 * the end of line handler since end of
610 * line terminates comments.
612 goto end_of_line;
615 case dollar_char:
616 /* Macro reference */
617 if (source->already_expanded) {
619 * If we are reading from the expansion of a
620 * macro we already expanded everything enough.
622 goto start_new_line_no_skip;
625 * Expand the value and push the Source on the stack of
626 * things being read.
628 source_p++;
629 UNCACHE_SOURCE();
631 Source t = (Source) alloca((int) sizeof (Source_rec));
632 source = push_macro_value(t,
633 buffer,
634 sizeof buffer,
635 source);
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;
645 * We found the first normal char (one that starts an identifier)
646 * on the newline.
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);
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);
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;
684 eoln_1:
685 if (!macro_seen_in_string) {
686 INIT_STRING_FROM_STACK(name_string,
687 name_buffer);
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++;
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);
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;
721 default:
722 goto line_evald;
725 /* We now have a line we can start reading */
726 line_evald:
727 if (source == NULL) {
728 GOTO_STATE(exit_state);
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");
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;
746 * Yes, this is an include.
747 * Skip spaces to get to the filename.
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);
757 break;
759 default:
760 source_p++;
761 break;
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);
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);
785 break;
787 default:
788 source_p++;
789 break;
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;
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;
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;
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;
825 INIT_STRING_FROM_STACK(include_name, include_buffer);
826 APPEND_NAME(true_makefile_name,
827 &include_name,
828 true_makefile_name->hash.length);
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);
837 name_start = include_name.buffer.start;
838 name_length = include_name.text.p - name_start;
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;
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);
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);
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;
888 } else {
889 /* Check if the word include was split across 8K boundary. */
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;
899 if (tmp_maybe_include) {
900 GET_NEXT_BLOCK(source);
901 tmp_maybe_include = false;
902 goto line_evald;
908 /* Reset the status in preparation for the new line */
909 for (nvp = &target; nvp != NULL; nvp = nvp->next) {
910 nvp->used = 0;
912 for (nvp = &depes; nvp != NULL; nvp = nvp->next) {
913 nvp->used = 0;
915 target_group_seen = false;
916 command = command_tail = NULL;
917 macro_value = NULL;
918 append = false;
919 current_names = &target;
920 SET_STATE(scan_name_state);
921 on_eoln_state = illegal_eoln_state;
922 separator = none_seen;
924 /* The state machine starts here */
925 enter_state:
926 while (1) switch (state) {
928 /****************************************************************
929 * Scan name state
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);
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++;
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);
958 if (*source_p == (int) newline_char) {
959 if (source->fd >= 0) {
960 line_number++;
962 } else {
963 source_p--;
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);
979 if (source->error_converting) {
980 // Illegal byte sequence - skip its first byte
981 source->inp_buf_ptr++;
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);
991 if (source->error_converting) {
992 // Illegal byte sequence - skip its first byte
993 source->inp_buf_ptr++;
994 source_p--;
995 break;
998 if(*source_p == (int) newline_char) {
999 if (source->fd >= 0) {
1000 line_number++;
1003 break;
1004 case newline_char:
1005 source_p++;
1006 if (source->fd >= 0) {
1007 line_number++;
1009 GOTO_STATE(on_eoln_state);
1012 case dollar_char:
1013 /* Macro reference. Expand and push value */
1014 if (source->already_expanded) {
1015 goto scan_name;
1017 source_p++;
1018 UNCACHE_SOURCE();
1020 Source t = (Source) alloca((int) sizeof (Source_rec));
1021 source = push_macro_value(t,
1022 buffer,
1023 sizeof buffer,
1024 source);
1026 CACHE_SOURCE(1);
1027 break;
1028 default:
1029 /* End of white space */
1030 goto scan_name;
1033 /* First proper identifier character */
1034 scan_name:
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);
1049 append_string(string_start,
1050 &name_string,
1051 source_p - string_start);
1052 macro_seen_in_string = true;
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);
1061 break;
1062 case newline_char:
1063 if (paren_count > 0) {
1064 fatal_reader(gettext("Unmatched `(' on line"));
1066 if (brace_count > 0) {
1067 fatal_reader(gettext("Unmatched `{' on line"));
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));
1083 /* Do postprocessing or return error */
1084 if (source->fd >= 0) {
1085 line_number++;
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;
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);
1104 if (*source_p == (int) newline_char) {
1105 if (source->fd >= 0) {
1106 line_number++;
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;
1115 break;
1116 case numbersign_char:
1117 if (paren_count + brace_count > 0) {
1118 break;
1120 fatal_reader(gettext("Unexpected comment seen"));
1121 case dollar_char:
1122 if (source->already_expanded) {
1123 break;
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);
1131 append_string(string_start,
1132 &name_string,
1133 source_p - string_start);
1134 macro_seen_in_string = true;
1136 /* Eval and push the macro */
1137 source_p++;
1138 UNCACHE_SOURCE();
1140 Source t =
1141 (Source) alloca((int) sizeof (Source_rec));
1142 source = push_macro_value(t,
1143 buffer,
1144 sizeof buffer,
1145 source);
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"));
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"));
1165 break;
1166 case ampersand_char:
1167 case greater_char:
1168 case bar_char:
1169 if (paren_count + brace_count == 0) {
1170 source_p++;
1172 /* Fall into */
1173 case tab_char:
1174 case space_char:
1175 if (paren_count + brace_count > 0) {
1176 break;
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));
1190 goto enter_state;
1191 case colon_char:
1192 if (paren_count + brace_count > 0) {
1193 break;
1195 if (separator == conditional_seen) {
1196 break;
1198 /** POSIX **/
1199 #if 0
1200 if(posix) {
1201 emptycount = 0;
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"));
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));
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);
1237 goto scan_colon_label;
1238 case equal_char:
1239 if(svr4) {
1240 fatal_reader(gettext("syntax error"));
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;
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;
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"));
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));
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;
1295 GOTO_STATE(scan_command_state);
1296 case plus_char:
1298 ** following code drops the target separator plus char if it starts
1299 ** a line.
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);
1311 append_string(string_start,
1312 &name_string,
1313 source_p - string_start);
1314 macro_seen_in_string = true;
1316 GET_NEXT_BLOCK(source);
1317 string_start = source_p;
1318 source_p--;
1319 if (source == NULL) {
1320 GOTO_STATE(on_eoln_state);
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);
1331 append_string(string_start,
1332 &name_string,
1333 source_p - string_start);
1334 macro_seen_in_string = true;
1336 GET_NEXT_BLOCK(source);
1337 string_start = source_p;
1338 if (source == NULL) {
1339 GOTO_STATE(on_eoln_state);
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;
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;
1358 if (paren_count + brace_count > 0) {
1359 break;
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;
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);
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);
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"));
1392 break;
1393 default:
1394 /* The "+" just starts a regular name. */
1395 /* Start reading that name */
1396 goto resume_name_scan;
1398 /* Fall into */
1399 case equal_char:
1400 if (paren_count + brace_count > 0) {
1401 break;
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);
1423 if (!macro_seen_in_string) {
1424 INIT_STRING_FROM_STACK(name_string,
1425 name_buffer);
1427 append_string(string_start,
1428 &name_string,
1429 source_p - string_start
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];
1443 INIT_STRING_FROM_STACK(macro_name,
1444 buffer);
1445 APPEND_NAME(target.names[0],
1446 &macro_name,
1447 FIND_LENGTH);
1448 append_char((int) colon_char,
1449 &macro_name);
1450 APPEND_NAME(sh_name,
1451 &macro_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];
1470 INIT_STRING_FROM_STACK(macro_name,
1471 buffer);
1472 APPEND_NAME(target.names[0],
1473 &macro_name,
1474 FIND_LENGTH);
1475 append_char((int) colon_char,
1476 &macro_name);
1477 APPEND_NAME(shell_name,
1478 &macro_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;
1487 if(svr4) {
1488 fatal_reader(gettext("syntax error"));
1490 else {
1491 fatal_reader(gettext("Macro assignment on dependency line"));
1494 if (append) {
1495 source_p--;
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));
1515 if (append) {
1516 source_p++;
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);
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);
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);
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++;
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;
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);
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);
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);
1593 break;
1594 case backslash_char:
1595 source_p++;
1596 if (distance != 0) {
1597 *source_p =
1598 *(source_p + distance);
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);
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);
1619 if (distance != 0) {
1620 *source_p =
1621 *(source_p +
1622 distance);
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);
1629 /****************/
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++;
1645 break;
1646 case newline_char:
1647 case numbersign_char:
1648 goto macro_value_end;
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);
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);
1666 if (name_string.free_after_use) {
1667 retmem(name_string.buffer.start);
1669 for (; distance > 0; distance--) {
1670 *source_p++ = (int) space_char;
1672 GOTO_STATE(on_eoln_state);
1676 /****************************************************************
1677 * enter dependencies state
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 */
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;
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);
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;
1718 eoln_2:
1719 if (!macro_seen_in_string) {
1720 INIT_STRING_FROM_STACK(name_string,
1721 name_buffer);
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);
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;
1750 case dollar_char:
1751 if (source->already_expanded) {
1752 break;
1754 source_p++;
1755 UNCACHE_SOURCE();
1757 Source t = (Source) alloca((int) sizeof (Source_rec));
1758 source = push_macro_value(t,
1759 buffer,
1760 sizeof buffer,
1761 source);
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);
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);
1777 if (source->error_converting) {
1778 // Illegal byte sequence - skip its first byte
1779 source->inp_buf_ptr++;
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);
1789 if (source->error_converting) {
1790 // Illegal byte sequence - skip its first byte
1791 source->inp_buf_ptr++;
1792 source_p--;
1793 break;
1796 if(*source_p == (int) newline_char) {
1797 if (source->fd >= 0) {
1798 line_number++;
1801 break;
1802 case newline_char:
1803 source_p++;
1804 if (source->fd >= 0) {
1805 line_number++;
1807 goto enter_dependencies_label;
1811 case tab_char:
1812 GOTO_STATE(scan_command_state);
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);
1820 goto start_new_line;
1822 /****************************************************************
1823 * scan command state
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);
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;
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++;
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;
1861 if (*source_p == (int) tab_char) {
1862 source_p++;
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;
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--;
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;
1894 while ((*string_start != (int) newline_char) &&
1895 iswspace(*string_start)){
1896 string_start++;
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;
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);
1926 do {
1927 if ((source != NULL) && (source->fd >= 0)) {
1928 line_number++;
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);
1937 } while (*source_p == (int) newline_char);
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);
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);
1955 break;
1959 /****************************************************************
1960 * enter equal state
1962 case enter_equal_state:
1963 if (target.used != 1) {
1964 GOTO_STATE(poorly_formed_macro_state);
1966 enter_equal(target.names[0], macro_value, append);
1967 goto start_new_line;
1969 /****************************************************************
1970 * enter conditional state
1972 case enter_conditional_state:
1973 if (depes.used != 1) {
1974 GOTO_STATE(poorly_formed_macro_state);
1976 for (nvp = &target; 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);
1984 goto start_new_line;
1986 /****************************************************************
1987 * Error states
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?)"));
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"));
2009 * push_macro_value(bp, buffer, size, source)
2011 * Macro and function that evaluates one macro
2012 * and makes the reader read from the value of it
2014 * Return value:
2015 * The source block to read the macro from
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
2023 * Global variables used:
2025 static Source
2026 push_macro_value(register Source bp, register wchar_t *buffer, int size, register Source source)
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;
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
2042 while (iswspace(*bp->string.text.p)) {
2043 bp->string.text.p++;
2046 bp->fd = -1;
2047 bp->already_expanded = true;
2048 bp->previous = source;
2049 return bp;
2053 * enter_target_groups_and_dependencies(target, depes, command, separator,
2054 * target_group_seen)
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
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.
2077 void
2078 enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen)
2080 int i;
2081 Boolean reset= true;
2082 Chain target_group_member;
2083 Percent percent_ptr;
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"));
2095 reset = false;
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;
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);
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;
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;
2136 enter_dependencies
2137 (target->names[i],
2138 target->target_group[i],
2139 depes,
2140 command,
2141 separator);