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