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