110d63b7Richard Lowe#ifndef _MKSH_DEFS_H
210d63b7Richard Lowe#define _MKSH_DEFS_H
310d63b7Richard Lowe/*
410d63b7Richard Lowe * CDDL HEADER START
510d63b7Richard Lowe *
610d63b7Richard Lowe * The contents of this file are subject to the terms of the
710d63b7Richard Lowe * Common Development and Distribution License (the "License").
810d63b7Richard Lowe * You may not use this file except in compliance with the License.
910d63b7Richard Lowe *
1010d63b7Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1110d63b7Richard Lowe * or http://www.opensolaris.org/os/licensing.
1210d63b7Richard Lowe * See the License for the specific language governing permissions
1310d63b7Richard Lowe * and limitations under the License.
1410d63b7Richard Lowe *
1510d63b7Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1610d63b7Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1710d63b7Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
1810d63b7Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1910d63b7Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
2010d63b7Richard Lowe *
2110d63b7Richard Lowe * CDDL HEADER END
2210d63b7Richard Lowe */
2310d63b7Richard Lowe/*
2410d63b7Richard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2510d63b7Richard Lowe * Use is subject to license terms.
2610d63b7Richard Lowe */
2710d63b7Richard Lowe
2810d63b7Richard Lowe#include <limits.h>		/* MB_LEN_MAX */
2910d63b7Richard Lowe#include <stdio.h>
3010d63b7Richard Lowe#include <stdlib.h>		/* wchar_t */
3110d63b7Richard Lowe#include <string.h>		/* strcmp() */
3210d63b7Richard Lowe#include <sys/param.h>		/* MAXPATHLEN */
3310d63b7Richard Lowe#include <sys/types.h>		/* time_t, caddr_t */
3410d63b7Richard Lowe#include <vroot/vroot.h>	/* pathpt */
3510d63b7Richard Lowe#include <sys/time.h>		/* timestruc_t */
3610d63b7Richard Lowe#include <errno.h>		/* errno */
3710d63b7Richard Lowe
3810d63b7Richard Lowe#include <wctype.h>
3910d63b7Richard Lowe
4010d63b7Richard Lowe/*
4110d63b7Richard Lowe * A type and some utilities for boolean values
4210d63b7Richard Lowe */
4310d63b7Richard Lowe
4410d63b7Richard Lowe#define	false	BOOLEAN_false
4510d63b7Richard Lowe#define	true	BOOLEAN_true
4610d63b7Richard Lowe
4710d63b7Richard Lowetypedef enum {
4810d63b7Richard Lowe	false =		0,
4910d63b7Richard Lowe	true =		1,
5010d63b7Richard Lowe	failed =	0,
5110d63b7Richard Lowe	succeeded =	1
5210d63b7Richard Lowe} Boolean;
5310d63b7Richard Lowe#define BOOLEAN(expr)		((expr) ? true : false)
5410d63b7Richard Lowe
5510d63b7Richard Lowe/*
5610d63b7Richard Lowe * Some random constants (in an enum so dbx knows their values)
5710d63b7Richard Lowe */
5810d63b7Richard Loweenum {
5910d63b7Richard Lowe	update_delay = 30,		/* time between rstat checks */
6010d63b7Richard Lowe	ar_member_name_len = 1024,
6110d63b7Richard Lowe	hashsize = 2048			/* size of hash table */
6210d63b7Richard Lowe};
6310d63b7Richard Lowe
6410d63b7Richard Lowe
6510d63b7Richard Lowe/*
6610d63b7Richard Lowe * Symbols that defines all the different char constants make uses
6710d63b7Richard Lowe */
6810d63b7Richard Loweenum {
6910d63b7Richard Lowe	ampersand_char =	'&',
7010d63b7Richard Lowe	asterisk_char =		'*',
7110d63b7Richard Lowe	at_char =		'@',
7210d63b7Richard Lowe	backquote_char =	'`',
7310d63b7Richard Lowe	backslash_char =	'\\',
7410d63b7Richard Lowe	bar_char =		'|',
7510d63b7Richard Lowe	braceleft_char =	'{',
7610d63b7Richard Lowe	braceright_char =	'}',
7710d63b7Richard Lowe	bracketleft_char =	'[',
7810d63b7Richard Lowe	bracketright_char =	']',
7910d63b7Richard Lowe	colon_char =		':',
8010d63b7Richard Lowe	comma_char =		',',
8110d63b7Richard Lowe	dollar_char =		'$',
8210d63b7Richard Lowe	doublequote_char =	'"',
8310d63b7Richard Lowe	equal_char =		'=',
8410d63b7Richard Lowe	exclam_char =		'!',
8510d63b7Richard Lowe	greater_char =		'>',
8610d63b7Richard Lowe	hat_char =		'^',
8710d63b7Richard Lowe	hyphen_char =		'-',
8810d63b7Richard Lowe	less_char =		'<',
8910d63b7Richard Lowe	newline_char =		'\n',
9010d63b7Richard Lowe	nul_char =		'\0',
9110d63b7Richard Lowe	numbersign_char =	'#',
9210d63b7Richard Lowe	parenleft_char =	'(',
9310d63b7Richard Lowe	parenright_char =	')',
9410d63b7Richard Lowe	percent_char =		'%',
9510d63b7Richard Lowe	period_char =		'.',
9610d63b7Richard Lowe	plus_char =		'+',
9710d63b7Richard Lowe	question_char =		'?',
9810d63b7Richard Lowe	quote_char =		'\'',
9910d63b7Richard Lowe	semicolon_char =	';',
10010d63b7Richard Lowe	slash_char =		'/',
10110d63b7Richard Lowe	space_char =		' ',
10210d63b7Richard Lowe	tab_char =		'\t',
10310d63b7Richard Lowe	tilde_char =		'~'
10410d63b7Richard Lowe};
10510d63b7Richard Lowe
10610d63b7Richard Lowe/*
10710d63b7Richard Lowe * For make i18n. Codeset independent.
10810d63b7Richard Lowe * Setup character semantics by identifying all the special characters
10910d63b7Richard Lowe * of make, and assigning each an entry in the char_semantics[] vector.
11010d63b7Richard Lowe */
11110d63b7Richard Loweenum {
11210d63b7Richard Lowe	ampersand_char_entry = 0,	/*  0 */
11310d63b7Richard Lowe	asterisk_char_entry,		/*  1 */
11410d63b7Richard Lowe	at_char_entry,			/*  2 */
11510d63b7Richard Lowe	backquote_char_entry,		/*  3 */
11610d63b7Richard Lowe	backslash_char_entry,		/*  4 */
11710d63b7Richard Lowe	bar_char_entry,			/*  5 */
11810d63b7Richard Lowe	bracketleft_char_entry,		/*  6 */
11910d63b7Richard Lowe	bracketright_char_entry,	/*  7 */
12010d63b7Richard Lowe	colon_char_entry,		/*  8 */
12110d63b7Richard Lowe	dollar_char_entry,		/*  9 */
12210d63b7Richard Lowe	doublequote_char_entry,		/* 10 */
12310d63b7Richard Lowe	equal_char_entry,		/* 11 */
12410d63b7Richard Lowe	exclam_char_entry,		/* 12 */
12510d63b7Richard Lowe	greater_char_entry,		/* 13 */
12610d63b7Richard Lowe	hat_char_entry,			/* 14 */
12710d63b7Richard Lowe	hyphen_char_entry,		/* 15 */
12810d63b7Richard Lowe	less_char_entry,		/* 16 */
12910d63b7Richard Lowe	newline_char_entry,		/* 17 */
13010d63b7Richard Lowe	numbersign_char_entry,		/* 18 */
13110d63b7Richard Lowe	parenleft_char_entry,		/* 19 */
13210d63b7Richard Lowe	parenright_char_entry,		/* 20 */
13310d63b7Richard Lowe	percent_char_entry,		/* 21 */
13410d63b7Richard Lowe	plus_char_entry,		/* 22 */
13510d63b7Richard Lowe	question_char_entry,		/* 23 */
13610d63b7Richard Lowe	quote_char_entry,		/* 24 */
13710d63b7Richard Lowe	semicolon_char_entry,		/* 25 */
13810d63b7Richard Lowe	no_semantics_entry		/* 26 */
13910d63b7Richard Lowe};
14010d63b7Richard Lowe
14110d63b7Richard Lowe/*
14210d63b7Richard Lowe * CHAR_SEMANTICS_ENTRIES should be the number of entries above.
14310d63b7Richard Lowe * The last entry in char_semantics[] should be blank.
14410d63b7Richard Lowe */
14510d63b7Richard Lowe#define CHAR_SEMANTICS_ENTRIES	27
14610d63b7Richard Lowe/*
14710d63b7Richard Lowe#define CHAR_SEMANTICS_STRING	"&*@`\\|[]:$=!>-\n#()%+?;^<'\""
14810d63b7Richard Lowe */
14910d63b7Richard Lowe
15010d63b7Richard Lowe/*
15110d63b7Richard Lowe * Some utility macros
15210d63b7Richard Lowe */
15310d63b7Richard Lowe#define ALLOC(x)		((struct _##x *)getmem(sizeof (struct _##x)))
15410d63b7Richard Lowe#define ALLOC_WC(x)		((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
15510d63b7Richard Lowe#define FIND_LENGTH		-1
15610d63b7Richard Lowe#define GETNAME(a,b)		getname_fn((a), (b), false)
15710d63b7Richard Lowe#define IS_EQUAL(a,b)		(!strcmp((a), (b)))
15810d63b7Richard Lowe#define IS_EQUALN(a,b,n)	(!strncmp((a), (b), (n)))
15910d63b7Richard Lowe#define IS_WEQUAL(a,b)		(!wcscmp((a), (b)))
16010d63b7Richard Lowe#define IS_WEQUALN(a,b,n)	(!wcsncmp((a), (b), (n)))
16110d63b7Richard Lowe#define MBLEN(a)		mblen((a), MB_LEN_MAX)
16210d63b7Richard Lowe#define MBSTOWCS(a,b)		(void) mbstowcs_with_check((a), (b), MAXPATHLEN)
16310d63b7Richard Lowe#define	MBTOWC(a,b)		mbtowc((a), (b), MB_LEN_MAX)
16410d63b7Richard Lowe#define	SIZEOFWCHAR_T		(sizeof (wchar_t))
16510d63b7Richard Lowe#define VSIZEOF(v)		(sizeof (v) / sizeof ((v)[0]))
16610d63b7Richard Lowe#define WCSTOMBS(a,b)		(void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
16710d63b7Richard Lowe#define WCTOMB(a,b)		(void) wctomb((a), (b))
16810d63b7Richard Lowe#define	HASH(v, c)		(v = (v)*31 + (unsigned int)(c))
16910d63b7Richard Lowe
17010d63b7Richard Loweextern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
17110d63b7Richard Lowe
17210d63b7Richard Lowe/*
17310d63b7Richard Lowe * Bits stored in funny vector to classify chars
17410d63b7Richard Lowe */
17510d63b7Richard Loweenum {
17610d63b7Richard Lowe	dollar_sem =		0001,
17710d63b7Richard Lowe	meta_sem =		0002,
17810d63b7Richard Lowe	percent_sem =		0004,
17910d63b7Richard Lowe	wildcard_sem =		0010,
18010d63b7Richard Lowe	command_prefix_sem =	0020,
18110d63b7Richard Lowe	special_macro_sem =	0040,
18210d63b7Richard Lowe	colon_sem =		0100,
18310d63b7Richard Lowe	parenleft_sem =		0200
18410d63b7Richard Lowe};
18510d63b7Richard Lowe
18610d63b7Richard Lowe/*
18710d63b7Richard Lowe * Type returned from doname class functions
18810d63b7Richard Lowe */
18910d63b7Richard Lowetypedef enum {
19010d63b7Richard Lowe	build_dont_know = 0,
19110d63b7Richard Lowe	build_failed,
19210d63b7Richard Lowe	build_ok,
19310d63b7Richard Lowe	build_in_progress,
19410d63b7Richard Lowe	build_running,		/* PARALLEL & DISTRIBUTED */
19510d63b7Richard Lowe	build_pending,		/* PARALLEL & DISTRIBUTED */
19610d63b7Richard Lowe	build_serial,		/* PARALLEL & DISTRIBUTED */
19710d63b7Richard Lowe	build_subtree		/* PARALLEL & DISTRIBUTED */
19810d63b7Richard Lowe} Doname;
19910d63b7Richard Lowe
20010d63b7Richard Lowe/*
20110d63b7Richard Lowe * The String struct defines a string with the following layout
20210d63b7Richard Lowe *	"xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
20310d63b7Richard Lowe *	^		^		^		^
20410d63b7Richard Lowe *	|		|		|		|
20510d63b7Richard Lowe *	buffer.start	text.p		text.end	buffer.end
20610d63b7Richard Lowe *	text.p points to the next char to read/write.
20710d63b7Richard Lowe */
20810d63b7Richard Lowestruct _String {
20910d63b7Richard Lowe	struct Text {
21010d63b7Richard Lowe		wchar_t		*p;	/* Read/Write pointer */
21110d63b7Richard Lowe		wchar_t		*end;	/* Read limit pointer */
21210d63b7Richard Lowe	}		text;
21310d63b7Richard Lowe	struct Physical_buffer {
21410d63b7Richard Lowe		wchar_t		*start;	/* Points to start of buffer */
21510d63b7Richard Lowe		wchar_t		*end;	/* End of physical buffer */
21610d63b7Richard Lowe	}		buffer;
21710d63b7Richard Lowe	Boolean		free_after_use:1;
21810d63b7Richard Lowe};
21910d63b7Richard Lowe
22010d63b7Richard Lowe#define STRING_BUFFER_LENGTH	1024
22110d63b7Richard Lowe#define INIT_STRING_FROM_STACK(str, buf) { \
22210d63b7Richard Lowe			str.buffer.start = (buf); \
22310d63b7Richard Lowe			str.text.p = (buf); \
22410d63b7Richard Lowe			str.text.end = NULL; \
22510d63b7Richard Lowe			str.buffer.end = (buf) \
22610d63b7Richard Lowe                          + (sizeof (buf)/SIZEOFWCHAR_T); \
22710d63b7Richard Lowe			str.free_after_use = false; \
22810d63b7Richard Lowe		  }
22910d63b7Richard Lowe
23010d63b7Richard Lowe#define APPEND_NAME(np, dest, len)	append_string((np)->string_mb, (dest), (len));
23110d63b7Richard Lowe
23210d63b7Richard Loweclass Wstring {
23310d63b7Richard Lowe	public:
23410d63b7Richard Lowe		struct _String	string;
23510d63b7Richard Lowe		wchar_t		string_buf[STRING_BUFFER_LENGTH];
23610d63b7Richard Lowe
23710d63b7Richard Lowe	public:
23810d63b7Richard Lowe		Wstring();
23910d63b7Richard Lowe		Wstring(struct _Name * name);
24010d63b7Richard Lowe		~Wstring();
24110d63b7Richard Lowe
24210d63b7Richard Lowe		void init(struct _Name * name);
24310d63b7Richard Lowe		void init(wchar_t * name, unsigned length);
24410d63b7Richard Lowe		unsigned length() {
24510d63b7Richard Lowe			return wcslen(string.buffer.start);
24610d63b7Richard Lowe		};
24710d63b7Richard Lowe		void append_to_str(struct _String * str, unsigned off, unsigned length);
24810d63b7Richard Lowe
24910d63b7Richard Lowe		wchar_t * get_string() {
25010d63b7Richard Lowe			return string.buffer.start;
25110d63b7Richard Lowe		};
25210d63b7Richard Lowe
25310d63b7Richard Lowe		wchar_t * get_string(unsigned off) {
25410d63b7Richard Lowe			return string.buffer.start + off;
25510d63b7Richard Lowe		};
25610d63b7Richard Lowe
25710d63b7Richard Lowe		Boolean equaln(wchar_t * str, unsigned length);
25810d63b7Richard Lowe		Boolean equal(wchar_t * str);
25910d63b7Richard Lowe		Boolean equal(wchar_t * str, unsigned off);
26010d63b7Richard Lowe		Boolean equal(wchar_t * str, unsigned off, unsigned length);
26110d63b7Richard Lowe
26210d63b7Richard Lowe		Boolean equaln(Wstring * str, unsigned length);
26310d63b7Richard Lowe		Boolean equal(Wstring * str);
26410d63b7Richard Lowe		Boolean equal(Wstring * str, unsigned off);
26510d63b7Richard Lowe		Boolean equal(Wstring * str, unsigned off, unsigned length);
26610d63b7Richard Lowe};
26710d63b7Richard Lowe
26810d63b7Richard Lowe
26910d63b7Richard Lowe/*
27010d63b7Richard Lowe * Used for storing the $? list and also for the "target + target:"
27110d63b7Richard Lowe * construct.
27210d63b7Richard Lowe */
27310d63b7Richard Lowestruct _Chain {
27410d63b7Richard Lowe	struct _Chain		*next;
27510d63b7Richard Lowe	struct _Name		*name;
27610d63b7Richard Lowe	struct _Percent	*percent_member;
27710d63b7Richard Lowe};
27810d63b7Richard Lowe
27910d63b7Richard Lowe/*
28010d63b7Richard Lowe * Stores one command line for a rule
28110d63b7Richard Lowe */
28210d63b7Richard Lowestruct _Cmd_line {
28310d63b7Richard Lowe	struct _Cmd_line	*next;
28410d63b7Richard Lowe	struct _Name		*command_line;
28510d63b7Richard Lowe	Boolean			make_refd:1;	/* $(MAKE) referenced? */
28610d63b7Richard Lowe	/*
28710d63b7Richard Lowe	 * Remember any command line prefixes given
28810d63b7Richard Lowe	 */
28910d63b7Richard Lowe	Boolean			ignore_command_dependency:1;	/* `?' */
29010d63b7Richard Lowe	Boolean			assign:1;			/* `=' */
29110d63b7Richard Lowe	Boolean			ignore_error:1;			/* `-' */
29210d63b7Richard Lowe	Boolean			silent:1;			/* `@' */
29310d63b7Richard Lowe	Boolean			always_exec:1;			/* `+' */
29410d63b7Richard Lowe};
29510d63b7Richard Lowe
29610d63b7Richard Lowe/*
29710d63b7Richard Lowe * Linked list of targets/files
29810d63b7Richard Lowe */
29910d63b7Richard Lowestruct _Dependency {
30010d63b7Richard Lowe	struct _Dependency	*next;
30110d63b7Richard Lowe	struct _Name		*name;
30210d63b7Richard Lowe	Boolean			automatic:1;
30310d63b7Richard Lowe	Boolean			stale:1;
30410d63b7Richard Lowe	Boolean			built:1;
30510d63b7Richard Lowe};
30610d63b7Richard Lowe
30710d63b7Richard Lowe/*
30810d63b7Richard Lowe * The specials are markers for targets that the reader should special case
30910d63b7Richard Lowe */
31010d63b7Richard Lowetypedef enum {
31110d63b7Richard Lowe	no_special,
31210d63b7Richard Lowe	built_last_make_run_special,
31310d63b7Richard Lowe	default_special,
31410d63b7Richard Lowe	get_posix_special,
31510d63b7Richard Lowe	get_special,
31610d63b7Richard Lowe	ignore_special,
31710d63b7Richard Lowe	keep_state_file_special,
31810d63b7Richard Lowe	keep_state_special,
31910d63b7Richard Lowe	make_version_special,
32010d63b7Richard Lowe	no_parallel_special,
32110d63b7Richard Lowe	parallel_special,
32210d63b7Richard Lowe	posix_special,
32310d63b7Richard Lowe	precious_special,
32410d63b7Richard Lowe	sccs_get_posix_special,
32510d63b7Richard Lowe	sccs_get_special,
32610d63b7Richard Lowe	silent_special,
32710d63b7Richard Lowe	suffixes_special,
32810d63b7Richard Lowe	svr4_special,
32910d63b7Richard Lowe	localhost_special
33010d63b7Richard Lowe} Special;
33110d63b7Richard Lowe
33210d63b7Richard Lowetypedef enum {
33310d63b7Richard Lowe	no_colon,
33410d63b7Richard Lowe	one_colon,
33510d63b7Richard Lowe	two_colon,
33610d63b7Richard Lowe	equal_seen,
33710d63b7Richard Lowe	conditional_seen,
33810d63b7Richard Lowe	none_seen
33910d63b7Richard Lowe} Separator;
34010d63b7Richard Lowe
34110d63b7Richard Lowe/*
34210d63b7Richard Lowe * Magic values for the timestamp stored with each name object
34310d63b7Richard Lowe */
34410d63b7Richard Lowe
34510d63b7Richard Lowe
34610d63b7Richard Loweextern const timestruc_t file_no_time;
34710d63b7Richard Loweextern const timestruc_t file_doesnt_exist;
34810d63b7Richard Loweextern const timestruc_t file_is_dir;
34910d63b7Richard Loweextern const timestruc_t file_min_time;
35010d63b7Richard Loweextern const timestruc_t file_max_time;
35110d63b7Richard Lowe
35210d63b7Richard Lowe/*
35310d63b7Richard Lowe * Each Name has a list of properties
35410d63b7Richard Lowe * The properties are used to store information that only
35510d63b7Richard Lowe * a subset of the Names need
35610d63b7Richard Lowe */
35710d63b7Richard Lowetypedef enum {
35810d63b7Richard Lowe	no_prop,
35910d63b7Richard Lowe	conditional_prop,
36010d63b7Richard Lowe	line_prop,
36110d63b7Richard Lowe	macro_prop,
36210d63b7Richard Lowe	makefile_prop,
36310d63b7Richard Lowe	member_prop,
36410d63b7Richard Lowe	recursive_prop,
36510d63b7Richard Lowe	sccs_prop,
36610d63b7Richard Lowe	suffix_prop,
36710d63b7Richard Lowe	target_prop,
36810d63b7Richard Lowe	time_prop,
36910d63b7Richard Lowe	vpath_alias_prop,
37010d63b7Richard Lowe	long_member_name_prop,
37110d63b7Richard Lowe	macro_append_prop,
37210d63b7Richard Lowe	env_mem_prop
37310d63b7Richard Lowe} Property_id;
37410d63b7Richard Lowe
37510d63b7Richard Lowetypedef enum {
37610d63b7Richard Lowe	no_daemon = 0,
37710d63b7Richard Lowe	chain_daemon
37810d63b7Richard Lowe} Daemon;
37910d63b7Richard Lowe
38010d63b7Richard Lowestruct _Env_mem {
38110d63b7Richard Lowe	char		*value;
38210d63b7Richard Lowe};
38310d63b7Richard Lowe
38410d63b7Richard Lowestruct _Macro_appendix {
38510d63b7Richard Lowe	struct _Name		*value;
38610d63b7Richard Lowe	struct _Name		*value_to_append;
38710d63b7Richard Lowe};
38810d63b7Richard Lowe
38910d63b7Richard Lowestruct _Macro {
39010d63b7Richard Lowe	/*
39110d63b7Richard Lowe	* For "ABC = xyz" constructs
39210d63b7Richard Lowe	* Name "ABC" get one macro prop
39310d63b7Richard Lowe	*/
39410d63b7Richard Lowe	struct _Name		*value;
39510d63b7Richard Lowe	Boolean			exported:1;
39610d63b7Richard Lowe	Boolean			read_only:1;
39710d63b7Richard Lowe	/*
39810d63b7Richard Lowe	* This macro is defined conditionally
39910d63b7Richard Lowe	*/
40010d63b7Richard Lowe	Boolean			is_conditional:1;
40110d63b7Richard Lowe	/*
40210d63b7Richard Lowe	* The list for $? is stored as a structured list that
40310d63b7Richard Lowe	* is translated into a string iff it is referenced.
40410d63b7Richard Lowe	* This is why  some macro values need a daemon.
40510d63b7Richard Lowe	*/
40610d63b7Richard Lowe	Daemon			daemon:2;
40710d63b7Richard Lowe};
40810d63b7Richard Lowe
40910d63b7Richard Lowestruct _Macro_list {
41010d63b7Richard Lowe	struct _Macro_list	*next;
41110d63b7Richard Lowe	char			*macro_name;
41210d63b7Richard Lowe	char			*value;
41310d63b7Richard Lowe};
41410d63b7Richard Lowe
41510d63b7Richard Loweenum sccs_stat {
41610d63b7Richard Lowe	DONT_KNOW_SCCS = 0,
41710d63b7Richard Lowe	NO_SCCS,
41810d63b7Richard Lowe	HAS_SCCS
41910d63b7Richard Lowe};
42010d63b7Richard Lowe
42110d63b7Richard Lowestruct _Name {
42210d63b7Richard Lowe	struct _Property	*prop;		/* List of properties */
42310d63b7Richard Lowe	char			*string_mb;     /* Multi-byte name string */
42410d63b7Richard Lowe	struct {
42510d63b7Richard Lowe		unsigned int		length;
42610d63b7Richard Lowe	}                       hash;
42710d63b7Richard Lowe	struct {
42810d63b7Richard Lowe		timestruc_t		time;		/* Modification */
42910d63b7Richard Lowe		int			stat_errno;	/* error from "stat" */
43010d63b7Richard Lowe		off_t			size;		/* Of file */
43110d63b7Richard Lowe		mode_t			mode;		/* Of file */
43210d63b7Richard Lowe		Boolean			is_file:1;
43310d63b7Richard Lowe		Boolean			is_dir:1;
43410d63b7Richard Lowe		Boolean			is_sym_link:1;
43510d63b7Richard Lowe		Boolean			is_precious:1;
43610d63b7Richard Lowe		enum sccs_stat		has_sccs:2;
43710d63b7Richard Lowe	}                       stat;
43810d63b7Richard Lowe	/*
43910d63b7Richard Lowe	 * Count instances of :: definitions for this target
44010d63b7Richard Lowe	 */
44110d63b7Richard Lowe	short			colon_splits;
44210d63b7Richard Lowe	/*
44310d63b7Richard Lowe	 * We only clear the automatic depes once per target per report
44410d63b7Richard Lowe	 */
44510d63b7Richard Lowe	short			temp_file_number;
44610d63b7Richard Lowe	/*
44710d63b7Richard Lowe	 * Count how many conditional macros this target has defined
44810d63b7Richard Lowe	 */
44910d63b7Richard Lowe	short			conditional_cnt;
45010d63b7Richard Lowe	/*
45110d63b7Richard Lowe	 * A conditional macro was used when building this target
45210d63b7Richard Lowe	 */
45310d63b7Richard Lowe	Boolean			depends_on_conditional:1;
45410d63b7Richard Lowe	/*
45510d63b7Richard Lowe	 * Pointer to list of conditional macros which were used to build
45610d63b7Richard Lowe	 * this target
45710d63b7Richard Lowe	 */
45810d63b7Richard Lowe	struct _Macro_list	*conditional_macro_list;
45910d63b7Richard Lowe	Boolean			has_member_depe:1;
46010d63b7Richard Lowe	Boolean			is_member:1;
46110d63b7Richard Lowe	/*
46210d63b7Richard Lowe	 * This target is a directory that has been read
46310d63b7Richard Lowe	 */
46410d63b7Richard Lowe	Boolean			has_read_dir:1;
46510d63b7Richard Lowe	/*
46610d63b7Richard Lowe	 * This name is a macro that is now being expanded
46710d63b7Richard Lowe	 */
46810d63b7Richard Lowe	Boolean			being_expanded:1;
46910d63b7Richard Lowe	/*
47010d63b7Richard Lowe	 * This name is a magic name that the reader must know about
47110d63b7Richard Lowe	 */
47210d63b7Richard Lowe	Special			special_reader:5;
47310d63b7Richard Lowe	Doname			state:3;
47410d63b7Richard Lowe	Separator		colons:3;
47510d63b7Richard Lowe	Boolean			has_depe_list_expanded:1;
47610d63b7Richard Lowe	Boolean			suffix_scan_done:1;
47710d63b7Richard Lowe	Boolean			has_complained:1;	/* For sccs */
47810d63b7Richard Lowe	/*
47910d63b7Richard Lowe	 * This target has been built during this make run
48010d63b7Richard Lowe	 */
48110d63b7Richard Lowe	Boolean			ran_command:1;
48210d63b7Richard Lowe	Boolean			with_squiggle:1;	/* for .SUFFIXES */
48310d63b7Richard Lowe	Boolean			without_squiggle:1;	/* for .SUFFIXES */
48410d63b7Richard Lowe	Boolean			has_read_suffixes:1;	/* Suffix list cached*/
48510d63b7Richard Lowe	Boolean			has_suffixes:1;
48610d63b7Richard Lowe	Boolean			has_target_prop:1;
48710d63b7Richard Lowe	Boolean			has_vpath_alias_prop:1;
48810d63b7Richard Lowe	Boolean			dependency_printed:1;	/* For dump_make_state() */
48910d63b7Richard Lowe	Boolean			dollar:1;		/* In namestring */
49010d63b7Richard Lowe	Boolean			meta:1;			/* In namestring */
49110d63b7Richard Lowe	Boolean			percent:1;		/* In namestring */
49210d63b7Richard Lowe	Boolean			wildcard:1;		/* In namestring */
49310d63b7Richard Lowe        Boolean                 has_parent:1;
49410d63b7Richard Lowe        Boolean                 is_target:1;
49510d63b7Richard Lowe	Boolean			has_built:1;
49610d63b7Richard Lowe	Boolean			colon:1;		/* In namestring */
49710d63b7Richard Lowe	Boolean			parenleft:1;		/* In namestring */
49810d63b7Richard Lowe	Boolean			has_recursive_dependency:1;
49910d63b7Richard Lowe	Boolean			has_regular_dependency:1;
50010d63b7Richard Lowe	Boolean			is_double_colon:1;
50110d63b7Richard Lowe	Boolean			is_double_colon_parent:1;
50210d63b7Richard Lowe	Boolean			has_long_member_name:1;
50310d63b7Richard Lowe	/*
50410d63b7Richard Lowe	 * allowed to run in parallel
50510d63b7Richard Lowe	 */
50610d63b7Richard Lowe	Boolean			parallel:1;
50710d63b7Richard Lowe	/*
50810d63b7Richard Lowe	 * not allowed to run in parallel
50910d63b7Richard Lowe	 */
51010d63b7Richard Lowe	Boolean			no_parallel:1;
51110d63b7Richard Lowe	/*
51210d63b7Richard Lowe	 * used in dependency_conflict
51310d63b7Richard Lowe	 */
51410d63b7Richard Lowe	Boolean			checking_subtree:1;
51510d63b7Richard Lowe	Boolean			added_pattern_conditionals:1;
51610d63b7Richard Lowe	/*
51710d63b7Richard Lowe	 * rechecking target for possible rebuild
51810d63b7Richard Lowe	 */
51910d63b7Richard Lowe	Boolean			rechecking_target:1;
52010d63b7Richard Lowe	/*
52110d63b7Richard Lowe	 * build this target in silent mode
52210d63b7Richard Lowe	 */
52310d63b7Richard Lowe	Boolean			silent_mode:1;
52410d63b7Richard Lowe	/*
52510d63b7Richard Lowe	 * build this target in ignore error mode
52610d63b7Richard Lowe	 */
52710d63b7Richard Lowe	Boolean			ignore_error_mode:1;
52810d63b7Richard Lowe	Boolean			dont_activate_cond_values:1;
52910d63b7Richard Lowe	/*
53010d63b7Richard Lowe	 * allowed to run serially on local host
53110d63b7Richard Lowe	 */
53210d63b7Richard Lowe	Boolean			localhost:1;
53310d63b7Richard Lowe};
53410d63b7Richard Lowe
53510d63b7Richard Lowe/*
53610d63b7Richard Lowe * Stores the % matched default rules
53710d63b7Richard Lowe */
53810d63b7Richard Lowestruct _Percent {
53910d63b7Richard Lowe	struct _Percent	*next;
54010d63b7Richard Lowe	struct _Name		**patterns;
54110d63b7Richard Lowe	struct _Name		*name;
54210d63b7Richard Lowe	struct _Percent		*dependencies;
54310d63b7Richard Lowe	struct _Cmd_line	*command_template;
54410d63b7Richard Lowe	struct _Chain		*target_group;
54510d63b7Richard Lowe	int			patterns_total;
54610d63b7Richard Lowe	Boolean			being_expanded;
54710d63b7Richard Lowe};
54810d63b7Richard Lowe
54910d63b7Richard Lowestruct Conditional {
55010d63b7Richard Lowe	/*
55110d63b7Richard Lowe	 * For "foo := ABC [+]= xyz" constructs
55210d63b7Richard Lowe	 * Name "foo" gets one conditional prop
55310d63b7Richard Lowe	 */
55410d63b7Richard Lowe	struct _Name		*target;
55510d63b7Richard Lowe	struct _Name		*name;
55610d63b7Richard Lowe	struct _Name		*value;
55710d63b7Richard Lowe	int			sequence;
55810d63b7Richard Lowe	Boolean			append:1;
55910d63b7Richard Lowe};
56010d63b7Richard Lowe
56110d63b7Richard Lowestruct Line {
56210d63b7Richard Lowe	/*
56310d63b7Richard Lowe	 * For "target : dependencies" constructs
56410d63b7Richard Lowe	 * Name "target" gets one line prop
56510d63b7Richard Lowe	 */
56610d63b7Richard Lowe	struct _Cmd_line	*command_template;
56710d63b7Richard Lowe	struct _Cmd_line	*command_used;
56810d63b7Richard Lowe	struct _Dependency	*dependencies;
56910d63b7Richard Lowe	timestruc_t		dependency_time;
57010d63b7Richard Lowe	struct _Chain		*target_group;
57110d63b7Richard Lowe	Boolean			is_out_of_date:1;
57210d63b7Richard Lowe	Boolean			sccs_command:1;
57310d63b7Richard Lowe	Boolean			command_template_redefined:1;
57410d63b7Richard Lowe	Boolean			dont_rebuild_command_used:1;
57510d63b7Richard Lowe	/*
57610d63b7Richard Lowe	 * Values for the dynamic macros
57710d63b7Richard Lowe	 */
57810d63b7Richard Lowe	struct _Name		*target;
57910d63b7Richard Lowe	struct _Name		*star;
58010d63b7Richard Lowe	struct _Name		*less;
58110d63b7Richard Lowe	struct _Name		*percent;
58210d63b7Richard Lowe	struct _Chain		*query;
58310d63b7Richard Lowe};
58410d63b7Richard Lowe
58510d63b7Richard Lowestruct Makefile {
58610d63b7Richard Lowe	/*
58710d63b7Richard Lowe	 * Names that reference makefiles gets one prop
58810d63b7Richard Lowe	 */
58910d63b7Richard Lowe	wchar_t			*contents;
59010d63b7Richard Lowe	off_t			size;
59110d63b7Richard Lowe};
59210d63b7Richard Lowe
59310d63b7Richard Lowestruct Member {
59410d63b7Richard Lowe	/*
59510d63b7Richard Lowe	 * For "lib(member)" and "lib((entry))" constructs
59610d63b7Richard Lowe	 * Name "lib(member)" gets one member prop
59710d63b7Richard Lowe	 * Name "lib((entry))" gets one member prop
59810d63b7Richard Lowe	 * The member field is filled in when the prop is refd
59910d63b7Richard Lowe	 */
60010d63b7Richard Lowe	struct _Name		*library;
60110d63b7Richard Lowe	struct _Name		*entry;
60210d63b7Richard Lowe	struct _Name		*member;
60310d63b7Richard Lowe};
60410d63b7Richard Lowe
60510d63b7Richard Lowestruct Recursive {
60610d63b7Richard Lowe	/*
60710d63b7Richard Lowe	 * For "target: .RECURSIVE dir makefiles" constructs
60810d63b7Richard Lowe	 * Used to keep track of recursive calls to make
60910d63b7Richard Lowe	 * Name "target" gets one recursive prop
61010d63b7Richard Lowe	 */
61110d63b7Richard Lowe	struct _Name		*directory;
61210d63b7Richard Lowe	struct _Name		*target;
61310d63b7Richard Lowe	struct _Dependency	*makefiles;
61410d63b7Richard Lowe	Boolean			has_built;
61510d63b7Richard Lowe	Boolean			in_depinfo;
61610d63b7Richard Lowe};
61710d63b7Richard Lowe
61810d63b7Richard Lowestruct Sccs {
61910d63b7Richard Lowe	/*
62010d63b7Richard Lowe	 * Each file that has a SCCS s. file gets one prop
62110d63b7Richard Lowe	 */
62210d63b7Richard Lowe	struct _Name		*file;
62310d63b7Richard Lowe};
62410d63b7Richard Lowe
62510d63b7Richard Lowestruct Suffix {
62610d63b7Richard Lowe	/*
62710d63b7Richard Lowe	 * Cached list of suffixes that can build this target
62810d63b7Richard Lowe	 * suffix is built from .SUFFIXES
62910d63b7Richard Lowe	 */
63010d63b7Richard Lowe	struct _Name		*suffix;
63110d63b7Richard Lowe	struct _Cmd_line	*command_template;
63210d63b7Richard Lowe};
63310d63b7Richard Lowe
63410d63b7Richard Lowestruct Target {
63510d63b7Richard Lowe	/*
63610d63b7Richard Lowe	 * For "target:: dependencies" constructs
63710d63b7Richard Lowe	 * The "::" construct is handled by converting it to
63810d63b7Richard Lowe	 * "foo: 1@foo" + "1@foo: dependecies"
63910d63b7Richard Lowe	 * "1@foo" gets one target prop
64010d63b7Richard Lowe	 * This target prop cause $@ to be bound to "foo"
64110d63b7Richard Lowe	 * not "1@foo" when the rule is evaluated
64210d63b7Richard Lowe	 */
64310d63b7Richard Lowe	struct _Name		*target;
64410d63b7Richard Lowe};
64510d63b7Richard Lowe
64610d63b7Richard Lowestruct STime {
64710d63b7Richard Lowe	/*
64810d63b7Richard Lowe	 * Save the original time for :: targets
64910d63b7Richard Lowe	 */
65010d63b7Richard Lowe	timestruc_t			time;
65110d63b7Richard Lowe};
65210d63b7Richard Lowe
65310d63b7Richard Lowestruct Vpath_alias {
65410d63b7Richard Lowe	/*
65510d63b7Richard Lowe	 * If a file was found using the VPATH it gets
65610d63b7Richard Lowe	 * a vpath_alias prop
65710d63b7Richard Lowe	 */
65810d63b7Richard Lowe	struct _Name		*alias;
65910d63b7Richard Lowe};
66010d63b7Richard Lowe
66110d63b7Richard Lowestruct Long_member_name {
66210d63b7Richard Lowe	/*
66310d63b7Richard Lowe	 * Targets with a truncated member name carries
66410d63b7Richard Lowe	 * the full lib(member) name for the state file
66510d63b7Richard Lowe	 */
66610d63b7Richard Lowe	struct _Name		*member_name;
66710d63b7Richard Lowe};
66810d63b7Richard Lowe
66910d63b7Richard Loweunion Body {
67010d63b7Richard Lowe	struct _Macro		macro;
67110d63b7Richard Lowe	struct Conditional	conditional;
67210d63b7Richard Lowe	struct Line		line;
67310d63b7Richard Lowe	struct Makefile		makefile;
67410d63b7Richard Lowe	struct Member		member;
67510d63b7Richard Lowe	struct Recursive	recursive;
67610d63b7Richard Lowe	struct Sccs		sccs;
67710d63b7Richard Lowe	struct Suffix		suffix;
67810d63b7Richard Lowe	struct Target		target;
67910d63b7Richard Lowe	struct STime		time;
68010d63b7Richard Lowe	struct Vpath_alias	vpath_alias;
68110d63b7Richard Lowe	struct Long_member_name	long_member_name;
68210d63b7Richard Lowe	struct _Macro_appendix	macro_appendix;
68310d63b7Richard Lowe	struct _Env_mem		env_mem;
68410d63b7Richard Lowe};
68510d63b7Richard Lowe
68610d63b7Richard Lowe#define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
68710d63b7Richard Lowestruct _Property {
68810d63b7Richard Lowe	struct _Property	*next;
68910d63b7Richard Lowe	Property_id		type:4;
69010d63b7Richard Lowe	union Body		body;
69110d63b7Richard Lowe};
69210d63b7Richard Lowe
69310d63b7Richard Lowe/* Structure for dynamic "ascii" arrays */
69410d63b7Richard Lowestruct ASCII_Dyn_Array {
69510d63b7Richard Lowe	char			*start;
69610d63b7Richard Lowe	size_t			size;
69710d63b7Richard Lowe};
69810d63b7Richard Lowe
69910d63b7Richard Lowestruct _Envvar {
70010d63b7Richard Lowe	struct _Name		*name;
70110d63b7Richard Lowe	struct _Name		*value;
70210d63b7Richard Lowe	struct _Envvar		*next;
70310d63b7Richard Lowe	char			*env_string;
70410d63b7Richard Lowe	Boolean			already_put:1;
70510d63b7Richard Lowe};
70610d63b7Richard Lowe
70710d63b7Richard Lowe/*
70810d63b7Richard Lowe * Macros for the reader
70910d63b7Richard Lowe */
71010d63b7Richard Lowe#define GOTO_STATE(new_state) { \
71110d63b7Richard Lowe				  SET_STATE(new_state); \
71210d63b7Richard Lowe				    goto enter_state; \
71310d63b7Richard Lowe			      }
71410d63b7Richard Lowe#define SET_STATE(new_state) state = (new_state)
71510d63b7Richard Lowe
71610d63b7Richard Lowe#define UNCACHE_SOURCE()	if (source != NULL) { \
71710d63b7Richard Lowe					source->string.text.p = source_p; \
71810d63b7Richard Lowe				  }
71910d63b7Richard Lowe#define CACHE_SOURCE(comp)	if (source != NULL) { \
72010d63b7Richard Lowe					source_p = source->string.text.p - \
72110d63b7Richard Lowe					  (comp); \
72210d63b7Richard Lowe					source_end = source->string.text.end; \
72310d63b7Richard Lowe				  }
72410d63b7Richard Lowe#define GET_NEXT_BLOCK_NOCHK(source)	{ UNCACHE_SOURCE(); \
72510d63b7Richard Lowe				 source = get_next_block_fn(source); \
72610d63b7Richard Lowe				 CACHE_SOURCE(0) \
72710d63b7Richard Lowe			   }
72810d63b7Richard Lowe#define GET_NEXT_BLOCK(source)	{ GET_NEXT_BLOCK_NOCHK(source); \
72910d63b7Richard Lowe				 if (source != NULL && source->error_converting) { \
73010d63b7Richard Lowe				 	GOTO_STATE(illegal_bytes_state); \
73110d63b7Richard Lowe				 } \
73210d63b7Richard Lowe			   }
73310d63b7Richard Lowe#define GET_CHAR()		((source == NULL) || \
73410d63b7Richard Lowe				(source_p >= source_end) ? 0 : *source_p)
73510d63b7Richard Lowe
73610d63b7Richard Lowestruct _Source {
73710d63b7Richard Lowe	struct _String		string;
73810d63b7Richard Lowe	struct _Source		*previous;
73910d63b7Richard Lowe	off_t			bytes_left_in_file;
74010d63b7Richard Lowe	short			fd;
74110d63b7Richard Lowe	Boolean			already_expanded:1;
74210d63b7Richard Lowe	Boolean			error_converting:1;
74310d63b7Richard Lowe	char			*inp_buf;
74410d63b7Richard Lowe	char			*inp_buf_end;
74510d63b7Richard Lowe	char			*inp_buf_ptr;
74610d63b7Richard Lowe};
74710d63b7Richard Lowe
74810d63b7Richard Lowetypedef enum {
74910d63b7Richard Lowe	reading_nothing,
75010d63b7Richard Lowe	reading_makefile,
75110d63b7Richard Lowe	reading_statefile,
75210d63b7Richard Lowe	rereading_statefile,
75310d63b7Richard Lowe	reading_cpp_file
75410d63b7Richard Lowe} Makefile_type;
75510d63b7Richard Lowe
75610d63b7Richard Lowe/*
75710d63b7Richard Lowe * Typedefs for all structs
75810d63b7Richard Lowe */
75910d63b7Richard Lowetypedef struct _Chain		*Chain, Chain_rec;
76010d63b7Richard Lowetypedef struct _Envvar		*Envvar, Envvar_rec;
76110d63b7Richard Lowetypedef struct _Macro_list	*Macro_list, Macro_list_rec;
76210d63b7Richard Lowetypedef struct _Name		*Name, Name_rec;
76310d63b7Richard Lowetypedef struct _Property	*Property, Property_rec;
76410d63b7Richard Lowetypedef struct _Source		*Source, Source_rec;
76510d63b7Richard Lowetypedef struct _String		*String, String_rec;
76610d63b7Richard Lowe
76710d63b7Richard Lowe/*
76810d63b7Richard Lowe * name records hash table.
76910d63b7Richard Lowe */
77010d63b7Richard Lowestruct Name_set {
77110d63b7Richard Loweprivate:
77210d63b7Richard Lowe	// single node in a tree
77310d63b7Richard Lowe	struct entry {
77410d63b7Richard Lowe		entry(Name name_, entry *parent_) :
77510d63b7Richard Lowe			name(name_),
77610d63b7Richard Lowe			parent(parent_),
77710d63b7Richard Lowe			left(0),
77810d63b7Richard Lowe			right(0),
77910d63b7Richard Lowe			depth(1)
78010d63b7Richard Lowe		{}
78110d63b7Richard Lowe
78210d63b7Richard Lowe		Name		name;
78310d63b7Richard Lowe
78410d63b7Richard Lowe		entry		*parent;
78510d63b7Richard Lowe		entry		*left;
78610d63b7Richard Lowe		entry		*right;
78710d63b7Richard Lowe		unsigned	depth;
78810d63b7Richard Lowe
78910d63b7Richard Lowe		void setup_depth() {
79010d63b7Richard Lowe			unsigned rdepth = (right != 0) ? right->depth : 0;
79110d63b7Richard Lowe			unsigned ldepth = (left != 0) ? left->depth : 0;
79210d63b7Richard Lowe			depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
79310d63b7Richard Lowe		}
79410d63b7Richard Lowe	};
79510d63b7Richard Lowe
79610d63b7Richard Lowepublic:
79710d63b7Richard Lowe	// make iterator a friend of Name_set to have access to struct entry
79810d63b7Richard Lowe	struct iterator;
79910d63b7Richard Lowe	friend struct Name_set::iterator;
80010d63b7Richard Lowe
80110d63b7Richard Lowe	// iterator over tree nodes
80210d63b7Richard Lowe	struct iterator {
80310d63b7Richard Lowe	public:
80410d63b7Richard Lowe		// constructors
80510d63b7Richard Lowe		iterator() : node(0) {}
80610d63b7Richard Lowe		iterator(entry *node_) : node(node_) {}
80750d9677Toomas Soome		iterator(const iterator&) = default;
80810d63b7Richard Lowe
80910d63b7Richard Lowe		// dereference operator
81010d63b7Richard Lowe		Name operator->() const { return node->name; }
81110d63b7Richard Lowe
812