xref: /illumos-gate/usr/src/cmd/make/bin/main.cc (revision 356ba08c15b26adbde3440aa89d8b31cd39fc526)
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.
2436cd0120SRobert Mustacchi  *
2536cd0120SRobert Mustacchi  * Copyright 2019, Joyent, Inc.
2610d63b7dSRichard Lowe  */
2710d63b7dSRichard Lowe 
2810d63b7dSRichard Lowe /*
2910d63b7dSRichard Lowe  *	main.cc
3010d63b7dSRichard Lowe  *
3110d63b7dSRichard Lowe  *	make program main routine plus some helper routines
3210d63b7dSRichard Lowe  */
3310d63b7dSRichard Lowe 
3410d63b7dSRichard Lowe /*
3510d63b7dSRichard Lowe  * Included files
3610d63b7dSRichard Lowe  */
3710d63b7dSRichard Lowe #include <bsd/bsd.h>		/* bsd_signal() */
3810d63b7dSRichard Lowe 
3910d63b7dSRichard Lowe 
4010d63b7dSRichard Lowe #include <locale.h>		/* setlocale() */
4110d63b7dSRichard Lowe #include <libgen.h>
4210d63b7dSRichard Lowe #include <mk/defs.h>
4310d63b7dSRichard Lowe #include <mksh/macro.h>		/* getvar() */
4410d63b7dSRichard Lowe #include <mksh/misc.h>		/* getmem(), setup_char_semantics() */
4510d63b7dSRichard Lowe 
4610d63b7dSRichard Lowe #include <pwd.h>		/* getpwnam() */
4710d63b7dSRichard Lowe #include <setjmp.h>
4810d63b7dSRichard Lowe #include <signal.h>
4910d63b7dSRichard Lowe #include <stdlib.h>
5010d63b7dSRichard Lowe #include <sys/errno.h>		/* ENOENT */
5110d63b7dSRichard Lowe #include <sys/stat.h>		/* fstat() */
5210d63b7dSRichard Lowe #include <fcntl.h>		/* open() */
5310d63b7dSRichard Lowe 
5410d63b7dSRichard Lowe #	include <sys/systeminfo.h>	/* sysinfo() */
5510d63b7dSRichard Lowe 
5610d63b7dSRichard Lowe #include <sys/types.h>		/* stat() */
5710d63b7dSRichard Lowe #include <sys/wait.h>		/* wait() */
5810d63b7dSRichard Lowe #include <unistd.h>		/* execv(), unlink(), access() */
5910d63b7dSRichard Lowe #include <vroot/report.h>	/* report_dependency(), get_report_file() */
6010d63b7dSRichard Lowe 
6110d63b7dSRichard Lowe // From read2.cc
6210d63b7dSRichard Lowe extern	Name		normalize_name(register wchar_t *name_string, register int length);
6310d63b7dSRichard Lowe 
6410d63b7dSRichard Lowe extern void job_adjust_fini();
6510d63b7dSRichard Lowe 
6610d63b7dSRichard Lowe 
6710d63b7dSRichard Lowe /*
6810d63b7dSRichard Lowe  * Defined macros
6910d63b7dSRichard Lowe  */
7010d63b7dSRichard Lowe #define	LD_SUPPORT_ENV_VAR	"SGS_SUPPORT_32"
7110d63b7dSRichard Lowe #define	LD_SUPPORT_ENV_VAR_32	"SGS_SUPPORT_32"
7210d63b7dSRichard Lowe #define	LD_SUPPORT_ENV_VAR_64	"SGS_SUPPORT_64"
7310d63b7dSRichard Lowe #define	LD_SUPPORT_MAKE_LIB	"libmakestate.so.1"
74*356ba08cSToomas Soome #ifdef __x86
7510d63b7dSRichard Lowe #define	LD_SUPPORT_MAKE_ARCH	"i386"
7610d63b7dSRichard Lowe #elif __sparc
7710d63b7dSRichard Lowe #define	LD_SUPPORT_MAKE_ARCH	"sparc"
7810d63b7dSRichard Lowe #else
7910d63b7dSRichard Lowe #error "Unsupported architecture"
8010d63b7dSRichard Lowe #endif
8110d63b7dSRichard Lowe 
8210d63b7dSRichard Lowe /*
8310d63b7dSRichard Lowe  * typedefs & structs
8410d63b7dSRichard Lowe  */
8510d63b7dSRichard Lowe 
8610d63b7dSRichard Lowe /*
8710d63b7dSRichard Lowe  * Static variables
8810d63b7dSRichard Lowe  */
8910d63b7dSRichard Lowe static	char		*argv_zero_string;
9010d63b7dSRichard Lowe static	Boolean		build_failed_ever_seen;
9110d63b7dSRichard Lowe static	Boolean		continue_after_error_ever_seen;	/* `-k' */
9210d63b7dSRichard Lowe static	Boolean		dmake_group_specified;		/* `-g' */
9310d63b7dSRichard Lowe static	Boolean		dmake_max_jobs_specified;	/* `-j' */
9410d63b7dSRichard Lowe static	Boolean		dmake_mode_specified;		/* `-m' */
9510d63b7dSRichard Lowe static	Boolean		dmake_add_mode_specified;	/* `-x' */
9610d63b7dSRichard Lowe static	Boolean		dmake_output_mode_specified;	/* `-x DMAKE_OUTPUT_MODE=' */
9710d63b7dSRichard Lowe static	Boolean		dmake_compat_mode_specified;	/* `-x SUN_MAKE_COMPAT_MODE=' */
9810d63b7dSRichard Lowe static	Boolean		dmake_odir_specified;		/* `-o' */
9910d63b7dSRichard Lowe static	Boolean		dmake_rcfile_specified;		/* `-c' */
10010d63b7dSRichard Lowe static	Boolean		env_wins;			/* `-e' */
10110d63b7dSRichard Lowe static	Boolean		ignore_default_mk;		/* `-r' */
10210d63b7dSRichard Lowe static	Boolean		list_all_targets;		/* `-T' */
10310d63b7dSRichard Lowe static	int		mf_argc;
10410d63b7dSRichard Lowe static	char		**mf_argv;
10510d63b7dSRichard Lowe static	Dependency_rec  not_auto_depen_struct;
10610d63b7dSRichard Lowe static	Dependency 	not_auto_depen = &not_auto_depen_struct;
10710d63b7dSRichard Lowe static	Boolean		pmake_cap_r_specified;		/* `-R' */
10810d63b7dSRichard Lowe static	Boolean		pmake_machinesfile_specified;	/* `-M' */
10910d63b7dSRichard Lowe static	Boolean		stop_after_error_ever_seen;	/* `-S' */
11010d63b7dSRichard Lowe static	Boolean		trace_status;			/* `-p' */
11110d63b7dSRichard Lowe 
11210d63b7dSRichard Lowe #ifdef DMAKE_STATISTICS
11310d63b7dSRichard Lowe static	Boolean		getname_stat = false;
11410d63b7dSRichard Lowe #endif
11510d63b7dSRichard Lowe 
11610d63b7dSRichard Lowe 	static	time_t		start_time;
11710d63b7dSRichard Lowe 	static	int		g_argc;
11810d63b7dSRichard Lowe 	static	char		**g_argv;
11910d63b7dSRichard Lowe 
12010d63b7dSRichard Lowe /*
12110d63b7dSRichard Lowe  * File table of contents
12210d63b7dSRichard Lowe  */
12310d63b7dSRichard Lowe 	extern "C" void		cleanup_after_exit(void);
12410d63b7dSRichard Lowe 
12510d63b7dSRichard Lowe extern "C" {
12610d63b7dSRichard Lowe 	extern	void		dmake_exit_callback(void);
12710d63b7dSRichard Lowe 	extern	void		dmake_message_callback(char *);
12810d63b7dSRichard Lowe }
12910d63b7dSRichard Lowe 
13010d63b7dSRichard Lowe extern	Name		normalize_name(register wchar_t *name_string, register int length);
13110d63b7dSRichard Lowe 
13210d63b7dSRichard Lowe extern	int		main(int, char * []);
13310d63b7dSRichard Lowe 
13410d63b7dSRichard Lowe static	void		append_makeflags_string(Name, String);
13510d63b7dSRichard Lowe static	void		doalarm(int);
13610d63b7dSRichard Lowe static	void		enter_argv_values(int , char **, ASCII_Dyn_Array *);
13710d63b7dSRichard Lowe static	void		make_targets(int, char **, Boolean);
13810d63b7dSRichard Lowe static	int		parse_command_option(char);
13910d63b7dSRichard Lowe static	void		read_command_options(int, char **);
14010d63b7dSRichard Lowe static	void		read_environment(Boolean);
14110d63b7dSRichard Lowe static	void		read_files_and_state(int, char **);
14210d63b7dSRichard Lowe static	Boolean		read_makefile(Name, Boolean, Boolean, Boolean);
14310d63b7dSRichard Lowe static	void		report_recursion(Name);
14410d63b7dSRichard Lowe static	void		set_sgs_support(void);
14510d63b7dSRichard Lowe static	void		setup_for_projectdir(void);
14610d63b7dSRichard Lowe static	void		setup_makeflags_argv(void);
14710d63b7dSRichard Lowe static	void		report_dir_enter_leave(Boolean entering);
14810d63b7dSRichard Lowe 
14910d63b7dSRichard Lowe extern void expand_value(Name, register String , Boolean);
15010d63b7dSRichard Lowe 
15110d63b7dSRichard Lowe static const char	verstring[] = "illumos make";
15210d63b7dSRichard Lowe 
15310d63b7dSRichard Lowe jmp_buf jmpbuffer;
15410d63b7dSRichard Lowe 
15510d63b7dSRichard Lowe /*
15610d63b7dSRichard Lowe  *	main(argc, argv)
15710d63b7dSRichard Lowe  *
15810d63b7dSRichard Lowe  *	Parameters:
15910d63b7dSRichard Lowe  *		argc			You know what this is
16010d63b7dSRichard Lowe  *		argv			You know what this is
16110d63b7dSRichard Lowe  *
16210d63b7dSRichard Lowe  *	Static variables used:
16310d63b7dSRichard Lowe  *		list_all_targets	make -T seen
16410d63b7dSRichard Lowe  *		trace_status		make -p seen
16510d63b7dSRichard Lowe  *
16610d63b7dSRichard Lowe  *	Global variables used:
16710d63b7dSRichard Lowe  *		debug_level		Should we trace make actions?
16810d63b7dSRichard Lowe  *		keep_state		Set if .KEEP_STATE seen
16910d63b7dSRichard Lowe  *		makeflags		The Name "MAKEFLAGS", used to get macro
17010d63b7dSRichard Lowe  *		remote_command_name	Name of remote invocation cmd ("on")
17110d63b7dSRichard Lowe  *		running_list		List of parallel running processes
17210d63b7dSRichard Lowe  *		stdout_stderr_same	true if stdout and stderr are the same
17310d63b7dSRichard Lowe  *		auto_dependencies	The Name "SUNPRO_DEPENDENCIES"
17410d63b7dSRichard Lowe  *		temp_file_directory	Set to the dir where we create tmp file
17510d63b7dSRichard Lowe  *		trace_reader		Set to reflect tracing status
17610d63b7dSRichard Lowe  *		working_on_targets	Set when building user targets
17710d63b7dSRichard Lowe  */
17810d63b7dSRichard Lowe int
17910d63b7dSRichard Lowe main(int argc, char *argv[])
18010d63b7dSRichard Lowe {
18110d63b7dSRichard Lowe 	/*
18210d63b7dSRichard Lowe 	 * cp is a -> to the value of the MAKEFLAGS env var,
18310d63b7dSRichard Lowe 	 * which has to be regular chars.
18410d63b7dSRichard Lowe 	 */
18510d63b7dSRichard Lowe 	register char		*cp;
18610d63b7dSRichard Lowe 	char 			make_state_dir[MAXPATHLEN];
18710d63b7dSRichard Lowe 	Boolean			parallel_flag = false;
18836cd0120SRobert Mustacchi 	Boolean			argv_zero_relative = false;
18910d63b7dSRichard Lowe 	char			*prognameptr;
19010d63b7dSRichard Lowe 	char 			*slash_ptr;
19110d63b7dSRichard Lowe 	mode_t			um;
19210d63b7dSRichard Lowe 	int			i;
19310d63b7dSRichard Lowe 	struct itimerval	value;
19410d63b7dSRichard Lowe 	char			def_dmakerc_path[MAXPATHLEN];
19510d63b7dSRichard Lowe 	Name			dmake_name, dmake_name2;
19610d63b7dSRichard Lowe 	Name			dmake_value, dmake_value2;
19710d63b7dSRichard Lowe 	Property		prop, prop2;
19810d63b7dSRichard Lowe 	struct stat		statbuf;
19910d63b7dSRichard Lowe 	int			statval;
20010d63b7dSRichard Lowe 
20110d63b7dSRichard Lowe 	struct stat		out_stat, err_stat;
20210d63b7dSRichard Lowe 	hostid = gethostid();
20310d63b7dSRichard Lowe 	bsd_signals();
20410d63b7dSRichard Lowe 
20510d63b7dSRichard Lowe 	(void) setlocale(LC_ALL, "");
20610d63b7dSRichard Lowe 
20710d63b7dSRichard Lowe 
20810d63b7dSRichard Lowe #ifdef DMAKE_STATISTICS
20910d63b7dSRichard Lowe 	if (getenv("DMAKE_STATISTICS")) {
21010d63b7dSRichard Lowe 		getname_stat = true;
21110d63b7dSRichard Lowe 	}
21210d63b7dSRichard Lowe #endif
21310d63b7dSRichard Lowe 
21410d63b7dSRichard Lowe #ifndef TEXT_DOMAIN
21510d63b7dSRichard Lowe #define	TEXT_DOMAIN	"SYS_TEST"
21610d63b7dSRichard Lowe #endif
21710d63b7dSRichard Lowe 	textdomain(TEXT_DOMAIN);
21810d63b7dSRichard Lowe 
21910d63b7dSRichard Lowe 	g_argc = argc;
22010d63b7dSRichard Lowe 	g_argv = (char **) malloc((g_argc + 1) * sizeof(char *));
22110d63b7dSRichard Lowe 	for (i = 0; i < argc; i++) {
22210d63b7dSRichard Lowe 		g_argv[i] = argv[i];
22310d63b7dSRichard Lowe 	}
22410d63b7dSRichard Lowe 	g_argv[i] = NULL;
22510d63b7dSRichard Lowe 
22610d63b7dSRichard Lowe 	/*
22710d63b7dSRichard Lowe 	 * Set argv_zero_string to some form of argv[0] for
22810d63b7dSRichard Lowe 	 * recursive MAKE builds.
22910d63b7dSRichard Lowe 	 */
23010d63b7dSRichard Lowe 
23110d63b7dSRichard Lowe 	if (*argv[0] == (int) slash_char) {
23210d63b7dSRichard Lowe 		/* argv[0] starts with a slash */
23310d63b7dSRichard Lowe 		argv_zero_string = strdup(argv[0]);
23410d63b7dSRichard Lowe 	} else if (strchr(argv[0], (int) slash_char) == NULL) {
23510d63b7dSRichard Lowe 		/* argv[0] contains no slashes */
23610d63b7dSRichard Lowe 		argv_zero_string = strdup(argv[0]);
23710d63b7dSRichard Lowe 	} else {
23810d63b7dSRichard Lowe 		/*
23910d63b7dSRichard Lowe 		 * argv[0] contains at least one slash,
24010d63b7dSRichard Lowe 		 * but doesn't start with a slash
24110d63b7dSRichard Lowe 		 */
24210d63b7dSRichard Lowe 		char	*tmp_current_path;
24310d63b7dSRichard Lowe 		char	*tmp_string;
24410d63b7dSRichard Lowe 
24510d63b7dSRichard Lowe 		tmp_current_path = get_current_path();
24610d63b7dSRichard Lowe 		tmp_string = getmem(strlen(tmp_current_path) + 1 +
24710d63b7dSRichard Lowe 		                    strlen(argv[0]) + 1);
24810d63b7dSRichard Lowe 		(void) sprintf(tmp_string,
24910d63b7dSRichard Lowe 		               "%s/%s",
25010d63b7dSRichard Lowe 		               tmp_current_path,
25110d63b7dSRichard Lowe 		               argv[0]);
25210d63b7dSRichard Lowe 		argv_zero_string = strdup(tmp_string);
25310d63b7dSRichard Lowe 		retmem_mb(tmp_string);
25436cd0120SRobert Mustacchi 		argv_zero_relative = true;
25510d63b7dSRichard Lowe 	}
25610d63b7dSRichard Lowe 
25710d63b7dSRichard Lowe 	/*
25810d63b7dSRichard Lowe 	 * The following flags are reset if we don't have the
25910d63b7dSRichard Lowe 	 * (.nse_depinfo or .make.state) files locked and only set
26010d63b7dSRichard Lowe 	 * AFTER the file has been locked. This ensures that if the user
26110d63b7dSRichard Lowe 	 * interrupts the program while file_lock() is waiting to lock
26210d63b7dSRichard Lowe 	 * the file, the interrupt handler doesn't remove a lock
26310d63b7dSRichard Lowe 	 * that doesn't belong to us.
26410d63b7dSRichard Lowe 	 */
26510d63b7dSRichard Lowe 	make_state_lockfile = NULL;
26610d63b7dSRichard Lowe 	make_state_locked = false;
26710d63b7dSRichard Lowe 
26810d63b7dSRichard Lowe 
26910d63b7dSRichard Lowe 	/*
27010d63b7dSRichard Lowe 	 * look for last slash char in the path to look at the binary
27110d63b7dSRichard Lowe 	 * name. This is to resolve the hard link and invoke make
27210d63b7dSRichard Lowe 	 * in svr4 mode.
27310d63b7dSRichard Lowe 	 */
27410d63b7dSRichard Lowe 
27510d63b7dSRichard Lowe 	/* Sun OS make standart */
27610d63b7dSRichard Lowe 	svr4 = false;
27710d63b7dSRichard Lowe 	posix = false;
27810d63b7dSRichard Lowe 	if(!strcmp(argv_zero_string, "/usr/xpg4/bin/make")) {
27910d63b7dSRichard Lowe 		svr4 = false;
28010d63b7dSRichard Lowe 		posix = true;
28110d63b7dSRichard Lowe 	} else {
28210d63b7dSRichard Lowe 		prognameptr = strrchr(argv[0], '/');
28310d63b7dSRichard Lowe 		if(prognameptr) {
28410d63b7dSRichard Lowe 			prognameptr++;
28510d63b7dSRichard Lowe 		} else {
28610d63b7dSRichard Lowe 			prognameptr = argv[0];
28710d63b7dSRichard Lowe 		}
28810d63b7dSRichard Lowe 		if(!strcmp(prognameptr, "svr4.make")) {
28910d63b7dSRichard Lowe 			svr4 = true;
29010d63b7dSRichard Lowe 			posix = false;
29110d63b7dSRichard Lowe 		}
29210d63b7dSRichard Lowe 	}
29310d63b7dSRichard Lowe 	if (getenv(USE_SVR4_MAKE) || getenv("USE_SVID")){
29410d63b7dSRichard Lowe 	   svr4 = true;
29510d63b7dSRichard Lowe 	   posix = false;
29610d63b7dSRichard Lowe 	}
29710d63b7dSRichard Lowe 
29810d63b7dSRichard Lowe 	/*
29910d63b7dSRichard Lowe 	 * Find the dmake_compat_mode: posix, sun, svr4, or gnu_style, .
30010d63b7dSRichard Lowe 	 */
30110d63b7dSRichard Lowe 	char * dmake_compat_mode_var = getenv("SUN_MAKE_COMPAT_MODE");
30210d63b7dSRichard Lowe 	if (dmake_compat_mode_var != NULL) {
30310d63b7dSRichard Lowe 		if (0 == strcasecmp(dmake_compat_mode_var, "GNU")) {
30410d63b7dSRichard Lowe 			gnu_style = true;
30510d63b7dSRichard Lowe 		}
30610d63b7dSRichard Lowe 		//svr4 = false;
30710d63b7dSRichard Lowe 		//posix = false;
30810d63b7dSRichard Lowe 	}
30910d63b7dSRichard Lowe 
31010d63b7dSRichard Lowe 	/*
31110d63b7dSRichard Lowe 	 * Temporary directory set up.
31210d63b7dSRichard Lowe 	 */
31310d63b7dSRichard Lowe 	char * tmpdir_var = getenv("TMPDIR");
31410d63b7dSRichard Lowe 	if (tmpdir_var != NULL && *tmpdir_var == '/' && strlen(tmpdir_var) < MAXPATHLEN) {
31510d63b7dSRichard Lowe 		strcpy(mbs_buffer, tmpdir_var);
31610d63b7dSRichard Lowe 		for (tmpdir_var = mbs_buffer+strlen(mbs_buffer);
31710d63b7dSRichard Lowe 			*(--tmpdir_var) == '/' && tmpdir_var > mbs_buffer;
31810d63b7dSRichard Lowe 			*tmpdir_var = '\0');
31910d63b7dSRichard Lowe 		if (strlen(mbs_buffer) + 32 < MAXPATHLEN) { /* 32 = strlen("/dmake.stdout.%d.%d.XXXXXX") */
32010d63b7dSRichard Lowe 			sprintf(mbs_buffer2, "%s/dmake.tst.%d.XXXXXX",
32110d63b7dSRichard Lowe 				mbs_buffer, getpid());
32210d63b7dSRichard Lowe 			int fd = mkstemp(mbs_buffer2);
32310d63b7dSRichard Lowe 			if (fd >= 0) {
32410d63b7dSRichard Lowe 				close(fd);
32510d63b7dSRichard Lowe 				unlink(mbs_buffer2);
32610d63b7dSRichard Lowe 				tmpdir = strdup(mbs_buffer);
32710d63b7dSRichard Lowe 			}
32810d63b7dSRichard Lowe 		}
32910d63b7dSRichard Lowe 	}
33010d63b7dSRichard Lowe 
33110d63b7dSRichard Lowe 	/* find out if stdout and stderr point to the same place */
33210d63b7dSRichard Lowe 	if (fstat(1, &out_stat) < 0) {
33310d63b7dSRichard Lowe 		fatal(gettext("fstat of standard out failed: %s"), errmsg(errno));
33410d63b7dSRichard Lowe 	}
33510d63b7dSRichard Lowe 	if (fstat(2, &err_stat) < 0) {
33610d63b7dSRichard Lowe 		fatal(gettext("fstat of standard error failed: %s"), errmsg(errno));
33710d63b7dSRichard Lowe 	}
33810d63b7dSRichard Lowe 	if ((out_stat.st_dev == err_stat.st_dev) &&
33910d63b7dSRichard Lowe 	    (out_stat.st_ino == err_stat.st_ino)) {
34010d63b7dSRichard Lowe 		stdout_stderr_same = true;
34110d63b7dSRichard Lowe 	} else {
34210d63b7dSRichard Lowe 		stdout_stderr_same = false;
34310d63b7dSRichard Lowe 	}
34410d63b7dSRichard Lowe 	/* Make the vroot package scan the path using shell semantics */
34510d63b7dSRichard Lowe 	set_path_style(0);
34610d63b7dSRichard Lowe 
34710d63b7dSRichard Lowe 	setup_char_semantics();
34810d63b7dSRichard Lowe 
34910d63b7dSRichard Lowe 	/*
35010d63b7dSRichard Lowe 	 * If running with .KEEP_STATE, curdir will be set with
35110d63b7dSRichard Lowe 	 * the connected directory.
35210d63b7dSRichard Lowe 	 */
35310d63b7dSRichard Lowe 	(void) atexit(cleanup_after_exit);
35410d63b7dSRichard Lowe 
35510d63b7dSRichard Lowe 	load_cached_names();
35610d63b7dSRichard Lowe 
35710d63b7dSRichard Lowe /*
35810d63b7dSRichard Lowe  *	Set command line flags
35910d63b7dSRichard Lowe  */
36010d63b7dSRichard Lowe 	setup_makeflags_argv();
36110d63b7dSRichard Lowe 	read_command_options(mf_argc, mf_argv);
36210d63b7dSRichard Lowe 	read_command_options(argc, argv);
36310d63b7dSRichard Lowe 	if (debug_level > 0) {
36410d63b7dSRichard Lowe 		cp = getenv(makeflags->string_mb);
36510d63b7dSRichard Lowe 		(void) printf(gettext("MAKEFLAGS value: %s\n"), cp == NULL ? "" : cp);
36610d63b7dSRichard Lowe 	}
36710d63b7dSRichard Lowe 
36836cd0120SRobert Mustacchi 	/*
36936cd0120SRobert Mustacchi 	 * Reset argv_zero_string if it was built from a relative path and the
37036cd0120SRobert Mustacchi 	 * -C option was specified.
37136cd0120SRobert Mustacchi 	 */
37236cd0120SRobert Mustacchi 	if (argv_zero_relative && rebuild_arg0) {
37336cd0120SRobert Mustacchi 		char	*tmp_current_path;
37436cd0120SRobert Mustacchi 		char	*tmp_string;
37536cd0120SRobert Mustacchi 
37636cd0120SRobert Mustacchi 		free(argv_zero_string);
37736cd0120SRobert Mustacchi 		tmp_current_path = get_current_path();
37836cd0120SRobert Mustacchi 		tmp_string = getmem(strlen(tmp_current_path) + 1 +
37936cd0120SRobert Mustacchi 		                    strlen(argv[0]) + 1);
38036cd0120SRobert Mustacchi 		(void) sprintf(tmp_string,
38136cd0120SRobert Mustacchi 		               "%s/%s",
38236cd0120SRobert Mustacchi 		               tmp_current_path,
38336cd0120SRobert Mustacchi 		               argv[0]);
38436cd0120SRobert Mustacchi 		argv_zero_string = strdup(tmp_string);
38536cd0120SRobert Mustacchi 		retmem_mb(tmp_string);
38636cd0120SRobert Mustacchi 	}
38736cd0120SRobert Mustacchi 
38836cd0120SRobert Mustacchi 	setup_for_projectdir();
38936cd0120SRobert Mustacchi 
39010d63b7dSRichard Lowe 	setup_interrupt(handle_interrupt);
39110d63b7dSRichard Lowe 
39210d63b7dSRichard Lowe 	read_files_and_state(argc, argv);
39310d63b7dSRichard Lowe 
39410d63b7dSRichard Lowe 	/*
39510d63b7dSRichard Lowe 	 * Find the dmake_output_mode: TXT1, TXT2 or HTML1.
39610d63b7dSRichard Lowe 	 */
39710d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "DMAKE_OUTPUT_MODE");
39810d63b7dSRichard Lowe 	dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
39910d63b7dSRichard Lowe 	prop2 = get_prop(dmake_name2->prop, macro_prop);
40010d63b7dSRichard Lowe 	if (prop2 == NULL) {
40110d63b7dSRichard Lowe 		/* DMAKE_OUTPUT_MODE not defined, default to TXT1 mode */
40210d63b7dSRichard Lowe 		output_mode = txt1_mode;
40310d63b7dSRichard Lowe 	} else {
40410d63b7dSRichard Lowe 		dmake_value2 = prop2->body.macro.value;
40510d63b7dSRichard Lowe 		if ((dmake_value2 == NULL) ||
40610d63b7dSRichard Lowe 		    (IS_EQUAL(dmake_value2->string_mb, "TXT1"))) {
40710d63b7dSRichard Lowe 			output_mode = txt1_mode;
40810d63b7dSRichard Lowe 		} else if (IS_EQUAL(dmake_value2->string_mb, "TXT2")) {
40910d63b7dSRichard Lowe 			output_mode = txt2_mode;
41010d63b7dSRichard Lowe 		} else if (IS_EQUAL(dmake_value2->string_mb, "HTML1")) {
41110d63b7dSRichard Lowe 			output_mode = html1_mode;
41210d63b7dSRichard Lowe 		} else {
41310d63b7dSRichard Lowe 			warning(gettext("Unsupported value `%s' for DMAKE_OUTPUT_MODE after -x flag (ignored)"),
41410d63b7dSRichard Lowe 			      dmake_value2->string_mb);
41510d63b7dSRichard Lowe 		}
41610d63b7dSRichard Lowe 	}
41710d63b7dSRichard Lowe 	/*
41810d63b7dSRichard Lowe 	 * Find the dmake_mode: parallel, or serial.
41910d63b7dSRichard Lowe 	 */
42010d63b7dSRichard Lowe     if ((!pmake_cap_r_specified) &&
42110d63b7dSRichard Lowe         (!pmake_machinesfile_specified)) {
42210d63b7dSRichard Lowe 	char *s, *b;
42310d63b7dSRichard Lowe 
42410d63b7dSRichard Lowe 	if ((s = strdup(argv[0])) == NULL)
42510d63b7dSRichard Lowe 		fatal(gettext("Out of memory"));
42610d63b7dSRichard Lowe 
42710d63b7dSRichard Lowe 	b = basename(s);
42810d63b7dSRichard Lowe 
42910d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "DMAKE_MODE");
43010d63b7dSRichard Lowe 	dmake_name2 = GETNAME(wcs_buffer, FIND_LENGTH);
43110d63b7dSRichard Lowe 	prop2 = get_prop(dmake_name2->prop, macro_prop);
43210d63b7dSRichard Lowe 	// If we're invoked as 'make' run serially, regardless of DMAKE_MODE
43310d63b7dSRichard Lowe 	// If we're invoked as 'make' but passed -j, run parallel
43410d63b7dSRichard Lowe 	// If we're invoked as 'dmake', without DMAKE_MODE, default parallel
43510d63b7dSRichard Lowe 	// If we're invoked as 'dmake' and DMAKE_MODE is set, honour it.
43610d63b7dSRichard Lowe 	if ((strcmp(b, "make") == 0) &&
43710d63b7dSRichard Lowe 	    !dmake_max_jobs_specified) {
43810d63b7dSRichard Lowe 		dmake_mode_type = serial_mode;
43910d63b7dSRichard Lowe 		no_parallel = true;
44010d63b7dSRichard Lowe 	} else if (prop2 == NULL) {
44110d63b7dSRichard Lowe 		/* DMAKE_MODE not defined, default based on our name */
44210d63b7dSRichard Lowe 		if (strcmp(b, "dmake") == 0) {
44310d63b7dSRichard Lowe 			dmake_mode_type = parallel_mode;
44410d63b7dSRichard Lowe 			no_parallel = false;
44510d63b7dSRichard Lowe 		}
44610d63b7dSRichard Lowe 	} else {
44710d63b7dSRichard Lowe 		dmake_value2 = prop2->body.macro.value;
44810d63b7dSRichard Lowe 		if (IS_EQUAL(dmake_value2->string_mb, "parallel")) {
44910d63b7dSRichard Lowe 			dmake_mode_type = parallel_mode;
45010d63b7dSRichard Lowe 			no_parallel = false;
45110d63b7dSRichard Lowe 		} else if (IS_EQUAL(dmake_value2->string_mb, "serial")) {
45210d63b7dSRichard Lowe 			dmake_mode_type = serial_mode;
45310d63b7dSRichard Lowe 			no_parallel = true;
45410d63b7dSRichard Lowe 		} else {
45510d63b7dSRichard Lowe 			fatal(gettext("Unknown dmake mode argument `%s' after -m flag"), dmake_value2->string_mb);
45610d63b7dSRichard Lowe 		}
45710d63b7dSRichard Lowe 	}
45810d63b7dSRichard Lowe 	free(s);
45910d63b7dSRichard Lowe     }
46010d63b7dSRichard Lowe 
46110d63b7dSRichard Lowe 	parallel_flag = true;
46210d63b7dSRichard Lowe 	putenv(strdup("DMAKE_CHILD=TRUE"));
46310d63b7dSRichard Lowe 
46410d63b7dSRichard Lowe //
46510d63b7dSRichard Lowe // If dmake is running with -t option, set dmake_mode_type to serial.
46610d63b7dSRichard Lowe // This is done because doname() calls touch_command() that runs serially.
46710d63b7dSRichard Lowe // If we do not do that, maketool will have problems.
46810d63b7dSRichard Lowe //
46910d63b7dSRichard Lowe 	if(touch) {
47010d63b7dSRichard Lowe 		dmake_mode_type = serial_mode;
47110d63b7dSRichard Lowe 		no_parallel = true;
47210d63b7dSRichard Lowe 	}
47310d63b7dSRichard Lowe 
47410d63b7dSRichard Lowe 	/*
47510d63b7dSRichard Lowe 	 * Check whether stdout and stderr are physically same.
47610d63b7dSRichard Lowe 	 * This is in order to decide whether we need to redirect
47710d63b7dSRichard Lowe 	 * stderr separately from stdout.
47810d63b7dSRichard Lowe 	 * This check is performed only if __DMAKE_SEPARATE_STDERR
47910d63b7dSRichard Lowe 	 * is not set. This variable may be used in order to preserve
48010d63b7dSRichard Lowe 	 * the 'old' behaviour.
48110d63b7dSRichard Lowe 	 */
48210d63b7dSRichard Lowe 	out_err_same = true;
48310d63b7dSRichard Lowe 	char * dmake_sep_var = getenv("__DMAKE_SEPARATE_STDERR");
48410d63b7dSRichard Lowe 	if (dmake_sep_var == NULL || (0 != strcasecmp(dmake_sep_var, "NO"))) {
48510d63b7dSRichard Lowe 		struct stat stdout_stat;
48610d63b7dSRichard Lowe 		struct stat stderr_stat;
48710d63b7dSRichard Lowe 		if( (fstat(1, &stdout_stat) == 0)
48810d63b7dSRichard Lowe 		 && (fstat(2, &stderr_stat) == 0) )
48910d63b7dSRichard Lowe 		{
49010d63b7dSRichard Lowe 			if( (stdout_stat.st_dev != stderr_stat.st_dev)
49110d63b7dSRichard Lowe 			 || (stdout_stat.st_ino != stderr_stat.st_ino) )
49210d63b7dSRichard Lowe 			{
49310d63b7dSRichard Lowe 				out_err_same = false;
49410d63b7dSRichard Lowe 			}
49510d63b7dSRichard Lowe 		}
49610d63b7dSRichard Lowe 	}
49710d63b7dSRichard Lowe 
49810d63b7dSRichard Lowe 
49910d63b7dSRichard Lowe /*
50010d63b7dSRichard Lowe  *	Enable interrupt handler for alarms
50110d63b7dSRichard Lowe  */
50210d63b7dSRichard Lowe         (void) bsd_signal(SIGALRM, (SIG_PF)doalarm);
50310d63b7dSRichard Lowe 
50410d63b7dSRichard Lowe /*
50510d63b7dSRichard Lowe  *	Check if make should report
50610d63b7dSRichard Lowe  */
50710d63b7dSRichard Lowe 	if (getenv(sunpro_dependencies->string_mb) != NULL) {
50810d63b7dSRichard Lowe 		FILE	*report_file;
50910d63b7dSRichard Lowe 
51010d63b7dSRichard Lowe 		report_dependency("");
51110d63b7dSRichard Lowe 		report_file = get_report_file();
51210d63b7dSRichard Lowe 		if ((report_file != NULL) && (report_file != (FILE*)-1)) {
51310d63b7dSRichard Lowe 			(void) fprintf(report_file, "\n");
51410d63b7dSRichard Lowe 		}
51510d63b7dSRichard Lowe 	}
51610d63b7dSRichard Lowe 
51710d63b7dSRichard Lowe /*
51810d63b7dSRichard Lowe  *	Make sure SUNPRO_DEPENDENCIES is exported (or not) properly.
51910d63b7dSRichard Lowe  */
52010d63b7dSRichard Lowe 	if (keep_state) {
52110d63b7dSRichard Lowe 		maybe_append_prop(sunpro_dependencies, macro_prop)->
52210d63b7dSRichard Lowe 		  body.macro.exported = true;
52310d63b7dSRichard Lowe 	} else {
52410d63b7dSRichard Lowe 		maybe_append_prop(sunpro_dependencies, macro_prop)->
52510d63b7dSRichard Lowe 		  body.macro.exported = false;
52610d63b7dSRichard Lowe 	}
52710d63b7dSRichard Lowe 
52810d63b7dSRichard Lowe 	working_on_targets = true;
52910d63b7dSRichard Lowe 	if (trace_status) {
53010d63b7dSRichard Lowe 		dump_make_state();
53110d63b7dSRichard Lowe 		fclose(stdout);
53210d63b7dSRichard Lowe 		fclose(stderr);
53310d63b7dSRichard Lowe 		exit_status = 0;
53410d63b7dSRichard Lowe 		exit(0);
53510d63b7dSRichard Lowe 	}
53610d63b7dSRichard Lowe 	if (list_all_targets) {
53710d63b7dSRichard Lowe 		dump_target_list();
53810d63b7dSRichard Lowe 		fclose(stdout);
53910d63b7dSRichard Lowe 		fclose(stderr);
54010d63b7dSRichard Lowe 		exit_status = 0;
54110d63b7dSRichard Lowe 		exit(0);
54210d63b7dSRichard Lowe 	}
54310d63b7dSRichard Lowe 	trace_reader = false;
54410d63b7dSRichard Lowe 
54510d63b7dSRichard Lowe  	/*
54610d63b7dSRichard Lowe  	 * Set temp_file_directory to the directory the .make.state
54710d63b7dSRichard Lowe  	 * file is written to.
54810d63b7dSRichard Lowe  	 */
54910d63b7dSRichard Lowe  	if ((slash_ptr = strrchr(make_state->string_mb, (int) slash_char)) == NULL) {
55010d63b7dSRichard Lowe  		temp_file_directory = strdup(get_current_path());
55110d63b7dSRichard Lowe  	} else {
55210d63b7dSRichard Lowe  		*slash_ptr = (int) nul_char;
55310d63b7dSRichard Lowe  		(void) strcpy(make_state_dir, make_state->string_mb);
55410d63b7dSRichard Lowe  		*slash_ptr = (int) slash_char;
55510d63b7dSRichard Lowe 		   /* when there is only one slash and it's the first
55610d63b7dSRichard Lowe 		   ** character, make_state_dir should point to '/'.
55710d63b7dSRichard Lowe 		   */
55810d63b7dSRichard Lowe 		if(make_state_dir[0] == '\0') {
55910d63b7dSRichard Lowe 		   make_state_dir[0] = '/';
56010d63b7dSRichard Lowe 		   make_state_dir[1] = '\0';
56110d63b7dSRichard Lowe 		}
56210d63b7dSRichard Lowe  		if (make_state_dir[0] == (int) slash_char) {
56310d63b7dSRichard Lowe  			temp_file_directory = strdup(make_state_dir);
56410d63b7dSRichard Lowe  		} else {
56510d63b7dSRichard Lowe  			char	tmp_current_path2[MAXPATHLEN];
56610d63b7dSRichard Lowe 
56710d63b7dSRichard Lowe  			(void) sprintf(tmp_current_path2,
56810d63b7dSRichard Lowe  			               "%s/%s",
56910d63b7dSRichard Lowe  			               get_current_path(),
57010d63b7dSRichard Lowe  			               make_state_dir);
57110d63b7dSRichard Lowe  			temp_file_directory = strdup(tmp_current_path2);
57210d63b7dSRichard Lowe  		}
57310d63b7dSRichard Lowe  	}
57410d63b7dSRichard Lowe 
57510d63b7dSRichard Lowe 
57610d63b7dSRichard Lowe 	report_dir_enter_leave(true);
57710d63b7dSRichard Lowe 
57810d63b7dSRichard Lowe 	make_targets(argc, argv, parallel_flag);
57910d63b7dSRichard Lowe 
58010d63b7dSRichard Lowe 	report_dir_enter_leave(false);
58110d63b7dSRichard Lowe 
58210d63b7dSRichard Lowe 	if (build_failed_ever_seen) {
58310d63b7dSRichard Lowe 		if (posix) {
58410d63b7dSRichard Lowe 			exit_status = 1;
58510d63b7dSRichard Lowe 		}
58610d63b7dSRichard Lowe 		exit(1);
58710d63b7dSRichard Lowe 	}
58810d63b7dSRichard Lowe 	exit_status = 0;
58910d63b7dSRichard Lowe 	exit(0);
59010d63b7dSRichard Lowe 	/* NOTREACHED */
59110d63b7dSRichard Lowe }
59210d63b7dSRichard Lowe 
59310d63b7dSRichard Lowe /*
59410d63b7dSRichard Lowe  *	cleanup_after_exit()
59510d63b7dSRichard Lowe  *
59610d63b7dSRichard Lowe  *	Called from exit(), performs cleanup actions.
59710d63b7dSRichard Lowe  *
59810d63b7dSRichard Lowe  *	Parameters:
59910d63b7dSRichard Lowe  *		status		The argument exit() was called with
60010d63b7dSRichard Lowe  *		arg		Address of an argument vector to
60110d63b7dSRichard Lowe  *				cleanup_after_exit()
60210d63b7dSRichard Lowe  *
60310d63b7dSRichard Lowe  *	Global variables used:
60410d63b7dSRichard Lowe  *		command_changed	Set if we think .make.state should be rewritten
60510d63b7dSRichard Lowe  *		current_line	Is set we set commands_changed
60610d63b7dSRichard Lowe  *		do_not_exec_rule
60710d63b7dSRichard Lowe  *				True if -n flag on
60810d63b7dSRichard Lowe  *		done		The Name ".DONE", rule we run
60910d63b7dSRichard Lowe  *		keep_state	Set if .KEEP_STATE seen
61010d63b7dSRichard Lowe  *		parallel	True if building in parallel
61110d63b7dSRichard Lowe  *		quest		If -q is on we do not run .DONE
61210d63b7dSRichard Lowe  *		report_dependencies
61310d63b7dSRichard Lowe  *				True if -P flag on
61410d63b7dSRichard Lowe  *		running_list	List of parallel running processes
61510d63b7dSRichard Lowe  *		temp_file_name	The temp file is removed, if any
61610d63b7dSRichard Lowe  */
61710d63b7dSRichard Lowe extern "C" void
61810d63b7dSRichard Lowe cleanup_after_exit(void)
61910d63b7dSRichard Lowe {
62010d63b7dSRichard Lowe 	Running		rp;
62110d63b7dSRichard Lowe 
62210d63b7dSRichard Lowe extern long	getname_bytes_count;
62310d63b7dSRichard Lowe extern long	getname_names_count;
62410d63b7dSRichard Lowe extern long	getname_struct_count;
62510d63b7dSRichard Lowe extern long	freename_bytes_count;
62610d63b7dSRichard Lowe extern long	freename_names_count;
62710d63b7dSRichard Lowe extern long	freename_struct_count;
62810d63b7dSRichard Lowe extern long	other_alloc;
62910d63b7dSRichard Lowe 
63010d63b7dSRichard Lowe extern long	env_alloc_num;
63110d63b7dSRichard Lowe extern long	env_alloc_bytes;
63210d63b7dSRichard Lowe 
63310d63b7dSRichard Lowe 
63410d63b7dSRichard Lowe #ifdef DMAKE_STATISTICS
63510d63b7dSRichard Lowe if(getname_stat) {
63610d63b7dSRichard Lowe 	printf(">>> Getname statistics:\n");
63710d63b7dSRichard Lowe 	printf("  Allocated:\n");
63810d63b7dSRichard Lowe 	printf("        Names: %ld\n", getname_names_count);
63910d63b7dSRichard Lowe 	printf("      Strings: %ld Kb (%ld bytes)\n", getname_bytes_count/1000, getname_bytes_count);
64010d63b7dSRichard Lowe 	printf("      Structs: %ld Kb (%ld bytes)\n", getname_struct_count/1000, getname_struct_count);
64110d63b7dSRichard Lowe 	printf("  Total bytes: %ld Kb (%ld bytes)\n", getname_struct_count/1000 + getname_bytes_count/1000, getname_struct_count + getname_bytes_count);
64210d63b7dSRichard Lowe 
64310d63b7dSRichard Lowe 	printf("\n  Unallocated: %ld\n", freename_names_count);
64410d63b7dSRichard Lowe 	printf("        Names: %ld\n", freename_names_count);
64510d63b7dSRichard Lowe 	printf("      Strings: %ld Kb (%ld bytes)\n", freename_bytes_count/1000, freename_bytes_count);
64610d63b7dSRichard Lowe 	printf("      Structs: %ld Kb (%ld bytes)\n", freename_struct_count/1000, freename_struct_count);
64710d63b7dSRichard Lowe 	printf("  Total bytes: %ld Kb (%ld bytes)\n", freename_struct_count/1000 + freename_bytes_count/1000, freename_struct_count + freename_bytes_count);
64810d63b7dSRichard Lowe 
64910d63b7dSRichard Lowe 	printf("\n  Total used: %ld Kb (%ld bytes)\n", (getname_struct_count/1000 + getname_bytes_count/1000) - (freename_struct_count/1000 + freename_bytes_count/1000), (getname_struct_count + getname_bytes_count) - (freename_struct_count + freename_bytes_count));
65010d63b7dSRichard Lowe 
65110d63b7dSRichard Lowe 	printf("\n>>> Other:\n");
65210d63b7dSRichard Lowe 	printf(
65310d63b7dSRichard Lowe 		"       Env (%ld): %ld Kb (%ld bytes)\n",
65410d63b7dSRichard Lowe 		env_alloc_num,
65510d63b7dSRichard Lowe 		env_alloc_bytes/1000,
65610d63b7dSRichard Lowe 		env_alloc_bytes
65710d63b7dSRichard Lowe 	);
65810d63b7dSRichard Lowe 
65910d63b7dSRichard Lowe }
66010d63b7dSRichard Lowe #endif
66110d63b7dSRichard Lowe 
66210d63b7dSRichard Lowe 	parallel = false;
66310d63b7dSRichard Lowe 	/* If we used the SVR4_MAKE, don't build .DONE or .FAILED */
66410d63b7dSRichard Lowe 	if (!getenv(USE_SVR4_MAKE)){
66510d63b7dSRichard Lowe 	    /* Build the target .DONE or .FAILED if we caught an error */
66610d63b7dSRichard Lowe 	    if (!quest && !list_all_targets) {
66710d63b7dSRichard Lowe 		Name		failed_name;
66810d63b7dSRichard Lowe 
66910d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, ".FAILED");
67010d63b7dSRichard Lowe 		failed_name = GETNAME(wcs_buffer, FIND_LENGTH);
67110d63b7dSRichard Lowe 		if ((exit_status != 0) && (failed_name->prop != NULL)) {
67210d63b7dSRichard Lowe 			/*
67310d63b7dSRichard Lowe 			 * [tolik] switch DMake to serial mode
67410d63b7dSRichard Lowe 			 */
67510d63b7dSRichard Lowe 			dmake_mode_type = serial_mode;
67610d63b7dSRichard Lowe 			no_parallel = true;
67710d63b7dSRichard Lowe 			(void) doname(failed_name, false, true);
67810d63b7dSRichard Lowe 		} else {
67910d63b7dSRichard Lowe 		    if (!trace_status) {
68010d63b7dSRichard Lowe 			/*
68110d63b7dSRichard Lowe 			 * Switch DMake to serial mode
68210d63b7dSRichard Lowe 			 */
68310d63b7dSRichard Lowe 			dmake_mode_type = serial_mode;
68410d63b7dSRichard Lowe 			no_parallel = true;
68510d63b7dSRichard Lowe 			(void) doname(done, false, true);
68610d63b7dSRichard Lowe 		    }
68710d63b7dSRichard Lowe 		}
68810d63b7dSRichard Lowe 	    }
68910d63b7dSRichard Lowe 	}
69010d63b7dSRichard Lowe 	/*
69110d63b7dSRichard Lowe 	 * Remove the temp file utilities report dependencies thru if it
69210d63b7dSRichard Lowe 	 * is still around
69310d63b7dSRichard Lowe 	 */
69410d63b7dSRichard Lowe 	if (temp_file_name != NULL) {
69510d63b7dSRichard Lowe 		(void) unlink(temp_file_name->string_mb);
69610d63b7dSRichard Lowe 	}
69710d63b7dSRichard Lowe 	/*
69810d63b7dSRichard Lowe 	 * Do not save the current command in .make.state if make
69910d63b7dSRichard Lowe 	 * was interrupted.
70010d63b7dSRichard Lowe 	 */
70110d63b7dSRichard Lowe 	if (current_line != NULL) {
70210d63b7dSRichard Lowe 		command_changed = true;
70310d63b7dSRichard Lowe 		current_line->body.line.command_used = NULL;
70410d63b7dSRichard Lowe 	}
70510d63b7dSRichard Lowe 	/*
70610d63b7dSRichard Lowe 	 * For each parallel build process running, remove the temp files
70710d63b7dSRichard Lowe 	 * and zap the command line so it won't be put in .make.state
70810d63b7dSRichard Lowe 	 */
70910d63b7dSRichard Lowe 	for (rp = running_list; rp != NULL; rp = rp->next) {
71010d63b7dSRichard Lowe 		if (rp->temp_file != NULL) {
71110d63b7dSRichard Lowe 			(void) unlink(rp->temp_file->string_mb);
71210d63b7dSRichard Lowe 		}
71310d63b7dSRichard Lowe 		if (rp->stdout_file != NULL) {
71410d63b7dSRichard Lowe 			(void) unlink(rp->stdout_file);
71510d63b7dSRichard Lowe 			retmem_mb(rp->stdout_file);
71610d63b7dSRichard Lowe 			rp->stdout_file = NULL;
71710d63b7dSRichard Lowe 		}
71810d63b7dSRichard Lowe 		if (rp->stderr_file != NULL) {
71910d63b7dSRichard Lowe 			(void) unlink(rp->stderr_file);
72010d63b7dSRichard Lowe 			retmem_mb(rp->stderr_file);
72110d63b7dSRichard Lowe 			rp->stderr_file = NULL;
72210d63b7dSRichard Lowe 		}
72310d63b7dSRichard Lowe 		command_changed = true;
72410d63b7dSRichard Lowe /*
72510d63b7dSRichard Lowe 		line = get_prop(rp->target->prop, line_prop);
72610d63b7dSRichard Lowe 		if (line != NULL) {
72710d63b7dSRichard Lowe 			line->body.line.command_used = NULL;
72810d63b7dSRichard Lowe 		}
72910d63b7dSRichard Lowe  */
73010d63b7dSRichard Lowe 	}
73110d63b7dSRichard Lowe 	/* Remove the statefile lock file if the file has been locked */
73210d63b7dSRichard Lowe 	if ((make_state_lockfile != NULL) && (make_state_locked)) {
73310d63b7dSRichard Lowe 		(void) unlink(make_state_lockfile);
73410d63b7dSRichard Lowe 		make_state_lockfile = NULL;
73510d63b7dSRichard Lowe 		make_state_locked = false;
73610d63b7dSRichard Lowe 	}
73710d63b7dSRichard Lowe 	/* Write .make.state */
73810d63b7dSRichard Lowe 	write_state_file(1, (Boolean) 1);
73910d63b7dSRichard Lowe 
74010d63b7dSRichard Lowe 	job_adjust_fini();
74110d63b7dSRichard Lowe }
74210d63b7dSRichard Lowe 
74310d63b7dSRichard Lowe /*
74410d63b7dSRichard Lowe  *	handle_interrupt()
74510d63b7dSRichard Lowe  *
74610d63b7dSRichard Lowe  *	This is where C-C traps are caught.
74710d63b7dSRichard Lowe  *
74810d63b7dSRichard Lowe  *	Parameters:
74910d63b7dSRichard Lowe  *
75010d63b7dSRichard Lowe  *	Global variables used (except DMake 1.0):
75110d63b7dSRichard Lowe  *		current_target		Sometimes the current target is removed
75210d63b7dSRichard Lowe  *		do_not_exec_rule	But not if -n is on
75310d63b7dSRichard Lowe  *		quest			or -q
75410d63b7dSRichard Lowe  *		running_list		List of parallel running processes
75510d63b7dSRichard Lowe  *		touch			Current target is not removed if -t on
75610d63b7dSRichard Lowe  */
75710d63b7dSRichard Lowe void
75810d63b7dSRichard Lowe handle_interrupt(int)
75910d63b7dSRichard Lowe {
76010d63b7dSRichard Lowe 	Property		member;
76110d63b7dSRichard Lowe 	Running			rp;
76210d63b7dSRichard Lowe 
76310d63b7dSRichard Lowe 	(void) fflush(stdout);
76410d63b7dSRichard Lowe 	if (childPid > 0) {
76510d63b7dSRichard Lowe 		kill(childPid, SIGTERM);
76610d63b7dSRichard Lowe 		childPid = -1;
76710d63b7dSRichard Lowe 	}
76810d63b7dSRichard Lowe 	for (rp = running_list; rp != NULL; rp = rp->next) {
76910d63b7dSRichard Lowe 		if (rp->state != build_running) {
77010d63b7dSRichard Lowe 			continue;
77110d63b7dSRichard Lowe 		}
77210d63b7dSRichard Lowe 		if (rp->pid > 0) {
77310d63b7dSRichard Lowe 			kill(rp->pid, SIGTERM);
77410d63b7dSRichard Lowe 			rp->pid = -1;
77510d63b7dSRichard Lowe 		}
77610d63b7dSRichard Lowe 	}
77710d63b7dSRichard Lowe 	if (getpid() == getpgrp()) {
77810d63b7dSRichard Lowe 		bsd_signal(SIGTERM, SIG_IGN);
77910d63b7dSRichard Lowe 		kill (-getpid(), SIGTERM);
78010d63b7dSRichard Lowe 	}
78110d63b7dSRichard Lowe 	/* Clean up all parallel children already finished */
78210d63b7dSRichard Lowe         finish_children(false);
78310d63b7dSRichard Lowe 
78410d63b7dSRichard Lowe 	/* Make sure the processes running under us terminate first */
78510d63b7dSRichard Lowe 
78610d63b7dSRichard Lowe 	while (wait((int *) NULL) != -1);
78710d63b7dSRichard Lowe 	/* Delete the current targets unless they are precious */
78810d63b7dSRichard Lowe 	if ((current_target != NULL) &&
78910d63b7dSRichard Lowe 	    current_target->is_member &&
79010d63b7dSRichard Lowe 	    ((member = get_prop(current_target->prop, member_prop)) != NULL)) {
79110d63b7dSRichard Lowe 		current_target = member->body.member.library;
79210d63b7dSRichard Lowe 	}
79310d63b7dSRichard Lowe 	if (!do_not_exec_rule &&
79410d63b7dSRichard Lowe 	    !touch &&
79510d63b7dSRichard Lowe 	    !quest &&
79610d63b7dSRichard Lowe 	    (current_target != NULL) &&
79710d63b7dSRichard Lowe 	    !(current_target->stat.is_precious || all_precious)) {
79810d63b7dSRichard Lowe 
79910d63b7dSRichard Lowe /* BID_1030811 */
80010d63b7dSRichard Lowe /* azv 16 Oct 95 */
80110d63b7dSRichard Lowe 		current_target->stat.time = file_no_time;
80210d63b7dSRichard Lowe 
80310d63b7dSRichard Lowe 		if (exists(current_target) != file_doesnt_exist) {
80410d63b7dSRichard Lowe 			(void) fprintf(stderr,
80510d63b7dSRichard Lowe 				       "\n*** %s ",
80610d63b7dSRichard Lowe 				       current_target->string_mb);
80710d63b7dSRichard Lowe 			if (current_target->stat.is_dir) {
80810d63b7dSRichard Lowe 				(void) fprintf(stderr,
80910d63b7dSRichard Lowe 					       gettext("not removed.\n"),
81010d63b7dSRichard Lowe 					       current_target->string_mb);
81110d63b7dSRichard Lowe 			} else if (unlink(current_target->string_mb) == 0) {
81210d63b7dSRichard Lowe 				(void) fprintf(stderr,
81310d63b7dSRichard Lowe 					       gettext("removed.\n"),
81410d63b7dSRichard Lowe 					       current_target->string_mb);
81510d63b7dSRichard Lowe 			} else {
81610d63b7dSRichard Lowe 				(void) fprintf(stderr,
81710d63b7dSRichard Lowe 					       gettext("could not be removed: %s.\n"),
81810d63b7dSRichard Lowe 					       current_target->string_mb,
81910d63b7dSRichard Lowe 					       errmsg(errno));
82010d63b7dSRichard Lowe 			}
82110d63b7dSRichard Lowe 		}
82210d63b7dSRichard Lowe 	}
82310d63b7dSRichard Lowe 	for (rp = running_list; rp != NULL; rp = rp->next) {
82410d63b7dSRichard Lowe 		if (rp->state != build_running) {
82510d63b7dSRichard Lowe 			continue;
82610d63b7dSRichard Lowe 		}
82710d63b7dSRichard Lowe 		if (rp->target->is_member &&
82810d63b7dSRichard Lowe 		    ((member = get_prop(rp->target->prop, member_prop)) !=
82910d63b7dSRichard Lowe 		     NULL)) {
83010d63b7dSRichard Lowe 			rp->target = member->body.member.library;
83110d63b7dSRichard Lowe 		}
83210d63b7dSRichard Lowe 		if (!do_not_exec_rule &&
83310d63b7dSRichard Lowe 		    !touch &&
83410d63b7dSRichard Lowe 		    !quest &&
83510d63b7dSRichard Lowe 		    !(rp->target->stat.is_precious || all_precious)) {
83610d63b7dSRichard Lowe 
83710d63b7dSRichard Lowe 			rp->target->stat.time = file_no_time;
83810d63b7dSRichard Lowe 			if (exists(rp->target) != file_doesnt_exist) {
83910d63b7dSRichard Lowe 				(void) fprintf(stderr,
84010d63b7dSRichard Lowe 					       "\n*** %s ",
84110d63b7dSRichard Lowe 					       rp->target->string_mb);
84210d63b7dSRichard Lowe 				if (rp->target->stat.is_dir) {
84310d63b7dSRichard Lowe 					(void) fprintf(stderr,
84410d63b7dSRichard Lowe 						       gettext("not removed.\n"),
84510d63b7dSRichard Lowe 						       rp->target->string_mb);
84610d63b7dSRichard Lowe 				} else if (unlink(rp->target->string_mb) == 0) {
84710d63b7dSRichard Lowe 					(void) fprintf(stderr,
84810d63b7dSRichard Lowe 						       gettext("removed.\n"),
84910d63b7dSRichard Lowe 						       rp->target->string_mb);
85010d63b7dSRichard Lowe 				} else {
85110d63b7dSRichard Lowe 					(void) fprintf(stderr,
85210d63b7dSRichard Lowe 						       gettext("could not be removed: %s.\n"),
85310d63b7dSRichard Lowe 						       rp->target->string_mb,
85410d63b7dSRichard Lowe 						       errmsg(errno));
85510d63b7dSRichard Lowe 				}
85610d63b7dSRichard Lowe 			}
85710d63b7dSRichard Lowe 		}
85810d63b7dSRichard Lowe 	}
85910d63b7dSRichard Lowe 
86010d63b7dSRichard Lowe 
86110d63b7dSRichard Lowe 	/* Have we locked .make.state or .nse_depinfo? */
86210d63b7dSRichard Lowe 	if ((make_state_lockfile != NULL) && (make_state_locked)) {
86310d63b7dSRichard Lowe 		unlink(make_state_lockfile);
86410d63b7dSRichard Lowe 		make_state_lockfile = NULL;
86510d63b7dSRichard Lowe 		make_state_locked = false;
86610d63b7dSRichard Lowe 	}
86710d63b7dSRichard Lowe 	/*
86810d63b7dSRichard Lowe 	 * Re-read .make.state file (it might be changed by recursive make)
86910d63b7dSRichard Lowe 	 */
87010d63b7dSRichard Lowe 	check_state(NULL);
87110d63b7dSRichard Lowe 
87210d63b7dSRichard Lowe 	report_dir_enter_leave(false);
87310d63b7dSRichard Lowe 
87410d63b7dSRichard Lowe 	exit_status = 2;
87510d63b7dSRichard Lowe 	exit(2);
87610d63b7dSRichard Lowe }
87710d63b7dSRichard Lowe 
87810d63b7dSRichard Lowe /*
87910d63b7dSRichard Lowe  *	doalarm(sig, ...)
88010d63b7dSRichard Lowe  *
88110d63b7dSRichard Lowe  *	Handle the alarm interrupt but do nothing.  Side effect is to
88210d63b7dSRichard Lowe  *	cause return from wait3.
88310d63b7dSRichard Lowe  *
88410d63b7dSRichard Lowe  *	Parameters:
88510d63b7dSRichard Lowe  *		sig
88610d63b7dSRichard Lowe  *
88710d63b7dSRichard Lowe  *	Global variables used:
88810d63b7dSRichard Lowe  */
88910d63b7dSRichard Lowe /*ARGSUSED*/
89010d63b7dSRichard Lowe static void
89110d63b7dSRichard Lowe doalarm(int)
89210d63b7dSRichard Lowe {
89310d63b7dSRichard Lowe 	return;
89410d63b7dSRichard Lowe }
89510d63b7dSRichard Lowe 
89610d63b7dSRichard Lowe 
89710d63b7dSRichard Lowe /*
89810d63b7dSRichard Lowe  *	read_command_options(argc, argv)
89910d63b7dSRichard Lowe  *
90010d63b7dSRichard Lowe  *	Scan the cmd line options and process the ones that start with "-"
90110d63b7dSRichard Lowe  *
90210d63b7dSRichard Lowe  *	Return value:
90310d63b7dSRichard Lowe  *				-M argument, if any
90410d63b7dSRichard Lowe  *
90510d63b7dSRichard Lowe  *	Parameters:
90610d63b7dSRichard Lowe  *		argc		You know what this is
90710d63b7dSRichard Lowe  *		argv		You know what this is
90810d63b7dSRichard Lowe  *
90910d63b7dSRichard Lowe  *	Global variables used:
91010d63b7dSRichard Lowe  */
91110d63b7dSRichard Lowe static void
91210d63b7dSRichard Lowe read_command_options(register int argc, register char **argv)
91310d63b7dSRichard Lowe {
91410d63b7dSRichard Lowe 	register int		ch;
91510d63b7dSRichard Lowe 	int			current_optind = 1;
91610d63b7dSRichard Lowe 	int			last_optind_with_double_hyphen = 0;
91710d63b7dSRichard Lowe 	int			last_optind;
91810d63b7dSRichard Lowe 	int			last_current_optind;
91910d63b7dSRichard Lowe 	register int		i;
92010d63b7dSRichard Lowe 	register int		j;
92110d63b7dSRichard Lowe 	register int		k;
92210d63b7dSRichard Lowe 	register int		makefile_next = 0; /*
92310d63b7dSRichard Lowe 						    * flag to note options:
92410d63b7dSRichard Lowe 						    * -c, f, g, j, m, o
92510d63b7dSRichard Lowe 						    */
92610d63b7dSRichard Lowe 	const char		*tptr;
92710d63b7dSRichard Lowe 	const char		*CMD_OPTS;
92810d63b7dSRichard Lowe 
92910d63b7dSRichard Lowe 	extern char		*optarg;
93010d63b7dSRichard Lowe 	extern int		optind, opterr, optopt;
93110d63b7dSRichard Lowe 
93236cd0120SRobert Mustacchi #define SUNPRO_CMD_OPTS	"-~Bbc:C:Ddef:g:ij:K:kM:m:NnO:o:PpqRrSsTtuVvwx:"
93310d63b7dSRichard Lowe 
93436cd0120SRobert Mustacchi #	define SVR4_CMD_OPTS   "-c:C:ef:g:ij:km:nO:o:pqrsTtVv"
93510d63b7dSRichard Lowe 
93610d63b7dSRichard Lowe 	/*
93710d63b7dSRichard Lowe 	 * Added V in SVR4_CMD_OPTS also, which is going to be a hidden
93810d63b7dSRichard Lowe 	 * option, just to make sure that the getopt doesn't fail when some
93910d63b7dSRichard Lowe 	 * users leave their USE_SVR4_MAKE set and try to use the makefiles
94010d63b7dSRichard Lowe 	 * that are designed to issue commands like $(MAKE) -V. Anyway it
94110d63b7dSRichard Lowe 	 * sets the same flag but ensures that getopt doesn't fail.
94210d63b7dSRichard Lowe 	 */
94310d63b7dSRichard Lowe 
94410d63b7dSRichard Lowe 	opterr = 0;
94510d63b7dSRichard Lowe 	optind = 1;
94610d63b7dSRichard Lowe 	while (1) {
94710d63b7dSRichard Lowe 		last_optind=optind;			/* Save optind and current_optind values */
94810d63b7dSRichard Lowe 		last_current_optind=current_optind;	/* in case we have to repeat this round. */
94910d63b7dSRichard Lowe 		if (svr4) {
95010d63b7dSRichard Lowe 			CMD_OPTS=SVR4_CMD_OPTS;
95110d63b7dSRichard Lowe 			ch = getopt(argc, argv, SVR4_CMD_OPTS);
95210d63b7dSRichard Lowe 		} else {
95310d63b7dSRichard Lowe 			CMD_OPTS=SUNPRO_CMD_OPTS;
95410d63b7dSRichard Lowe 			ch = getopt(argc, argv, SUNPRO_CMD_OPTS);
95510d63b7dSRichard Lowe 		}
95610d63b7dSRichard Lowe 		if (ch == EOF) {
95710d63b7dSRichard Lowe 			if(optind < argc) {
95810d63b7dSRichard Lowe 				/*
95910d63b7dSRichard Lowe 				 * Fixing bug 4102537:
96010d63b7dSRichard Lowe 				 *    Strange behaviour of command make using -- option.
96110d63b7dSRichard Lowe 				 * Not all argv have been processed
96210d63b7dSRichard Lowe 				 * Skip non-flag argv and continue processing.
96310d63b7dSRichard Lowe 				 */
96410d63b7dSRichard Lowe 				optind++;
96510d63b7dSRichard Lowe 				current_optind++;
96610d63b7dSRichard Lowe 				continue;
96710d63b7dSRichard Lowe 			} else {
96810d63b7dSRichard Lowe 				break;
96910d63b7dSRichard Lowe 			}
97010d63b7dSRichard Lowe 
97110d63b7dSRichard Lowe 		}
97210d63b7dSRichard Lowe 		if (ch == '?') {
97310d63b7dSRichard Lowe 		 	if (optopt == '-') {
97410d63b7dSRichard Lowe 				/* Bug 5060758: getopt() changed behavior (s10_60),
97510d63b7dSRichard Lowe 				 * and now we have to deal with cases when options
97610d63b7dSRichard Lowe 				 * with double hyphen appear here, from -$(MAKEFLAGS)
97710d63b7dSRichard Lowe 				 */
97810d63b7dSRichard Lowe 				i = current_optind;
97910d63b7dSRichard Lowe 				if (argv[i][0] == '-') {
98010d63b7dSRichard Lowe 				  if (argv[i][1] == '-') {
98110d63b7dSRichard Lowe 				    if (argv[i][2] != '\0') {
98210d63b7dSRichard Lowe 				      /* Check if this option is allowed */
98310d63b7dSRichard Lowe 				      tptr = strchr(CMD_OPTS, argv[i][2]);
98410d63b7dSRichard Lowe 				      if (tptr) {
98510d63b7dSRichard Lowe 				        if (last_optind_with_double_hyphen != current_optind) {
98610d63b7dSRichard Lowe 				          /* This is first time we are trying to fix "--"
98710d63b7dSRichard Lowe 				           * problem with this option. If we come here second
98810d63b7dSRichard Lowe 				           * time, we will go to fatal error.
98910d63b7dSRichard Lowe 				           */
99010d63b7dSRichard Lowe 				          last_optind_with_double_hyphen = current_optind;
99110d63b7dSRichard Lowe 
99210d63b7dSRichard Lowe 				          /* Eliminate first hyphen character */
99310d63b7dSRichard Lowe 				          for (j=0; argv[i][j] != '\0'; j++) {
99410d63b7dSRichard Lowe 				            argv[i][j] = argv[i][j+1];
99510d63b7dSRichard Lowe 				          }
99610d63b7dSRichard Lowe 
99710d63b7dSRichard Lowe 				          /* Repeat the processing of this argument */
99810d63b7dSRichard Lowe 				          optind=last_optind;
99910d63b7dSRichard Lowe 				          current_optind=last_current_optind;
100010d63b7dSRichard Lowe 				          continue;
100110d63b7dSRichard Lowe 				        }
100210d63b7dSRichard Lowe 				      }
100310d63b7dSRichard Lowe 				    }
100410d63b7dSRichard Lowe 				  }
100510d63b7dSRichard Lowe 				}
100610d63b7dSRichard Lowe 			}
100710d63b7dSRichard Lowe 		}
100810d63b7dSRichard Lowe 
100910d63b7dSRichard Lowe 		if (ch == '?') {
101010d63b7dSRichard Lowe 			if (svr4) {
101110d63b7dSRichard Lowe 				fprintf(stderr,
101236cd0120SRobert Mustacchi 					gettext("Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ][-C directory]\n"));
101310d63b7dSRichard Lowe 				fprintf(stderr,
101410d63b7dSRichard Lowe 					gettext("              [ -j dmake_max_jobs ][ -m dmake_mode ][ -o dmake_odir ]...\n"));
101510d63b7dSRichard Lowe 				fprintf(stderr,
101610d63b7dSRichard Lowe 					gettext("              [ -e ][ -i ][ -k ][ -n ][ -p ][ -q ][ -r ][ -s ][ -t ][ -v ]\n"));
101710d63b7dSRichard Lowe 				tptr = strchr(SVR4_CMD_OPTS, optopt);
101810d63b7dSRichard Lowe 			} else {
101910d63b7dSRichard Lowe 				fprintf(stderr,
102036cd0120SRobert Mustacchi 					gettext("Usage : dmake [ -f makefile ][ -c dmake_rcfile ][ -g dmake_group ][-C directory]\n"));
102110d63b7dSRichard Lowe 				fprintf(stderr,
102210d63b7dSRichard Lowe 					gettext("              [ -j dmake_max_jobs ][ -K statefile ][ -m dmake_mode ][ -x MODE_NAME=VALUE ][ -o dmake_odir ]...\n"));
102310d63b7dSRichard Lowe 				fprintf(stderr,
102410d63b7dSRichard Lowe 					gettext("              [ -d ][ -dd ][ -D ][ -DD ][ -e ][ -i ][ -k ][ -n ][ -p ][ -P ][ -u ][ -w ]\n"));
102510d63b7dSRichard Lowe 				fprintf(stderr,
102610d63b7dSRichard Lowe 					gettext("              [ -q ][ -r ][ -s ][ -S ][ -t ][ -v ][ -V ][ target... ][ macro=value... ][ \"macro +=value\"... ]\n"));
102710d63b7dSRichard Lowe 				tptr = strchr(SUNPRO_CMD_OPTS, optopt);
102810d63b7dSRichard Lowe 			}
102910d63b7dSRichard Lowe 			if (!tptr) {
103010d63b7dSRichard Lowe 				fatal(gettext("Unknown option `-%c'"), optopt);
103110d63b7dSRichard Lowe 			} else {
103210d63b7dSRichard Lowe 				fatal(gettext("Missing argument after `-%c'"), optopt);
103310d63b7dSRichard Lowe 			}
103410d63b7dSRichard Lowe 		}
103510d63b7dSRichard Lowe 
103610d63b7dSRichard Lowe 
103710d63b7dSRichard Lowe 
103810d63b7dSRichard Lowe 		makefile_next |= parse_command_option(ch);
103910d63b7dSRichard Lowe 		/*
104010d63b7dSRichard Lowe 		 * If we're done processing all of the options of
104110d63b7dSRichard Lowe 		 * ONE argument string...
104210d63b7dSRichard Lowe 		 */
104310d63b7dSRichard Lowe 		if (current_optind < optind) {
104410d63b7dSRichard Lowe 			i = current_optind;
104510d63b7dSRichard Lowe 			k = 0;
104610d63b7dSRichard Lowe 			/* If there's an argument for an option... */
104710d63b7dSRichard Lowe 			if ((optind - current_optind) > 1) {
104810d63b7dSRichard Lowe 				k = i + 1;
104910d63b7dSRichard Lowe 			}
105010d63b7dSRichard Lowe 			switch (makefile_next) {
105110d63b7dSRichard Lowe 			case 0:
105210d63b7dSRichard Lowe 				argv[i] = NULL;
105310d63b7dSRichard Lowe 				/* This shouldn't happen */
105410d63b7dSRichard Lowe 				if (k) {
105510d63b7dSRichard Lowe 					argv[k] = NULL;
105610d63b7dSRichard Lowe 				}
105710d63b7dSRichard Lowe 				break;
105810d63b7dSRichard Lowe 			case 1:	/* -f seen */
105910d63b7dSRichard Lowe 				argv[i] = (char *)"-f";
106010d63b7dSRichard Lowe 				break;
106110d63b7dSRichard Lowe 			case 2:	/* -c seen */
106210d63b7dSRichard Lowe 				argv[i] = (char *)"-c";
106310d63b7dSRichard Lowe 				break;
106410d63b7dSRichard Lowe 			case 4:	/* -g seen */
106510d63b7dSRichard Lowe 				argv[i] = (char *)"-g";
106610d63b7dSRichard Lowe 				break;
106710d63b7dSRichard Lowe 			case 8:	/* -j seen */
106810d63b7dSRichard Lowe 				argv[i] = (char *)"-j";
106910d63b7dSRichard Lowe 				break;
107010d63b7dSRichard Lowe 			case 16: /* -M seen */
107110d63b7dSRichard Lowe 				argv[i] = (char *)"-M";
107210d63b7dSRichard Lowe 				break;
107310d63b7dSRichard Lowe 			case 32: /* -m seen */
107410d63b7dSRichard Lowe 				argv[i] = (char *)"-m";
107510d63b7dSRichard Lowe 				break;
107610d63b7dSRichard Lowe 			case 128: /* -O seen */
107710d63b7dSRichard Lowe 				argv[i] = (char *)"-O";
107810d63b7dSRichard Lowe 				break;
107910d63b7dSRichard Lowe 			case 256: /* -K seen */
108010d63b7dSRichard Lowe 				argv[i] = (char *)"-K";
108110d63b7dSRichard Lowe 			        break;
108210d63b7dSRichard Lowe 			case 512:	/* -o seen */
108310d63b7dSRichard Lowe 				argv[i] = (char *)"-o";
108410d63b7dSRichard Lowe 				break;
108510d63b7dSRichard Lowe 			case 1024: /* -x seen */
108610d63b7dSRichard Lowe 				argv[i] = (char *)"-x";
108710d63b7dSRichard Lowe 				break;
108836cd0120SRobert Mustacchi 			case 2048:
108936cd0120SRobert Mustacchi 				argv[i] = (char *)"-C";
109036cd0120SRobert Mustacchi 				break;
109110d63b7dSRichard Lowe 			default: /* > 1 of -c, f, g, j, K, M, m, O, o, x seen */
109210d63b7dSRichard Lowe 				fatal(gettext("Illegal command line. More than one option requiring\nan argument given in the same argument group"));
109310d63b7dSRichard Lowe 			}
109410d63b7dSRichard Lowe 
109510d63b7dSRichard Lowe 			makefile_next = 0;
109610d63b7dSRichard Lowe 			current_optind = optind;
109710d63b7dSRichard Lowe 		}
109810d63b7dSRichard Lowe 	}
109910d63b7dSRichard Lowe }
110010d63b7dSRichard Lowe 
110110d63b7dSRichard Lowe static void
110210d63b7dSRichard Lowe quote_str(char *str, char *qstr)
110310d63b7dSRichard Lowe {
110410d63b7dSRichard Lowe 	char		*to;
110510d63b7dSRichard Lowe 	char		*from;
110610d63b7dSRichard Lowe 
110710d63b7dSRichard Lowe 	to = qstr;
110810d63b7dSRichard Lowe 	for (from = str; *from; from++) {
110910d63b7dSRichard Lowe 		switch (*from) {
111010d63b7dSRichard Lowe 		case ';':	/* End of command */
111110d63b7dSRichard Lowe 		case '(':	/* Start group */
111210d63b7dSRichard Lowe 		case ')':	/* End group */
111310d63b7dSRichard Lowe 		case '{':	/* Start group */
111410d63b7dSRichard Lowe 		case '}':	/* End group */
111510d63b7dSRichard Lowe 		case '[':	/* Reg expr - any of a set of chars */
111610d63b7dSRichard Lowe 		case ']':	/* End of set of chars */
111710d63b7dSRichard Lowe 		case '|':	/* Pipe or logical-or */
111810d63b7dSRichard Lowe 		case '^':	/* Old-fashioned pipe */
111910d63b7dSRichard Lowe 		case '&':	/* Background or logical-and */
112010d63b7dSRichard Lowe 		case '<':	/* Redirect stdin */
112110d63b7dSRichard Lowe 		case '>':	/* Redirect stdout */
112210d63b7dSRichard Lowe 		case '*':	/* Reg expr - any sequence of chars */
112310d63b7dSRichard Lowe 		case '?':	/* Reg expr - any single char */
112410d63b7dSRichard Lowe 		case '$':	/* Variable substitution */
112510d63b7dSRichard Lowe 		case '\'':	/* Singe quote - turn off all magic */
112610d63b7dSRichard Lowe 		case '"':	/* Double quote - span whitespace */
112710d63b7dSRichard Lowe 		case '`':	/* Backquote - run a command */
112810d63b7dSRichard Lowe 		case '#':	/* Comment */
112910d63b7dSRichard Lowe 		case ' ':	/* Space (for MACRO=value1 value2  */
113010d63b7dSRichard Lowe 		case '\\':	/* Escape char - turn off magic of next char */
113110d63b7dSRichard Lowe 			*to++ = '\\';
113210d63b7dSRichard Lowe 			break;
113310d63b7dSRichard Lowe 
113410d63b7dSRichard Lowe 		default:
113510d63b7dSRichard Lowe 			break;
113610d63b7dSRichard Lowe 		}
113710d63b7dSRichard Lowe 		*to++ = *from;
113810d63b7dSRichard Lowe 	}
113910d63b7dSRichard Lowe 	*to = '\0';
114010d63b7dSRichard Lowe }
114110d63b7dSRichard Lowe 
114210d63b7dSRichard Lowe static void
114310d63b7dSRichard Lowe unquote_str(char *str, char *qstr)
114410d63b7dSRichard Lowe {
114510d63b7dSRichard Lowe 	char		*to;
114610d63b7dSRichard Lowe 	char		*from;
114710d63b7dSRichard Lowe 
114810d63b7dSRichard Lowe 	to = qstr;
114910d63b7dSRichard Lowe 	for (from = str; *from; from++) {
115010d63b7dSRichard Lowe 		if (*from == '\\') {
115110d63b7dSRichard Lowe 			from++;
115210d63b7dSRichard Lowe 		}
115310d63b7dSRichard Lowe 		*to++ = *from;
115410d63b7dSRichard Lowe 	}
115510d63b7dSRichard Lowe 	*to = '\0';
115610d63b7dSRichard Lowe }
115710d63b7dSRichard Lowe 
115810d63b7dSRichard Lowe /*
115910d63b7dSRichard Lowe  * Convert the MAKEFLAGS string value into a vector of char *, similar
116010d63b7dSRichard Lowe  * to argv.
116110d63b7dSRichard Lowe  */
116210d63b7dSRichard Lowe static void
116310d63b7dSRichard Lowe setup_makeflags_argv()
116410d63b7dSRichard Lowe {
116510d63b7dSRichard Lowe 	char		*cp;
116610d63b7dSRichard Lowe 	char		*cp1;
116710d63b7dSRichard Lowe 	char		*cp2;
116810d63b7dSRichard Lowe 	char		*cp3;
116910d63b7dSRichard Lowe 	char		*cp_orig;
117010d63b7dSRichard Lowe 	Boolean		add_hyphen;
117110d63b7dSRichard Lowe 	int		i;
117210d63b7dSRichard Lowe 	char		tmp_char;
117310d63b7dSRichard Lowe 
117410d63b7dSRichard Lowe 	mf_argc = 1;
117510d63b7dSRichard Lowe 	cp = getenv(makeflags->string_mb);
117610d63b7dSRichard Lowe 	cp_orig = cp;
117710d63b7dSRichard Lowe 
117810d63b7dSRichard Lowe 	if (cp) {
117910d63b7dSRichard Lowe 		/*
118010d63b7dSRichard Lowe 		 * If new MAKEFLAGS format, no need to add hyphen.
118110d63b7dSRichard Lowe 		 * If old MAKEFLAGS format, add hyphen before flags.
118210d63b7dSRichard Lowe 		 */
118310d63b7dSRichard Lowe 
118410d63b7dSRichard Lowe 		if ((strchr(cp, (int) hyphen_char) != NULL) ||
118510d63b7dSRichard Lowe 		    (strchr(cp, (int) equal_char) != NULL)) {
118610d63b7dSRichard Lowe 
118710d63b7dSRichard Lowe 			/* New MAKEFLAGS format */
118810d63b7dSRichard Lowe 
118910d63b7dSRichard Lowe 			add_hyphen = false;
119010d63b7dSRichard Lowe 
119110d63b7dSRichard Lowe 			/* Check if MAKEFLAGS value begins with multiple
119210d63b7dSRichard Lowe 			 * hyphen characters, and remove all duplicates.
119310d63b7dSRichard Lowe 			 * Usually it happens when the next command is
119410d63b7dSRichard Lowe 			 * used: $(MAKE) -$(MAKEFLAGS)
119510d63b7dSRichard Lowe 			 *
119610d63b7dSRichard Lowe 			 * This was a workaround for BugID 5060758, but
119710d63b7dSRichard Lowe 			 * appears to have survived as a fix in make.
119810d63b7dSRichard Lowe 			 */
119910d63b7dSRichard Lowe 			while (*cp) {
120010d63b7dSRichard Lowe 				if (*cp != (int) hyphen_char) {
120110d63b7dSRichard Lowe 					break;
120210d63b7dSRichard Lowe 				}
120310d63b7dSRichard Lowe 				cp++;
120410d63b7dSRichard Lowe 				if (*cp == (int) hyphen_char) {
120510d63b7dSRichard Lowe 					/* There are two hyphens. Skip one */
120610d63b7dSRichard Lowe 					cp_orig = cp;
120710d63b7dSRichard Lowe 					cp++;
120810d63b7dSRichard Lowe 				}
120910d63b7dSRichard Lowe 				if (!(*cp)) {
121010d63b7dSRichard Lowe 					/* There are hyphens only. Skip all */
121110d63b7dSRichard Lowe 					cp_orig = cp;
121210d63b7dSRichard Lowe 					break;
121310d63b7dSRichard Lowe 				}
121410d63b7dSRichard Lowe 			}
121510d63b7dSRichard Lowe 		} else {
121610d63b7dSRichard Lowe 
121710d63b7dSRichard Lowe 			/* Old MAKEFLAGS format */
121810d63b7dSRichard Lowe 
121910d63b7dSRichard Lowe 			add_hyphen = true;
122010d63b7dSRichard Lowe 		}
122110d63b7dSRichard Lowe 	}
122210d63b7dSRichard Lowe 
122310d63b7dSRichard Lowe 	/* Find the number of arguments in MAKEFLAGS */
122410d63b7dSRichard Lowe 	while (cp && *cp) {
122510d63b7dSRichard Lowe 		/* Skip white spaces */
122610d63b7dSRichard Lowe 		while (cp && *cp && isspace(*cp)) {
122710d63b7dSRichard Lowe 			cp++;
122810d63b7dSRichard Lowe 		}
122910d63b7dSRichard Lowe 		if (cp && *cp) {
123010d63b7dSRichard Lowe 			/* Increment arg count */
123110d63b7dSRichard Lowe 			mf_argc++;
123210d63b7dSRichard Lowe 			/* Go to next white space */
123310d63b7dSRichard Lowe 			while (cp && *cp && !isspace(*cp)) {
123410d63b7dSRichard Lowe 				if(*cp == (int) backslash_char) {
123510d63b7dSRichard Lowe 					cp++;
123610d63b7dSRichard Lowe 				}
123710d63b7dSRichard Lowe 				cp++;
123810d63b7dSRichard Lowe 			}
123910d63b7dSRichard Lowe 		}
124010d63b7dSRichard Lowe 	}
124110d63b7dSRichard Lowe 	/* Allocate memory for the new MAKEFLAGS argv */
124210d63b7dSRichard Lowe 	mf_argv = (char **) malloc((mf_argc + 1) * sizeof(char *));
124310d63b7dSRichard Lowe 	mf_argv[0] = (char *)"MAKEFLAGS";
124410d63b7dSRichard Lowe 	/*
124510d63b7dSRichard Lowe 	 * Convert the MAKEFLAGS string value into a vector of char *,
124610d63b7dSRichard Lowe 	 * similar to argv.
124710d63b7dSRichard Lowe 	 */
124810d63b7dSRichard Lowe 	cp = cp_orig;
124910d63b7dSRichard Lowe 	for (i = 1; i < mf_argc; i++) {
125010d63b7dSRichard Lowe 		/* Skip white spaces */
125110d63b7dSRichard Lowe 		while (cp && *cp && isspace(*cp)) {
125210d63b7dSRichard Lowe 			cp++;
125310d63b7dSRichard Lowe 		}
125410d63b7dSRichard Lowe 		if (cp && *cp) {
125510d63b7dSRichard Lowe 			cp_orig = cp;
125610d63b7dSRichard Lowe 			/* Go to next white space */
125710d63b7dSRichard Lowe 			while (cp && *cp && !isspace(*cp)) {
125810d63b7dSRichard Lowe 				if(*cp == (int) backslash_char) {
125910d63b7dSRichard Lowe 					cp++;
126010d63b7dSRichard Lowe 				}
126110d63b7dSRichard Lowe 				cp++;
126210d63b7dSRichard Lowe 			}
126310d63b7dSRichard Lowe 			tmp_char = *cp;
126410d63b7dSRichard Lowe 			*cp = (int) nul_char;
126510d63b7dSRichard Lowe 			if (add_hyphen) {
126610d63b7dSRichard Lowe 				mf_argv[i] = getmem(2 + strlen(cp_orig));
126710d63b7dSRichard Lowe 				mf_argv[i][0] = '\0';
126810d63b7dSRichard Lowe 				(void) strcat(mf_argv[i], "-");
126910d63b7dSRichard Lowe 				// (void) strcat(mf_argv[i], cp_orig);
127010d63b7dSRichard Lowe 				unquote_str(cp_orig, mf_argv[i]+1);
127110d63b7dSRichard Lowe 			} else {
127210d63b7dSRichard Lowe 				mf_argv[i] = getmem(2 + strlen(cp_orig));
127310d63b7dSRichard Lowe 				//mf_argv[i] = strdup(cp_orig);
127410d63b7dSRichard Lowe 				unquote_str(cp_orig, mf_argv[i]);
127510d63b7dSRichard Lowe 			}
127610d63b7dSRichard Lowe 			*cp = tmp_char;
127710d63b7dSRichard Lowe 		}
127810d63b7dSRichard Lowe 	}
127910d63b7dSRichard Lowe 	mf_argv[i] = NULL;
128010d63b7dSRichard Lowe }
128110d63b7dSRichard Lowe 
128210d63b7dSRichard Lowe /*
128310d63b7dSRichard Lowe  *	parse_command_option(ch)
128410d63b7dSRichard Lowe  *
128510d63b7dSRichard Lowe  *	Parse make command line options.
128610d63b7dSRichard Lowe  *
128710d63b7dSRichard Lowe  *	Return value:
128810d63b7dSRichard Lowe  *				Indicates if any -f -c or -M were seen
128910d63b7dSRichard Lowe  *
129010d63b7dSRichard Lowe  *	Parameters:
129110d63b7dSRichard Lowe  *		ch		The character to parse
129210d63b7dSRichard Lowe  *
129310d63b7dSRichard Lowe  *	Static variables used:
129410d63b7dSRichard Lowe  *		dmake_group_specified	Set for make -g
129510d63b7dSRichard Lowe  *		dmake_max_jobs_specified	Set for make -j
129610d63b7dSRichard Lowe  *		dmake_mode_specified	Set for make -m
129710d63b7dSRichard Lowe  *		dmake_add_mode_specified	Set for make -x
129810d63b7dSRichard Lowe  *		dmake_compat_mode_specified	Set for make -x SUN_MAKE_COMPAT_MODE=
129910d63b7dSRichard Lowe  *		dmake_output_mode_specified	Set for make -x DMAKE_OUTPUT_MODE=
130010d63b7dSRichard Lowe  *		dmake_odir_specified	Set for make -o
130110d63b7dSRichard Lowe  *		dmake_rcfile_specified	Set for make -c
130210d63b7dSRichard Lowe  *		env_wins		Set for make -e
130310d63b7dSRichard Lowe  *		ignore_default_mk	Set for make -r
130410d63b7dSRichard Lowe  *		trace_status		Set for make -p
130510d63b7dSRichard Lowe  *
130610d63b7dSRichard Lowe  *	Global variables used:
130710d63b7dSRichard Lowe  *		.make.state path & name set for make -K
130810d63b7dSRichard Lowe  *		continue_after_error	Set for make -k
130910d63b7dSRichard Lowe  *		debug_level		Set for make -d
131010d63b7dSRichard Lowe  *		do_not_exec_rule	Set for make -n
131110d63b7dSRichard Lowe  *		filter_stderr		Set for make -X
131210d63b7dSRichard Lowe  *		ignore_errors_all	Set for make -i
131310d63b7dSRichard Lowe  *		no_parallel		Set for make -R
131410d63b7dSRichard Lowe  *		quest			Set for make -q
131510d63b7dSRichard Lowe  *		read_trace_level	Set for make -D
131610d63b7dSRichard Lowe  *		report_dependencies	Set for make -P
131710d63b7dSRichard Lowe  *		silent_all		Set for make -s
131810d63b7dSRichard Lowe  *		touch			Set for make -t
131910d63b7dSRichard Lowe  */
132010d63b7dSRichard Lowe static int
132110d63b7dSRichard Lowe parse_command_option(register char ch)
132210d63b7dSRichard Lowe {
132310d63b7dSRichard Lowe 	static int		invert_next = 0;
132410d63b7dSRichard Lowe 	int			invert_this = invert_next;
132510d63b7dSRichard Lowe 
132610d63b7dSRichard Lowe 	invert_next = 0;
132710d63b7dSRichard Lowe 	switch (ch) {
132810d63b7dSRichard Lowe 	case '-':			 /* Ignore "--" */
132910d63b7dSRichard Lowe 		return 0;
133010d63b7dSRichard Lowe 	case '~':			 /* Invert next option */
133110d63b7dSRichard Lowe 		invert_next = 1;
133210d63b7dSRichard Lowe 		return 0;
133310d63b7dSRichard Lowe 	case 'B':			 /* Obsolete */
133410d63b7dSRichard Lowe 		return 0;
133510d63b7dSRichard Lowe 	case 'b':			 /* Obsolete */
133610d63b7dSRichard Lowe 		return 0;
133710d63b7dSRichard Lowe 	case 'c':			 /* Read alternative dmakerc file */
133810d63b7dSRichard Lowe 		if (invert_this) {
133910d63b7dSRichard Lowe 			dmake_rcfile_specified = false;
134010d63b7dSRichard Lowe 		} else {
134110d63b7dSRichard Lowe 			dmake_rcfile_specified = true;
134210d63b7dSRichard Lowe 		}
134310d63b7dSRichard Lowe 		return 2;
134436cd0120SRobert Mustacchi 	case 'C':			/* Change directory */
134536cd0120SRobert Mustacchi 		return 2048;
134610d63b7dSRichard Lowe 	case 'D':			 /* Show lines read */
134710d63b7dSRichard Lowe 		if (invert_this) {
134810d63b7dSRichard Lowe 			read_trace_level--;
134910d63b7dSRichard Lowe 		} else {
135010d63b7dSRichard Lowe 			read_trace_level++;
135110d63b7dSRichard Lowe 		}
135210d63b7dSRichard Lowe 		return 0;
135310d63b7dSRichard Lowe 	case 'd':			 /* Debug flag */
135410d63b7dSRichard Lowe 		if (invert_this) {
135510d63b7dSRichard Lowe 			debug_level--;
135610d63b7dSRichard Lowe 		} else {
135710d63b7dSRichard Lowe 			debug_level++;
135810d63b7dSRichard Lowe 		}
135910d63b7dSRichard Lowe 		return 0;
136010d63b7dSRichard Lowe 	case 'e':			 /* Environment override flag */
136110d63b7dSRichard Lowe 		if (invert_this) {
136210d63b7dSRichard Lowe 			env_wins = false;
136310d63b7dSRichard Lowe 		} else {
136410d63b7dSRichard Lowe 			env_wins = true;
136510d63b7dSRichard Lowe 		}
136610d63b7dSRichard Lowe 		return 0;
136710d63b7dSRichard Lowe 	case 'f':			 /* Read alternative makefile(s) */
136810d63b7dSRichard Lowe 		return 1;
136910d63b7dSRichard Lowe 	case 'g':			 /* Use alternative DMake group */
137010d63b7dSRichard Lowe 		if (invert_this) {
137110d63b7dSRichard Lowe 			dmake_group_specified = false;
137210d63b7dSRichard Lowe 		} else {
137310d63b7dSRichard Lowe 			dmake_group_specified = true;
137410d63b7dSRichard Lowe 		}
137510d63b7dSRichard Lowe 		return 4;
137610d63b7dSRichard Lowe 	case 'i':			 /* Ignore errors */
137710d63b7dSRichard Lowe 		if (invert_this) {
137810d63b7dSRichard Lowe 			ignore_errors_all = false;
137910d63b7dSRichard Lowe 		} else {
138010d63b7dSRichard Lowe 			ignore_errors_all = true;
138110d63b7dSRichard Lowe 		}
138210d63b7dSRichard Lowe 		return 0;
138310d63b7dSRichard Lowe 	case 'j':			 /* Use alternative DMake max jobs */
138410d63b7dSRichard Lowe 		if (invert_this) {
138510d63b7dSRichard Lowe 			dmake_max_jobs_specified = false;
138610d63b7dSRichard Lowe 		} else {
138710d63b7dSRichard Lowe 			dmake_mode_type = parallel_mode;
138810d63b7dSRichard Lowe 			no_parallel = false;
138910d63b7dSRichard Lowe 			dmake_max_jobs_specified = true;
139010d63b7dSRichard Lowe 		}
139110d63b7dSRichard Lowe 		return 8;
139210d63b7dSRichard Lowe 	case 'K':			 /* Read alternative .make.state */
139310d63b7dSRichard Lowe 		return 256;
139410d63b7dSRichard Lowe 	case 'k':			 /* Keep making even after errors */
139510d63b7dSRichard Lowe 		if (invert_this) {
139610d63b7dSRichard Lowe 			continue_after_error = false;
139710d63b7dSRichard Lowe 		} else {
139810d63b7dSRichard Lowe 			continue_after_error = true;
139910d63b7dSRichard Lowe 			continue_after_error_ever_seen = true;
140010d63b7dSRichard Lowe 		}
140110d63b7dSRichard Lowe 		return 0;
140210d63b7dSRichard Lowe 	case 'M':			 /* Read alternative make.machines file */
140310d63b7dSRichard Lowe 		if (invert_this) {
140410d63b7dSRichard Lowe 			pmake_machinesfile_specified = false;
140510d63b7dSRichard Lowe 		} else {
140610d63b7dSRichard Lowe 			pmake_machinesfile_specified = true;
140710d63b7dSRichard Lowe 			dmake_mode_type = parallel_mode;
140810d63b7dSRichard Lowe 			no_parallel = false;
140910d63b7dSRichard Lowe 		}
141010d63b7dSRichard Lowe 		return 16;
141110d63b7dSRichard Lowe 	case 'm':			 /* Use alternative DMake build mode */
141210d63b7dSRichard Lowe 		if (invert_this) {
141310d63b7dSRichard Lowe 			dmake_mode_specified = false;
141410d63b7dSRichard Lowe 		} else {
141510d63b7dSRichard Lowe 			dmake_mode_specified = true;
141610d63b7dSRichard Lowe 		}
141710d63b7dSRichard Lowe 		return 32;
141810d63b7dSRichard Lowe 	case 'x':			 /* Use alternative DMake mode */
141910d63b7dSRichard Lowe 		if (invert_this) {
142010d63b7dSRichard Lowe 			dmake_add_mode_specified = false;
142110d63b7dSRichard Lowe 		} else {
142210d63b7dSRichard Lowe 			dmake_add_mode_specified = true;
142310d63b7dSRichard Lowe 		}
142410d63b7dSRichard Lowe 		return 1024;
142510d63b7dSRichard Lowe 	case 'N':			 /* Reverse -n */
142610d63b7dSRichard Lowe 		if (invert_this) {
142710d63b7dSRichard Lowe 			do_not_exec_rule = true;
142810d63b7dSRichard Lowe 		} else {
142910d63b7dSRichard Lowe 			do_not_exec_rule = false;
143010d63b7dSRichard Lowe 		}
143110d63b7dSRichard Lowe 		return 0;
143210d63b7dSRichard Lowe 	case 'n':			 /* Print, not exec commands */
143310d63b7dSRichard Lowe 		if (invert_this) {
143410d63b7dSRichard Lowe 			do_not_exec_rule = false;
143510d63b7dSRichard Lowe 		} else {
143610d63b7dSRichard Lowe 			do_not_exec_rule = true;
143710d63b7dSRichard Lowe 		}
143810d63b7dSRichard Lowe 		return 0;
143910d63b7dSRichard Lowe 	case 'O':			 /* Integrate with maketool, obsolete */
144010d63b7dSRichard Lowe 		return 0;
144110d63b7dSRichard Lowe 	case 'o':			 /* Use alternative dmake output dir */
144210d63b7dSRichard Lowe 		if (invert_this) {
144310d63b7dSRichard Lowe 			dmake_odir_specified = false;
144410d63b7dSRichard Lowe 		} else {
144510d63b7dSRichard Lowe 			dmake_odir_specified = true;
144610d63b7dSRichard Lowe 		}
144710d63b7dSRichard Lowe 		return 512;
144810d63b7dSRichard Lowe 	case 'P':			 /* Print for selected targets */
144910d63b7dSRichard Lowe 		if (invert_this) {
145010d63b7dSRichard Lowe 			report_dependencies_level--;
145110d63b7dSRichard Lowe 		} else {
145210d63b7dSRichard Lowe 			report_dependencies_level++;
145310d63b7dSRichard Lowe 		}
145410d63b7dSRichard Lowe 		return 0;
145510d63b7dSRichard Lowe 	case 'p':			 /* Print description */
145610d63b7dSRichard Lowe 		if (invert_this) {
145710d63b7dSRichard Lowe 			trace_status = false;
145810d63b7dSRichard Lowe 			do_not_exec_rule = false;
145910d63b7dSRichard Lowe 		} else {
146010d63b7dSRichard Lowe 			trace_status = true;
146110d63b7dSRichard Lowe 			do_not_exec_rule = true;
146210d63b7dSRichard Lowe 		}
146310d63b7dSRichard Lowe 		return 0;
146410d63b7dSRichard Lowe 	case 'q':			 /* Question flag */
146510d63b7dSRichard Lowe 		if (invert_this) {
146610d63b7dSRichard Lowe 			quest = false;
146710d63b7dSRichard Lowe 		} else {
146810d63b7dSRichard Lowe 			quest = true;
146910d63b7dSRichard Lowe 		}
147010d63b7dSRichard Lowe 		return 0;
147110d63b7dSRichard Lowe 	case 'R':			 /* Don't run in parallel */
147210d63b7dSRichard Lowe 		if (invert_this) {
147310d63b7dSRichard Lowe 			pmake_cap_r_specified = false;
147410d63b7dSRichard Lowe 			no_parallel = false;
147510d63b7dSRichard Lowe 		} else {
147610d63b7dSRichard Lowe 			pmake_cap_r_specified = true;
147710d63b7dSRichard Lowe 			dmake_mode_type = serial_mode;
147810d63b7dSRichard Lowe 			no_parallel = true;
147910d63b7dSRichard Lowe 		}
148010d63b7dSRichard Lowe 		return 0;
148110d63b7dSRichard Lowe 	case 'r':			 /* Turn off internal rules */
148210d63b7dSRichard Lowe 		if (invert_this) {
148310d63b7dSRichard Lowe 			ignore_default_mk = false;
148410d63b7dSRichard Lowe 		} else {
148510d63b7dSRichard Lowe 			ignore_default_mk = true;
148610d63b7dSRichard Lowe 		}
148710d63b7dSRichard Lowe 		return 0;
148810d63b7dSRichard Lowe 	case 'S':			 /* Reverse -k */
148910d63b7dSRichard Lowe 		if (invert_this) {
149010d63b7dSRichard Lowe 			continue_after_error = true;
149110d63b7dSRichard Lowe 		} else {
149210d63b7dSRichard Lowe 			continue_after_error = false;
149310d63b7dSRichard Lowe 			stop_after_error_ever_seen = true;
149410d63b7dSRichard Lowe 		}
149510d63b7dSRichard Lowe 		return 0;
149610d63b7dSRichard Lowe 	case 's':			 /* Silent flag */
149710d63b7dSRichard Lowe 		if (invert_this) {
149810d63b7dSRichard Lowe 			silent_all = false;
149910d63b7dSRichard Lowe 		} else {
150010d63b7dSRichard Lowe 			silent_all = true;
150110d63b7dSRichard Lowe 		}
150210d63b7dSRichard Lowe 		return 0;
150310d63b7dSRichard Lowe 	case 'T':			 /* Print target list */
150410d63b7dSRichard Lowe 		if (invert_this) {
150510d63b7dSRichard Lowe 			list_all_targets = false;
150610d63b7dSRichard Lowe 			do_not_exec_rule = false;
150710d63b7dSRichard Lowe 		} else {
150810d63b7dSRichard Lowe 			list_all_targets = true;
150910d63b7dSRichard Lowe 			do_not_exec_rule = true;
151010d63b7dSRichard Lowe 		}
151110d63b7dSRichard Lowe 		return 0;
151210d63b7dSRichard Lowe 	case 't':			 /* Touch flag */
151310d63b7dSRichard Lowe 		if (invert_this) {
151410d63b7dSRichard Lowe 			touch = false;
151510d63b7dSRichard Lowe 		} else {
151610d63b7dSRichard Lowe 			touch = true;
151710d63b7dSRichard Lowe 		}
151810d63b7dSRichard Lowe 		return 0;
151910d63b7dSRichard Lowe 	case 'u':			 /* Unconditional flag */
152010d63b7dSRichard Lowe 		if (invert_this) {
152110d63b7dSRichard Lowe 			build_unconditional = false;
152210d63b7dSRichard Lowe 		} else {
152310d63b7dSRichard Lowe 			build_unconditional = true;
152410d63b7dSRichard Lowe 		}
152510d63b7dSRichard Lowe 		return 0;
152610d63b7dSRichard Lowe 	case 'V':			/* SVR4 mode */
152710d63b7dSRichard Lowe 		svr4 = true;
152810d63b7dSRichard Lowe 		return 0;
152910d63b7dSRichard Lowe 	case 'v':			/* Version flag */
153010d63b7dSRichard Lowe 		if (invert_this) {
153110d63b7dSRichard Lowe 		} else {
153210d63b7dSRichard Lowe 			fprintf(stdout, "%s: %s\n", getprogname(), verstring);
153310d63b7dSRichard Lowe 			exit_status = 0;
153410d63b7dSRichard Lowe 			exit(0);
153510d63b7dSRichard Lowe 		}
153610d63b7dSRichard Lowe 		return 0;
153710d63b7dSRichard Lowe 	case 'w':			 /* Unconditional flag */
153810d63b7dSRichard Lowe 		if (invert_this) {
153910d63b7dSRichard Lowe 			report_cwd = false;
154010d63b7dSRichard Lowe 		} else {
154110d63b7dSRichard Lowe 			report_cwd = true;
154210d63b7dSRichard Lowe 		}
154310d63b7dSRichard Lowe 		return 0;
154410d63b7dSRichard Lowe #if 0
154510d63b7dSRichard Lowe 	case 'X':			/* Filter stdout */
154610d63b7dSRichard Lowe 		if (invert_this) {
154710d63b7dSRichard Lowe 			filter_stderr = false;
154810d63b7dSRichard Lowe 		} else {
154910d63b7dSRichard Lowe 			filter_stderr = true;
155010d63b7dSRichard Lowe 		}
155110d63b7dSRichard Lowe 		return 0;
155210d63b7dSRichard Lowe #endif
155310d63b7dSRichard Lowe 	default:
155410d63b7dSRichard Lowe 		break;
155510d63b7dSRichard Lowe 	}
155610d63b7dSRichard Lowe 	return 0;
155710d63b7dSRichard Lowe }
155810d63b7dSRichard Lowe 
155910d63b7dSRichard Lowe /*
156010d63b7dSRichard Lowe  *	setup_for_projectdir()
156110d63b7dSRichard Lowe  *
156210d63b7dSRichard Lowe  *	Read the PROJECTDIR variable, if defined, and set the sccs path
156310d63b7dSRichard Lowe  *
156410d63b7dSRichard Lowe  *	Parameters:
156510d63b7dSRichard Lowe  *
156610d63b7dSRichard Lowe  *	Global variables used:
156710d63b7dSRichard Lowe  *		sccs_dir_path	Set to point to SCCS dir to use
156810d63b7dSRichard Lowe  */
156910d63b7dSRichard Lowe static void
157010d63b7dSRichard Lowe setup_for_projectdir(void)
157110d63b7dSRichard Lowe {
157210d63b7dSRichard Lowe static char	path[MAXPATHLEN];
157310d63b7dSRichard Lowe char		cwdpath[MAXPATHLEN];
157410d63b7dSRichard Lowe uid_t uid;
157510d63b7dSRichard Lowe int   done=0;
157610d63b7dSRichard Lowe 
157710d63b7dSRichard Lowe 	/* Check if we should use PROJECTDIR when reading the SCCS dir. */
157810d63b7dSRichard Lowe 	sccs_dir_path = getenv("PROJECTDIR");
157910d63b7dSRichard Lowe 	if ((sccs_dir_path != NULL) &&
158010d63b7dSRichard Lowe 	    (sccs_dir_path[0] != (int) slash_char)) {
158110d63b7dSRichard Lowe 		struct passwd *pwent;
158210d63b7dSRichard Lowe 
158310d63b7dSRichard Lowe 	     {
158410d63b7dSRichard Lowe 		uid = getuid();
158510d63b7dSRichard Lowe 		pwent = getpwuid(uid);
158610d63b7dSRichard Lowe 		if (pwent == NULL) {
158710d63b7dSRichard Lowe 		   fatal(gettext("Bogus USERID "));
158810d63b7dSRichard Lowe 		}
158910d63b7dSRichard Lowe 		if ((pwent = getpwnam(sccs_dir_path)) == NULL) {
159010d63b7dSRichard Lowe 			/*empty block : it'll go & check cwd  */
159110d63b7dSRichard Lowe 		}
159210d63b7dSRichard Lowe 		else {
159310d63b7dSRichard Lowe 		  (void) sprintf(path, "%s/src", pwent->pw_dir);
159410d63b7dSRichard Lowe 		  if (access(path, F_OK) == 0) {
159510d63b7dSRichard Lowe 			sccs_dir_path = path;
159610d63b7dSRichard Lowe 			done = 1;
159710d63b7dSRichard Lowe 		  } else {
159810d63b7dSRichard Lowe 			(void) sprintf(path, "%s/source", pwent->pw_dir);
159910d63b7dSRichard Lowe 			if (access(path, F_OK) == 0) {
160010d63b7dSRichard Lowe 				sccs_dir_path = path;
160110d63b7dSRichard Lowe 				done = 1;
160210d63b7dSRichard Lowe 			}
160310d63b7dSRichard Lowe 		     }
160410d63b7dSRichard Lowe 		}
160510d63b7dSRichard Lowe 		if (!done) {
160610d63b7dSRichard Lowe 		    if (getcwd(cwdpath, MAXPATHLEN - 1 )) {
160710d63b7dSRichard Lowe 
160810d63b7dSRichard Lowe 		       (void) sprintf(path, "%s/%s", cwdpath,sccs_dir_path);
160910d63b7dSRichard Lowe 		       if (access(path, F_OK) == 0) {
161010d63b7dSRichard Lowe 		        	sccs_dir_path = path;
161110d63b7dSRichard Lowe 				done = 1;
161210d63b7dSRichard Lowe 		        } else {
161310d63b7dSRichard Lowe 		  	       	fatal(gettext("Bogus PROJECTDIR '%s'"), sccs_dir_path);
161410d63b7dSRichard Lowe 		        }
161510d63b7dSRichard Lowe 		    }
161610d63b7dSRichard Lowe 		}
161710d63b7dSRichard Lowe 	   }
161810d63b7dSRichard Lowe 	}
161910d63b7dSRichard Lowe }
162010d63b7dSRichard Lowe 
162110d63b7dSRichard Lowe char *
162210d63b7dSRichard Lowe make_install_prefix(void)
162310d63b7dSRichard Lowe {
162410d63b7dSRichard Lowe 	int ret;
162510d63b7dSRichard Lowe 	char origin[PATH_MAX];
162610d63b7dSRichard Lowe 	char *dir;
162710d63b7dSRichard Lowe 
162810d63b7dSRichard Lowe 	if ((ret = readlink("/proc/self/path/a.out", origin,
162910d63b7dSRichard Lowe 	    PATH_MAX - 1)) < 0)
163010d63b7dSRichard Lowe 		fatal("failed to read origin from /proc\n");
163110d63b7dSRichard Lowe 
163210d63b7dSRichard Lowe 
163310d63b7dSRichard Lowe 	origin[ret] = '\0';
163410d63b7dSRichard Lowe 	return strdup(dirname(origin));
163510d63b7dSRichard Lowe }
163610d63b7dSRichard Lowe 
163710d63b7dSRichard Lowe static char *
163810d63b7dSRichard Lowe add_to_env(const char *var, const char *value, const char *fallback)
163910d63b7dSRichard Lowe {
164010d63b7dSRichard Lowe 	const char *oldpath;
164110d63b7dSRichard Lowe 	char *newpath;
164210d63b7dSRichard Lowe 
164310d63b7dSRichard Lowe 	oldpath = getenv(var);
164410d63b7dSRichard Lowe 	if (oldpath == NULL) {
164510d63b7dSRichard Lowe 		if (value != NULL) {
164610d63b7dSRichard Lowe 			asprintf(&newpath, "%s=%s",
164710d63b7dSRichard Lowe 			    var, value);
164810d63b7dSRichard Lowe 		} else {
164910d63b7dSRichard Lowe 			asprintf(&newpath, "%s=%s",
165010d63b7dSRichard Lowe 			    var, fallback);
165110d63b7dSRichard Lowe 		}
165210d63b7dSRichard Lowe 	} else {
165310d63b7dSRichard Lowe 		if (value != NULL) {
165410d63b7dSRichard Lowe 			asprintf(&newpath, "%s=%s:%s",
165510d63b7dSRichard Lowe 			    var, oldpath, value);
165610d63b7dSRichard Lowe 		} else {
165710d63b7dSRichard Lowe 			asprintf(&newpath, "%s=%s:%s",
165810d63b7dSRichard Lowe 			    var, oldpath, fallback);
165910d63b7dSRichard Lowe 		}
166010d63b7dSRichard Lowe 	}
166110d63b7dSRichard Lowe 
166210d63b7dSRichard Lowe 	return (newpath);
166310d63b7dSRichard Lowe }
166410d63b7dSRichard Lowe 
166510d63b7dSRichard Lowe /*
166610d63b7dSRichard Lowe  *	set_sgs_support()
166710d63b7dSRichard Lowe  *
166810d63b7dSRichard Lowe  *	Add the libmakestate.so.1 lib to the env var SGS_SUPPORT
166910d63b7dSRichard Lowe  *	  if it's not already in there.
167010d63b7dSRichard Lowe  *	The SGS_SUPPORT env var and libmakestate.so.1 is used by
167110d63b7dSRichard Lowe  *	  the linker ld to report .make.state info back to make.
167210d63b7dSRichard Lowe  *
167310d63b7dSRichard Lowe  * In the new world we always will set the 32-bit and 64-bit versions of this
167410d63b7dSRichard Lowe  * variable explicitly so that we can take into account the correct isa and our
167510d63b7dSRichard Lowe  * prefix. So say that the prefix was /opt/local. Then we would want to search
167610d63b7dSRichard Lowe  * /opt/local/lib/libmakestate.so.1:libmakestate.so.1. We still want to search
167710d63b7dSRichard Lowe  * the original location just as a safety measure.
167810d63b7dSRichard Lowe  */
167910d63b7dSRichard Lowe static void
168010d63b7dSRichard Lowe set_sgs_support()
168110d63b7dSRichard Lowe {
168210d63b7dSRichard Lowe 	int		len;
168310d63b7dSRichard Lowe 	char		*newpath, *newpath64;
168410d63b7dSRichard Lowe 	char 		*lib32, *lib64;
168510d63b7dSRichard Lowe 	static char	*prev_path, *prev_path64;
168610d63b7dSRichard Lowe 	char		*origin = make_install_prefix();
168710d63b7dSRichard Lowe 	struct stat st;
168810d63b7dSRichard Lowe 
168910d63b7dSRichard Lowe 	asprintf(&lib32, "%s/%s/%s", origin, "../lib",
169010d63b7dSRichard Lowe 	    LD_SUPPORT_MAKE_LIB);
169110d63b7dSRichard Lowe 
169210d63b7dSRichard Lowe 	if (stat(lib32, &st) != 0) {
169310d63b7dSRichard Lowe 		free(lib32);
169410d63b7dSRichard Lowe 		// Try the tools path
169510d63b7dSRichard Lowe 		asprintf(&lib32, "%s/%s/%s/%s", origin, "../../lib/",
169610d63b7dSRichard Lowe 		    LD_SUPPORT_MAKE_ARCH, LD_SUPPORT_MAKE_LIB);
169710d63b7dSRichard Lowe 
169810d63b7dSRichard Lowe 		if (stat(lib32, &st) != 0) {
169910d63b7dSRichard Lowe 			free(lib32);
170010d63b7dSRichard Lowe 			lib32 = NULL;
170110d63b7dSRichard Lowe 		}
170210d63b7dSRichard Lowe 	}
170310d63b7dSRichard Lowe 
170410d63b7dSRichard Lowe 	asprintf(&lib64, "%s/%s/64/%s", origin, "../lib",
170510d63b7dSRichard Lowe 	    LD_SUPPORT_MAKE_LIB);
170610d63b7dSRichard Lowe 
170710d63b7dSRichard Lowe 	if (stat(lib64, &st) != 0) {
170810d63b7dSRichard Lowe 		free(lib64);
170910d63b7dSRichard Lowe 		// Try the tools path
171010d63b7dSRichard Lowe 		asprintf(&lib64, "%s/%s/%s/64/%s", origin, "../../lib/",
171110d63b7dSRichard Lowe 		    LD_SUPPORT_MAKE_ARCH, LD_SUPPORT_MAKE_LIB);
171210d63b7dSRichard Lowe 
171310d63b7dSRichard Lowe 		if (stat(lib64, &st) != 0) {
171410d63b7dSRichard Lowe 			free(lib64);
171510d63b7dSRichard Lowe 			lib64 = NULL;
171610d63b7dSRichard Lowe 		}
171710d63b7dSRichard Lowe 	}
171810d63b7dSRichard Lowe 
171910d63b7dSRichard Lowe 	newpath = add_to_env(LD_SUPPORT_ENV_VAR_32, lib32, LD_SUPPORT_MAKE_LIB);
172010d63b7dSRichard Lowe 	newpath64 = add_to_env(LD_SUPPORT_ENV_VAR_64, lib64, LD_SUPPORT_MAKE_LIB);
172110d63b7dSRichard Lowe 
172210d63b7dSRichard Lowe 	putenv(newpath);
172310d63b7dSRichard Lowe 	if (prev_path) {
172410d63b7dSRichard Lowe 		free(prev_path);
172510d63b7dSRichard Lowe 	}
172610d63b7dSRichard Lowe 	prev_path = newpath;
172710d63b7dSRichard Lowe 
172810d63b7dSRichard Lowe 	putenv(newpath64);
172910d63b7dSRichard Lowe 	if (prev_path64) {
173010d63b7dSRichard Lowe 		free(prev_path64);
173110d63b7dSRichard Lowe 	}
173210d63b7dSRichard Lowe 	prev_path64 = newpath64;
173310d63b7dSRichard Lowe 	free(lib32);
173410d63b7dSRichard Lowe 	free(lib64);
173510d63b7dSRichard Lowe 	free(origin);
173610d63b7dSRichard Lowe }
173710d63b7dSRichard Lowe 
173810d63b7dSRichard Lowe /*
173910d63b7dSRichard Lowe  *	read_files_and_state(argc, argv)
174010d63b7dSRichard Lowe  *
174110d63b7dSRichard Lowe  *	Read the makefiles we care about and the environment
174210d63b7dSRichard Lowe  *	Also read the = style command line options
174310d63b7dSRichard Lowe  *
174410d63b7dSRichard Lowe  *	Parameters:
174510d63b7dSRichard Lowe  *		argc		You know what this is
174610d63b7dSRichard Lowe  *		argv		You know what this is
174710d63b7dSRichard Lowe  *
174810d63b7dSRichard Lowe  *	Static variables used:
174910d63b7dSRichard Lowe  *		env_wins	make -e, determines if env vars are RO
175010d63b7dSRichard Lowe  *		ignore_default_mk make -r, determines if make.rules is read
175110d63b7dSRichard Lowe  *		not_auto_depen	dwight
175210d63b7dSRichard Lowe  *
175310d63b7dSRichard Lowe  *	Global variables used:
175410d63b7dSRichard Lowe  *		default_target_to_build	Set to first proper target from file
175510d63b7dSRichard Lowe  *		do_not_exec_rule Set to false when makfile is made
175610d63b7dSRichard Lowe  *		dot		The Name ".", used to read current dir
175710d63b7dSRichard Lowe  *		empty_name	The Name "", use as macro value
175810d63b7dSRichard Lowe  *		keep_state	Set if KEEP_STATE is in environment
175910d63b7dSRichard Lowe  *		make_state	The Name ".make.state", used to read file
176010d63b7dSRichard Lowe  *		makefile_type	Set to type of file being read
176110d63b7dSRichard Lowe  *		makeflags	The Name "MAKEFLAGS", used to set macro value
176210d63b7dSRichard Lowe  *		not_auto	dwight
176310d63b7dSRichard Lowe  *		read_trace_level Checked to se if the reader should trace
176410d63b7dSRichard Lowe  *		report_dependencies If -P is on we do not read .make.state
176510d63b7dSRichard Lowe  *		trace_reader	Set if reader should trace
176610d63b7dSRichard Lowe  *		virtual_root	The Name "VIRTUAL_ROOT", used to check value
176710d63b7dSRichard Lowe  */
176810d63b7dSRichard Lowe static void
176910d63b7dSRichard Lowe read_files_and_state(int argc, char **argv)
177010d63b7dSRichard Lowe {
177110d63b7dSRichard Lowe 	wchar_t			buffer[1000];
177210d63b7dSRichard Lowe 	wchar_t			buffer_posix[1000];
177310d63b7dSRichard Lowe 	register char		ch;
177410d63b7dSRichard Lowe 	register char		*cp;
177510d63b7dSRichard Lowe 	Property		def_make_macro = NULL;
177610d63b7dSRichard Lowe 	Name			def_make_name;
177710d63b7dSRichard Lowe 	Name			default_makefile;
177810d63b7dSRichard Lowe 	String_rec		dest;
177910d63b7dSRichard Lowe 	wchar_t			destbuffer[STRING_BUFFER_LENGTH];
178010d63b7dSRichard Lowe 	register int		i;
178110d63b7dSRichard Lowe 	register int		j;
178210d63b7dSRichard Lowe 	Name			keep_state_name;
178310d63b7dSRichard Lowe 	int			length;
178410d63b7dSRichard Lowe 	Name			Makefile;
178510d63b7dSRichard Lowe 	register Property	macro;
178610d63b7dSRichard Lowe 	struct stat		make_state_stat;
178710d63b7dSRichard Lowe 	Name			makefile_name;
178810d63b7dSRichard Lowe         register int		makefile_next = 0;
178910d63b7dSRichard Lowe 	register Boolean	makefile_read = false;
179010d63b7dSRichard Lowe 	String_rec		makeflags_string;
179110d63b7dSRichard Lowe 	String_rec		makeflags_string_posix;
179210d63b7dSRichard Lowe 	String_rec *		makeflags_string_current;
179310d63b7dSRichard Lowe 	Name			makeflags_value_saved;
179410d63b7dSRichard Lowe 	register Name		name;
179510d63b7dSRichard Lowe 	Name			new_make_value;
179610d63b7dSRichard Lowe 	Boolean			save_do_not_exec_rule;
179710d63b7dSRichard Lowe 	Name			sdotMakefile;
179810d63b7dSRichard Lowe 	Name			sdotmakefile_name;
179910d63b7dSRichard Lowe 	static wchar_t		state_file_str;
180010d63b7dSRichard Lowe 	static char		state_file_str_mb[MAXPATHLEN];
180110d63b7dSRichard Lowe 	static struct _Name	state_filename;
180210d63b7dSRichard Lowe 	Boolean			temp;
180310d63b7dSRichard Lowe 	char			tmp_char;
180410d63b7dSRichard Lowe 	wchar_t			*tmp_wcs_buffer;
180510d63b7dSRichard Lowe 	register Name		value;
180610d63b7dSRichard Lowe 	ASCII_Dyn_Array		makeflags_and_macro;
180710d63b7dSRichard Lowe 	Boolean			is_xpg4;
180810d63b7dSRichard Lowe 
180910d63b7dSRichard Lowe /*
181010d63b7dSRichard Lowe  *	Remember current mode. It may be changed after reading makefile
181110d63b7dSRichard Lowe  *	and we will have to correct MAKEFLAGS variable.
181210d63b7dSRichard Lowe  */
181310d63b7dSRichard Lowe 	is_xpg4 = posix;
181410d63b7dSRichard Lowe 
181510d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "KEEP_STATE");
181610d63b7dSRichard Lowe 	keep_state_name = GETNAME(wcs_buffer, FIND_LENGTH);
181710d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "Makefile");
181810d63b7dSRichard Lowe 	Makefile = GETNAME(wcs_buffer, FIND_LENGTH);
181910d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "makefile");
182010d63b7dSRichard Lowe 	makefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
182110d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "s.makefile");
182210d63b7dSRichard Lowe 	sdotmakefile_name = GETNAME(wcs_buffer, FIND_LENGTH);
182310d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "s.Makefile");
182410d63b7dSRichard Lowe 	sdotMakefile = GETNAME(wcs_buffer, FIND_LENGTH);
182510d63b7dSRichard Lowe 
182610d63b7dSRichard Lowe /*
182710d63b7dSRichard Lowe  *	initialize global dependency entry for .NOT_AUTO
182810d63b7dSRichard Lowe  */
182910d63b7dSRichard Lowe 	not_auto_depen->next = NULL;
183010d63b7dSRichard Lowe 	not_auto_depen->name = not_auto;
183110d63b7dSRichard Lowe 	not_auto_depen->automatic = not_auto_depen->stale = false;
183210d63b7dSRichard Lowe 
183310d63b7dSRichard Lowe /*
183410d63b7dSRichard Lowe  *	Read internal definitions and rules.
183510d63b7dSRichard Lowe  */
183610d63b7dSRichard Lowe 	if (read_trace_level > 1) {
183710d63b7dSRichard Lowe 		trace_reader = true;
183810d63b7dSRichard Lowe 	}
183910d63b7dSRichard Lowe 	if (!ignore_default_mk) {
184010d63b7dSRichard Lowe 		if (svr4) {
184110d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "svr4.make.rules");
184210d63b7dSRichard Lowe 			default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
184310d63b7dSRichard Lowe 		} else {
184410d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "make.rules");
184510d63b7dSRichard Lowe 			default_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
184610d63b7dSRichard Lowe 		}
184710d63b7dSRichard Lowe 		default_makefile->stat.is_file = true;
184810d63b7dSRichard Lowe 
184910d63b7dSRichard Lowe 		(void) read_makefile(default_makefile,
185010d63b7dSRichard Lowe 				     true,
185110d63b7dSRichard Lowe 				     false,
185210d63b7dSRichard Lowe 				     true);
185310d63b7dSRichard Lowe 	}
185410d63b7dSRichard Lowe 
185510d63b7dSRichard Lowe 	/*
185610d63b7dSRichard Lowe 	 * If the user did not redefine the MAKE macro in the
185710d63b7dSRichard Lowe 	 * default makefile (make.rules), then we'd like to
185810d63b7dSRichard Lowe 	 * change the macro value of MAKE to be some form
185910d63b7dSRichard Lowe 	 * of argv[0] for recursive MAKE builds.
186010d63b7dSRichard Lowe 	 */
186110d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, "MAKE");
186210d63b7dSRichard Lowe 	def_make_name = GETNAME(wcs_buffer, wcslen(wcs_buffer));
186310d63b7dSRichard Lowe 	def_make_macro = get_prop(def_make_name->prop, macro_prop);
186410d63b7dSRichard Lowe 	if ((def_make_macro != NULL) &&
186510d63b7dSRichard Lowe 	    (IS_EQUAL(def_make_macro->body.macro.value->string_mb,
186610d63b7dSRichard Lowe 	              "make"))) {
186710d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, argv_zero_string);
186810d63b7dSRichard Lowe 		new_make_value = GETNAME(wcs_buffer, wcslen(wcs_buffer));
186910d63b7dSRichard Lowe 		(void) SETVAR(def_make_name,
187010d63b7dSRichard Lowe 		              new_make_value,
187110d63b7dSRichard Lowe 		              false);
187210d63b7dSRichard Lowe 	}
187310d63b7dSRichard Lowe 
187410d63b7dSRichard Lowe 	default_target_to_build = NULL;
187510d63b7dSRichard Lowe 	trace_reader = false;
187610d63b7dSRichard Lowe 
187710d63b7dSRichard Lowe /*
187810d63b7dSRichard Lowe  *	Read environment args. Let file args which follow override unless
187910d63b7dSRichard Lowe  *	-e option seen. If -e option is not mentioned.
188010d63b7dSRichard Lowe  */
188110d63b7dSRichard Lowe 	read_environment(env_wins);
188210d63b7dSRichard Lowe 	if (getvar(virtual_root)->hash.length == 0) {
188310d63b7dSRichard Lowe 		maybe_append_prop(virtual_root, macro_prop)
188410d63b7dSRichard Lowe 		  ->body.macro.exported = true;
188510d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "/");
188610d63b7dSRichard Lowe 		(void) SETVAR(virtual_root,
188710d63b7dSRichard Lowe 			      GETNAME(wcs_buffer, FIND_LENGTH),
188810d63b7dSRichard Lowe 			      false);
188910d63b7dSRichard Lowe 	}
189010d63b7dSRichard Lowe 
189110d63b7dSRichard Lowe /*
189210d63b7dSRichard Lowe  * We now scan mf_argv and argv to see if we need to set
189310d63b7dSRichard Lowe  * any of the DMake-added options/variables in MAKEFLAGS.
189410d63b7dSRichard Lowe  */
189510d63b7dSRichard Lowe 
189610d63b7dSRichard Lowe 	makeflags_and_macro.start = 0;
189710d63b7dSRichard Lowe 	makeflags_and_macro.size = 0;
189810d63b7dSRichard Lowe 	enter_argv_values(mf_argc, mf_argv, &makeflags_and_macro);
189910d63b7dSRichard Lowe 	enter_argv_values(argc, argv, &makeflags_and_macro);
190010d63b7dSRichard Lowe 
190110d63b7dSRichard Lowe /*
190210d63b7dSRichard Lowe  *	Set MFLAGS and MAKEFLAGS
190310d63b7dSRichard Lowe  *
190410d63b7dSRichard Lowe  *	Before reading makefile we do not know exactly which mode
190510d63b7dSRichard Lowe  *	(posix or not) is used. So prepare two MAKEFLAGS strings
190610d63b7dSRichard Lowe  *	for both posix and solaris modes because they are different.
190710d63b7dSRichard Lowe  */
190810d63b7dSRichard Lowe 	INIT_STRING_FROM_STACK(makeflags_string, buffer);
190910d63b7dSRichard Lowe 	INIT_STRING_FROM_STACK(makeflags_string_posix, buffer_posix);
191010d63b7dSRichard Lowe 	append_char((int) hyphen_char, &makeflags_string);
191110d63b7dSRichard Lowe 	append_char((int) hyphen_char, &makeflags_string_posix);
191210d63b7dSRichard Lowe 
191310d63b7dSRichard Lowe 	switch (read_trace_level) {
191410d63b7dSRichard Lowe 	case 2:
191510d63b7dSRichard Lowe 		append_char('D', &makeflags_string);
191610d63b7dSRichard Lowe 		append_char('D', &makeflags_string_posix);
191710d63b7dSRichard Lowe 	case 1:
191810d63b7dSRichard Lowe 		append_char('D', &makeflags_string);
191910d63b7dSRichard Lowe 		append_char('D', &makeflags_string_posix);
192010d63b7dSRichard Lowe 	}
192110d63b7dSRichard Lowe 	switch (debug_level) {
192210d63b7dSRichard Lowe 	case 2:
192310d63b7dSRichard Lowe 		append_char('d', &makeflags_string);
192410d63b7dSRichard Lowe 		append_char('d', &makeflags_string_posix);
192510d63b7dSRichard Lowe 	case 1:
192610d63b7dSRichard Lowe 		append_char('d', &makeflags_string);
192710d63b7dSRichard Lowe 		append_char('d', &makeflags_string_posix);
192810d63b7dSRichard Lowe 	}
192910d63b7dSRichard Lowe 	if (env_wins) {
193010d63b7dSRichard Lowe 		append_char('e', &makeflags_string);
193110d63b7dSRichard Lowe 		append_char('e', &makeflags_string_posix);
193210d63b7dSRichard Lowe 	}
193310d63b7dSRichard Lowe 	if (ignore_errors_all) {
193410d63b7dSRichard Lowe 		append_char('i', &makeflags_string);
193510d63b7dSRichard Lowe 		append_char('i', &makeflags_string_posix);
193610d63b7dSRichard Lowe 	}
193710d63b7dSRichard Lowe 	if (continue_after_error) {
193810d63b7dSRichard Lowe 		if (stop_after_error_ever_seen) {
193910d63b7dSRichard Lowe 			append_char('S', &makeflags_string_posix);
194010d63b7dSRichard Lowe 			append_char((int) space_char, &makeflags_string_posix);
194110d63b7dSRichard Lowe 			append_char((int) hyphen_char, &makeflags_string_posix);
194210d63b7dSRichard Lowe 		}
194310d63b7dSRichard Lowe 		append_char('k', &makeflags_string);
194410d63b7dSRichard Lowe 		append_char('k', &makeflags_string_posix);
194510d63b7dSRichard Lowe 	} else {
194610d63b7dSRichard Lowe 		if (stop_after_error_ever_seen
194710d63b7dSRichard Lowe 		    && continue_after_error_ever_seen) {
194810d63b7dSRichard Lowe 			append_char('k', &makeflags_string_posix);
194910d63b7dSRichard Lowe 			append_char((int) space_char, &makeflags_string_posix);
195010d63b7dSRichard Lowe 			append_char((int) hyphen_char, &makeflags_string_posix);
195110d63b7dSRichard Lowe 			append_char('S', &makeflags_string_posix);
195210d63b7dSRichard Lowe 		}
195310d63b7dSRichard Lowe 	}
195410d63b7dSRichard Lowe 	if (do_not_exec_rule) {
195510d63b7dSRichard Lowe 		append_char('n', &makeflags_string);
195610d63b7dSRichard Lowe 		append_char('n', &makeflags_string_posix);
195710d63b7dSRichard Lowe 	}
195810d63b7dSRichard Lowe 	switch (report_dependencies_level) {
195910d63b7dSRichard Lowe 	case 4:
196010d63b7dSRichard Lowe 		append_char('P', &makeflags_string);
196110d63b7dSRichard Lowe 		append_char('P', &makeflags_string_posix);
196210d63b7dSRichard Lowe 	case 3:
196310d63b7dSRichard Lowe 		append_char('P', &makeflags_string);
196410d63b7dSRichard Lowe 		append_char('P', &makeflags_string_posix);
196510d63b7dSRichard Lowe 	case 2:
196610d63b7dSRichard Lowe 		append_char('P', &makeflags_string);
196710d63b7dSRichard Lowe 		append_char('P', &makeflags_string_posix);
196810d63b7dSRichard Lowe 	case 1:
196910d63b7dSRichard Lowe 		append_char('P', &makeflags_string);
197010d63b7dSRichard Lowe 		append_char('P', &makeflags_string_posix);
197110d63b7dSRichard Lowe 	}
197210d63b7dSRichard Lowe 	if (trace_status) {
197310d63b7dSRichard Lowe 		append_char('p', &makeflags_string);
197410d63b7dSRichard Lowe 		append_char('p', &makeflags_string_posix);
197510d63b7dSRichard Lowe 	}
197610d63b7dSRichard Lowe 	if (quest) {
197710d63b7dSRichard Lowe 		append_char('q', &makeflags_string);
197810d63b7dSRichard Lowe 		append_char('q', &makeflags_string_posix);
197910d63b7dSRichard Lowe 	}
198010d63b7dSRichard Lowe 	if (silent_all) {
198110d63b7dSRichard Lowe 		append_char('s', &makeflags_string);
198210d63b7dSRichard Lowe 		append_char('s', &makeflags_string_posix);
198310d63b7dSRichard Lowe 	}
198410d63b7dSRichard Lowe 	if (touch) {
198510d63b7dSRichard Lowe 		append_char('t', &makeflags_string);
198610d63b7dSRichard Lowe 		append_char('t', &makeflags_string_posix);
198710d63b7dSRichard Lowe 	}
198810d63b7dSRichard Lowe 	if (build_unconditional) {
198910d63b7dSRichard Lowe 		append_char('u', &makeflags_string);
199010d63b7dSRichard Lowe 		append_char('u', &makeflags_string_posix);
199110d63b7dSRichard Lowe 	}
199210d63b7dSRichard Lowe 	if (report_cwd) {
199310d63b7dSRichard Lowe 		append_char('w', &makeflags_string);
199410d63b7dSRichard Lowe 		append_char('w', &makeflags_string_posix);
199510d63b7dSRichard Lowe 	}
199610d63b7dSRichard Lowe 	/* -c dmake_rcfile */
199710d63b7dSRichard Lowe 	if (dmake_rcfile_specified) {
199810d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_RCFILE");
199910d63b7dSRichard Lowe 		dmake_rcfile = GETNAME(wcs_buffer, FIND_LENGTH);
200010d63b7dSRichard Lowe 		append_makeflags_string(dmake_rcfile, &makeflags_string);
200110d63b7dSRichard Lowe 		append_makeflags_string(dmake_rcfile, &makeflags_string_posix);
200210d63b7dSRichard Lowe 	}
200310d63b7dSRichard Lowe 	/* -g dmake_group */
200410d63b7dSRichard Lowe 	if (dmake_group_specified) {
200510d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_GROUP");
200610d63b7dSRichard Lowe 		dmake_group = GETNAME(wcs_buffer, FIND_LENGTH);
200710d63b7dSRichard Lowe 		append_makeflags_string(dmake_group, &makeflags_string);
200810d63b7dSRichard Lowe 		append_makeflags_string(dmake_group, &makeflags_string_posix);
200910d63b7dSRichard Lowe 	}
201010d63b7dSRichard Lowe 	/* -j dmake_max_jobs */
201110d63b7dSRichard Lowe 	if (dmake_max_jobs_specified) {
201210d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_MAX_JOBS");
201310d63b7dSRichard Lowe 		dmake_max_jobs = GETNAME(wcs_buffer, FIND_LENGTH);
201410d63b7dSRichard Lowe 		append_makeflags_string(dmake_max_jobs, &makeflags_string);
201510d63b7dSRichard Lowe 		append_makeflags_string(dmake_max_jobs, &makeflags_string_posix);
201610d63b7dSRichard Lowe 	}
201710d63b7dSRichard Lowe 	/* -m dmake_mode */
201810d63b7dSRichard Lowe 	if (dmake_mode_specified) {
201910d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_MODE");
202010d63b7dSRichard Lowe 		dmake_mode = GETNAME(wcs_buffer, FIND_LENGTH);
202110d63b7dSRichard Lowe 		append_makeflags_string(dmake_mode, &makeflags_string);
202210d63b7dSRichard Lowe 		append_makeflags_string(dmake_mode, &makeflags_string_posix);
202310d63b7dSRichard Lowe 	}
202410d63b7dSRichard Lowe 	/* -x dmake_compat_mode */
202510d63b7dSRichard Lowe //	if (dmake_compat_mode_specified) {
202610d63b7dSRichard Lowe //		MBSTOWCS(wcs_buffer, "SUN_MAKE_COMPAT_MODE");
202710d63b7dSRichard Lowe //		dmake_compat_mode = GETNAME(wcs_buffer, FIND_LENGTH);
202810d63b7dSRichard Lowe //		append_makeflags_string(dmake_compat_mode, &makeflags_string);
202910d63b7dSRichard Lowe //		append_makeflags_string(dmake_compat_mode, &makeflags_string_posix);
203010d63b7dSRichard Lowe //	}
203110d63b7dSRichard Lowe 	/* -x dmake_output_mode */
203210d63b7dSRichard Lowe 	if (dmake_output_mode_specified) {
203310d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_OUTPUT_MODE");
203410d63b7dSRichard Lowe 		dmake_output_mode = GETNAME(wcs_buffer, FIND_LENGTH);
203510d63b7dSRichard Lowe 		append_makeflags_string(dmake_output_mode, &makeflags_string);
203610d63b7dSRichard Lowe 		append_makeflags_string(dmake_output_mode, &makeflags_string_posix);
203710d63b7dSRichard Lowe 	}
203810d63b7dSRichard Lowe 	/* -o dmake_odir */
203910d63b7dSRichard Lowe 	if (dmake_odir_specified) {
204010d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "DMAKE_ODIR");
204110d63b7dSRichard Lowe 		dmake_odir = GETNAME(wcs_buffer, FIND_LENGTH);
204210d63b7dSRichard Lowe 		append_makeflags_string(dmake_odir, &makeflags_string);
204310d63b7dSRichard Lowe 		append_makeflags_string(dmake_odir, &makeflags_string_posix);
204410d63b7dSRichard Lowe 	}
204510d63b7dSRichard Lowe 	/* -M pmake_machinesfile */
204610d63b7dSRichard Lowe 	if (pmake_machinesfile_specified) {
204710d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "PMAKE_MACHINESFILE");
204810d63b7dSRichard Lowe 		pmake_machinesfile = GETNAME(wcs_buffer, FIND_LENGTH);
204910d63b7dSRichard Lowe 		append_makeflags_string(pmake_machinesfile, &makeflags_string);
205010d63b7dSRichard Lowe 		append_makeflags_string(pmake_machinesfile, &makeflags_string_posix);
205110d63b7dSRichard Lowe 	}
205210d63b7dSRichard Lowe 	/* -R */
205310d63b7dSRichard Lowe 	if (pmake_cap_r_specified) {
205410d63b7dSRichard Lowe 		append_char((int) space_char, &makeflags_string);
205510d63b7dSRichard Lowe 		append_char((int) hyphen_char, &makeflags_string);
205610d63b7dSRichard Lowe 		append_char('R', &makeflags_string);
205710d63b7dSRichard Lowe 		append_char((int) space_char, &makeflags_string_posix);
205810d63b7dSRichard Lowe 		append_char((int) hyphen_char, &makeflags_string_posix);
205910d63b7dSRichard Lowe 		append_char('R', &makeflags_string_posix);
206010d63b7dSRichard Lowe 	}
206110d63b7dSRichard Lowe 
206210d63b7dSRichard Lowe /*
206310d63b7dSRichard Lowe  *	Make sure MAKEFLAGS is exported
206410d63b7dSRichard Lowe  */
206510d63b7dSRichard Lowe 	maybe_append_prop(makeflags, macro_prop)->
206610d63b7dSRichard Lowe 	  body.macro.exported = true;
206710d63b7dSRichard Lowe 
206810d63b7dSRichard Lowe 	if (makeflags_string.buffer.start[1] != (int) nul_char) {
206910d63b7dSRichard Lowe 		if (makeflags_string.buffer.start[1] != (int) space_char) {
207010d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "MFLAGS");
207110d63b7dSRichard Lowe 			(void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
207210d63b7dSRichard Lowe 				      GETNAME(makeflags_string.buffer.start,
207310d63b7dSRichard Lowe 					      FIND_LENGTH),
207410d63b7dSRichard Lowe 				      false);
207510d63b7dSRichard Lowe 		} else {
207610d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "MFLAGS");
207710d63b7dSRichard Lowe 			(void) SETVAR(GETNAME(wcs_buffer, FIND_LENGTH),
207810d63b7dSRichard Lowe 				      GETNAME(makeflags_string.buffer.start + 2,
207910d63b7dSRichard Lowe 					      FIND_LENGTH),
208010d63b7dSRichard Lowe 				      false);
208110d63b7dSRichard Lowe 		}
208210d63b7dSRichard Lowe 	}
208310d63b7dSRichard Lowe 
208410d63b7dSRichard Lowe /*
208510d63b7dSRichard Lowe  *	Add command line macro to POSIX makeflags_string
208610d63b7dSRichard Lowe  */
208710d63b7dSRichard Lowe 	if (makeflags_and_macro.start) {
208810d63b7dSRichard Lowe 		tmp_char = (char) space_char;
208910d63b7dSRichard Lowe 		cp = makeflags_and_macro.start;
209010d63b7dSRichard Lowe 		do {
209110d63b7dSRichard Lowe 			append_char(tmp_char, &makeflags_string_posix);
209210d63b7dSRichard Lowe 		} while ( tmp_char = *cp++ );
209310d63b7dSRichard Lowe 		retmem_mb(makeflags_and_macro.start);
209410d63b7dSRichard Lowe 	}
209510d63b7dSRichard Lowe 
209610d63b7dSRichard Lowe /*
209710d63b7dSRichard Lowe  *	Now set the value of MAKEFLAGS macro in accordance
209810d63b7dSRichard Lowe  *	with current mode.
209910d63b7dSRichard Lowe  */
210010d63b7dSRichard Lowe 	macro = maybe_append_prop(makeflags, macro_prop);
210110d63b7dSRichard Lowe 	temp = (Boolean) macro->body.macro.read_only;
210210d63b7dSRichard Lowe 	macro->body.macro.read_only = false;
210310d63b7dSRichard Lowe 	if(posix || gnu_style) {
210410d63b7dSRichard Lowe 		makeflags_string_current = &makeflags_string_posix;
210510d63b7dSRichard Lowe 	} else {
210610d63b7dSRichard Lowe 		makeflags_string_current = &makeflags_string;
210710d63b7dSRichard Lowe 	}
210810d63b7dSRichard Lowe 	if (makeflags_string_current->buffer.start[1] == (int) nul_char) {
210910d63b7dSRichard Lowe 		makeflags_value_saved =
211010d63b7dSRichard Lowe 			GETNAME( makeflags_string_current->buffer.start + 1
211110d63b7dSRichard Lowe 			       , FIND_LENGTH
211210d63b7dSRichard Lowe 			       );
211310d63b7dSRichard Lowe 	} else {
211410d63b7dSRichard Lowe 		if (makeflags_string_current->buffer.start[1] != (int) space_char) {
211510d63b7dSRichard Lowe 			makeflags_value_saved =
211610d63b7dSRichard Lowe 				GETNAME( makeflags_string_current->buffer.start
211710d63b7dSRichard Lowe 				       , FIND_LENGTH
211810d63b7dSRichard Lowe 				       );
211910d63b7dSRichard Lowe 		} else {
212010d63b7dSRichard Lowe 			makeflags_value_saved =
212110d63b7dSRichard Lowe 				GETNAME( makeflags_string_current->buffer.start + 2
212210d63b7dSRichard Lowe 				       , FIND_LENGTH
212310d63b7dSRichard Lowe 				       );
212410d63b7dSRichard Lowe 		}
212510d63b7dSRichard Lowe 	}
212610d63b7dSRichard Lowe 	(void) SETVAR( makeflags
212710d63b7dSRichard Lowe 	             , makeflags_value_saved
212810d63b7dSRichard Lowe 	             , false
212910d63b7dSRichard Lowe 	             );
213010d63b7dSRichard Lowe 	macro->body.macro.read_only = temp;
213110d63b7dSRichard Lowe 
213210d63b7dSRichard Lowe /*
213310d63b7dSRichard Lowe  *	Read command line "-f" arguments and ignore -c, g, j, K, M, m, O and o args.
213410d63b7dSRichard Lowe  */
213510d63b7dSRichard Lowe 	save_do_not_exec_rule = do_not_exec_rule;
213610d63b7dSRichard Lowe 	do_not_exec_rule = false;
213710d63b7dSRichard Lowe 	if (read_trace_level > 0) {
213810d63b7dSRichard Lowe 		trace_reader = true;
213910d63b7dSRichard Lowe 	}
214010d63b7dSRichard Lowe 
214110d63b7dSRichard Lowe 	for (i = 1; i < argc; i++) {
214210d63b7dSRichard Lowe 		if (argv[i] &&
214310d63b7dSRichard Lowe 		    (argv[i][0] == (int) hyphen_char) &&
214410d63b7dSRichard Lowe 		    (argv[i][1] == 'f') &&
214510d63b7dSRichard Lowe 		    (argv[i][2] == (int) nul_char)) {
214610d63b7dSRichard Lowe 			argv[i] = NULL;		/* Remove -f */
214710d63b7dSRichard Lowe 			if (i >= argc - 1) {
214810d63b7dSRichard Lowe 				fatal(gettext("No filename argument after -f flag"));
214910d63b7dSRichard Lowe 			}
215010d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, argv[++i]);
215110d63b7dSRichard Lowe 			primary_makefile = GETNAME(wcs_buffer, FIND_LENGTH);
215210d63b7dSRichard Lowe 			(void) read_makefile(primary_makefile, true, true, true);
215310d63b7dSRichard Lowe 			argv[i] = NULL;		/* Remove filename */
215410d63b7dSRichard Lowe 			makefile_read = true;
215510d63b7dSRichard Lowe 		} else if (argv[i] &&
215610d63b7dSRichard Lowe 			   (argv[i][0] == (int) hyphen_char) &&
215710d63b7dSRichard Lowe 			   (argv[i][1] == 'c' ||
215810d63b7dSRichard Lowe 			    argv[i][1] == 'g' ||
215910d63b7dSRichard Lowe 			    argv[i][1] == 'j' ||
216010d63b7dSRichard Lowe 			    argv[i][1] == 'K' ||
216110d63b7dSRichard Lowe 			    argv[i][1] == 'M' ||
216210d63b7dSRichard Lowe 			    argv[i][1] == 'm' ||
216310d63b7dSRichard Lowe 			    argv[i][1] == 'O' ||
216410d63b7dSRichard Lowe 			    argv[i][1] == 'o') &&
216510d63b7dSRichard Lowe 			   (argv[i][2] == (int) nul_char)) {
216610d63b7dSRichard Lowe 			argv[i] = NULL;
216710d63b7dSRichard Lowe 			argv[++i] = NULL;
216810d63b7dSRichard Lowe 		}
216910d63b7dSRichard Lowe 	}
217010d63b7dSRichard Lowe 
217110d63b7dSRichard Lowe /*
217210d63b7dSRichard Lowe  *	If no command line "-f" args then look for "makefile", and then for
217310d63b7dSRichard Lowe  *	"Makefile" if "makefile" isn't found.
217410d63b7dSRichard Lowe  */
217510d63b7dSRichard Lowe 	if (!makefile_read) {
217610d63b7dSRichard Lowe 		(void) read_dir(dot,
217710d63b7dSRichard Lowe 				(wchar_t *) NULL,
217810d63b7dSRichard Lowe 				(Property) NULL,
217910d63b7dSRichard Lowe 				(wchar_t *) NULL);
218010d63b7dSRichard Lowe 	    if (!posix) {
218110d63b7dSRichard Lowe 		if (makefile_name->stat.is_file) {
218210d63b7dSRichard Lowe 			if (Makefile->stat.is_file) {
218310d63b7dSRichard Lowe 				warning(gettext("Both `makefile' and `Makefile' exist"));
218410d63b7dSRichard Lowe 			}
218510d63b7dSRichard Lowe 			primary_makefile = makefile_name;
218610d63b7dSRichard Lowe 			makefile_read = read_makefile(makefile_name,
218710d63b7dSRichard Lowe 						      false,
218810d63b7dSRichard Lowe 						      false,
218910d63b7dSRichard Lowe 						      true);
219010d63b7dSRichard Lowe 		}
219110d63b7dSRichard Lowe 		if (!makefile_read &&
219210d63b7dSRichard Lowe 		    Makefile->stat.is_file) {
219310d63b7dSRichard Lowe 			primary_makefile = Makefile;
219410d63b7dSRichard Lowe 			makefile_read = read_makefile(Makefile,
219510d63b7dSRichard Lowe 						      false,
219610d63b7dSRichard Lowe 						      false,
219710d63b7dSRichard Lowe 						      true);
219810d63b7dSRichard Lowe 		}
219910d63b7dSRichard Lowe 	    } else {
220010d63b7dSRichard Lowe 
220110d63b7dSRichard Lowe 		enum sccs_stat save_m_has_sccs = NO_SCCS;
220210d63b7dSRichard Lowe 		enum sccs_stat save_M_has_sccs = NO_SCCS;
220310d63b7dSRichard Lowe 
220410d63b7dSRichard Lowe 		if (makefile_name->stat.is_file) {
220510d63b7dSRichard Lowe 			if (Makefile->stat.is_file) {
220610d63b7dSRichard Lowe 				warning(gettext("Both `makefile' and `Makefile' exist"));
220710d63b7dSRichard Lowe 			}
220810d63b7dSRichard Lowe 		}
220910d63b7dSRichard Lowe 		if (makefile_name->stat.is_file) {
221010d63b7dSRichard Lowe 			if (makefile_name->stat.has_sccs == NO_SCCS) {
221110d63b7dSRichard Lowe 			   primary_makefile = makefile_name;
221210d63b7dSRichard Lowe 			   makefile_read = read_makefile(makefile_name,
221310d63b7dSRichard Lowe 						      false,
221410d63b7dSRichard Lowe 						      false,
221510d63b7dSRichard Lowe 						      true);
221610d63b7dSRichard Lowe 			} else {
221710d63b7dSRichard Lowe 			  save_m_has_sccs = makefile_name->stat.has_sccs;
221810d63b7dSRichard Lowe 			  makefile_name->stat.has_sccs = NO_SCCS;
221910d63b7dSRichard Lowe 			  primary_makefile = makefile_name;
222010d63b7dSRichard Lowe 			  makefile_read = read_makefile(makefile_name,
222110d63b7dSRichard Lowe 						      false,
222210d63b7dSRichard Lowe 						      false,
222310d63b7dSRichard Lowe 						      true);
222410d63b7dSRichard Lowe 			}
222510d63b7dSRichard Lowe 		}
222610d63b7dSRichard Lowe 		if (!makefile_read &&
222710d63b7dSRichard Lowe 		    Makefile->stat.is_file) {
222810d63b7dSRichard Lowe 			if (Makefile->stat.has_sccs == NO_SCCS) {
222910d63b7dSRichard Lowe 			   primary_makefile = Makefile;
223010d63b7dSRichard Lowe 			   makefile_read = read_makefile(Makefile,
223110d63b7dSRichard Lowe 						      false,
223210d63b7dSRichard Lowe 						      false,
223310d63b7dSRichard Lowe 						      true);
223410d63b7dSRichard Lowe 			} else {
223510d63b7dSRichard Lowe 			  save_M_has_sccs = Makefile->stat.has_sccs;
223610d63b7dSRichard Lowe 			  Makefile->stat.has_sccs = NO_SCCS;
223710d63b7dSRichard Lowe 			  primary_makefile = Makefile;
223810d63b7dSRichard Lowe 			  makefile_read = read_makefile(Makefile,
223910d63b7dSRichard Lowe 						      false,
224010d63b7dSRichard Lowe 						      false,
224110d63b7dSRichard Lowe 						      true);
224210d63b7dSRichard Lowe 			}
224310d63b7dSRichard Lowe 		}
224410d63b7dSRichard Lowe 		if (!makefile_read &&
224510d63b7dSRichard Lowe 		        makefile_name->stat.is_file) {
224610d63b7dSRichard Lowe 			   makefile_name->stat.has_sccs = save_m_has_sccs;
224710d63b7dSRichard Lowe 			   primary_makefile = makefile_name;
224810d63b7dSRichard Lowe 			   makefile_read = read_makefile(makefile_name,
224910d63b7dSRichard Lowe 						      false,
225010d63b7dSRichard Lowe 						      false,
225110d63b7dSRichard Lowe 						      true);
225210d63b7dSRichard Lowe 		}
225310d63b7dSRichard Lowe 		if (!makefile_read &&
225410d63b7dSRichard Lowe 		    Makefile->stat.is_file) {
225510d63b7dSRichard Lowe 			   Makefile->stat.has_sccs = save_M_has_sccs;
225610d63b7dSRichard Lowe 			   primary_makefile = Makefile;
225710d63b7dSRichard Lowe 			   makefile_read = read_makefile(Makefile,
225810d63b7dSRichard Lowe 						      false,
225910d63b7dSRichard Lowe 						      false,
226010d63b7dSRichard Lowe 						      true);
226110d63b7dSRichard Lowe 		}
226210d63b7dSRichard Lowe 	    }
226310d63b7dSRichard Lowe 	}
226410d63b7dSRichard Lowe 	do_not_exec_rule = save_do_not_exec_rule;
226510d63b7dSRichard Lowe 	allrules_read = makefile_read;
226610d63b7dSRichard Lowe 	trace_reader = false;
226710d63b7dSRichard Lowe 
226810d63b7dSRichard Lowe /*
226910d63b7dSRichard Lowe  *	Now get current value of MAKEFLAGS and compare it with
227010d63b7dSRichard Lowe  *	the saved value we set before reading makefile.
227110d63b7dSRichard Lowe  *	If they are different then MAKEFLAGS is subsequently set by
227210d63b7dSRichard Lowe  *	makefile, just leave it there. Otherwise, if make mode
227310d63b7dSRichard Lowe  *	is changed by using .POSIX target in makefile we need
227410d63b7dSRichard Lowe  *	to correct MAKEFLAGS value.
227510d63b7dSRichard Lowe  */
227610d63b7dSRichard Lowe 	Name mf_val = getvar(makeflags);
227710d63b7dSRichard Lowe 	if( (posix != is_xpg4)
227810d63b7dSRichard Lowe 	 && (!strcmp(mf_val->string_mb, makeflags_value_saved->string_mb)))
227910d63b7dSRichard Lowe 	{
228010d63b7dSRichard Lowe 		if (makeflags_string_posix.buffer.start[1] == (int) nul_char) {
228110d63b7dSRichard Lowe 			(void) SETVAR(makeflags,
228210d63b7dSRichard Lowe 				      GETNAME(makeflags_string_posix.buffer.start + 1,
228310d63b7dSRichard Lowe 					      FIND_LENGTH),
228410d63b7dSRichard Lowe 				      false);
228510d63b7dSRichard Lowe 		} else {
228610d63b7dSRichard Lowe 			if (makeflags_string_posix.buffer.start[1] != (int) space_char) {
228710d63b7dSRichard Lowe 				(void) SETVAR(makeflags,
228810d63b7dSRichard Lowe 					      GETNAME(makeflags_string_posix.buffer.start,
228910d63b7dSRichard Lowe 						      FIND_LENGTH),
229010d63b7dSRichard Lowe 					      false);
229110d63b7dSRichard Lowe 			} else {
229210d63b7dSRichard Lowe 				(void) SETVAR(makeflags,
229310d63b7dSRichard Lowe 					      GETNAME(makeflags_string_posix.buffer.start + 2,
229410d63b7dSRichard Lowe 						      FIND_LENGTH),
229510d63b7dSRichard Lowe 					      false);
229610d63b7dSRichard Lowe 			}
229710d63b7dSRichard Lowe 		}
229810d63b7dSRichard Lowe 	}
229910d63b7dSRichard Lowe 
230010d63b7dSRichard Lowe 	if (makeflags_string.free_after_use) {
230110d63b7dSRichard Lowe 		retmem(makeflags_string.buffer.start);
230210d63b7dSRichard Lowe 	}
230310d63b7dSRichard Lowe 	if (makeflags_string_posix.free_after_use) {
230410d63b7dSRichard Lowe 		retmem(makeflags_string_posix.buffer.start);
230510d63b7dSRichard Lowe 	}
230610d63b7dSRichard Lowe 	makeflags_string.buffer.start = NULL;
230710d63b7dSRichard Lowe 	makeflags_string_posix.buffer.start = NULL;
230810d63b7dSRichard Lowe 
230910d63b7dSRichard Lowe 	if (posix) {
231010d63b7dSRichard Lowe 		/*
231110d63b7dSRichard Lowe 		 * If the user did not redefine the ARFLAGS macro in the
231210d63b7dSRichard Lowe 		 * default makefile (make.rules), then we'd like to
231310d63b7dSRichard Lowe 		 * change the macro value of ARFLAGS to be in accordance
231410d63b7dSRichard Lowe 		 * with "POSIX" requirements.
231510d63b7dSRichard Lowe 		 */
231610d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, "ARFLAGS");
231710d63b7dSRichard Lowe 		name = GETNAME(wcs_buffer, wcslen(wcs_buffer));
231810d63b7dSRichard Lowe 		macro = get_prop(name->prop, macro_prop);
231910d63b7dSRichard Lowe 		if ((macro != NULL) && /* Maybe (macro == NULL) || ? */
232010d63b7dSRichard Lowe 		    (IS_EQUAL(macro->body.macro.value->string_mb,
232110d63b7dSRichard Lowe 		              "rv"))) {
232210d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, "-rv");
232310d63b7dSRichard Lowe 			value = GETNAME(wcs_buffer, wcslen(wcs_buffer));
232410d63b7dSRichard Lowe 			(void) SETVAR(name,
232510d63b7dSRichard Lowe 			              value,
232610d63b7dSRichard Lowe 			              false);
232710d63b7dSRichard Lowe 		}
232810d63b7dSRichard Lowe 	}
232910d63b7dSRichard Lowe 
233010d63b7dSRichard Lowe 	if (!posix && !svr4) {
233110d63b7dSRichard Lowe 		set_sgs_support();
233210d63b7dSRichard Lowe 	}
233310d63b7dSRichard Lowe 
233410d63b7dSRichard Lowe 
233510d63b7dSRichard Lowe /*
233610d63b7dSRichard Lowe  *	Make sure KEEP_STATE is in the environment if KEEP_STATE is on.
233710d63b7dSRichard Lowe  */
233810d63b7dSRichard Lowe 	macro = get_prop(keep_state_name->prop, macro_prop);
233910d63b7dSRichard Lowe 	if ((macro != NULL) &&
234010d63b7dSRichard Lowe 	    macro->body.macro.exported) {
234110d63b7dSRichard Lowe 		keep_state = true;
234210d63b7dSRichard Lowe 	}
234310d63b7dSRichard Lowe 	if (keep_state) {
234410d63b7dSRichard Lowe 		if (macro == NULL) {
234510d63b7dSRichard Lowe 			macro = maybe_append_prop(keep_state_name,
234610d63b7dSRichard Lowe 						  macro_prop);
234710d63b7dSRichard Lowe 		}
234810d63b7dSRichard Lowe 		macro->body.macro.exported = true;
234910d63b7dSRichard Lowe 		(void) SETVAR(keep_state_name,
235010d63b7dSRichard Lowe 			      empty_name,
235110d63b7dSRichard Lowe 			      false);
235210d63b7dSRichard Lowe 
235310d63b7dSRichard Lowe 		/*
235410d63b7dSRichard Lowe 		 *	Read state file
235510d63b7dSRichard Lowe 		 */
235610d63b7dSRichard Lowe 
235710d63b7dSRichard Lowe 		/* Before we read state, let's make sure we have
235810d63b7dSRichard Lowe 		** right state file.
235910d63b7dSRichard Lowe 		*/
236010d63b7dSRichard Lowe 		/* just in case macro references are used in make_state file
236110d63b7dSRichard Lowe 		** name, we better expand them at this stage using expand_value.
236210d63b7dSRichard Lowe 		*/
236310d63b7dSRichard Lowe 		INIT_STRING_FROM_STACK(dest, destbuffer);
236410d63b7dSRichard Lowe 		expand_value(make_state, &dest, false);
236510d63b7dSRichard Lowe 
236610d63b7dSRichard Lowe 		make_state = GETNAME(dest.buffer.start, FIND_LENGTH);
236710d63b7dSRichard Lowe 
236810d63b7dSRichard Lowe 		if(!stat(make_state->string_mb, &make_state_stat)) {
236910d63b7dSRichard Lowe 		   if(!(make_state_stat.st_mode & S_IFREG) ) {
237010d63b7dSRichard Lowe 			/* copy the make_state structure to the other
237110d63b7dSRichard Lowe 			** and then let make_state point to the new
237210d63b7dSRichard Lowe 			** one.
237310d63b7dSRichard Lowe 			*/
237410d63b7dSRichard Lowe 		      memcpy(&state_filename, make_state,sizeof(state_filename));
237510d63b7dSRichard Lowe 		      state_filename.string_mb = state_file_str_mb;
237610d63b7dSRichard Lowe 		/* Just a kludge to avoid two slashes back to back */
237710d63b7dSRichard Lowe 		      if((make_state->hash.length == 1)&&
237810d63b7dSRichard Lowe 			        (make_state->string_mb[0] == '/')) {
237910d63b7dSRichard Lowe 			 make_state->hash.length = 0;
238010d63b7dSRichard Lowe 			 make_state->string_mb[0] = '\0';
238110d63b7dSRichard Lowe 		      }
238210d63b7dSRichard Lowe 	   	      sprintf(state_file_str_mb,"%s%s",
238310d63b7dSRichard Lowe 		       make_state->string_mb,"/.make.state");
238410d63b7dSRichard Lowe 		      make_state = &state_filename;
238510d63b7dSRichard Lowe 			/* adjust the length to reflect the appended string */
238610d63b7dSRichard Lowe 		      make_state->hash.length += 12;
238710d63b7dSRichard Lowe 		   }
238810d63b7dSRichard Lowe 		} else { /* the file doesn't exist or no permission */
238910d63b7dSRichard Lowe 		   char tmp_path[MAXPATHLEN];
239010d63b7dSRichard Lowe 		   char *slashp;
239110d63b7dSRichard Lowe 
239210d63b7dSRichard Lowe 		   if (slashp = strrchr(make_state->string_mb, '/')) {
239310d63b7dSRichard Lowe 		      strncpy(tmp_path, make_state->string_mb,
239410d63b7dSRichard Lowe 				(slashp - make_state->string_mb));
239510d63b7dSRichard Lowe 			tmp_path[slashp - make_state->string_mb]=0;
239610d63b7dSRichard Lowe 		      if(strlen(tmp_path)) {
239710d63b7dSRichard Lowe 		        if(stat(tmp_path, &make_state_stat)) {
239810d63b7dSRichard Lowe 			  warning(gettext("directory %s for .KEEP_STATE_FILE does not exist"),tmp_path);
239910d63b7dSRichard Lowe 		        }
240010d63b7dSRichard Lowe 		        if (access(tmp_path, F_OK) != 0) {
240110d63b7dSRichard Lowe 			  warning(gettext("can't access dir %s"),tmp_path);
240210d63b7dSRichard Lowe 		        }
240310d63b7dSRichard Lowe 		      }
240410d63b7dSRichard Lowe 		   }
240510d63b7dSRichard Lowe 		}
240610d63b7dSRichard Lowe 		if (report_dependencies_level != 1) {
240710d63b7dSRichard Lowe 			Makefile_type	makefile_type_temp = makefile_type;
240810d63b7dSRichard Lowe 			makefile_type = reading_statefile;
240910d63b7dSRichard Lowe 			if (read_trace_level > 1) {
241010d63b7dSRichard Lowe 				trace_reader = true;
241110d63b7dSRichard Lowe 			}
241210d63b7dSRichard Lowe 			(void) read_simple_file(make_state,
241310d63b7dSRichard Lowe 						false,
241410d63b7dSRichard Lowe 						false,
241510d63b7dSRichard Lowe 						false,
241610d63b7dSRichard Lowe 						false,
241710d63b7dSRichard Lowe 						false,
241810d63b7dSRichard Lowe 						true);
241910d63b7dSRichard Lowe 			trace_reader = false;
242010d63b7dSRichard Lowe 			makefile_type = makefile_type_temp;
242110d63b7dSRichard Lowe 		}
242210d63b7dSRichard Lowe 	}
242310d63b7dSRichard Lowe }
242410d63b7dSRichard Lowe 
242510d63b7dSRichard Lowe /*
242610d63b7dSRichard Lowe  * Scan the argv for options and "=" type args and make them readonly.
242710d63b7dSRichard Lowe  */
242810d63b7dSRichard Lowe static void
242910d63b7dSRichard Lowe enter_argv_values(int argc, char *argv[], ASCII_Dyn_Array *makeflags_and_macro)
243010d63b7dSRichard Lowe {
243110d63b7dSRichard Lowe 	register char		*cp;
243210d63b7dSRichard Lowe 	register int		i;
243310d63b7dSRichard Lowe 	int			length;
243410d63b7dSRichard Lowe 	register Name		name;
243510d63b7dSRichard Lowe 	int			opt_separator = argc;
243610d63b7dSRichard Lowe 	char			tmp_char;
243710d63b7dSRichard Lowe 	wchar_t			*tmp_wcs_buffer;
243810d63b7dSRichard Lowe 	register Name		value;
243910d63b7dSRichard Lowe 	Boolean			append = false;
244010d63b7dSRichard Lowe 	Property		macro;
244110d63b7dSRichard Lowe 	struct stat		statbuf;
244210d63b7dSRichard Lowe 
244310d63b7dSRichard Lowe 
244410d63b7dSRichard Lowe 	/* Read argv options and "=" type args and make them readonly. */
244510d63b7dSRichard Lowe 	makefile_type = reading_nothing;
244610d63b7dSRichard Lowe 	for (i = 1; i < argc; ++i) {
244710d63b7dSRichard Lowe 		append = false;
244810d63b7dSRichard Lowe 		if (argv[i] == NULL) {
244910d63b7dSRichard Lowe 			continue;
245010d63b7dSRichard Lowe 		} else if (((argv[i][0] == '-') && (argv[i][1] == '-')) ||
245110d63b7dSRichard Lowe 			   ((argv[i][0] == (int) ' ') &&
245210d63b7dSRichard Lowe 			    (argv[i][1] == (int) '-') &&
245310d63b7dSRichard Lowe 			    (argv[i][2] == (int) ' ') &&
245410d63b7dSRichard Lowe 			    (argv[i][3] == (int) '-'))) {
245510d63b7dSRichard Lowe 			argv[i] = NULL;
245610d63b7dSRichard Lowe 			opt_separator = i;
245710d63b7dSRichard Lowe 			continue;
245810d63b7dSRichard Lowe 		} else if ((i < opt_separator) && (argv[i][0] == (int) hyphen_char)) {
245910d63b7dSRichard Lowe 			switch (parse_command_option(argv[i][1])) {
246010d63b7dSRichard Lowe 			case 1:	/* -f seen */
246110d63b7dSRichard Lowe 				++i;
246210d63b7dSRichard Lowe 				continue;
246310d63b7dSRichard Lowe 			case 2:	/* -c seen */
246410d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
246510d63b7dSRichard Lowe 					fatal(gettext("No dmake rcfile argument after -c flag"));
246610d63b7dSRichard Lowe 				}
246710d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "DMAKE_RCFILE");
246810d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
246910d63b7dSRichard Lowe 				break;
247010d63b7dSRichard Lowe 			case 4:	/* -g seen */
247110d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
247210d63b7dSRichard Lowe 					fatal(gettext("No dmake group argument after -g flag"));
247310d63b7dSRichard Lowe 				}
247410d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "DMAKE_GROUP");
247510d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
247610d63b7dSRichard Lowe 				break;
247710d63b7dSRichard Lowe 			case 8:	/* -j seen */
247810d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
247910d63b7dSRichard Lowe 					fatal(gettext("No dmake max jobs argument after -j flag"));
248010d63b7dSRichard Lowe 				}
248110d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "DMAKE_MAX_JOBS");
248210d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
248310d63b7dSRichard Lowe 				break;
248410d63b7dSRichard Lowe 			case 16: /* -M seen */
248510d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
248610d63b7dSRichard Lowe 					fatal(gettext("No pmake machinesfile argument after -M flag"));
248710d63b7dSRichard Lowe 				}
248810d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "PMAKE_MACHINESFILE");
248910d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
249010d63b7dSRichard Lowe 				break;
249110d63b7dSRichard Lowe 			case 32: /* -m seen */
249210d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
249310d63b7dSRichard Lowe 					fatal(gettext("No dmake mode argument after -m flag"));
249410d63b7dSRichard Lowe 				}
249510d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "DMAKE_MODE");
249610d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
249710d63b7dSRichard Lowe 				break;
249810d63b7dSRichard Lowe 			case 256: /* -K seen */
249910d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
250010d63b7dSRichard Lowe 					fatal(gettext("No makestate filename argument after -K flag"));
250110d63b7dSRichard Lowe 				}
250210d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, argv[i+1]);
250310d63b7dSRichard Lowe 				make_state = GETNAME(wcs_buffer, FIND_LENGTH);
250410d63b7dSRichard Lowe 				keep_state = true;
250510d63b7dSRichard Lowe 				argv[i] = NULL;
250610d63b7dSRichard Lowe 				argv[i+1] = NULL;
250710d63b7dSRichard Lowe 				continue;
250810d63b7dSRichard Lowe 			case 512:	/* -o seen */
250910d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
251010d63b7dSRichard Lowe 					fatal(gettext("No dmake output dir argument after -o flag"));
251110d63b7dSRichard Lowe 				}
251210d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, "DMAKE_ODIR");
251310d63b7dSRichard Lowe 				name = GETNAME(wcs_buffer, FIND_LENGTH);
251410d63b7dSRichard Lowe 				break;
251510d63b7dSRichard Lowe 			case 1024: /* -x seen */
251610d63b7dSRichard Lowe 				if (argv[i+1] == NULL) {
251710d63b7dSRichard Lowe 					fatal(gettext("No argument after -x flag"));
251810d63b7dSRichard Lowe 				}
251910d63b7dSRichard Lowe 				length = strlen( "SUN_MAKE_COMPAT_MODE=");
252010d63b7dSRichard Lowe 				if (strncmp(argv[i+1], "SUN_MAKE_COMPAT_MODE=", length) == 0) {
252110d63b7dSRichard Lowe 					argv[i+1] = &argv[i+1][length];
252210d63b7dSRichard Lowe 					MBSTOWCS(wcs_buffer, "SUN_MAKE_COMPAT_MODE");
252310d63b7dSRichard Lowe 					name = GETNAME(wcs_buffer, FIND_LENGTH);
252410d63b7dSRichard Lowe 					dmake_compat_mode_specified = dmake_add_mode_specified;
252510d63b7dSRichard Lowe 					break;
252610d63b7dSRichard Lowe 				}
252710d63b7dSRichard Lowe 				length = strlen( "DMAKE_OUTPUT_MODE=");
252810d63b7dSRichard Lowe 				if (strncmp(argv[i+1], "DMAKE_OUTPUT_MODE=", length) == 0) {
252910d63b7dSRichard Lowe 					argv[i+1] = &argv[i+1][length];
253010d63b7dSRichard Lowe 					MBSTOWCS(wcs_buffer, "DMAKE_OUTPUT_MODE");
253110d63b7dSRichard Lowe 					name = GETNAME(wcs_buffer, FIND_LENGTH);
253210d63b7dSRichard Lowe 					dmake_output_mode_specified = dmake_add_mode_specified;
253310d63b7dSRichard Lowe 				} else {
253410d63b7dSRichard Lowe 					warning(gettext("Unknown argument `%s' after -x flag (ignored)"),
253510d63b7dSRichard Lowe 					      argv[i+1]);
253610d63b7dSRichard Lowe 					argv[i] = argv[i + 1] = NULL;
253710d63b7dSRichard Lowe 					continue;
253810d63b7dSRichard Lowe 				}
253910d63b7dSRichard Lowe 				break;
254036cd0120SRobert Mustacchi 			case 2048: /* -C seen */
254136cd0120SRobert Mustacchi 				if (argv[i + 1] == NULL) {
254236cd0120SRobert Mustacchi 					fatal(gettext("No argument after -C flag"));
254336cd0120SRobert Mustacchi 				}
254436cd0120SRobert Mustacchi 				if (chdir(argv[i + 1]) != 0) {
254536cd0120SRobert Mustacchi 					fatal(gettext("failed to change to directory %s: %s"),
254636cd0120SRobert Mustacchi 					    argv[i + 1], strerror(errno));
254736cd0120SRobert Mustacchi 				}
254832106ed6SJohn Levon 				MBSTOWCS(wcs_buffer, "DMAKE_CDIR");
254932106ed6SJohn Levon 				name = GETNAME(wcs_buffer, FIND_LENGTH);
255036cd0120SRobert Mustacchi 				path_reset = true;
255136cd0120SRobert Mustacchi 				rebuild_arg0 = true;
255236cd0120SRobert Mustacchi 				(void) get_current_path();
255336cd0120SRobert Mustacchi 				break;
255410d63b7dSRichard Lowe 			default: /* Shouldn't reach here */
255510d63b7dSRichard Lowe 				argv[i] = NULL;
255610d63b7dSRichard Lowe 				continue;
255710d63b7dSRichard Lowe 			}
255810d63b7dSRichard Lowe 			argv[i] = NULL;
255910d63b7dSRichard Lowe 			if (i == (argc - 1)) {
256010d63b7dSRichard Lowe 				break;
256110d63b7dSRichard Lowe 			}
256210d63b7dSRichard Lowe 			if ((length = strlen(argv[i+1])) >= MAXPATHLEN) {
256310d63b7dSRichard Lowe 				tmp_wcs_buffer = ALLOC_WC(length + 1);
256410d63b7dSRichard Lowe 				(void) mbstowcs(tmp_wcs_buffer, argv[i+1], length + 1);
256510d63b7dSRichard Lowe 				value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
256610d63b7dSRichard Lowe 				retmem(tmp_wcs_buffer);
256710d63b7dSRichard Lowe 			} else {
256810d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, argv[i+1]);
256910d63b7dSRichard Lowe 				value = GETNAME(wcs_buffer, FIND_LENGTH);
257010d63b7dSRichard Lowe 			}
257110d63b7dSRichard Lowe 			argv[i+1] = NULL;
257210d63b7dSRichard Lowe 		} else if ((cp = strchr(argv[i], (int) equal_char)) != NULL) {
257310d63b7dSRichard Lowe /*
257410d63b7dSRichard Lowe  * Combine all macro in dynamic array
257510d63b7dSRichard Lowe  */
257610d63b7dSRichard Lowe 			if(*(cp-1) == (int) plus_char)
257710d63b7dSRichard Lowe 			{
257810d63b7dSRichard Lowe 				if(isspace(*(cp-2))) {
257910d63b7dSRichard Lowe 					append = true;
258010d63b7dSRichard Lowe 					cp--;
258110d63b7dSRichard Lowe 				}
258210d63b7dSRichard Lowe 			}
258310d63b7dSRichard Lowe 			if(!append)
258410d63b7dSRichard Lowe 				append_or_replace_macro_in_dyn_array(makeflags_and_macro, argv[i]);
258510d63b7dSRichard Lowe 
258610d63b7dSRichard Lowe 			while (isspace(*(cp-1))) {
258710d63b7dSRichard Lowe 				cp--;
258810d63b7dSRichard Lowe 			}
258910d63b7dSRichard Lowe 			tmp_char = *cp;
259010d63b7dSRichard Lowe 			*cp = (int) nul_char;
259110d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, argv[i]);
259210d63b7dSRichard Lowe 			*cp = tmp_char;
259310d63b7dSRichard Lowe 			name = GETNAME(wcs_buffer, wcslen(wcs_buffer));
259410d63b7dSRichard Lowe 			while (*cp != (int) equal_char) {
259510d63b7dSRichard Lowe 				cp++;
259610d63b7dSRichard Lowe 			}
259710d63b7dSRichard Lowe 			cp++;
259810d63b7dSRichard Lowe 			while (isspace(*cp) && (*cp != (int) nul_char)) {
259910d63b7dSRichard Lowe 				cp++;
260010d63b7dSRichard Lowe 			}
260110d63b7dSRichard Lowe 			if ((length = strlen(cp)) >= MAXPATHLEN) {
260210d63b7dSRichard Lowe 				tmp_wcs_buffer = ALLOC_WC(length + 1);
260310d63b7dSRichard Lowe 				(void) mbstowcs(tmp_wcs_buffer, cp, length + 1);
260410d63b7dSRichard Lowe 				value = GETNAME(tmp_wcs_buffer, FIND_LENGTH);
260510d63b7dSRichard Lowe 				retmem(tmp_wcs_buffer);
260610d63b7dSRichard Lowe 			} else {
260710d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, cp);
260810d63b7dSRichard Lowe 				value = GETNAME(wcs_buffer, FIND_LENGTH);
260910d63b7dSRichard Lowe 			}
261010d63b7dSRichard Lowe 			argv[i] = NULL;
261110d63b7dSRichard Lowe 		} else {
261210d63b7dSRichard Lowe 			/* Illegal MAKEFLAGS argument */
261310d63b7dSRichard Lowe 			continue;
261410d63b7dSRichard Lowe 		}
261510d63b7dSRichard Lowe 		if(append) {
261610d63b7dSRichard Lowe 			setvar_append(name, value);
261710d63b7dSRichard Lowe 			append = false;
261810d63b7dSRichard Lowe 		} else {
261910d63b7dSRichard Lowe 			macro = maybe_append_prop(name, macro_prop);
262010d63b7dSRichard Lowe 			macro->body.macro.exported = true;
262110d63b7dSRichard Lowe 			SETVAR(name, value, false)->body.macro.read_only = true;
262210d63b7dSRichard Lowe 		}
262310d63b7dSRichard Lowe 	}
262410d63b7dSRichard Lowe }
262510d63b7dSRichard Lowe 
262610d63b7dSRichard Lowe /*
262710d63b7dSRichard Lowe  * Append the DMake option and value to the MAKEFLAGS string.
262810d63b7dSRichard Lowe  */
262910d63b7dSRichard Lowe static void
263010d63b7dSRichard Lowe append_makeflags_string(Name name, register String makeflags_string)
263110d63b7dSRichard Lowe {
263210d63b7dSRichard Lowe 	const char	*option;
263310d63b7dSRichard Lowe 
263410d63b7dSRichard Lowe 	if (strcmp(name->string_mb, "DMAKE_GROUP") == 0) {
263510d63b7dSRichard Lowe 		option = " -g ";
263610d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "DMAKE_MAX_JOBS") == 0) {
263710d63b7dSRichard Lowe 		option = " -j ";
263810d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "DMAKE_MODE") == 0) {
263910d63b7dSRichard Lowe 		option = " -m ";
264010d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "DMAKE_ODIR") == 0) {
264110d63b7dSRichard Lowe 		option = " -o ";
264210d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "DMAKE_RCFILE") == 0) {
264310d63b7dSRichard Lowe 		option = " -c ";
264410d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "PMAKE_MACHINESFILE") == 0) {
264510d63b7dSRichard Lowe 		option = " -M ";
264610d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "DMAKE_OUTPUT_MODE") == 0) {
264710d63b7dSRichard Lowe 		option = " -x DMAKE_OUTPUT_MODE=";
264810d63b7dSRichard Lowe 	} else if (strcmp(name->string_mb, "SUN_MAKE_COMPAT_MODE") == 0) {
264910d63b7dSRichard Lowe 		option = " -x SUN_MAKE_COMPAT_MODE=";
265010d63b7dSRichard Lowe 	} else {
265110d63b7dSRichard Lowe 		fatal(gettext("Internal error: name not recognized in append_makeflags_string()"));
265210d63b7dSRichard Lowe 	}
265310d63b7dSRichard Lowe 	Property prop = maybe_append_prop(name, macro_prop);
265410d63b7dSRichard Lowe 	if( prop == 0 || prop->body.macro.value == 0 ||
265510d63b7dSRichard Lowe 	    prop->body.macro.value->string_mb == 0 ) {
265610d63b7dSRichard Lowe 		return;
265710d63b7dSRichard Lowe 	}
265810d63b7dSRichard Lowe 	char mbs_value[MAXPATHLEN + 100];
265910d63b7dSRichard Lowe 	strcpy(mbs_value, option);
266010d63b7dSRichard Lowe 	strcat(mbs_value, prop->body.macro.value->string_mb);
266110d63b7dSRichard Lowe 	MBSTOWCS(wcs_buffer, mbs_value);
266210d63b7dSRichard Lowe 	append_string(wcs_buffer, makeflags_string, FIND_LENGTH);
266310d63b7dSRichard Lowe }
266410d63b7dSRichard Lowe 
266510d63b7dSRichard Lowe /*
266610d63b7dSRichard Lowe  *	read_environment(read_only)
266710d63b7dSRichard Lowe  *
266810d63b7dSRichard Lowe  *	This routine reads the process environment when make starts and enters
266910d63b7dSRichard Lowe  *	it as make macros. The environment variable SHELL is ignored.
267010d63b7dSRichard Lowe  *
267110d63b7dSRichard Lowe  *	Parameters:
267210d63b7dSRichard Lowe  *		read_only	Should we make env vars read only?
267310d63b7dSRichard Lowe  *
267410d63b7dSRichard Lowe  *	Global variables used:
267510d63b7dSRichard Lowe  *		report_pwd	Set if this make was started by other make
267610d63b7dSRichard Lowe  */
267710d63b7dSRichard Lowe static void
267810d63b7dSRichard Lowe read_environment(Boolean read_only)
267910d63b7dSRichard Lowe {
268010d63b7dSRichard Lowe 	register char		**environment;
268110d63b7dSRichard Lowe 	int			length;
268210d63b7dSRichard Lowe 	wchar_t			*tmp_wcs_buffer;
268310d63b7dSRichard Lowe 	Boolean			alloced_tmp_wcs_buffer = false;
268410d63b7dSRichard Lowe 	register wchar_t	*name;
268510d63b7dSRichard Lowe 	register wchar_t	*value;
268610d63b7dSRichard Lowe 	register Name		macro;
268710d63b7dSRichard Lowe 	Property		val;
268810d63b7dSRichard Lowe 	Boolean			read_only_saved;
268910d63b7dSRichard Lowe 
269010d63b7dSRichard Lowe 	reading_environment = true;
269110d63b7dSRichard Lowe 	environment = environ;
269210d63b7dSRichard Lowe 	for (; *environment; environment++) {
269310d63b7dSRichard Lowe 		read_only_saved = read_only;
269410d63b7dSRichard Lowe 		if ((length = strlen(*environment)) >= MAXPATHLEN) {
269510d63b7dSRichard Lowe 			tmp_wcs_buffer = ALLOC_WC(length + 1);
269610d63b7dSRichard Lowe 			alloced_tmp_wcs_buffer = true;
269710d63b7dSRichard Lowe 			(void) mbstowcs(tmp_wcs_buffer, *environment, length + 1);
269810d63b7dSRichard Lowe 			name = tmp_wcs_buffer;
269910d63b7dSRichard Lowe 		} else {
270010d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, *environment);
270110d63b7dSRichard Lowe 			name = wcs_buffer;
270210d63b7dSRichard Lowe 		}
270310d63b7dSRichard Lowe 		value = (wchar_t *) wcschr(name, (int) equal_char);
270410d63b7dSRichard Lowe 
270510d63b7dSRichard Lowe 		/*
270610d63b7dSRichard Lowe 		 * Looks like there's a bug in the system, but sometimes
270710d63b7dSRichard Lowe 		 * you can get blank lines in *environment.
270810d63b7dSRichard Lowe 		 */
270910d63b7dSRichard Lowe 		if (!value) {
271010d63b7dSRichard Lowe 			continue;
271110d63b7dSRichard Lowe 		}
271210d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer2, "SHELL=");
271310d63b7dSRichard Lowe 		if (IS_WEQUALN(name, wcs_buffer2, wcslen(wcs_buffer2))) {
271410d63b7dSRichard Lowe 			continue;
271510d63b7dSRichard Lowe 		}
271610d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer2, "MAKEFLAGS=");
271710d63b7dSRichard Lowe 		if (IS_WEQUALN(name, wcs_buffer2, wcslen(wcs_buffer2))) {
271810d63b7dSRichard Lowe 			report_pwd = true;
271910d63b7dSRichard Lowe 			/*
272010d63b7dSRichard Lowe 			 * In POSIX mode we do not want MAKEFLAGS to be readonly.
272110d63b7dSRichard Lowe 			 * If the MAKEFLAGS macro is subsequently set by the makefile,
272210d63b7dSRichard Lowe 			 * it replaces the MAKEFLAGS variable currently found in the
272310d63b7dSRichard Lowe 			 * environment.
272410d63b7dSRichard Lowe 			 * See Assertion 50 in section 6.2.5.3 of standard P1003.3.2/D8.
272510d63b7dSRichard Lowe 			 */
272610d63b7dSRichard Lowe 			if(posix) {
272710d63b7dSRichard Lowe 				read_only_saved = false;
272810d63b7dSRichard Lowe 			}
272910d63b7dSRichard Lowe 		}
273010d63b7dSRichard Lowe 
273110d63b7dSRichard Lowe 		/*
273210d63b7dSRichard Lowe 		 * We ignore SUNPRO_DEPENDENCIES. This environment variable is
273310d63b7dSRichard Lowe 		 * set by make and read by cpp which then writes info to
273410d63b7dSRichard Lowe 		 * .make.dependency.xxx.  When make is invoked by another make
273510d63b7dSRichard Lowe 		 * (recursive make), we don't want to read this because then
273610d63b7dSRichard Lowe 		 * the child make will end up writing to the parent
273710d63b7dSRichard Lowe 		 * directory's .make.state and clobbering them.
273810d63b7dSRichard Lowe 		 */
273910d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer2, "SUNPRO_DEPENDENCIES");
274010d63b7dSRichard Lowe 		if (IS_WEQUALN(name, wcs_buffer2, wcslen(wcs_buffer2))) {
274110d63b7dSRichard Lowe 			continue;
274210d63b7dSRichard Lowe 		}
274310d63b7dSRichard Lowe 
274410d63b7dSRichard Lowe 		macro = GETNAME(name, value - name);
274510d63b7dSRichard Lowe 		maybe_append_prop(macro, macro_prop)->body.macro.exported =
274610d63b7dSRichard Lowe 		  true;
274710d63b7dSRichard Lowe 		if ((value == NULL) || ((value + 1)[0] == (int) nul_char)) {
274810d63b7dSRichard Lowe 			val = setvar_daemon(macro,
274910d63b7dSRichard Lowe 					    (Name) NULL,
275010d63b7dSRichard Lowe 					    false, no_daemon, false, debug_level);
275110d63b7dSRichard Lowe 		} else {
275210d63b7dSRichard Lowe 			val = setvar_daemon(macro,
275310d63b7dSRichard Lowe 					    GETNAME(value + 1, FIND_LENGTH),
275410d63b7dSRichard Lowe 					    false, no_daemon, false, debug_level);
275510d63b7dSRichard Lowe 		}
275610d63b7dSRichard Lowe 		val->body.macro.read_only = read_only_saved;
275710d63b7dSRichard Lowe 		if (alloced_tmp_wcs_buffer) {
275810d63b7dSRichard Lowe 			retmem(tmp_wcs_buffer);
275910d63b7dSRichard Lowe 			alloced_tmp_wcs_buffer = false;
276010d63b7dSRichard Lowe 		}
276110d63b7dSRichard Lowe 	}
276210d63b7dSRichard Lowe 	reading_environment = false;
276310d63b7dSRichard Lowe }
276410d63b7dSRichard Lowe 
276510d63b7dSRichard Lowe /*
276610d63b7dSRichard Lowe  *	read_makefile(makefile, complain, must_exist, report_file)
276710d63b7dSRichard Lowe  *
276810d63b7dSRichard Lowe  *	Read one makefile and check the result
276910d63b7dSRichard Lowe  *
277010d63b7dSRichard Lowe  *	Return value:
277110d63b7dSRichard Lowe  *				false is the read failed
277210d63b7dSRichard Lowe  *
277310d63b7dSRichard Lowe  *	Parameters:
277410d63b7dSRichard Lowe  *		makefile	The file to read
277510d63b7dSRichard Lowe  *		complain	Passed thru to read_simple_file()
277610d63b7dSRichard Lowe  *		must_exist	Passed thru to read_simple_file()
277710d63b7dSRichard Lowe  *		report_file	Passed thru to read_simple_file()
277810d63b7dSRichard Lowe  *
277910d63b7dSRichard Lowe  *	Global variables used:
278010d63b7dSRichard Lowe  *		makefile_type	Set to indicate we are reading main file
278110d63b7dSRichard Lowe  *		recursion_level	Initialized
278210d63b7dSRichard Lowe  */
278310d63b7dSRichard Lowe static Boolean
278410d63b7dSRichard Lowe read_makefile(register Name makefile, Boolean complain, Boolean must_exist, Boolean report_file)
278510d63b7dSRichard Lowe {
278610d63b7dSRichard Lowe 	Boolean			b;
278710d63b7dSRichard Lowe 
278810d63b7dSRichard Lowe 	makefile_type = reading_makefile;
278910d63b7dSRichard Lowe 	recursion_level = 0;
279010d63b7dSRichard Lowe 	reading_dependencies = true;
279110d63b7dSRichard Lowe 	b = read_simple_file(makefile, true, true, complain,
279210d63b7dSRichard Lowe 			     must_exist, report_file, false);
279310d63b7dSRichard Lowe 	reading_dependencies = false;
279410d63b7dSRichard Lowe 	return b;
279510d63b7dSRichard Lowe }
279610d63b7dSRichard Lowe 
279710d63b7dSRichard Lowe /*
279810d63b7dSRichard Lowe  *	make_targets(argc, argv, parallel_flag)
279910d63b7dSRichard Lowe  *
280010d63b7dSRichard Lowe  *	Call doname on the specified targets
280110d63b7dSRichard Lowe  *
280210d63b7dSRichard Lowe  *	Parameters:
280310d63b7dSRichard Lowe  *		argc		You know what this is
280410d63b7dSRichard Lowe  *		argv		You know what this is
280510d63b7dSRichard Lowe  *		parallel_flag	True if building in parallel
280610d63b7dSRichard Lowe  *
280710d63b7dSRichard Lowe  *	Global variables used:
280810d63b7dSRichard Lowe  *		build_failed_seen Used to generated message after failed -k
280910d63b7dSRichard Lowe  *		commands_done	Used to generate message "Up to date"
281010d63b7dSRichard Lowe  *		default_target_to_build	First proper target in makefile
281110d63b7dSRichard Lowe  *		init		The Name ".INIT", use to run command
281210d63b7dSRichard Lowe  *		parallel	Global parallel building flag
281310d63b7dSRichard Lowe  *		quest		make -q, suppresses messages
281410d63b7dSRichard Lowe  *		recursion_level	Initialized, used for tracing
281510d63b7dSRichard Lowe  *		report_dependencies make -P, regroves whole process
281610d63b7dSRichard Lowe  */
281710d63b7dSRichard Lowe static void
281810d63b7dSRichard Lowe make_targets(int argc, char **argv, Boolean parallel_flag)
281910d63b7dSRichard Lowe {
282010d63b7dSRichard Lowe 	int			i;
282110d63b7dSRichard Lowe 	char			*cp;
282210d63b7dSRichard Lowe 	Doname			result;
282310d63b7dSRichard Lowe 	register Boolean	target_to_make_found = false;
282410d63b7dSRichard Lowe 
282510d63b7dSRichard Lowe 	(void) doname(init, true, true);
282610d63b7dSRichard Lowe 	recursion_level = 1;
282710d63b7dSRichard Lowe 	parallel = parallel_flag;
282810d63b7dSRichard Lowe /*
282910d63b7dSRichard Lowe  *	make remaining args
283010d63b7dSRichard Lowe  */
283110d63b7dSRichard Lowe /*
283210d63b7dSRichard Lowe 	if ((report_dependencies_level == 0) && parallel) {
283310d63b7dSRichard Lowe  */
283410d63b7dSRichard Lowe 	if (parallel) {
283510d63b7dSRichard Lowe 		/*
283610d63b7dSRichard Lowe 		 * If building targets in parallel, start all of the
283710d63b7dSRichard Lowe 		 * remaining args to build in parallel.
283810d63b7dSRichard Lowe 		 */
283910d63b7dSRichard Lowe 		for (i = 1; i < argc; i++) {
284010d63b7dSRichard Lowe 			if ((cp = argv[i]) != NULL) {
284110d63b7dSRichard Lowe 				commands_done = false;
284210d63b7dSRichard Lowe 				if ((cp[0] == (int) period_char) &&
284310d63b7dSRichard Lowe 				    (cp[1] == (int) slash_char)) {
284410d63b7dSRichard Lowe 					cp += 2;
284510d63b7dSRichard Lowe 				}
284610d63b7dSRichard Lowe 				 if((cp[0] == (int) ' ') &&
284710d63b7dSRichard Lowe 				    (cp[1] == (int) '-') &&
284810d63b7dSRichard Lowe 				    (cp[2] == (int) ' ') &&
284910d63b7dSRichard Lowe 				    (cp[3] == (int) '-')) {
285010d63b7dSRichard Lowe 			            argv[i] = NULL;
285110d63b7dSRichard Lowe 					continue;
285210d63b7dSRichard Lowe 				}
285310d63b7dSRichard Lowe 				MBSTOWCS(wcs_buffer, cp);
285410d63b7dSRichard Lowe 				//default_target_to_build = GETNAME(wcs_buffer,
285510d63b7dSRichard Lowe 				//				  FIND_LENGTH);
285610d63b7dSRichard Lowe 				default_target_to_build = normalize_name(wcs_buffer,
285710d63b7dSRichard Lowe 								  wcslen(wcs_buffer));
285810d63b7dSRichard Lowe 				if (default_target_to_build == wait_name) {
285910d63b7dSRichard Lowe 					if (parallel_process_cnt > 0) {
286010d63b7dSRichard Lowe 						finish_running();
286110d63b7dSRichard Lowe 					}
286210d63b7dSRichard Lowe 					continue;
286310d63b7dSRichard Lowe 				}
286410d63b7dSRichard Lowe 				top_level_target = get_wstring(default_target_to_build->string_mb);
286510d63b7dSRichard Lowe 				/*
286610d63b7dSRichard Lowe 				 * If we can't execute the current target in
286710d63b7dSRichard Lowe 				 * parallel, hold off the target processing
286810d63b7dSRichard Lowe 				 * to preserve the order of the targets as they appeared
286910d63b7dSRichard Lowe 				 * in command line.
287010d63b7dSRichard Lowe 				 */
287110d63b7dSRichard Lowe 				if (!parallel_ok(default_target_to_build, false)
287210d63b7dSRichard Lowe 						&& parallel_process_cnt > 0) {
287310d63b7dSRichard Lowe 					finish_running();
287410d63b7dSRichard Lowe 				}
287510d63b7dSRichard Lowe 				result = doname_check(default_target_to_build,
287610d63b7dSRichard Lowe 						      true,
287710d63b7dSRichard Lowe 						      false,
287810d63b7dSRichard Lowe 						      false);
287910d63b7dSRichard Lowe 				gather_recursive_deps();
288010d63b7dSRichard Lowe 				if (/* !commands_done && */
288110d63b7dSRichard Lowe 				    (result == build_ok) &&
288210d63b7dSRichard Lowe 				    !quest &&
288310d63b7dSRichard Lowe 				    (report_dependencies_level == 0) /*  &&
288410d63b7dSRichard Lowe 				    (exists(default_target_to_build) > file_doesnt_exist)  */) {
288510d63b7dSRichard Lowe 					if (posix) {
288610d63b7dSRichard Lowe 						if (!commands_done) {
288710d63b7dSRichard Lowe 							(void) printf(gettext("`%s' is updated.\n"),
288810d63b7dSRichard Lowe 						 		      default_target_to_build->string_mb);
288910d63b7dSRichard Lowe 						} else {
289010d63b7dSRichard Lowe 							if (no_action_was_taken) {
289110d63b7dSRichard Lowe 								(void) printf(gettext("`%s': no action was taken.\n"),
289210d63b7dSRichard Lowe 						 			      default_target_to_build->string_mb);
289310d63b7dSRichard Lowe 							}
289410d63b7dSRichard Lowe 						}
289510d63b7dSRichard Lowe 					} else {
289610d63b7dSRichard Lowe 						default_target_to_build->stat.time = file_no_time;
289710d63b7dSRichard Lowe 						if (!commands_done &&
289810d63b7dSRichard Lowe 						    (exists(default_target_to_build) > file_doesnt_exist)) {
289910d63b7dSRichard Lowe 							(void) printf(gettext("`%s' is up to date.\n"),
290010d63b7dSRichard Lowe 								      default_target_to_build->string_mb);
290110d63b7dSRichard Lowe 						}
290210d63b7dSRichard Lowe 					}
290310d63b7dSRichard Lowe 				}
290410d63b7dSRichard Lowe 			}
290510d63b7dSRichard Lowe 		}
290610d63b7dSRichard Lowe 		/* Now wait for all of the targets to finish running */
290710d63b7dSRichard Lowe 		finish_running();
290810d63b7dSRichard Lowe 		//		setjmp(jmpbuffer);
290910d63b7dSRichard Lowe 
291010d63b7dSRichard Lowe 	}
291110d63b7dSRichard Lowe 	for (i = 1; i < argc; i++) {
291210d63b7dSRichard Lowe 		if ((cp = argv[i]) != NULL) {
291310d63b7dSRichard Lowe 			target_to_make_found = true;
291410d63b7dSRichard Lowe 			if ((cp[0] == (int) period_char) &&
291510d63b7dSRichard Lowe 			    (cp[1] == (int) slash_char)) {
291610d63b7dSRichard Lowe 				cp += 2;
291710d63b7dSRichard Lowe 			}
291810d63b7dSRichard Lowe 				 if((cp[0] == (int) ' ') &&
291910d63b7dSRichard Lowe 				    (cp[1] == (int) '-') &&
292010d63b7dSRichard Lowe 				    (cp[2] == (int) ' ') &&
292110d63b7dSRichard Lowe 				    (cp[3] == (int) '-')) {
292210d63b7dSRichard Lowe 			            argv[i] = NULL;
292310d63b7dSRichard Lowe 					continue;
292410d63b7dSRichard Lowe 				}
292510d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, cp);
292610d63b7dSRichard Lowe 			default_target_to_build = normalize_name(wcs_buffer, wcslen(wcs_buffer));
292710d63b7dSRichard Lowe 			top_level_target = get_wstring(default_target_to_build->string_mb);
292810d63b7dSRichard Lowe 			report_recursion(default_target_to_build);
292910d63b7dSRichard Lowe 			commands_done = false;
293010d63b7dSRichard Lowe 			if (parallel) {
293110d63b7dSRichard Lowe 				result = (Doname) default_target_to_build->state;
293210d63b7dSRichard Lowe 			} else {
293310d63b7dSRichard Lowe 				result = doname_check(default_target_to_build,
293410d63b7dSRichard Lowe 						      true,
293510d63b7dSRichard Lowe 						      false,
293610d63b7dSRichard Lowe 						      false);
293710d63b7dSRichard Lowe 			}
293810d63b7dSRichard Lowe 			gather_recursive_deps();
293910d63b7dSRichard Lowe 			if (build_failed_seen) {
294010d63b7dSRichard Lowe 				build_failed_ever_seen = true;
294110d63b7dSRichard Lowe 				warning(gettext("Target `%s' not remade because of errors"),
294210d63b7dSRichard Lowe 					default_target_to_build->string_mb);
294310d63b7dSRichard Lowe 			}
294410d63b7dSRichard Lowe 			build_failed_seen = false;
294510d63b7dSRichard Lowe 			if (report_dependencies_level > 0) {
294610d63b7dSRichard Lowe 				print_dependencies(default_target_to_build,
294710d63b7dSRichard Lowe 						   get_prop(default_target_to_build->prop,
294810d63b7dSRichard Lowe 							    line_prop));
294910d63b7dSRichard Lowe 			}
295010d63b7dSRichard Lowe 			default_target_to_build->stat.time =
295110d63b7dSRichard Lowe 			  file_no_time;
295210d63b7dSRichard Lowe 			if (default_target_to_build->colon_splits > 0) {
295310d63b7dSRichard Lowe 				default_target_to_build->state =
295410d63b7dSRichard Lowe 				  build_dont_know;
295510d63b7dSRichard Lowe 			}
295610d63b7dSRichard Lowe 			if (!parallel &&
295710d63b7dSRichard Lowe 			    /* !commands_done && */
295810d63b7dSRichard Lowe 			    (result == build_ok) &&
295910d63b7dSRichard Lowe 			    !quest &&
296010d63b7dSRichard Lowe 			    (report_dependencies_level == 0) /*  &&
296110d63b7dSRichard Lowe 			    (exists(default_target_to_build) > file_doesnt_exist)  */) {
296210d63b7dSRichard Lowe 				if (posix) {
296310d63b7dSRichard Lowe 					if (!commands_done) {
296410d63b7dSRichard Lowe 						(void) printf(gettext("`%s' is updated.\n"),
296510d63b7dSRichard Lowe 					 		      default_target_to_build->string_mb);
296610d63b7dSRichard Lowe 					} else {
296710d63b7dSRichard Lowe 						if (no_action_was_taken) {
296810d63b7dSRichard Lowe 							(void) printf(gettext("`%s': no action was taken.\n"),
296910d63b7dSRichard Lowe 					 			      default_target_to_build->string_mb);
297010d63b7dSRichard Lowe 						}
297110d63b7dSRichard Lowe 					}
297210d63b7dSRichard Lowe 				} else {
297310d63b7dSRichard Lowe 					if (!commands_done &&
297410d63b7dSRichard Lowe 					    (exists(default_target_to_build) > file_doesnt_exist)) {
297510d63b7dSRichard Lowe 						(void) printf(gettext("`%s' is up to date.\n"),
297610d63b7dSRichard Lowe 							      default_target_to_build->string_mb);
297710d63b7dSRichard Lowe 					}
297810d63b7dSRichard Lowe 				}
297910d63b7dSRichard Lowe 			}
298010d63b7dSRichard Lowe 		}
298110d63b7dSRichard Lowe 	}
298210d63b7dSRichard Lowe 
298310d63b7dSRichard Lowe /*
298410d63b7dSRichard Lowe  *	If no file arguments have been encountered,
298510d63b7dSRichard Lowe  *	make the first name encountered that doesnt start with a dot
298610d63b7dSRichard Lowe  */
298710d63b7dSRichard Lowe 	if (!target_to_make_found) {
298810d63b7dSRichard Lowe 		if (default_target_to_build == NULL) {
298910d63b7dSRichard Lowe 			fatal(gettext("No arguments to build"));
299010d63b7dSRichard Lowe 		}
299110d63b7dSRichard Lowe 		commands_done = false;
299210d63b7dSRichard Lowe 		top_level_target = get_wstring(default_target_to_build->string_mb);
299310d63b7dSRichard Lowe 		report_recursion(default_target_to_build);
299410d63b7dSRichard Lowe 
299510d63b7dSRichard Lowe 
299610d63b7dSRichard Lowe 		if (getenv("SPRO_EXPAND_ERRORS")){
299710d63b7dSRichard Lowe 			(void) printf("::(%s)\n",
299810d63b7dSRichard Lowe 				      default_target_to_build->string_mb);
299910d63b7dSRichard Lowe 		}
300010d63b7dSRichard Lowe 
300110d63b7dSRichard Lowe 
300210d63b7dSRichard Lowe 		result = doname_parallel(default_target_to_build, true, false);
300310d63b7dSRichard Lowe 		gather_recursive_deps();
300410d63b7dSRichard Lowe 		if (build_failed_seen) {
300510d63b7dSRichard Lowe 			build_failed_ever_seen = true;
300610d63b7dSRichard Lowe 			warning(gettext("Target `%s' not remade because of errors"),
300710d63b7dSRichard Lowe 				default_target_to_build->string_mb);
300810d63b7dSRichard Lowe 		}
300910d63b7dSRichard Lowe 		build_failed_seen = false;
301010d63b7dSRichard Lowe 		if (report_dependencies_level > 0) {
301110d63b7dSRichard Lowe 			print_dependencies(default_target_to_build,
301210d63b7dSRichard Lowe 					   get_prop(default_target_to_build->
301310d63b7dSRichard Lowe 						    prop,
301410d63b7dSRichard Lowe 						    line_prop));
301510d63b7dSRichard Lowe 		}
301610d63b7dSRichard Lowe 		default_target_to_build->stat.time = file_no_time;
301710d63b7dSRichard Lowe 		if (default_target_to_build->colon_splits > 0) {
301810d63b7dSRichard Lowe 			default_target_to_build->state = build_dont_know;
301910d63b7dSRichard Lowe 		}
302010d63b7dSRichard Lowe 		if (/* !commands_done && */
302110d63b7dSRichard Lowe 		    (result == build_ok) &&
302210d63b7dSRichard Lowe 		    !quest &&
302310d63b7dSRichard Lowe 		    (report_dependencies_level == 0) /*  &&
302410d63b7dSRichard Lowe 		    (exists(default_target_to_build) > file_doesnt_exist)  */) {
302510d63b7dSRichard Lowe 			if (posix) {
302610d63b7dSRichard Lowe 				if (!commands_done) {
302710d63b7dSRichard Lowe 					(void) printf(gettext("`%s' is updated.\n"),
302810d63b7dSRichard Lowe 				 		      default_target_to_build->string_mb);
302910d63b7dSRichard Lowe 				} else {
303010d63b7dSRichard Lowe 					if (no_action_was_taken) {
303110d63b7dSRichard Lowe 						(void) printf(gettext("`%s': no action was taken.\n"),
303210d63b7dSRichard Lowe 							      default_target_to_build->string_mb);
303310d63b7dSRichard Lowe 					}
303410d63b7dSRichard Lowe 				}
303510d63b7dSRichard Lowe 			} else {
303610d63b7dSRichard Lowe 				if (!commands_done &&
303710d63b7dSRichard Lowe 				    (exists(default_target_to_build) > file_doesnt_exist)) {
303810d63b7dSRichard Lowe 					(void) printf(gettext("`%s' is up to date.\n"),
303910d63b7dSRichard Lowe 						      default_target_to_build->string_mb);
304010d63b7dSRichard Lowe 				}
304110d63b7dSRichard Lowe 			}
304210d63b7dSRichard Lowe 		}
304310d63b7dSRichard Lowe 	}
304410d63b7dSRichard Lowe }
304510d63b7dSRichard Lowe 
304610d63b7dSRichard Lowe /*
304710d63b7dSRichard Lowe  *	report_recursion(target)
304810d63b7dSRichard Lowe  *
304910d63b7dSRichard Lowe  *	If this is a recursive make and the parent make has KEEP_STATE on
305010d63b7dSRichard Lowe  *	this routine reports the dependency to the parent make
305110d63b7dSRichard Lowe  *
305210d63b7dSRichard Lowe  *	Parameters:
305310d63b7dSRichard Lowe  *		target		Target to report
305410d63b7dSRichard Lowe  *
305510d63b7dSRichard Lowe  *	Global variables used:
305610d63b7dSRichard Lowe  *		makefiles_used		List of makefiles read
305710d63b7dSRichard Lowe  *		recursive_name		The Name ".RECURSIVE", printed
305810d63b7dSRichard Lowe  *		report_dependency	dwight
305910d63b7dSRichard Lowe  */
306010d63b7dSRichard Lowe static void
306110d63b7dSRichard Lowe report_recursion(register Name target)
306210d63b7dSRichard Lowe {
306310d63b7dSRichard Lowe 	register FILE		*report_file = get_report_file();
306410d63b7dSRichard Lowe 
306510d63b7dSRichard Lowe 	if ((report_file == NULL) || (report_file == (FILE*)-1)) {
306610d63b7dSRichard Lowe 		return;
306710d63b7dSRichard Lowe 	}
306810d63b7dSRichard Lowe 	if (primary_makefile == NULL) {
306910d63b7dSRichard Lowe 		/*
307010d63b7dSRichard Lowe 		 * This can happen when there is no makefile and
307110d63b7dSRichard Lowe 		 * only implicit rules are being used.
307210d63b7dSRichard Lowe 		 */
307310d63b7dSRichard Lowe 		return;
307410d63b7dSRichard Lowe 	}
307510d63b7dSRichard Lowe 	(void) fprintf(report_file,
307610d63b7dSRichard Lowe 		       "%s: %s ",
307710d63b7dSRichard Lowe 		       get_target_being_reported_for(),
307810d63b7dSRichard Lowe 		       recursive_name->string_mb);
307910d63b7dSRichard Lowe 	report_dependency(get_current_path());
308010d63b7dSRichard Lowe 	report_dependency(target->string_mb);
308110d63b7dSRichard Lowe 	report_dependency(primary_makefile->string_mb);
308210d63b7dSRichard Lowe 	(void) fprintf(report_file, "\n");
308310d63b7dSRichard Lowe }
308410d63b7dSRichard Lowe 
308510d63b7dSRichard Lowe /* Next function "append_or_replace_macro_in_dyn_array" must be in "misc.cc". */
308610d63b7dSRichard Lowe /* NIKMOL */
308710d63b7dSRichard Lowe extern void
308810d63b7dSRichard Lowe append_or_replace_macro_in_dyn_array(ASCII_Dyn_Array *Ar, char *macro)
308910d63b7dSRichard Lowe {
309010d63b7dSRichard Lowe 	register char	*cp0;	/* work pointer in macro */
309110d63b7dSRichard Lowe 	register char	*cp1;	/* work pointer in array */
309210d63b7dSRichard Lowe 	register char	*cp2;	/* work pointer in array */
309310d63b7dSRichard Lowe 	register char	*cp3;	/* work pointer in array */
309410d63b7dSRichard Lowe 	register char	*name;	/* macro name */
309510d63b7dSRichard Lowe 	register char	*value;	/* macro value */
309610d63b7dSRichard Lowe 	register int 	len_array;
309710d63b7dSRichard Lowe 	register int 	len_macro;
309810d63b7dSRichard Lowe 
309910d63b7dSRichard Lowe 	char * esc_value = NULL;
310010d63b7dSRichard Lowe 	int esc_len;
310110d63b7dSRichard Lowe 
310210d63b7dSRichard Lowe 	if (!(len_macro = strlen(macro))) return;
310310d63b7dSRichard Lowe 	name = macro;
310410d63b7dSRichard Lowe 	while (isspace(*(name))) {
310510d63b7dSRichard Lowe 		name++;
310610d63b7dSRichard Lowe 	}
310710d63b7dSRichard Lowe 	if (!(value = strchr(name, (int) equal_char))) {
310810d63b7dSRichard Lowe 		/* no '=' in macro */
310910d63b7dSRichard Lowe 		goto ERROR_MACRO;
311010d63b7dSRichard Lowe 	}
311110d63b7dSRichard Lowe 	cp0 = value;
311210d63b7dSRichard Lowe 	value++;
311310d63b7dSRichard Lowe 	while (isspace(*(value))) {
311410d63b7dSRichard Lowe 		value++;
311510d63b7dSRichard Lowe 	}
311610d63b7dSRichard Lowe 	while (isspace(*(cp0-1))) {
311710d63b7dSRichard Lowe 		cp0--;
311810d63b7dSRichard Lowe 	}
311910d63b7dSRichard Lowe 	if (cp0 <= name) goto ERROR_MACRO; /* no name */
312010d63b7dSRichard Lowe 	if (!(Ar->size)) goto ALLOC_ARRAY;
312110d63b7dSRichard Lowe 	cp1 = Ar->start;
312210d63b7dSRichard Lowe 
312310d63b7dSRichard Lowe LOOK_FOR_NAME:
312410d63b7dSRichard Lowe 	if (!(cp1 = strchr(cp1, name[0]))) goto APPEND_MACRO;
312510d63b7dSRichard Lowe 	if (!(cp2 = strchr(cp1, (int) equal_char))) goto APPEND_MACRO;
312610d63b7dSRichard Lowe 	if (strncmp(cp1, name, (size_t)(cp0-name))) {
312710d63b7dSRichard Lowe 		/* another name */
312810d63b7dSRichard Lowe 		cp1++;
312910d63b7dSRichard Lowe 		goto LOOK_FOR_NAME;
313010d63b7dSRichard Lowe 	}
313110d63b7dSRichard Lowe 	if (cp1 != Ar->start) {
313210d63b7dSRichard Lowe 		if (!isspace(*(cp1-1))) {
313310d63b7dSRichard Lowe 			/* another name */
313410d63b7dSRichard Lowe 			cp1++;
313510d63b7dSRichard Lowe 			goto LOOK_FOR_NAME;
313610d63b7dSRichard Lowe 		}
313710d63b7dSRichard Lowe 	}
313810d63b7dSRichard Lowe 	for (cp3 = cp1 + (cp0-name); cp3 < cp2; cp3++) {
313910d63b7dSRichard Lowe 		if (isspace(*cp3)) continue;
314010d63b7dSRichard Lowe 		/* else: another name */
314110d63b7dSRichard Lowe 		cp1++;
314210d63b7dSRichard Lowe 		goto LOOK_FOR_NAME;
314310d63b7dSRichard Lowe 	}
314410d63b7dSRichard Lowe 	/* Look for the next macro name in array */
314510d63b7dSRichard Lowe 	cp3 = cp2+1;
314610d63b7dSRichard Lowe 	if (*cp3 != (int) doublequote_char) {
314710d63b7dSRichard Lowe 		/* internal error */
314810d63b7dSRichard Lowe 		goto ERROR_MACRO;
314910d63b7dSRichard Lowe 	}
315010d63b7dSRichard Lowe 	if (!(cp3 = strchr(cp3+1, (int) doublequote_char))) {
315110d63b7dSRichard Lowe 		/* internal error */
315210d63b7dSRichard Lowe 		goto ERROR_MACRO;
315310d63b7dSRichard Lowe 	}
315410d63b7dSRichard Lowe 	cp3++;
315510d63b7dSRichard Lowe 	while (isspace(*cp3)) {
315610d63b7dSRichard Lowe 		cp3++;
315710d63b7dSRichard Lowe 	}
315810d63b7dSRichard Lowe 
315910d63b7dSRichard Lowe 	cp2 = cp1;  /* remove old macro */
316010d63b7dSRichard Lowe 	if ((*cp3) && (cp3 < Ar->start + Ar->size)) {
316110d63b7dSRichard Lowe 		for (; cp3 < Ar->start + Ar->size; cp3++) {
316210d63b7dSRichard Lowe 			*cp2++ = *cp3;
316310d63b7dSRichard Lowe 		}
316410d63b7dSRichard Lowe 	}
316510d63b7dSRichard Lowe 	for (; cp2 < Ar->start + Ar->size; cp2++) {
316610d63b7dSRichard Lowe 		*cp2 = 0;
316710d63b7dSRichard Lowe 	}
316810d63b7dSRichard Lowe 	if (*cp1) {
316910d63b7dSRichard Lowe 		/* check next name */
317010d63b7dSRichard Lowe 		goto LOOK_FOR_NAME;
317110d63b7dSRichard Lowe 	}
317210d63b7dSRichard Lowe 	goto APPEND_MACRO;
317310d63b7dSRichard Lowe 
317410d63b7dSRichard Lowe ALLOC_ARRAY:
317510d63b7dSRichard Lowe 	if (Ar->size) {
317610d63b7dSRichard Lowe 		cp1 = Ar->start;
317710d63b7dSRichard Lowe 	} else {
317810d63b7dSRichard Lowe 		cp1 = 0;
317910d63b7dSRichard Lowe 	}
318010d63b7dSRichard Lowe 	Ar->size += 128;
318110d63b7dSRichard Lowe 	Ar->start = getmem(Ar->size);
318210d63b7dSRichard Lowe 	for (len_array=0; len_array < Ar->size; len_array++) {
318310d63b7dSRichard Lowe 		Ar->start[len_array] = 0;
318410d63b7dSRichard Lowe 	}
318510d63b7dSRichard Lowe 	if (cp1) {
318610d63b7dSRichard Lowe 		strcpy(Ar->start, cp1);
318710d63b7dSRichard Lowe 		retmem((wchar_t *) cp1);
318810d63b7dSRichard Lowe 	}
318910d63b7dSRichard Lowe 
319010d63b7dSRichard Lowe APPEND_MACRO:
319110d63b7dSRichard Lowe 	len_array = strlen(Ar->start);
319210d63b7dSRichard Lowe 	esc_value = (char*)malloc(strlen(value)*2 + 1);
319310d63b7dSRichard Lowe 	quote_str(value, esc_value);
319410d63b7dSRichard Lowe 	esc_len = strlen(esc_value) - strlen(value);
319510d63b7dSRichard Lowe 	if (len_array + len_macro + esc_len + 5 >= Ar->size) goto  ALLOC_ARRAY;
319610d63b7dSRichard Lowe 	strcat(Ar->start, " ");
319710d63b7dSRichard Lowe 	strncat(Ar->start, name, cp0-name);
319810d63b7dSRichard Lowe 	strcat(Ar->start, "=");
319910d63b7dSRichard Lowe 	strncat(Ar->start, esc_value, strlen(esc_value));
320010d63b7dSRichard Lowe 	free(esc_value);
320110d63b7dSRichard Lowe 	return;
320210d63b7dSRichard Lowe ERROR_MACRO:
320310d63b7dSRichard Lowe 	/* Macro without '=' or with invalid left/right part */
320410d63b7dSRichard Lowe 	return;
320510d63b7dSRichard Lowe }
320610d63b7dSRichard Lowe 
320710d63b7dSRichard Lowe static void
320810d63b7dSRichard Lowe report_dir_enter_leave(Boolean entering)
320910d63b7dSRichard Lowe {
321010d63b7dSRichard Lowe 	char	rcwd[MAXPATHLEN];
321110d63b7dSRichard Lowe static	char *	mlev = NULL;
321210d63b7dSRichard Lowe 	char *	make_level_str = NULL;
321310d63b7dSRichard Lowe 	int	make_level_val = 0;
321410d63b7dSRichard Lowe 
321510d63b7dSRichard Lowe 	make_level_str = getenv("MAKELEVEL");
321610d63b7dSRichard Lowe 	if(make_level_str) {
321710d63b7dSRichard Lowe 		make_level_val = atoi(make_level_str);
321810d63b7dSRichard Lowe 	}
321910d63b7dSRichard Lowe 	if(mlev == NULL) {
322010d63b7dSRichard Lowe 		mlev = (char*) malloc(MAXPATHLEN);
322110d63b7dSRichard Lowe 	}
322210d63b7dSRichard Lowe 	if(entering) {
322310d63b7dSRichard Lowe 		sprintf(mlev, "MAKELEVEL=%d", make_level_val + 1);
322410d63b7dSRichard Lowe 	} else {
322510d63b7dSRichard Lowe 		make_level_val--;
322610d63b7dSRichard Lowe 		sprintf(mlev, "MAKELEVEL=%d", make_level_val);
322710d63b7dSRichard Lowe 	}
322810d63b7dSRichard Lowe 	putenv(mlev);
322910d63b7dSRichard Lowe 
323010d63b7dSRichard Lowe 	if(report_cwd) {
323110d63b7dSRichard Lowe 		if(make_level_val <= 0) {
323210d63b7dSRichard Lowe 			if(entering) {
323310d63b7dSRichard Lowe 				sprintf(rcwd,
323410d63b7dSRichard Lowe 				    gettext("%s: Entering directory `%s'\n"),
323510d63b7dSRichard Lowe 				    getprogname(),
323610d63b7dSRichard Lowe 				    get_current_path());
323710d63b7dSRichard Lowe 			} else {
323810d63b7dSRichard Lowe 				sprintf(rcwd,
323910d63b7dSRichard Lowe 				    gettext("%s: Leaving directory `%s'\n"),
324010d63b7dSRichard Lowe 				    getprogname(),
324110d63b7dSRichard Lowe 				    get_current_path());
324210d63b7dSRichard Lowe 			}
324310d63b7dSRichard Lowe 		} else {
324410d63b7dSRichard Lowe 			if(entering) {
324510d63b7dSRichard Lowe 				sprintf(rcwd,
324610d63b7dSRichard Lowe 				    gettext("%s[%d]: Entering directory `%s'\n"),
324710d63b7dSRichard Lowe 				    getprogname(),
324810d63b7dSRichard Lowe 				    make_level_val, get_current_path());
324910d63b7dSRichard Lowe 			} else {
325010d63b7dSRichard Lowe 				sprintf(rcwd,
325110d63b7dSRichard Lowe 				    gettext("%s[%d]: Leaving directory `%s'\n"),
325210d63b7dSRichard Lowe 				    getprogname(),
325310d63b7dSRichard Lowe 				    make_level_val, get_current_path());
325410d63b7dSRichard Lowe 			}
325510d63b7dSRichard Lowe 		}
325610d63b7dSRichard Lowe 		printf("%s", rcwd);
325710d63b7dSRichard Lowe 	}
325810d63b7dSRichard Lowe }
3259