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