xref: /illumos-gate/usr/src/cmd/make/bin/read.cc (revision e7afc443)
110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe  * CDDL HEADER START
310d63b7dSRichard Lowe  *
410d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe  *
810d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe  * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe  * and limitations under the License.
1210d63b7dSRichard Lowe  *
1310d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe  *
1910d63b7dSRichard Lowe  * CDDL HEADER END
2010d63b7dSRichard Lowe  */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe  * Use is subject to license terms.
248e0c8248SAndrew Stormont  *
258e0c8248SAndrew Stormont  * Copyright 2019 RackTop Systems.
2610d63b7dSRichard Lowe  */
2710d63b7dSRichard Lowe 
2810d63b7dSRichard Lowe /*
2910d63b7dSRichard Lowe  *	read.c
3010d63b7dSRichard Lowe  *
3110d63b7dSRichard Lowe  *	This file contains the makefile reader.
3210d63b7dSRichard Lowe  */
3310d63b7dSRichard Lowe 
3410d63b7dSRichard Lowe /*
3510d63b7dSRichard Lowe  * Included files
3610d63b7dSRichard Lowe  */
3710d63b7dSRichard Lowe #include <alloca.h>		/* alloca() */
3810d63b7dSRichard Lowe #include <errno.h>		/* errno */
3910d63b7dSRichard Lowe #include <fcntl.h>		/* fcntl() */
4010d63b7dSRichard Lowe #include <mk/defs.h>
4110d63b7dSRichard Lowe #include <mksh/macro.h>		/* expand_value(), expand_macro() */
4210d63b7dSRichard Lowe #include <mksh/misc.h>		/* getmem() */
4310d63b7dSRichard Lowe #include <mksh/read.h>		/* get_next_block_fn() */
4410d63b7dSRichard Lowe #include <sys/uio.h>		/* read() */
4510d63b7dSRichard Lowe #include <unistd.h>		/* read(), unlink() */
4610d63b7dSRichard Lowe #include <libintl.h>
4710d63b7dSRichard Lowe 
4810d63b7dSRichard Lowe 
4910d63b7dSRichard Lowe /*
5010d63b7dSRichard Lowe  * typedefs & structs
5110d63b7dSRichard Lowe  */
5210d63b7dSRichard Lowe 
5310d63b7dSRichard Lowe /*
5410d63b7dSRichard Lowe  * Static variables
5510d63b7dSRichard Lowe  */
5610d63b7dSRichard Lowe 
5710d63b7dSRichard Lowe static int line_started_with_space=0; // Used to diagnose spaces instead of tabs
5810d63b7dSRichard Lowe 
5910d63b7dSRichard Lowe /*
6010d63b7dSRichard Lowe  * File table of contents
6110d63b7dSRichard Lowe  */
62*e7afc443SToomas Soome static	void		parse_makefile(Name true_makefile_name, Source source);
63*e7afc443SToomas Soome static	Source		push_macro_value(Source bp, wchar_t *buffer, int size, Source source);
64ae389aa9SAndy Fiddaman extern  void		enter_target_groups_and_dependencies(Name_vector target, Name_vector depes, Cmd_line command, Separator separator, Boolean target_group_seen);
65*e7afc443SToomas Soome extern	Name		normalize_name(wchar_t *name_string, int length);
6610d63b7dSRichard Lowe 
6710d63b7dSRichard Lowe /*
6810d63b7dSRichard Lowe  *	read_simple_file(makefile_name, chase_path, doname_it,
6910d63b7dSRichard Lowe  *		 complain, must_exist, report_file, lock_makefile)
7010d63b7dSRichard Lowe  *
7110d63b7dSRichard Lowe  *	Make the makefile and setup to read it. Actually read it if it is stdio
7210d63b7dSRichard Lowe  *
7310d63b7dSRichard Lowe  *	Return value:
7410d63b7dSRichard Lowe  *				false if the read failed
7510d63b7dSRichard Lowe  *
7610d63b7dSRichard Lowe  *	Parameters:
7710d63b7dSRichard Lowe  *		makefile_name	Name of the file to read
7810d63b7dSRichard Lowe  *		chase_path	Use the makefile path when opening file
7910d63b7dSRichard Lowe  *		doname_it	Call doname() to build the file first
8010d63b7dSRichard Lowe  *		complain	Print message if doname/open fails
8110d63b7dSRichard Lowe  *		must_exist	Generate fatal if file is missing
8210d63b7dSRichard Lowe  *		report_file	Report file when running -P
8310d63b7dSRichard Lowe  *		lock_makefile	Lock the makefile when reading
8410d63b7dSRichard Lowe  *
8510d63b7dSRichard Lowe  *	Static variables used:
8610d63b7dSRichard Lowe  *
8710d63b7dSRichard Lowe  *	Global variables used:
8810d63b7dSRichard Lowe  *		do_not_exec_rule Is -n on?
8910d63b7dSRichard Lowe  *		file_being_read	Set to the name of the new file
9010d63b7dSRichard Lowe  *		line_number	The number of the current makefile line
9110d63b7dSRichard Lowe  *		makefiles_used	A list of all makefiles used, appended to
9210d63b7dSRichard Lowe  */
9310d63b7dSRichard Lowe 
9410d63b7dSRichard Lowe 
9510d63b7dSRichard Lowe Boolean
read_simple_file(Name makefile_name,Boolean chase_path,Boolean doname_it,Boolean complain,Boolean must_exist,Boolean report_file,Boolean lock_makefile)96*e7afc443SToomas Soome read_simple_file(Name makefile_name, Boolean chase_path, Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile)
9710d63b7dSRichard Lowe {
9810d63b7dSRichard Lowe 	static short		max_include_depth;
99*e7afc443SToomas Soome 	Property	makefile = maybe_append_prop(makefile_name,
10010d63b7dSRichard Lowe 							     makefile_prop);
10110d63b7dSRichard Lowe 	Boolean			forget_after_parse = false;
10210d63b7dSRichard Lowe 	static pathpt		makefile_path;
103*e7afc443SToomas Soome 	int		n;
10410d63b7dSRichard Lowe 	char			*path;
105*e7afc443SToomas Soome 	Source		source = ALLOC(Source);
10610d63b7dSRichard Lowe 	Property		orig_makefile = makefile;
10710d63b7dSRichard Lowe 	Dependency		*dpp;
10810d63b7dSRichard Lowe 	Dependency		dp;
109*e7afc443SToomas Soome 	int		length;
11010d63b7dSRichard Lowe 	wchar_t			*previous_file_being_read = file_being_read;
11110d63b7dSRichard Lowe 	int			previous_line_number = line_number;
11210d63b7dSRichard Lowe 	wchar_t			previous_current_makefile[MAXPATHLEN];
11310d63b7dSRichard Lowe 	Makefile_type		save_makefile_type;
114ae389aa9SAndy Fiddaman 	Name			normalized_makefile_name;
115*e7afc443SToomas Soome 	wchar_t        *string_start;
116*e7afc443SToomas Soome 	wchar_t        *string_end;
11710d63b7dSRichard Lowe 
11810d63b7dSRichard Lowe 
11910d63b7dSRichard Lowe 
12010d63b7dSRichard Lowe 	wchar_t * wcb = get_wstring(makefile_name->string_mb);
12110d63b7dSRichard Lowe 
12210d63b7dSRichard Lowe 	if (max_include_depth++ >= 40) {
12310d63b7dSRichard Lowe 		fatal(gettext("Too many nested include statements"));
12410d63b7dSRichard Lowe 	}
12510d63b7dSRichard Lowe 	if (makefile->body.makefile.contents != NULL) {
12610d63b7dSRichard Lowe 		retmem(makefile->body.makefile.contents);
12710d63b7dSRichard Lowe 	}
12810d63b7dSRichard Lowe 	source->inp_buf =
12910d63b7dSRichard Lowe 	  source->inp_buf_ptr =
13010d63b7dSRichard Lowe 	    source->inp_buf_end = NULL;
13110d63b7dSRichard Lowe 	source->error_converting = false;
13210d63b7dSRichard Lowe 	makefile->body.makefile.contents = NULL;
13310d63b7dSRichard Lowe 	makefile->body.makefile.size = 0;
13410d63b7dSRichard Lowe 	if ((makefile_name->hash.length != 1) ||
13510d63b7dSRichard Lowe 	    (wcb[0] != (int) hyphen_char)) {
13610d63b7dSRichard Lowe 		if ((makefile->body.makefile.contents == NULL) &&
13710d63b7dSRichard Lowe 		    (doname_it)) {
13810d63b7dSRichard Lowe 			if (makefile_path == NULL) {
13910d63b7dSRichard Lowe 				char *pfx = make_install_prefix();
14010d63b7dSRichard Lowe 				char *path;
14110d63b7dSRichard Lowe 
14210d63b7dSRichard Lowe 				add_dir_to_path(".",
14310d63b7dSRichard Lowe 						&makefile_path,
14410d63b7dSRichard Lowe 						-1);
14510d63b7dSRichard Lowe 
14610d63b7dSRichard Lowe 				// As regularly installed
14710d63b7dSRichard Lowe 				asprintf(&path, "%s/../share/lib/make", pfx);
14810d63b7dSRichard Lowe 				add_dir_to_path(path, &makefile_path, -1);
14910d63b7dSRichard Lowe 				free(path);
15010d63b7dSRichard Lowe 
15110d63b7dSRichard Lowe 				// Tools build
15210d63b7dSRichard Lowe 				asprintf(&path, "%s/../../share/", pfx);
15310d63b7dSRichard Lowe 				add_dir_to_path(path, &makefile_path, -1);
15410d63b7dSRichard Lowe 				free(path);
155ae389aa9SAndy Fiddaman 
15610d63b7dSRichard Lowe 				add_dir_to_path("/usr/share/lib/make",
15710d63b7dSRichard Lowe 						&makefile_path,
15810d63b7dSRichard Lowe 						-1);
15910d63b7dSRichard Lowe 				add_dir_to_path("/etc/default",
16010d63b7dSRichard Lowe 						&makefile_path,
16110d63b7dSRichard Lowe 						-1);
16210d63b7dSRichard Lowe 
16310d63b7dSRichard Lowe 				free(pfx);
16410d63b7dSRichard Lowe 			}
16510d63b7dSRichard Lowe 			save_makefile_type = makefile_type;
16610d63b7dSRichard Lowe 			makefile_type = reading_nothing;
16710d63b7dSRichard Lowe 			if (doname(makefile_name, true, false) == build_dont_know) {
16810d63b7dSRichard Lowe 				/* Try normalized filename */
16910d63b7dSRichard Lowe 				string_start=get_wstring(makefile_name->string_mb);
17010d63b7dSRichard Lowe 				for (string_end=string_start+1; *string_end != L'\0'; string_end++);
17110d63b7dSRichard Lowe 				normalized_makefile_name=normalize_name(string_start, string_end - string_start);
172ae389aa9SAndy Fiddaman 				if ((strcmp(makefile_name->string_mb, normalized_makefile_name->string_mb) == 0) ||
17310d63b7dSRichard Lowe 					(doname(normalized_makefile_name, true, false) == build_dont_know)) {
17410d63b7dSRichard Lowe 					n = access_vroot(makefile_name->string_mb,
17510d63b7dSRichard Lowe 						 4,
17610d63b7dSRichard Lowe 						 chase_path ?
17710d63b7dSRichard Lowe 						 makefile_path : NULL,
17810d63b7dSRichard Lowe 						 VROOT_DEFAULT);
17910d63b7dSRichard Lowe 					if (n == 0) {
18010d63b7dSRichard Lowe 						get_vroot_path((char **) NULL,
18110d63b7dSRichard Lowe 						       &path,
18210d63b7dSRichard Lowe 						       (char **) NULL);
18310d63b7dSRichard Lowe 						if ((path[0] == (int) period_char) &&
18410d63b7dSRichard Lowe 						    (path[1] == (int) slash_char)) {
18510d63b7dSRichard Lowe 							path += 2;
18610d63b7dSRichard Lowe 						}
18710d63b7dSRichard Lowe 						MBSTOWCS(wcs_buffer, path);
18810d63b7dSRichard Lowe 						makefile_name = GETNAME(wcs_buffer,
18910d63b7dSRichard Lowe 								FIND_LENGTH);
19010d63b7dSRichard Lowe 					}
19110d63b7dSRichard Lowe 				}
19210d63b7dSRichard Lowe 				retmem(string_start);
193ae389aa9SAndy Fiddaman 				/*
19410d63b7dSRichard Lowe 				 * Commented out: retmem_mb(normalized_makefile_name->string_mb);
19510d63b7dSRichard Lowe 				 * We have to return this memory, but it seems to trigger a bug
19610d63b7dSRichard Lowe 				 * in dmake or in Sun C++ 5.7 compiler (it works ok if this code
19710d63b7dSRichard Lowe 				 * is compiled using Sun C++ 5.6).
19810d63b7dSRichard Lowe 				 */
199ae389aa9SAndy Fiddaman 				// retmem_mb(normalized_makefile_name->string_mb);
20010d63b7dSRichard Lowe 			}
20110d63b7dSRichard Lowe 			makefile_type = save_makefile_type;
20210d63b7dSRichard Lowe 		}
20310d63b7dSRichard Lowe 		source->string.free_after_use = false;
20410d63b7dSRichard Lowe 		source->previous = NULL;
20510d63b7dSRichard Lowe 		source->already_expanded = false;
20610d63b7dSRichard Lowe 		/* Lock the file for read, but not when -n. */
207ae389aa9SAndy Fiddaman 		if (lock_makefile &&
20810d63b7dSRichard Lowe 		    !do_not_exec_rule) {
20910d63b7dSRichard Lowe 
21010d63b7dSRichard Lowe 			 make_state_lockfile = getmem(strlen(make_state->string_mb) + strlen(".lock") + 1);
21110d63b7dSRichard Lowe 			 (void) sprintf(make_state_lockfile,
21210d63b7dSRichard Lowe 						"%s.lock",
21310d63b7dSRichard Lowe 						make_state->string_mb);
21410d63b7dSRichard Lowe 			(void) file_lock(make_state->string_mb,
21510d63b7dSRichard Lowe 					 make_state_lockfile,
21610d63b7dSRichard Lowe 					 (int *) &make_state_locked,
21710d63b7dSRichard Lowe 					 0);
21810d63b7dSRichard Lowe 			if(!make_state_locked) {
21910d63b7dSRichard Lowe 				printf("-- NO LOCKING for read\n");
22010d63b7dSRichard Lowe 				retmem_mb(make_state_lockfile);
22110d63b7dSRichard Lowe 				make_state_lockfile = 0;
22210d63b7dSRichard Lowe 				return failed;
22310d63b7dSRichard Lowe 			}
22410d63b7dSRichard Lowe 		}
22510d63b7dSRichard Lowe 		if (makefile->body.makefile.contents == NULL) {
22610d63b7dSRichard Lowe 			save_makefile_type = makefile_type;
22710d63b7dSRichard Lowe 			makefile_type = reading_nothing;
22810d63b7dSRichard Lowe 			if ((doname_it) &&
22910d63b7dSRichard Lowe 			    (doname(makefile_name, true, false) == build_failed)) {
23010d63b7dSRichard Lowe 				if (complain) {
23110d63b7dSRichard Lowe 					(void) fprintf(stderr,
23210d63b7dSRichard Lowe 						       gettext("%s: Couldn't make `%s'\n"),
23310d63b7dSRichard Lowe 						       getprogname(),
23410d63b7dSRichard Lowe 						       makefile_name->string_mb);
23510d63b7dSRichard Lowe 				}
23610d63b7dSRichard Lowe 				max_include_depth--;
23710d63b7dSRichard Lowe 				makefile_type = save_makefile_type;
23810d63b7dSRichard Lowe 				return failed;
23910d63b7dSRichard Lowe 			}
24010d63b7dSRichard Lowe 			makefile_type = save_makefile_type;
24110d63b7dSRichard Lowe 			//
24210d63b7dSRichard Lowe 			// Before calling exists() make sure that we have the right timestamp
24310d63b7dSRichard Lowe 			//
24410d63b7dSRichard Lowe 			makefile_name->stat.time = file_no_time;
24510d63b7dSRichard Lowe 
24610d63b7dSRichard Lowe 			if (exists(makefile_name) == file_doesnt_exist) {
24710d63b7dSRichard Lowe 				if (complain ||
24810d63b7dSRichard Lowe 				    (makefile_name->stat.stat_errno != ENOENT)) {
24910d63b7dSRichard Lowe 					if (must_exist) {
25010d63b7dSRichard Lowe 						fatal(gettext("Can't find `%s': %s"),
25110d63b7dSRichard Lowe 						      makefile_name->string_mb,
25210d63b7dSRichard Lowe 						      errmsg(makefile_name->
25310d63b7dSRichard Lowe 							     stat.stat_errno));
25410d63b7dSRichard Lowe 					} else {
25510d63b7dSRichard Lowe 						warning(gettext("Can't find `%s': %s"),
25610d63b7dSRichard Lowe 							makefile_name->string_mb,
25710d63b7dSRichard Lowe 							errmsg(makefile_name->
25810d63b7dSRichard Lowe 							       stat.stat_errno));
25910d63b7dSRichard Lowe 					}
26010d63b7dSRichard Lowe 				}
26110d63b7dSRichard Lowe 				max_include_depth--;
26210d63b7dSRichard Lowe 				if(make_state_locked && (make_state_lockfile != NULL)) {
26310d63b7dSRichard Lowe 					(void) unlink(make_state_lockfile);
26410d63b7dSRichard Lowe 					retmem_mb(make_state_lockfile);
26510d63b7dSRichard Lowe 					make_state_lockfile = NULL;
26610d63b7dSRichard Lowe 					make_state_locked = false;
26710d63b7dSRichard Lowe 				}
26810d63b7dSRichard Lowe 				retmem(wcb);
26910d63b7dSRichard Lowe 				retmem_mb((char *)source);
27010d63b7dSRichard Lowe 				return failed;
27110d63b7dSRichard Lowe 			}
27210d63b7dSRichard Lowe 			/*
27310d63b7dSRichard Lowe 			 * These values are the size and bytes of
27410d63b7dSRichard Lowe 			 * the MULTI-BYTE makefile.
27510d63b7dSRichard Lowe 			 */
27610d63b7dSRichard Lowe 			orig_makefile->body.makefile.size =
27710d63b7dSRichard Lowe 			  makefile->body.makefile.size =
27810d63b7dSRichard Lowe 			    source->bytes_left_in_file =
27910d63b7dSRichard Lowe 			      makefile_name->stat.size;
28010d63b7dSRichard Lowe 			if (report_file) {
28110d63b7dSRichard Lowe 				for (dpp = &makefiles_used;
28210d63b7dSRichard Lowe 				     *dpp != NULL;
28310d63b7dSRichard Lowe 				     dpp = &(*dpp)->next);
28410d63b7dSRichard Lowe 				dp = ALLOC(Dependency);
28510d63b7dSRichard Lowe 				dp->next = NULL;
28610d63b7dSRichard Lowe 				dp->name = makefile_name;
28710d63b7dSRichard Lowe 				dp->automatic = false;
28810d63b7dSRichard Lowe 				dp->stale = false;
28910d63b7dSRichard Lowe 				dp->built = false;
29010d63b7dSRichard Lowe 				*dpp = dp;
29110d63b7dSRichard Lowe 			}
29210d63b7dSRichard Lowe 			source->fd = open_vroot(makefile_name->string_mb,
29310d63b7dSRichard Lowe 						O_RDONLY,
29410d63b7dSRichard Lowe 						0,
29510d63b7dSRichard Lowe 						NULL,
29610d63b7dSRichard Lowe 						VROOT_DEFAULT);
29710d63b7dSRichard Lowe 			if (source->fd < 0) {
29810d63b7dSRichard Lowe 				if (complain || (errno != ENOENT)) {
29910d63b7dSRichard Lowe 					if (must_exist) {
30010d63b7dSRichard Lowe 						fatal(gettext("Can't open `%s': %s"),
30110d63b7dSRichard Lowe 						      makefile_name->string_mb,
30210d63b7dSRichard Lowe 						      errmsg(errno));
30310d63b7dSRichard Lowe 					} else {
30410d63b7dSRichard Lowe 						warning(gettext("Can't open `%s': %s"),
30510d63b7dSRichard Lowe 							makefile_name->string_mb,
30610d63b7dSRichard Lowe 							errmsg(errno));
30710d63b7dSRichard Lowe 					}
30810d63b7dSRichard Lowe 				}
30910d63b7dSRichard Lowe 				max_include_depth--;
31010d63b7dSRichard Lowe 				return failed;
31110d63b7dSRichard Lowe 			}
31210d63b7dSRichard Lowe 			(void) fcntl(source->fd, F_SETFD, 1);
31310d63b7dSRichard Lowe 			orig_makefile->body.makefile.contents =
31410d63b7dSRichard Lowe 			  makefile->body.makefile.contents =
31510d63b7dSRichard Lowe 			    source->string.text.p =
31610d63b7dSRichard Lowe 			      source->string.buffer.start =
31710d63b7dSRichard Lowe 				ALLOC_WC((int) (makefile_name->stat.size + 2));
31810d63b7dSRichard Lowe 			if (makefile_type == reading_cpp_file) {
31910d63b7dSRichard Lowe 				forget_after_parse = true;
32010d63b7dSRichard Lowe 			}
32110d63b7dSRichard Lowe 			source->string.text.end = source->string.text.p;
32210d63b7dSRichard Lowe 			source->string.buffer.end =
32310d63b7dSRichard Lowe 			  source->string.text.p + makefile_name->stat.size;
32410d63b7dSRichard Lowe 		} else {
32510d63b7dSRichard Lowe 			/* Do we ever reach here? */
32610d63b7dSRichard Lowe 			source->fd = -1;
32710d63b7dSRichard Lowe 			source->string.text.p =
32810d63b7dSRichard Lowe 			  source->string.buffer.start =
32910d63b7dSRichard Lowe 			    makefile->body.makefile.contents;
33010d63b7dSRichard Lowe 			source->string.text.end =
33110d63b7dSRichard Lowe 			  source->string.buffer.end =
33210d63b7dSRichard Lowe 			    source->string.text.p + makefile->body.makefile.size;
33310d63b7dSRichard Lowe 			source->bytes_left_in_file =
33410d63b7dSRichard Lowe 			  makefile->body.makefile.size;
33510d63b7dSRichard Lowe 		}
33610d63b7dSRichard Lowe 		file_being_read = wcb;
33710d63b7dSRichard Lowe 	} else {
33810d63b7dSRichard Lowe 		char		*stdin_text_p;
33910d63b7dSRichard Lowe 		char		*stdin_text_end;
34010d63b7dSRichard Lowe 		char		*stdin_buffer_start;
34110d63b7dSRichard Lowe 		char		*stdin_buffer_end;
34210d63b7dSRichard Lowe 		char		*p_mb;
34310d63b7dSRichard Lowe 		int		num_mb_chars;
34410d63b7dSRichard Lowe 		size_t		num_wc_chars;
34510d63b7dSRichard Lowe 
34610d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "Standard in");
34710d63b7dSRichard Lowe 		makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
34810d63b7dSRichard Lowe 		/*
34910d63b7dSRichard Lowe 		 * Memory to read standard in, then convert it
35010d63b7dSRichard Lowe 		 * to wide char strings.
35110d63b7dSRichard Lowe 		 */
35210d63b7dSRichard Lowe 		stdin_buffer_start =
35310d63b7dSRichard Lowe 		  stdin_text_p = getmem(length = 1024);
35410d63b7dSRichard Lowe 		stdin_buffer_end = stdin_text_p + length;
35510d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "standard input");
35610d63b7dSRichard Lowe 		file_being_read = (wchar_t *) wcsdup(wcs_buffer);
35710d63b7dSRichard Lowe 		line_number = 0;
35810d63b7dSRichard Lowe 		while ((n = read(fileno(stdin),
35910d63b7dSRichard Lowe 				 stdin_text_p,
36010d63b7dSRichard Lowe 				 length)) > 0) {
36110d63b7dSRichard Lowe 			length -= n;
36210d63b7dSRichard Lowe 			stdin_text_p += n;
36310d63b7dSRichard Lowe 			if (length == 0) {
36410d63b7dSRichard Lowe 				p_mb = getmem(length = 1024 +
36510d63b7dSRichard Lowe 					      (stdin_buffer_end -
36610d63b7dSRichard Lowe 					       stdin_buffer_start));
36710d63b7dSRichard Lowe 				(void) strncpy(p_mb,
36810d63b7dSRichard Lowe 					       stdin_buffer_start,
36910d63b7dSRichard Lowe 					       (stdin_buffer_end -
37010d63b7dSRichard Lowe 					        stdin_buffer_start));
37110d63b7dSRichard Lowe 				retmem_mb(stdin_buffer_start);
37210d63b7dSRichard Lowe 				stdin_text_p = p_mb +
37310d63b7dSRichard Lowe 				  (stdin_buffer_end - stdin_buffer_start);
37410d63b7dSRichard Lowe 				stdin_buffer_start = p_mb;
37510d63b7dSRichard Lowe 				stdin_buffer_end =
37610d63b7dSRichard Lowe 				  stdin_buffer_start + length;
37710d63b7dSRichard Lowe 				length = 1024;
37810d63b7dSRichard Lowe 			}
37910d63b7dSRichard Lowe 		}
38010d63b7dSRichard Lowe 		if (n < 0) {
38110d63b7dSRichard Lowe 			fatal(gettext("Error reading standard input: %s"),
38210d63b7dSRichard Lowe 			      errmsg(errno));
38310d63b7dSRichard Lowe 		}
38410d63b7dSRichard Lowe 		stdin_text_p = stdin_buffer_start;
38510d63b7dSRichard Lowe 		stdin_text_end = stdin_buffer_end - length;
38610d63b7dSRichard Lowe 		num_mb_chars = stdin_text_end - stdin_text_p;
38710d63b7dSRichard Lowe 
38810d63b7dSRichard Lowe 		/*
38910d63b7dSRichard Lowe 		 * Now, convert the sequence of multibyte chars into
39010d63b7dSRichard Lowe 		 * a sequence of corresponding wide character codes.
39110d63b7dSRichard Lowe 		 */
39210d63b7dSRichard Lowe 		source->string.free_after_use = false;
39310d63b7dSRichard Lowe 		source->previous = NULL;
39410d63b7dSRichard Lowe 		source->bytes_left_in_file = 0;
39510d63b7dSRichard Lowe 		source->fd = -1;
39610d63b7dSRichard Lowe 		source->already_expanded = false;
39710d63b7dSRichard Lowe 		source->string.buffer.start =
39810d63b7dSRichard Lowe 		  source->string.text.p = ALLOC_WC(num_mb_chars + 1);
39910d63b7dSRichard Lowe 		source->string.buffer.end =
40010d63b7dSRichard Lowe 		    source->string.text.p + num_mb_chars;
40110d63b7dSRichard Lowe 		num_wc_chars = mbstowcs(source->string.text.p,
40210d63b7dSRichard Lowe 					stdin_text_p,
40310d63b7dSRichard Lowe 					num_mb_chars);
40410d63b7dSRichard Lowe 		if ((int) num_wc_chars >= 0) {
40510d63b7dSRichard Lowe 			source->string.text.end =
40610d63b7dSRichard Lowe 			  source->string.text.p + num_wc_chars;
40710d63b7dSRichard Lowe 		}
40810d63b7dSRichard Lowe 		(void) retmem_mb(stdin_text_p);
40910d63b7dSRichard Lowe 	}
41010d63b7dSRichard Lowe 	line_number = 1;
41110d63b7dSRichard Lowe 	if (trace_reader) {
41210d63b7dSRichard Lowe 		(void) printf(gettext(">>>>>>>>>>>>>>>> Reading makefile %s\n"),
41310d63b7dSRichard Lowe 			      makefile_name->string_mb);
41410d63b7dSRichard Lowe 	}
41510d63b7dSRichard Lowe 	parse_makefile(makefile_name, source);
41610d63b7dSRichard Lowe 	if (trace_reader) {
41710d63b7dSRichard Lowe 		(void) printf(gettext(">>>>>>>>>>>>>>>> End of makefile %s\n"),
41810d63b7dSRichard Lowe 			      makefile_name->string_mb);
41910d63b7dSRichard Lowe 	}
42010d63b7dSRichard Lowe 	if(file_being_read) {
42110d63b7dSRichard Lowe 		retmem(file_being_read);
42210d63b7dSRichard Lowe 	}
42310d63b7dSRichard Lowe 	file_being_read = previous_file_being_read;
42410d63b7dSRichard Lowe 	line_number = previous_line_number;
42510d63b7dSRichard Lowe 	makefile_type = reading_nothing;
42610d63b7dSRichard Lowe 	max_include_depth--;
42710d63b7dSRichard Lowe 	if (make_state_locked) {
42810d63b7dSRichard Lowe 		/* Unlock .make.state. */
42910d63b7dSRichard Lowe 		unlink(make_state_lockfile);
43010d63b7dSRichard Lowe 		make_state_locked = false;
43110d63b7dSRichard Lowe 		retmem_mb(make_state_lockfile);
43210d63b7dSRichard Lowe 	}
43310d63b7dSRichard Lowe 	if (forget_after_parse) {
43410d63b7dSRichard Lowe 		retmem(makefile->body.makefile.contents);
43510d63b7dSRichard Lowe 		makefile->body.makefile.contents = NULL;
43610d63b7dSRichard Lowe 	}
43710d63b7dSRichard Lowe 	retmem_mb((char *)source);
43810d63b7dSRichard Lowe 	return succeeded;
43910d63b7dSRichard Lowe }
44010d63b7dSRichard Lowe 
44110d63b7dSRichard Lowe /*
44210d63b7dSRichard Lowe  *	parse_makefile(true_makefile_name, source)
44310d63b7dSRichard Lowe  *
44410d63b7dSRichard Lowe  *	Strings are read from Sources.
44510d63b7dSRichard Lowe  *	When macros are found, their values are represented by a
44610d63b7dSRichard Lowe  *	Source that is pushed on a stack. At end of string
44710d63b7dSRichard Lowe  *	(that is returned from GET_CHAR() as 0), the block is popped.
44810d63b7dSRichard Lowe  *
44910d63b7dSRichard Lowe  *	Parameters:
45010d63b7dSRichard Lowe  *		true_makefile_name	The name of makefile we are parsing
45110d63b7dSRichard Lowe  *		source			The source block to read from
45210d63b7dSRichard Lowe  *
45310d63b7dSRichard Lowe  *	Global variables used:
45410d63b7dSRichard Lowe  *		do_not_exec_rule Is -n on?
45510d63b7dSRichard Lowe  *		line_number	The number of the current makefile line
45610d63b7dSRichard Lowe  *		makefile_type	What kind of makefile are we reading?
45710d63b7dSRichard Lowe  *		empty_name	The Name ""
45810d63b7dSRichard Lowe  */
45910d63b7dSRichard Lowe static void
parse_makefile(Name true_makefile_name,Source source)460*e7afc443SToomas Soome parse_makefile(Name true_makefile_name, Source source)
46110d63b7dSRichard Lowe {
46210d63b7dSRichard Lowe /*
46310d63b7dSRichard Lowe 	char			mb_buffer[MB_LEN_MAX];
46410d63b7dSRichard Lowe  */
465*e7afc443SToomas Soome 	wchar_t	*source_p;
466*e7afc443SToomas Soome 	wchar_t	*source_end;
467*e7afc443SToomas Soome 	wchar_t	*string_start;
46810d63b7dSRichard Lowe 	wchar_t			*string_end;
469*e7afc443SToomas Soome 	Boolean	macro_seen_in_string;
47010d63b7dSRichard Lowe 	Boolean			append;
47110d63b7dSRichard Lowe 	String_rec		name_string;
47210d63b7dSRichard Lowe 	wchar_t			name_buffer[STRING_BUFFER_LENGTH];
473*e7afc443SToomas Soome 	int		distance;
474*e7afc443SToomas Soome 	int		paren_count;
47510d63b7dSRichard Lowe 	int			brace_count;
47610d63b7dSRichard Lowe 	int			char_number;
47710d63b7dSRichard Lowe 	Cmd_line		command;
47810d63b7dSRichard Lowe 	Cmd_line		command_tail;
47910d63b7dSRichard Lowe 	Name			macro_value;
48010d63b7dSRichard Lowe 
48110d63b7dSRichard Lowe 	Name_vector_rec		target;
48210d63b7dSRichard Lowe 	Name_vector_rec		depes;
48310d63b7dSRichard Lowe 	Name_vector_rec		extra_name_vector;
48410d63b7dSRichard Lowe 	Name_vector		current_names;
48510d63b7dSRichard Lowe 	Name_vector		extra_names = &extra_name_vector;
48610d63b7dSRichard Lowe 	Name_vector		nvp;
48710d63b7dSRichard Lowe 	Boolean			target_group_seen;
48810d63b7dSRichard Lowe 
489*e7afc443SToomas Soome 	Reader_state   state;
490*e7afc443SToomas Soome 	Reader_state   on_eoln_state;
491*e7afc443SToomas Soome 	Separator	separator;
49210d63b7dSRichard Lowe 
49310d63b7dSRichard Lowe 	wchar_t                 buffer[4 * STRING_BUFFER_LENGTH];
49410d63b7dSRichard Lowe 	Source			extrap;
49510d63b7dSRichard Lowe 
49610d63b7dSRichard Lowe 	Boolean                 save_do_not_exec_rule = do_not_exec_rule;
49710d63b7dSRichard Lowe 	Name                    makefile_name;
49810d63b7dSRichard Lowe 
49910d63b7dSRichard Lowe 	static Name		sh_name;
50010d63b7dSRichard Lowe 	static Name		shell_name;
50110d63b7dSRichard Lowe 	int			i;
50210d63b7dSRichard Lowe 
50310d63b7dSRichard Lowe 	static wchar_t		include_space[10];
50410d63b7dSRichard Lowe 	static wchar_t		include_tab[10];
50510d63b7dSRichard Lowe 	int			tmp_bytes_left_in_string;
50610d63b7dSRichard Lowe 	Boolean			tmp_maybe_include = false;
507ae389aa9SAndy Fiddaman 	int			emptycount = 0;
50810d63b7dSRichard Lowe 	Boolean			first_target;
50910d63b7dSRichard Lowe 
51010d63b7dSRichard Lowe 	String_rec		include_name;
51110d63b7dSRichard Lowe 	wchar_t			include_buffer[STRING_BUFFER_LENGTH];
51210d63b7dSRichard Lowe 
51310d63b7dSRichard Lowe 	target.next = depes.next = NULL;
51410d63b7dSRichard Lowe 	/* Move some values from their struct to register declared locals */
51510d63b7dSRichard Lowe 	CACHE_SOURCE(0);
51610d63b7dSRichard Lowe 
51710d63b7dSRichard Lowe  start_new_line:
51810d63b7dSRichard Lowe 	/*
51910d63b7dSRichard Lowe 	 * Read whitespace on old line. Leave pointer on first char on
52010d63b7dSRichard Lowe 	 * next line.
52110d63b7dSRichard Lowe 	 */
52210d63b7dSRichard Lowe 	first_target = true;
52310d63b7dSRichard Lowe 	on_eoln_state = exit_state;
52410d63b7dSRichard Lowe /*
52510d63b7dSRichard Lowe 	for (WCTOMB(mb_buffer, GET_CHAR());
52610d63b7dSRichard Lowe 	     1;
52710d63b7dSRichard Lowe 	     source_p++, WCTOMB(mb_buffer, GET_CHAR()))
52810d63b7dSRichard Lowe 		switch (mb_buffer[0]) {
52910d63b7dSRichard Lowe  */
53010d63b7dSRichard Lowe 	for (char_number=0; 1; source_p++,char_number++) switch (GET_CHAR()) {
53110d63b7dSRichard Lowe 	case nul_char:
53210d63b7dSRichard Lowe 		/* End of this string. Pop it and return to the previous one */
53310d63b7dSRichard Lowe 		GET_NEXT_BLOCK(source);
53410d63b7dSRichard Lowe 		source_p--;
53510d63b7dSRichard Lowe 		if (source == NULL) {
53610d63b7dSRichard Lowe 			GOTO_STATE(on_eoln_state);
53710d63b7dSRichard Lowe 		}
53810d63b7dSRichard Lowe 		break;
53910d63b7dSRichard Lowe 	case newline_char:
54010d63b7dSRichard Lowe 	end_of_line:
54110d63b7dSRichard Lowe 		source_p++;
54210d63b7dSRichard Lowe 		if (source->fd >= 0) {
54310d63b7dSRichard Lowe 			line_number++;
54410d63b7dSRichard Lowe 		}
54510d63b7dSRichard Lowe 		switch (GET_CHAR()) {
54610d63b7dSRichard Lowe 		case nul_char:
54710d63b7dSRichard Lowe 			GET_NEXT_BLOCK(source);
54810d63b7dSRichard Lowe 			if (source == NULL) {
54910d63b7dSRichard Lowe 				GOTO_STATE(on_eoln_state);
55010d63b7dSRichard Lowe 			}
55110d63b7dSRichard Lowe 			/* Go back to the top of this loop */
55210d63b7dSRichard Lowe 			goto start_new_line;
55310d63b7dSRichard Lowe 		case newline_char:
55410d63b7dSRichard Lowe 		case numbersign_char:
55510d63b7dSRichard Lowe 		case dollar_char:
55610d63b7dSRichard Lowe 		case space_char:
55710d63b7dSRichard Lowe 		case tab_char:
55810d63b7dSRichard Lowe 			/*
55910d63b7dSRichard Lowe 			 * Go back to the top of this loop since the
56010d63b7dSRichard Lowe 			 * new line does not start with a regular char.
56110d63b7dSRichard Lowe 			 */
56210d63b7dSRichard Lowe 			goto start_new_line;
56310d63b7dSRichard Lowe 		default:
56410d63b7dSRichard Lowe 			/* We found the first proper char on the new line */
56510d63b7dSRichard Lowe 			goto start_new_line_no_skip;
56610d63b7dSRichard Lowe 		}
56710d63b7dSRichard Lowe 	case space_char:
56810d63b7dSRichard Lowe 		if (char_number == 0)
56910d63b7dSRichard Lowe 			line_started_with_space=line_number;
57010d63b7dSRichard Lowe 	case tab_char:
57110d63b7dSRichard Lowe 		/* Whitespace. Just keep going in this loop */
57210d63b7dSRichard Lowe 		break;
57310d63b7dSRichard Lowe 	case numbersign_char:
57410d63b7dSRichard Lowe 		/* Comment. Skip over it */
57510d63b7dSRichard Lowe 		for (; 1; source_p++) {
57610d63b7dSRichard Lowe 			switch (GET_CHAR()) {
57710d63b7dSRichard Lowe 			case nul_char:
57810d63b7dSRichard Lowe 				GET_NEXT_BLOCK_NOCHK(source);
57910d63b7dSRichard Lowe 				if (source == NULL) {
58010d63b7dSRichard Lowe 					GOTO_STATE(on_eoln_state);
58110d63b7dSRichard Lowe 				}
58210d63b7dSRichard Lowe 				if (source->error_converting) {
58310d63b7dSRichard Lowe 				// Illegal byte sequence - skip its first byte
58410d63b7dSRichard Lowe 					source->inp_buf_ptr++;
58510d63b7dSRichard Lowe 				}
58610d63b7dSRichard Lowe 				source_p--;
58710d63b7dSRichard Lowe 				break;
58810d63b7dSRichard Lowe 			case backslash_char:
58910d63b7dSRichard Lowe 				/* Comments can be continued */
59010d63b7dSRichard Lowe 				if (*++source_p == (int) nul_char) {
59110d63b7dSRichard Lowe 					GET_NEXT_BLOCK_NOCHK(source);
59210d63b7dSRichard Lowe 					if (source == NULL) {
59310d63b7dSRichard Lowe 						GOTO_STATE(on_eoln_state);
59410d63b7dSRichard Lowe 					}
59510d63b7dSRichard Lowe 					if (source->error_converting) {
59610d63b7dSRichard Lowe 					// Illegal byte sequence - skip its first byte
59710d63b7dSRichard Lowe 						source->inp_buf_ptr++;
59810d63b7dSRichard Lowe 						source_p--;
59910d63b7dSRichard Lowe 						break;
60010d63b7dSRichard Lowe 					}
60110d63b7dSRichard Lowe 				}
60210d63b7dSRichard Lowe 				if(*source_p == (int) newline_char) {
60310d63b7dSRichard Lowe 					if (source->fd >= 0) {
60410d63b7dSRichard Lowe 						line_number++;
60510d63b7dSRichard Lowe 					}
60610d63b7dSRichard Lowe 				}
60710d63b7dSRichard Lowe 				break;
60810d63b7dSRichard Lowe 			case newline_char:
60910d63b7dSRichard Lowe 				/*
61010d63b7dSRichard Lowe 				 * After we skip the comment we go to
61110d63b7dSRichard Lowe 				 * the end of line handler since end of
61210d63b7dSRichard Lowe 				 * line terminates comments.
61310d63b7dSRichard Lowe 				 */
61410d63b7dSRichard Lowe 				goto end_of_line;
61510d63b7dSRichard Lowe 			}
61610d63b7dSRichard Lowe 		}
61710d63b7dSRichard Lowe 	case dollar_char:
61810d63b7dSRichard Lowe 		/* Macro reference */
61910d63b7dSRichard Lowe 		if (source->already_expanded) {
62010d63b7dSRichard Lowe 			/*
62110d63b7dSRichard Lowe 			 * If we are reading from the expansion of a
62210d63b7dSRichard Lowe 			 * macro we already expanded everything enough.
62310d63b7dSRichard Lowe 			 */
62410d63b7dSRichard Lowe 			goto start_new_line_no_skip;
62510d63b7dSRichard Lowe 		}
62610d63b7dSRichard Lowe 		/*
62710d63b7dSRichard Lowe 		 * Expand the value and push the Source on the stack of
62810d63b7dSRichard Lowe 		 * things being read.
62910d63b7dSRichard Lowe 		 */
63010d63b7dSRichard Lowe 		source_p++;
63110d63b7dSRichard Lowe 		UNCACHE_SOURCE();
63210d63b7dSRichard Lowe 		{
63310d63b7dSRichard Lowe 			Source t = (Source) alloca((int) sizeof (Source_rec));
63410d63b7dSRichard Lowe 			source = push_macro_value(t,
63510d63b7dSRichard Lowe 						  buffer,
63610d63b7dSRichard Lowe 						  sizeof buffer,
63710d63b7dSRichard Lowe 						  source);
63810d63b7dSRichard Lowe 		}
63910d63b7dSRichard Lowe 		CACHE_SOURCE(1);
64010d63b7dSRichard Lowe 		break;
64110d63b7dSRichard Lowe 	default:
64210d63b7dSRichard Lowe 		/* We found the first proper char on the new line */
64310d63b7dSRichard Lowe 		goto start_new_line_no_skip;
64410d63b7dSRichard Lowe 	}
64510d63b7dSRichard Lowe 
64610d63b7dSRichard Lowe 	/*
64710d63b7dSRichard Lowe 	 * We found the first normal char (one that starts an identifier)
64810d63b7dSRichard Lowe 	 * on the newline.
64910d63b7dSRichard Lowe 	 */
65010d63b7dSRichard Lowe start_new_line_no_skip:
65110d63b7dSRichard Lowe 	/* Inspect that first char to see if it maybe is special anyway */
65210d63b7dSRichard Lowe 	switch (GET_CHAR()) {
65310d63b7dSRichard Lowe 	case nul_char:
65410d63b7dSRichard Lowe 		GET_NEXT_BLOCK(source);
65510d63b7dSRichard Lowe 		if (source == NULL) {
65610d63b7dSRichard Lowe 			GOTO_STATE(on_eoln_state);
65710d63b7dSRichard Lowe 		}
65810d63b7dSRichard Lowe 		goto start_new_line_no_skip;
65910d63b7dSRichard Lowe 	case newline_char:
66010d63b7dSRichard Lowe 		/* Just in case */
66110d63b7dSRichard Lowe 		goto start_new_line;
66210d63b7dSRichard Lowe 	case exclam_char:
66310d63b7dSRichard Lowe 		/* Evaluate the line before it is read */
66410d63b7dSRichard Lowe 		string_start = source_p + 1;
66510d63b7dSRichard Lowe 		macro_seen_in_string = false;
66610d63b7dSRichard Lowe 		/* Stuff the line in a string so we can eval it. */
66710d63b7dSRichard Lowe 		for (; 1; source_p++) {
66810d63b7dSRichard Lowe 			switch (GET_CHAR()) {
66910d63b7dSRichard Lowe 			case newline_char:
67010d63b7dSRichard Lowe 				goto eoln_1;
67110d63b7dSRichard Lowe 			case nul_char:
67210d63b7dSRichard Lowe 				if (source->fd > 0) {
67310d63b7dSRichard Lowe 					if (!macro_seen_in_string) {
67410d63b7dSRichard Lowe 						macro_seen_in_string = true;
67510d63b7dSRichard Lowe 						INIT_STRING_FROM_STACK(
67610d63b7dSRichard Lowe 						      name_string, name_buffer);
67710d63b7dSRichard Lowe 					}
67810d63b7dSRichard Lowe 					append_string(string_start,
67910d63b7dSRichard Lowe 						      &name_string,
68010d63b7dSRichard Lowe 						      source_p - string_start);
68110d63b7dSRichard Lowe 					GET_NEXT_BLOCK(source);
68210d63b7dSRichard Lowe 					string_start = source_p;
68310d63b7dSRichard Lowe 					source_p--;
684