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