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