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