xref: /illumos-gate/usr/src/cmd/make/include/mksh/defs.h (revision 10d63b7d)
1*10d63b7dSRichard Lowe #ifndef _MKSH_DEFS_H
2*10d63b7dSRichard Lowe #define _MKSH_DEFS_H
3*10d63b7dSRichard Lowe /*
4*10d63b7dSRichard Lowe  * CDDL HEADER START
5*10d63b7dSRichard Lowe  *
6*10d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
7*10d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
8*10d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
9*10d63b7dSRichard Lowe  *
10*10d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*10d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
12*10d63b7dSRichard Lowe  * See the License for the specific language governing permissions
13*10d63b7dSRichard Lowe  * and limitations under the License.
14*10d63b7dSRichard Lowe  *
15*10d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
16*10d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*10d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
18*10d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
19*10d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
20*10d63b7dSRichard Lowe  *
21*10d63b7dSRichard Lowe  * CDDL HEADER END
22*10d63b7dSRichard Lowe  */
23*10d63b7dSRichard Lowe /*
24*10d63b7dSRichard Lowe  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
25*10d63b7dSRichard Lowe  * Use is subject to license terms.
26*10d63b7dSRichard Lowe  */
27*10d63b7dSRichard Lowe 
28*10d63b7dSRichard Lowe #include <limits.h>		/* MB_LEN_MAX */
29*10d63b7dSRichard Lowe #include <stdio.h>
30*10d63b7dSRichard Lowe #include <stdlib.h>		/* wchar_t */
31*10d63b7dSRichard Lowe #include <string.h>		/* strcmp() */
32*10d63b7dSRichard Lowe #include <sys/param.h>		/* MAXPATHLEN */
33*10d63b7dSRichard Lowe #include <sys/types.h>		/* time_t, caddr_t */
34*10d63b7dSRichard Lowe #include <vroot/vroot.h>	/* pathpt */
35*10d63b7dSRichard Lowe #include <sys/time.h>		/* timestruc_t */
36*10d63b7dSRichard Lowe #include <errno.h>		/* errno */
37*10d63b7dSRichard Lowe 
38*10d63b7dSRichard Lowe #include <wctype.h>
39*10d63b7dSRichard Lowe 
40*10d63b7dSRichard Lowe /*
41*10d63b7dSRichard Lowe  * A type and some utilities for boolean values
42*10d63b7dSRichard Lowe  */
43*10d63b7dSRichard Lowe 
44*10d63b7dSRichard Lowe #define	false	BOOLEAN_false
45*10d63b7dSRichard Lowe #define	true	BOOLEAN_true
46*10d63b7dSRichard Lowe 
47*10d63b7dSRichard Lowe typedef enum {
48*10d63b7dSRichard Lowe 	false =		0,
49*10d63b7dSRichard Lowe 	true =		1,
50*10d63b7dSRichard Lowe 	failed =	0,
51*10d63b7dSRichard Lowe 	succeeded =	1
52*10d63b7dSRichard Lowe } Boolean;
53*10d63b7dSRichard Lowe #define BOOLEAN(expr)		((expr) ? true : false)
54*10d63b7dSRichard Lowe 
55*10d63b7dSRichard Lowe /*
56*10d63b7dSRichard Lowe  * Some random constants (in an enum so dbx knows their values)
57*10d63b7dSRichard Lowe  */
58*10d63b7dSRichard Lowe enum {
59*10d63b7dSRichard Lowe 	update_delay = 30,		/* time between rstat checks */
60*10d63b7dSRichard Lowe 	ar_member_name_len = 1024,
61*10d63b7dSRichard Lowe 	hashsize = 2048			/* size of hash table */
62*10d63b7dSRichard Lowe };
63*10d63b7dSRichard Lowe 
64*10d63b7dSRichard Lowe 
65*10d63b7dSRichard Lowe /*
66*10d63b7dSRichard Lowe  * Symbols that defines all the different char constants make uses
67*10d63b7dSRichard Lowe  */
68*10d63b7dSRichard Lowe enum {
69*10d63b7dSRichard Lowe 	ampersand_char =	'&',
70*10d63b7dSRichard Lowe 	asterisk_char =		'*',
71*10d63b7dSRichard Lowe 	at_char =		'@',
72*10d63b7dSRichard Lowe 	backquote_char =	'`',
73*10d63b7dSRichard Lowe 	backslash_char =	'\\',
74*10d63b7dSRichard Lowe 	bar_char =		'|',
75*10d63b7dSRichard Lowe 	braceleft_char =	'{',
76*10d63b7dSRichard Lowe 	braceright_char =	'}',
77*10d63b7dSRichard Lowe 	bracketleft_char =	'[',
78*10d63b7dSRichard Lowe 	bracketright_char =	']',
79*10d63b7dSRichard Lowe 	colon_char =		':',
80*10d63b7dSRichard Lowe 	comma_char =		',',
81*10d63b7dSRichard Lowe 	dollar_char =		'$',
82*10d63b7dSRichard Lowe 	doublequote_char =	'"',
83*10d63b7dSRichard Lowe 	equal_char =		'=',
84*10d63b7dSRichard Lowe 	exclam_char =		'!',
85*10d63b7dSRichard Lowe 	greater_char =		'>',
86*10d63b7dSRichard Lowe 	hat_char =		'^',
87*10d63b7dSRichard Lowe 	hyphen_char =		'-',
88*10d63b7dSRichard Lowe 	less_char =		'<',
89*10d63b7dSRichard Lowe 	newline_char =		'\n',
90*10d63b7dSRichard Lowe 	nul_char =		'\0',
91*10d63b7dSRichard Lowe 	numbersign_char =	'#',
92*10d63b7dSRichard Lowe 	parenleft_char =	'(',
93*10d63b7dSRichard Lowe 	parenright_char =	')',
94*10d63b7dSRichard Lowe 	percent_char =		'%',
95*10d63b7dSRichard Lowe 	period_char =		'.',
96*10d63b7dSRichard Lowe 	plus_char =		'+',
97*10d63b7dSRichard Lowe 	question_char =		'?',
98*10d63b7dSRichard Lowe 	quote_char =		'\'',
99*10d63b7dSRichard Lowe 	semicolon_char =	';',
100*10d63b7dSRichard Lowe 	slash_char =		'/',
101*10d63b7dSRichard Lowe 	space_char =		' ',
102*10d63b7dSRichard Lowe 	tab_char =		'\t',
103*10d63b7dSRichard Lowe 	tilde_char =		'~'
104*10d63b7dSRichard Lowe };
105*10d63b7dSRichard Lowe 
106*10d63b7dSRichard Lowe /*
107*10d63b7dSRichard Lowe  * For make i18n. Codeset independent.
108*10d63b7dSRichard Lowe  * Setup character semantics by identifying all the special characters
109*10d63b7dSRichard Lowe  * of make, and assigning each an entry in the char_semantics[] vector.
110*10d63b7dSRichard Lowe  */
111*10d63b7dSRichard Lowe enum {
112*10d63b7dSRichard Lowe 	ampersand_char_entry = 0,	/*  0 */
113*10d63b7dSRichard Lowe 	asterisk_char_entry,		/*  1 */
114*10d63b7dSRichard Lowe 	at_char_entry,			/*  2 */
115*10d63b7dSRichard Lowe 	backquote_char_entry,		/*  3 */
116*10d63b7dSRichard Lowe 	backslash_char_entry,		/*  4 */
117*10d63b7dSRichard Lowe 	bar_char_entry,			/*  5 */
118*10d63b7dSRichard Lowe 	bracketleft_char_entry,		/*  6 */
119*10d63b7dSRichard Lowe 	bracketright_char_entry,	/*  7 */
120*10d63b7dSRichard Lowe 	colon_char_entry,		/*  8 */
121*10d63b7dSRichard Lowe 	dollar_char_entry,		/*  9 */
122*10d63b7dSRichard Lowe 	doublequote_char_entry,		/* 10 */
123*10d63b7dSRichard Lowe 	equal_char_entry,		/* 11 */
124*10d63b7dSRichard Lowe 	exclam_char_entry,		/* 12 */
125*10d63b7dSRichard Lowe 	greater_char_entry,		/* 13 */
126*10d63b7dSRichard Lowe 	hat_char_entry,			/* 14 */
127*10d63b7dSRichard Lowe 	hyphen_char_entry,		/* 15 */
128*10d63b7dSRichard Lowe 	less_char_entry,		/* 16 */
129*10d63b7dSRichard Lowe 	newline_char_entry,		/* 17 */
130*10d63b7dSRichard Lowe 	numbersign_char_entry,		/* 18 */
131*10d63b7dSRichard Lowe 	parenleft_char_entry,		/* 19 */
132*10d63b7dSRichard Lowe 	parenright_char_entry,		/* 20 */
133*10d63b7dSRichard Lowe 	percent_char_entry,		/* 21 */
134*10d63b7dSRichard Lowe 	plus_char_entry,		/* 22 */
135*10d63b7dSRichard Lowe 	question_char_entry,		/* 23 */
136*10d63b7dSRichard Lowe 	quote_char_entry,		/* 24 */
137*10d63b7dSRichard Lowe 	semicolon_char_entry,		/* 25 */
138*10d63b7dSRichard Lowe 	no_semantics_entry		/* 26 */
139*10d63b7dSRichard Lowe };
140*10d63b7dSRichard Lowe 
141*10d63b7dSRichard Lowe /*
142*10d63b7dSRichard Lowe  * CHAR_SEMANTICS_ENTRIES should be the number of entries above.
143*10d63b7dSRichard Lowe  * The last entry in char_semantics[] should be blank.
144*10d63b7dSRichard Lowe  */
145*10d63b7dSRichard Lowe #define CHAR_SEMANTICS_ENTRIES	27
146*10d63b7dSRichard Lowe /*
147*10d63b7dSRichard Lowe #define CHAR_SEMANTICS_STRING	"&*@`\\|[]:$=!>-\n#()%+?;^<'\""
148*10d63b7dSRichard Lowe  */
149*10d63b7dSRichard Lowe 
150*10d63b7dSRichard Lowe /*
151*10d63b7dSRichard Lowe  * Some utility macros
152*10d63b7dSRichard Lowe  */
153*10d63b7dSRichard Lowe #define ALLOC(x)		((struct _##x *)getmem(sizeof (struct _##x)))
154*10d63b7dSRichard Lowe #define ALLOC_WC(x)		((wchar_t *)getmem((x) * SIZEOFWCHAR_T))
155*10d63b7dSRichard Lowe #define FIND_LENGTH		-1
156*10d63b7dSRichard Lowe #define GETNAME(a,b)		getname_fn((a), (b), false)
157*10d63b7dSRichard Lowe #define IS_EQUAL(a,b)		(!strcmp((a), (b)))
158*10d63b7dSRichard Lowe #define IS_EQUALN(a,b,n)	(!strncmp((a), (b), (n)))
159*10d63b7dSRichard Lowe #define IS_WEQUAL(a,b)		(!wcscmp((a), (b)))
160*10d63b7dSRichard Lowe #define IS_WEQUALN(a,b,n)	(!wcsncmp((a), (b), (n)))
161*10d63b7dSRichard Lowe #define MBLEN(a)		mblen((a), MB_LEN_MAX)
162*10d63b7dSRichard Lowe #define MBSTOWCS(a,b)		(void) mbstowcs_with_check((a), (b), MAXPATHLEN)
163*10d63b7dSRichard Lowe #define	MBTOWC(a,b)		mbtowc((a), (b), MB_LEN_MAX)
164*10d63b7dSRichard Lowe #define	SIZEOFWCHAR_T		(sizeof (wchar_t))
165*10d63b7dSRichard Lowe #define VSIZEOF(v)		(sizeof (v) / sizeof ((v)[0]))
166*10d63b7dSRichard Lowe #define WCSTOMBS(a,b)		(void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX))
167*10d63b7dSRichard Lowe #define WCTOMB(a,b)		(void) wctomb((a), (b))
168*10d63b7dSRichard Lowe #define	HASH(v, c)		(v = (v)*31 + (unsigned int)(c))
169*10d63b7dSRichard Lowe 
170*10d63b7dSRichard Lowe extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n);
171*10d63b7dSRichard Lowe 
172*10d63b7dSRichard Lowe /*
173*10d63b7dSRichard Lowe  * Bits stored in funny vector to classify chars
174*10d63b7dSRichard Lowe  */
175*10d63b7dSRichard Lowe enum {
176*10d63b7dSRichard Lowe 	dollar_sem =		0001,
177*10d63b7dSRichard Lowe 	meta_sem =		0002,
178*10d63b7dSRichard Lowe 	percent_sem =		0004,
179*10d63b7dSRichard Lowe 	wildcard_sem =		0010,
180*10d63b7dSRichard Lowe 	command_prefix_sem =	0020,
181*10d63b7dSRichard Lowe 	special_macro_sem =	0040,
182*10d63b7dSRichard Lowe 	colon_sem =		0100,
183*10d63b7dSRichard Lowe 	parenleft_sem =		0200
184*10d63b7dSRichard Lowe };
185*10d63b7dSRichard Lowe 
186*10d63b7dSRichard Lowe /*
187*10d63b7dSRichard Lowe  * Type returned from doname class functions
188*10d63b7dSRichard Lowe  */
189*10d63b7dSRichard Lowe typedef enum {
190*10d63b7dSRichard Lowe 	build_dont_know = 0,
191*10d63b7dSRichard Lowe 	build_failed,
192*10d63b7dSRichard Lowe 	build_ok,
193*10d63b7dSRichard Lowe 	build_in_progress,
194*10d63b7dSRichard Lowe 	build_running,		/* PARALLEL & DISTRIBUTED */
195*10d63b7dSRichard Lowe 	build_pending,		/* PARALLEL & DISTRIBUTED */
196*10d63b7dSRichard Lowe 	build_serial,		/* PARALLEL & DISTRIBUTED */
197*10d63b7dSRichard Lowe 	build_subtree		/* PARALLEL & DISTRIBUTED */
198*10d63b7dSRichard Lowe } Doname;
199*10d63b7dSRichard Lowe 
200*10d63b7dSRichard Lowe /*
201*10d63b7dSRichard Lowe  * The String struct defines a string with the following layout
202*10d63b7dSRichard Lowe  *	"xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________"
203*10d63b7dSRichard Lowe  *	^		^		^		^
204*10d63b7dSRichard Lowe  *	|		|		|		|
205*10d63b7dSRichard Lowe  *	buffer.start	text.p		text.end	buffer.end
206*10d63b7dSRichard Lowe  *	text.p points to the next char to read/write.
207*10d63b7dSRichard Lowe  */
208*10d63b7dSRichard Lowe struct _String {
209*10d63b7dSRichard Lowe 	struct Text {
210*10d63b7dSRichard Lowe 		wchar_t		*p;	/* Read/Write pointer */
211*10d63b7dSRichard Lowe 		wchar_t		*end;	/* Read limit pointer */
212*10d63b7dSRichard Lowe 	}		text;
213*10d63b7dSRichard Lowe 	struct Physical_buffer {
214*10d63b7dSRichard Lowe 		wchar_t		*start;	/* Points to start of buffer */
215*10d63b7dSRichard Lowe 		wchar_t		*end;	/* End of physical buffer */
216*10d63b7dSRichard Lowe 	}		buffer;
217*10d63b7dSRichard Lowe 	Boolean		free_after_use:1;
218*10d63b7dSRichard Lowe };
219*10d63b7dSRichard Lowe 
220*10d63b7dSRichard Lowe #define STRING_BUFFER_LENGTH	1024
221*10d63b7dSRichard Lowe #define INIT_STRING_FROM_STACK(str, buf) { \
222*10d63b7dSRichard Lowe 			str.buffer.start = (buf); \
223*10d63b7dSRichard Lowe 			str.text.p = (buf); \
224*10d63b7dSRichard Lowe 			str.text.end = NULL; \
225*10d63b7dSRichard Lowe 			str.buffer.end = (buf) \
226*10d63b7dSRichard Lowe                           + (sizeof (buf)/SIZEOFWCHAR_T); \
227*10d63b7dSRichard Lowe 			str.free_after_use = false; \
228*10d63b7dSRichard Lowe 		  }
229*10d63b7dSRichard Lowe 
230*10d63b7dSRichard Lowe #define APPEND_NAME(np, dest, len)	append_string((np)->string_mb, (dest), (len));
231*10d63b7dSRichard Lowe 
232*10d63b7dSRichard Lowe class Wstring {
233*10d63b7dSRichard Lowe 	public:
234*10d63b7dSRichard Lowe 		struct _String	string;
235*10d63b7dSRichard Lowe 		wchar_t		string_buf[STRING_BUFFER_LENGTH];
236*10d63b7dSRichard Lowe 
237*10d63b7dSRichard Lowe 	public:
238*10d63b7dSRichard Lowe 		Wstring();
239*10d63b7dSRichard Lowe 		Wstring(struct _Name * name);
240*10d63b7dSRichard Lowe 		~Wstring();
241*10d63b7dSRichard Lowe 
242*10d63b7dSRichard Lowe 		void init(struct _Name * name);
243*10d63b7dSRichard Lowe 		void init(wchar_t * name, unsigned length);
244*10d63b7dSRichard Lowe 		unsigned length() {
245*10d63b7dSRichard Lowe 			return wcslen(string.buffer.start);
246*10d63b7dSRichard Lowe 		};
247*10d63b7dSRichard Lowe 		void append_to_str(struct _String * str, unsigned off, unsigned length);
248*10d63b7dSRichard Lowe 
249*10d63b7dSRichard Lowe 		wchar_t * get_string() {
250*10d63b7dSRichard Lowe 			return string.buffer.start;
251*10d63b7dSRichard Lowe 		};
252*10d63b7dSRichard Lowe 
253*10d63b7dSRichard Lowe 		wchar_t * get_string(unsigned off) {
254*10d63b7dSRichard Lowe 			return string.buffer.start + off;
255*10d63b7dSRichard Lowe 		};
256*10d63b7dSRichard Lowe 
257*10d63b7dSRichard Lowe 		Boolean equaln(wchar_t * str, unsigned length);
258*10d63b7dSRichard Lowe 		Boolean equal(wchar_t * str);
259*10d63b7dSRichard Lowe 		Boolean equal(wchar_t * str, unsigned off);
260*10d63b7dSRichard Lowe 		Boolean equal(wchar_t * str, unsigned off, unsigned length);
261*10d63b7dSRichard Lowe 
262*10d63b7dSRichard Lowe 		Boolean equaln(Wstring * str, unsigned length);
263*10d63b7dSRichard Lowe 		Boolean equal(Wstring * str);
264*10d63b7dSRichard Lowe 		Boolean equal(Wstring * str, unsigned off);
265*10d63b7dSRichard Lowe 		Boolean equal(Wstring * str, unsigned off, unsigned length);
266*10d63b7dSRichard Lowe };
267*10d63b7dSRichard Lowe 
268*10d63b7dSRichard Lowe 
269*10d63b7dSRichard Lowe /*
270*10d63b7dSRichard Lowe  * Used for storing the $? list and also for the "target + target:"
271*10d63b7dSRichard Lowe  * construct.
272*10d63b7dSRichard Lowe  */
273*10d63b7dSRichard Lowe struct _Chain {
274*10d63b7dSRichard Lowe 	struct _Chain		*next;
275*10d63b7dSRichard Lowe 	struct _Name		*name;
276*10d63b7dSRichard Lowe 	struct _Percent	*percent_member;
277*10d63b7dSRichard Lowe };
278*10d63b7dSRichard Lowe 
279*10d63b7dSRichard Lowe /*
280*10d63b7dSRichard Lowe  * Stores one command line for a rule
281*10d63b7dSRichard Lowe  */
282*10d63b7dSRichard Lowe struct _Cmd_line {
283*10d63b7dSRichard Lowe 	struct _Cmd_line	*next;
284*10d63b7dSRichard Lowe 	struct _Name		*command_line;
285*10d63b7dSRichard Lowe 	Boolean			make_refd:1;	/* $(MAKE) referenced? */
286*10d63b7dSRichard Lowe 	/*
287*10d63b7dSRichard Lowe 	 * Remember any command line prefixes given
288*10d63b7dSRichard Lowe 	 */
289*10d63b7dSRichard Lowe 	Boolean			ignore_command_dependency:1;	/* `?' */
290*10d63b7dSRichard Lowe 	Boolean			assign:1;			/* `=' */
291*10d63b7dSRichard Lowe 	Boolean			ignore_error:1;			/* `-' */
292*10d63b7dSRichard Lowe 	Boolean			silent:1;			/* `@' */
293*10d63b7dSRichard Lowe 	Boolean			always_exec:1;			/* `+' */
294*10d63b7dSRichard Lowe };
295*10d63b7dSRichard Lowe 
296*10d63b7dSRichard Lowe /*
297*10d63b7dSRichard Lowe  * Linked list of targets/files
298*10d63b7dSRichard Lowe  */
299*10d63b7dSRichard Lowe struct _Dependency {
300*10d63b7dSRichard Lowe 	struct _Dependency	*next;
301*10d63b7dSRichard Lowe 	struct _Name		*name;
302*10d63b7dSRichard Lowe 	Boolean			automatic:1;
303*10d63b7dSRichard Lowe 	Boolean			stale:1;
304*10d63b7dSRichard Lowe 	Boolean			built:1;
305*10d63b7dSRichard Lowe };
306*10d63b7dSRichard Lowe 
307*10d63b7dSRichard Lowe /*
308*10d63b7dSRichard Lowe  * The specials are markers for targets that the reader should special case
309*10d63b7dSRichard Lowe  */
310*10d63b7dSRichard Lowe typedef enum {
311*10d63b7dSRichard Lowe 	no_special,
312*10d63b7dSRichard Lowe 	built_last_make_run_special,
313*10d63b7dSRichard Lowe 	default_special,
314*10d63b7dSRichard Lowe 	get_posix_special,
315*10d63b7dSRichard Lowe 	get_special,
316*10d63b7dSRichard Lowe 	ignore_special,
317*10d63b7dSRichard Lowe 	keep_state_file_special,
318*10d63b7dSRichard Lowe 	keep_state_special,
319*10d63b7dSRichard Lowe 	make_version_special,
320*10d63b7dSRichard Lowe 	no_parallel_special,
321*10d63b7dSRichard Lowe 	parallel_special,
322*10d63b7dSRichard Lowe 	posix_special,
323*10d63b7dSRichard Lowe 	precious_special,
324*10d63b7dSRichard Lowe 	sccs_get_posix_special,
325*10d63b7dSRichard Lowe 	sccs_get_special,
326*10d63b7dSRichard Lowe 	silent_special,
327*10d63b7dSRichard Lowe 	suffixes_special,
328*10d63b7dSRichard Lowe 	svr4_special,
329*10d63b7dSRichard Lowe 	localhost_special
330*10d63b7dSRichard Lowe } Special;
331*10d63b7dSRichard Lowe 
332*10d63b7dSRichard Lowe typedef enum {
333*10d63b7dSRichard Lowe 	no_colon,
334*10d63b7dSRichard Lowe 	one_colon,
335*10d63b7dSRichard Lowe 	two_colon,
336*10d63b7dSRichard Lowe 	equal_seen,
337*10d63b7dSRichard Lowe 	conditional_seen,
338*10d63b7dSRichard Lowe 	none_seen
339*10d63b7dSRichard Lowe } Separator;
340*10d63b7dSRichard Lowe 
341*10d63b7dSRichard Lowe /*
342*10d63b7dSRichard Lowe  * Magic values for the timestamp stored with each name object
343*10d63b7dSRichard Lowe  */
344*10d63b7dSRichard Lowe 
345*10d63b7dSRichard Lowe 
346*10d63b7dSRichard Lowe extern const timestruc_t file_no_time;
347*10d63b7dSRichard Lowe extern const timestruc_t file_doesnt_exist;
348*10d63b7dSRichard Lowe extern const timestruc_t file_is_dir;
349*10d63b7dSRichard Lowe extern const timestruc_t file_min_time;
350*10d63b7dSRichard Lowe extern const timestruc_t file_max_time;
351*10d63b7dSRichard Lowe 
352*10d63b7dSRichard Lowe /*
353*10d63b7dSRichard Lowe  * Each Name has a list of properties
354*10d63b7dSRichard Lowe  * The properties are used to store information that only
355*10d63b7dSRichard Lowe  * a subset of the Names need
356*10d63b7dSRichard Lowe  */
357*10d63b7dSRichard Lowe typedef enum {
358*10d63b7dSRichard Lowe 	no_prop,
359*10d63b7dSRichard Lowe 	conditional_prop,
360*10d63b7dSRichard Lowe 	line_prop,
361*10d63b7dSRichard Lowe 	macro_prop,
362*10d63b7dSRichard Lowe 	makefile_prop,
363*10d63b7dSRichard Lowe 	member_prop,
364*10d63b7dSRichard Lowe 	recursive_prop,
365*10d63b7dSRichard Lowe 	sccs_prop,
366*10d63b7dSRichard Lowe 	suffix_prop,
367*10d63b7dSRichard Lowe 	target_prop,
368*10d63b7dSRichard Lowe 	time_prop,
369*10d63b7dSRichard Lowe 	vpath_alias_prop,
370*10d63b7dSRichard Lowe 	long_member_name_prop,
371*10d63b7dSRichard Lowe 	macro_append_prop,
372*10d63b7dSRichard Lowe 	env_mem_prop
373*10d63b7dSRichard Lowe } Property_id;
374*10d63b7dSRichard Lowe 
375*10d63b7dSRichard Lowe typedef enum {
376*10d63b7dSRichard Lowe 	no_daemon = 0,
377*10d63b7dSRichard Lowe 	chain_daemon
378*10d63b7dSRichard Lowe } Daemon;
379*10d63b7dSRichard Lowe 
380*10d63b7dSRichard Lowe struct _Env_mem {
381*10d63b7dSRichard Lowe 	char		*value;
382*10d63b7dSRichard Lowe };
383*10d63b7dSRichard Lowe 
384*10d63b7dSRichard Lowe struct _Macro_appendix {
385*10d63b7dSRichard Lowe 	struct _Name		*value;
386*10d63b7dSRichard Lowe 	struct _Name		*value_to_append;
387*10d63b7dSRichard Lowe };
388*10d63b7dSRichard Lowe 
389*10d63b7dSRichard Lowe struct _Macro {
390*10d63b7dSRichard Lowe 	/*
391*10d63b7dSRichard Lowe 	* For "ABC = xyz" constructs
392*10d63b7dSRichard Lowe 	* Name "ABC" get one macro prop
393*10d63b7dSRichard Lowe 	*/
394*10d63b7dSRichard Lowe 	struct _Name		*value;
395*10d63b7dSRichard Lowe 	Boolean			exported:1;
396*10d63b7dSRichard Lowe 	Boolean			read_only:1;
397*10d63b7dSRichard Lowe 	/*
398*10d63b7dSRichard Lowe 	* This macro is defined conditionally
399*10d63b7dSRichard Lowe 	*/
400*10d63b7dSRichard Lowe 	Boolean			is_conditional:1;
401*10d63b7dSRichard Lowe 	/*
402*10d63b7dSRichard Lowe 	* The list for $? is stored as a structured list that
403*10d63b7dSRichard Lowe 	* is translated into a string iff it is referenced.
404*10d63b7dSRichard Lowe 	* This is why  some macro values need a daemon.
405*10d63b7dSRichard Lowe 	*/
406*10d63b7dSRichard Lowe 	Daemon			daemon:2;
407*10d63b7dSRichard Lowe };
408*10d63b7dSRichard Lowe 
409*10d63b7dSRichard Lowe struct _Macro_list {
410*10d63b7dSRichard Lowe 	struct _Macro_list	*next;
411*10d63b7dSRichard Lowe 	char			*macro_name;
412*10d63b7dSRichard Lowe 	char			*value;
413*10d63b7dSRichard Lowe };
414*10d63b7dSRichard Lowe 
415*10d63b7dSRichard Lowe enum sccs_stat {
416*10d63b7dSRichard Lowe 	DONT_KNOW_SCCS = 0,
417*10d63b7dSRichard Lowe 	NO_SCCS,
418*10d63b7dSRichard Lowe 	HAS_SCCS
419*10d63b7dSRichard Lowe };
420*10d63b7dSRichard Lowe 
421*10d63b7dSRichard Lowe struct _Name {
422*10d63b7dSRichard Lowe 	struct _Property	*prop;		/* List of properties */
423*10d63b7dSRichard Lowe 	char			*string_mb;     /* Multi-byte name string */
424*10d63b7dSRichard Lowe 	struct {
425*10d63b7dSRichard Lowe 		unsigned int		length;
426*10d63b7dSRichard Lowe 	}                       hash;
427*10d63b7dSRichard Lowe 	struct {
428*10d63b7dSRichard Lowe 		timestruc_t		time;		/* Modification */
429*10d63b7dSRichard Lowe 		int			stat_errno;	/* error from "stat" */
430*10d63b7dSRichard Lowe 		off_t			size;		/* Of file */
431*10d63b7dSRichard Lowe 		mode_t			mode;		/* Of file */
432*10d63b7dSRichard Lowe 		Boolean			is_file:1;
433*10d63b7dSRichard Lowe 		Boolean			is_dir:1;
434*10d63b7dSRichard Lowe 		Boolean			is_sym_link:1;
435*10d63b7dSRichard Lowe 		Boolean			is_precious:1;
436*10d63b7dSRichard Lowe 		enum sccs_stat		has_sccs:2;
437*10d63b7dSRichard Lowe 	}                       stat;
438*10d63b7dSRichard Lowe 	/*
439*10d63b7dSRichard Lowe 	 * Count instances of :: definitions for this target
440*10d63b7dSRichard Lowe 	 */
441*10d63b7dSRichard Lowe 	short			colon_splits;
442*10d63b7dSRichard Lowe 	/*
443*10d63b7dSRichard Lowe 	 * We only clear the automatic depes once per target per report
444*10d63b7dSRichard Lowe 	 */
445*10d63b7dSRichard Lowe 	short			temp_file_number;
446*10d63b7dSRichard Lowe 	/*
447*10d63b7dSRichard Lowe 	 * Count how many conditional macros this target has defined
448*10d63b7dSRichard Lowe 	 */
449*10d63b7dSRichard Lowe 	short			conditional_cnt;
450*10d63b7dSRichard Lowe 	/*
451*10d63b7dSRichard Lowe 	 * A conditional macro was used when building this target
452*10d63b7dSRichard Lowe 	 */
453*10d63b7dSRichard Lowe 	Boolean			depends_on_conditional:1;
454*10d63b7dSRichard Lowe 	/*
455*10d63b7dSRichard Lowe 	 * Pointer to list of conditional macros which were used to build
456*10d63b7dSRichard Lowe 	 * this target
457*10d63b7dSRichard Lowe 	 */
458*10d63b7dSRichard Lowe 	struct _Macro_list	*conditional_macro_list;
459*10d63b7dSRichard Lowe 	Boolean			has_member_depe:1;
460*10d63b7dSRichard Lowe 	Boolean			is_member:1;
461*10d63b7dSRichard Lowe 	/*
462*10d63b7dSRichard Lowe 	 * This target is a directory that has been read
463*10d63b7dSRichard Lowe 	 */
464*10d63b7dSRichard Lowe 	Boolean			has_read_dir:1;
465*10d63b7dSRichard Lowe 	/*
466*10d63b7dSRichard Lowe 	 * This name is a macro that is now being expanded
467*10d63b7dSRichard Lowe 	 */
468*10d63b7dSRichard Lowe 	Boolean			being_expanded:1;
469*10d63b7dSRichard Lowe 	/*
470*10d63b7dSRichard Lowe 	 * This name is a magic name that the reader must know about
471*10d63b7dSRichard Lowe 	 */
472*10d63b7dSRichard Lowe 	Special			special_reader:5;
473*10d63b7dSRichard Lowe 	Doname			state:3;
474*10d63b7dSRichard Lowe 	Separator		colons:3;
475*10d63b7dSRichard Lowe 	Boolean			has_depe_list_expanded:1;
476*10d63b7dSRichard Lowe 	Boolean			suffix_scan_done:1;
477*10d63b7dSRichard Lowe 	Boolean			has_complained:1;	/* For sccs */
478*10d63b7dSRichard Lowe 	/*
479*10d63b7dSRichard Lowe 	 * This target has been built during this make run
480*10d63b7dSRichard Lowe 	 */
481*10d63b7dSRichard Lowe 	Boolean			ran_command:1;
482*10d63b7dSRichard Lowe 	Boolean			with_squiggle:1;	/* for .SUFFIXES */
483*10d63b7dSRichard Lowe 	Boolean			without_squiggle:1;	/* for .SUFFIXES */
484*10d63b7dSRichard Lowe 	Boolean			has_read_suffixes:1;	/* Suffix list cached*/
485*10d63b7dSRichard Lowe 	Boolean			has_suffixes:1;
486*10d63b7dSRichard Lowe 	Boolean			has_target_prop:1;
487*10d63b7dSRichard Lowe 	Boolean			has_vpath_alias_prop:1;
488*10d63b7dSRichard Lowe 	Boolean			dependency_printed:1;	/* For dump_make_state() */
489*10d63b7dSRichard Lowe 	Boolean			dollar:1;		/* In namestring */
490*10d63b7dSRichard Lowe 	Boolean			meta:1;			/* In namestring */
491*10d63b7dSRichard Lowe 	Boolean			percent:1;		/* In namestring */
492*10d63b7dSRichard Lowe 	Boolean			wildcard:1;		/* In namestring */
493*10d63b7dSRichard Lowe         Boolean                 has_parent:1;
494*10d63b7dSRichard Lowe         Boolean                 is_target:1;
495*10d63b7dSRichard Lowe 	Boolean			has_built:1;
496*10d63b7dSRichard Lowe 	Boolean			colon:1;		/* In namestring */
497*10d63b7dSRichard Lowe 	Boolean			parenleft:1;		/* In namestring */
498*10d63b7dSRichard Lowe 	Boolean			has_recursive_dependency:1;
499*10d63b7dSRichard Lowe 	Boolean			has_regular_dependency:1;
500*10d63b7dSRichard Lowe 	Boolean			is_double_colon:1;
501*10d63b7dSRichard Lowe 	Boolean			is_double_colon_parent:1;
502*10d63b7dSRichard Lowe 	Boolean			has_long_member_name:1;
503*10d63b7dSRichard Lowe 	/*
504*10d63b7dSRichard Lowe 	 * allowed to run in parallel
505*10d63b7dSRichard Lowe 	 */
506*10d63b7dSRichard Lowe 	Boolean			parallel:1;
507*10d63b7dSRichard Lowe 	/*
508*10d63b7dSRichard Lowe 	 * not allowed to run in parallel
509*10d63b7dSRichard Lowe 	 */
510*10d63b7dSRichard Lowe 	Boolean			no_parallel:1;
511*10d63b7dSRichard Lowe 	/*
512*10d63b7dSRichard Lowe 	 * used in dependency_conflict
513*10d63b7dSRichard Lowe 	 */
514*10d63b7dSRichard Lowe 	Boolean			checking_subtree:1;
515*10d63b7dSRichard Lowe 	Boolean			added_pattern_conditionals:1;
516*10d63b7dSRichard Lowe 	/*
517*10d63b7dSRichard Lowe 	 * rechecking target for possible rebuild
518*10d63b7dSRichard Lowe 	 */
519*10d63b7dSRichard Lowe 	Boolean			rechecking_target:1;
520*10d63b7dSRichard Lowe 	/*
521*10d63b7dSRichard Lowe 	 * build this target in silent mode
522*10d63b7dSRichard Lowe 	 */
523*10d63b7dSRichard Lowe 	Boolean			silent_mode:1;
524*10d63b7dSRichard Lowe 	/*
525*10d63b7dSRichard Lowe 	 * build this target in ignore error mode
526*10d63b7dSRichard Lowe 	 */
527*10d63b7dSRichard Lowe 	Boolean			ignore_error_mode:1;
528*10d63b7dSRichard Lowe 	Boolean			dont_activate_cond_values:1;
529*10d63b7dSRichard Lowe 	/*
530*10d63b7dSRichard Lowe 	 * allowed to run serially on local host
531*10d63b7dSRichard Lowe 	 */
532*10d63b7dSRichard Lowe 	Boolean			localhost:1;
533*10d63b7dSRichard Lowe };
534*10d63b7dSRichard Lowe 
535*10d63b7dSRichard Lowe /*
536*10d63b7dSRichard Lowe  * Stores the % matched default rules
537*10d63b7dSRichard Lowe  */
538*10d63b7dSRichard Lowe struct _Percent {
539*10d63b7dSRichard Lowe 	struct _Percent	*next;
540*10d63b7dSRichard Lowe 	struct _Name		**patterns;
541*10d63b7dSRichard Lowe 	struct _Name		*name;
542*10d63b7dSRichard Lowe 	struct _Percent		*dependencies;
543*10d63b7dSRichard Lowe 	struct _Cmd_line	*command_template;
544*10d63b7dSRichard Lowe 	struct _Chain		*target_group;
545*10d63b7dSRichard Lowe 	int			patterns_total;
546*10d63b7dSRichard Lowe 	Boolean			being_expanded;
547*10d63b7dSRichard Lowe };
548*10d63b7dSRichard Lowe 
549*10d63b7dSRichard Lowe struct Conditional {
550*10d63b7dSRichard Lowe 	/*
551*10d63b7dSRichard Lowe 	 * For "foo := ABC [+]= xyz" constructs
552*10d63b7dSRichard Lowe 	 * Name "foo" gets one conditional prop
553*10d63b7dSRichard Lowe 	 */
554*10d63b7dSRichard Lowe 	struct _Name		*target;
555*10d63b7dSRichard Lowe 	struct _Name		*name;
556*10d63b7dSRichard Lowe 	struct _Name		*value;
557*10d63b7dSRichard Lowe 	int			sequence;
558*10d63b7dSRichard Lowe 	Boolean			append:1;
559*10d63b7dSRichard Lowe };
560*10d63b7dSRichard Lowe 
561*10d63b7dSRichard Lowe struct Line {
562*10d63b7dSRichard Lowe 	/*
563*10d63b7dSRichard Lowe 	 * For "target : dependencies" constructs
564*10d63b7dSRichard Lowe 	 * Name "target" gets one line prop
565*10d63b7dSRichard Lowe 	 */
566*10d63b7dSRichard Lowe 	struct _Cmd_line	*command_template;
567*10d63b7dSRichard Lowe 	struct _Cmd_line	*command_used;
568*10d63b7dSRichard Lowe 	struct _Dependency	*dependencies;
569*10d63b7dSRichard Lowe 	timestruc_t		dependency_time;
570*10d63b7dSRichard Lowe 	struct _Chain		*target_group;
571*10d63b7dSRichard Lowe 	Boolean			is_out_of_date:1;
572*10d63b7dSRichard Lowe 	Boolean			sccs_command:1;
573*10d63b7dSRichard Lowe 	Boolean			command_template_redefined:1;
574*10d63b7dSRichard Lowe 	Boolean			dont_rebuild_command_used:1;
575*10d63b7dSRichard Lowe 	/*
576*10d63b7dSRichard Lowe 	 * Values for the dynamic macros
577*10d63b7dSRichard Lowe 	 */
578*10d63b7dSRichard Lowe 	struct _Name		*target;
579*10d63b7dSRichard Lowe 	struct _Name		*star;
580*10d63b7dSRichard Lowe 	struct _Name		*less;
581*10d63b7dSRichard Lowe 	struct _Name		*percent;
582*10d63b7dSRichard Lowe 	struct _Chain		*query;
583*10d63b7dSRichard Lowe };
584*10d63b7dSRichard Lowe 
585*10d63b7dSRichard Lowe struct Makefile {
586*10d63b7dSRichard Lowe 	/*
587*10d63b7dSRichard Lowe 	 * Names that reference makefiles gets one prop
588*10d63b7dSRichard Lowe 	 */
589*10d63b7dSRichard Lowe 	wchar_t			*contents;
590*10d63b7dSRichard Lowe 	off_t			size;
591*10d63b7dSRichard Lowe };
592*10d63b7dSRichard Lowe 
593*10d63b7dSRichard Lowe struct Member {
594*10d63b7dSRichard Lowe 	/*
595*10d63b7dSRichard Lowe 	 * For "lib(member)" and "lib((entry))" constructs
596*10d63b7dSRichard Lowe 	 * Name "lib(member)" gets one member prop
597*10d63b7dSRichard Lowe 	 * Name "lib((entry))" gets one member prop
598*10d63b7dSRichard Lowe 	 * The member field is filled in when the prop is refd
599*10d63b7dSRichard Lowe 	 */
600*10d63b7dSRichard Lowe 	struct _Name		*library;
601*10d63b7dSRichard Lowe 	struct _Name		*entry;
602*10d63b7dSRichard Lowe 	struct _Name		*member;
603*10d63b7dSRichard Lowe };
604*10d63b7dSRichard Lowe 
605*10d63b7dSRichard Lowe struct Recursive {
606*10d63b7dSRichard Lowe 	/*
607*10d63b7dSRichard Lowe 	 * For "target: .RECURSIVE dir makefiles" constructs
608*10d63b7dSRichard Lowe 	 * Used to keep track of recursive calls to make
609*10d63b7dSRichard Lowe 	 * Name "target" gets one recursive prop
610*10d63b7dSRichard Lowe 	 */
611*10d63b7dSRichard Lowe 	struct _Name		*directory;
612*10d63b7dSRichard Lowe 	struct _Name		*target;
613*10d63b7dSRichard Lowe 	struct _Dependency	*makefiles;
614*10d63b7dSRichard Lowe 	Boolean			has_built;
615*10d63b7dSRichard Lowe 	Boolean			in_depinfo;
616*10d63b7dSRichard Lowe };
617*10d63b7dSRichard Lowe 
618*10d63b7dSRichard Lowe struct Sccs {
619*10d63b7dSRichard Lowe 	/*
620*10d63b7dSRichard Lowe 	 * Each file that has a SCCS s. file gets one prop
621*10d63b7dSRichard Lowe 	 */
622*10d63b7dSRichard Lowe 	struct _Name		*file;
623*10d63b7dSRichard Lowe };
624*10d63b7dSRichard Lowe 
625*10d63b7dSRichard Lowe struct Suffix {
626*10d63b7dSRichard Lowe 	/*
627*10d63b7dSRichard Lowe 	 * Cached list of suffixes that can build this target
628*10d63b7dSRichard Lowe 	 * suffix is built from .SUFFIXES
629*10d63b7dSRichard Lowe 	 */
630*10d63b7dSRichard Lowe 	struct _Name		*suffix;
631*10d63b7dSRichard Lowe 	struct _Cmd_line	*command_template;
632*10d63b7dSRichard Lowe };
633*10d63b7dSRichard Lowe 
634*10d63b7dSRichard Lowe struct Target {
635*10d63b7dSRichard Lowe 	/*
636*10d63b7dSRichard Lowe 	 * For "target:: dependencies" constructs
637*10d63b7dSRichard Lowe 	 * The "::" construct is handled by converting it to
638*10d63b7dSRichard Lowe 	 * "foo: 1@foo" + "1@foo: dependecies"
639*10d63b7dSRichard Lowe 	 * "1@foo" gets one target prop
640*10d63b7dSRichard Lowe 	 * This target prop cause $@ to be bound to "foo"
641*10d63b7dSRichard Lowe 	 * not "1@foo" when the rule is evaluated
642*10d63b7dSRichard Lowe 	 */
643*10d63b7dSRichard Lowe 	struct _Name		*target;
644*10d63b7dSRichard Lowe };
645*10d63b7dSRichard Lowe 
646*10d63b7dSRichard Lowe struct STime {
647*10d63b7dSRichard Lowe 	/*
648*10d63b7dSRichard Lowe 	 * Save the original time for :: targets
649*10d63b7dSRichard Lowe 	 */
650*10d63b7dSRichard Lowe 	timestruc_t			time;
651*10d63b7dSRichard Lowe };
652*10d63b7dSRichard Lowe 
653*10d63b7dSRichard Lowe struct Vpath_alias {
654*10d63b7dSRichard Lowe 	/*
655*10d63b7dSRichard Lowe 	 * If a file was found using the VPATH it gets
656*10d63b7dSRichard Lowe 	 * a vpath_alias prop
657*10d63b7dSRichard Lowe 	 */
658*10d63b7dSRichard Lowe 	struct _Name		*alias;
659*10d63b7dSRichard Lowe };
660*10d63b7dSRichard Lowe 
661*10d63b7dSRichard Lowe struct Long_member_name {
662*10d63b7dSRichard Lowe 	/*
663*10d63b7dSRichard Lowe 	 * Targets with a truncated member name carries
664*10d63b7dSRichard Lowe 	 * the full lib(member) name for the state file
665*10d63b7dSRichard Lowe 	 */
666*10d63b7dSRichard Lowe 	struct _Name		*member_name;
667*10d63b7dSRichard Lowe };
668*10d63b7dSRichard Lowe 
669*10d63b7dSRichard Lowe union Body {
670*10d63b7dSRichard Lowe 	struct _Macro		macro;
671*10d63b7dSRichard Lowe 	struct Conditional	conditional;
672*10d63b7dSRichard Lowe 	struct Line		line;
673*10d63b7dSRichard Lowe 	struct Makefile		makefile;
674*10d63b7dSRichard Lowe 	struct Member		member;
675*10d63b7dSRichard Lowe 	struct Recursive	recursive;
676*10d63b7dSRichard Lowe 	struct Sccs		sccs;
677*10d63b7dSRichard Lowe 	struct Suffix		suffix;
678*10d63b7dSRichard Lowe 	struct Target		target;
679*10d63b7dSRichard Lowe 	struct STime		time;
680*10d63b7dSRichard Lowe 	struct Vpath_alias	vpath_alias;
681*10d63b7dSRichard Lowe 	struct Long_member_name	long_member_name;
682*10d63b7dSRichard Lowe 	struct _Macro_appendix	macro_appendix;
683*10d63b7dSRichard Lowe 	struct _Env_mem		env_mem;
684*10d63b7dSRichard Lowe };
685*10d63b7dSRichard Lowe 
686*10d63b7dSRichard Lowe #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body))
687*10d63b7dSRichard Lowe struct _Property {
688*10d63b7dSRichard Lowe 	struct _Property	*next;
689*10d63b7dSRichard Lowe 	Property_id		type:4;
690*10d63b7dSRichard Lowe 	union Body		body;
691*10d63b7dSRichard Lowe };
692*10d63b7dSRichard Lowe 
693*10d63b7dSRichard Lowe /* Structure for dynamic "ascii" arrays */
694*10d63b7dSRichard Lowe struct ASCII_Dyn_Array {
695*10d63b7dSRichard Lowe 	char			*start;
696*10d63b7dSRichard Lowe 	size_t			size;
697*10d63b7dSRichard Lowe };
698*10d63b7dSRichard Lowe 
699*10d63b7dSRichard Lowe struct _Envvar {
700*10d63b7dSRichard Lowe 	struct _Name		*name;
701*10d63b7dSRichard Lowe 	struct _Name		*value;
702*10d63b7dSRichard Lowe 	struct _Envvar		*next;
703*10d63b7dSRichard Lowe 	char			*env_string;
704*10d63b7dSRichard Lowe 	Boolean			already_put:1;
705*10d63b7dSRichard Lowe };
706*10d63b7dSRichard Lowe 
707*10d63b7dSRichard Lowe /*
708*10d63b7dSRichard Lowe  * Macros for the reader
709*10d63b7dSRichard Lowe  */
710*10d63b7dSRichard Lowe #define GOTO_STATE(new_state) { \
711*10d63b7dSRichard Lowe 				  SET_STATE(new_state); \
712*10d63b7dSRichard Lowe 				    goto enter_state; \
713*10d63b7dSRichard Lowe 			      }
714*10d63b7dSRichard Lowe #define SET_STATE(new_state) state = (new_state)
715*10d63b7dSRichard Lowe 
716*10d63b7dSRichard Lowe #define UNCACHE_SOURCE()	if (source != NULL) { \
717*10d63b7dSRichard Lowe 					source->string.text.p = source_p; \
718*10d63b7dSRichard Lowe 				  }
719*10d63b7dSRichard Lowe #define CACHE_SOURCE(comp)	if (source != NULL) { \
720*10d63b7dSRichard Lowe 					source_p = source->string.text.p - \
721*10d63b7dSRichard Lowe 					  (comp); \
722*10d63b7dSRichard Lowe 					source_end = source->string.text.end; \
723*10d63b7dSRichard Lowe 				  }
724*10d63b7dSRichard Lowe #define GET_NEXT_BLOCK_NOCHK(source)	{ UNCACHE_SOURCE(); \
725*10d63b7dSRichard Lowe 				 source = get_next_block_fn(source); \
726*10d63b7dSRichard Lowe 				 CACHE_SOURCE(0) \
727*10d63b7dSRichard Lowe 			   }
728*10d63b7dSRichard Lowe #define GET_NEXT_BLOCK(source)	{ GET_NEXT_BLOCK_NOCHK(source); \
729*10d63b7dSRichard Lowe 				 if (source != NULL && source->error_converting) { \
730*10d63b7dSRichard Lowe 				 	GOTO_STATE(illegal_bytes_state); \
731*10d63b7dSRichard Lowe 				 } \
732*10d63b7dSRichard Lowe 			   }
733*10d63b7dSRichard Lowe #define GET_CHAR()		((source == NULL) || \
734*10d63b7dSRichard Lowe 				(source_p >= source_end) ? 0 : *source_p)
735*10d63b7dSRichard Lowe 
736*10d63b7dSRichard Lowe struct _Source {
737*10d63b7dSRichard Lowe 	struct _String		string;
738*10d63b7dSRichard Lowe 	struct _Source		*previous;
739*10d63b7dSRichard Lowe 	off_t			bytes_left_in_file;
740*10d63b7dSRichard Lowe 	short			fd;
741*10d63b7dSRichard Lowe 	Boolean			already_expanded:1;
742*10d63b7dSRichard Lowe 	Boolean			error_converting:1;
743*10d63b7dSRichard Lowe 	char			*inp_buf;
744*10d63b7dSRichard Lowe 	char			*inp_buf_end;
745*10d63b7dSRichard Lowe 	char			*inp_buf_ptr;
746*10d63b7dSRichard Lowe };
747*10d63b7dSRichard Lowe 
748*10d63b7dSRichard Lowe typedef enum {
749*10d63b7dSRichard Lowe 	reading_nothing,
750*10d63b7dSRichard Lowe 	reading_makefile,
751*10d63b7dSRichard Lowe 	reading_statefile,
752*10d63b7dSRichard Lowe 	rereading_statefile,
753*10d63b7dSRichard Lowe 	reading_cpp_file
754*10d63b7dSRichard Lowe } Makefile_type;
755*10d63b7dSRichard Lowe 
756*10d63b7dSRichard Lowe /*
757*10d63b7dSRichard Lowe  * Typedefs for all structs
758*10d63b7dSRichard Lowe  */
759*10d63b7dSRichard Lowe typedef struct _Chain		*Chain, Chain_rec;
760*10d63b7dSRichard Lowe typedef struct _Envvar		*Envvar, Envvar_rec;
761*10d63b7dSRichard Lowe typedef struct _Macro_list	*Macro_list, Macro_list_rec;
762*10d63b7dSRichard Lowe typedef struct _Name		*Name, Name_rec;
763*10d63b7dSRichard Lowe typedef struct _Property	*Property, Property_rec;
764*10d63b7dSRichard Lowe typedef struct _Source		*Source, Source_rec;
765*10d63b7dSRichard Lowe typedef struct _String		*String, String_rec;
766*10d63b7dSRichard Lowe 
767*10d63b7dSRichard Lowe /*
768*10d63b7dSRichard Lowe  * name records hash table.
769*10d63b7dSRichard Lowe  */
770*10d63b7dSRichard Lowe struct Name_set {
771*10d63b7dSRichard Lowe private:
772*10d63b7dSRichard Lowe 	// single node in a tree
773*10d63b7dSRichard Lowe 	struct entry {
774*10d63b7dSRichard Lowe 		entry(Name name_, entry *parent_) :
775*10d63b7dSRichard Lowe 			name(name_),
776*10d63b7dSRichard Lowe 			parent(parent_),
777*10d63b7dSRichard Lowe 			left(0),
778*10d63b7dSRichard Lowe 			right(0),
779*10d63b7dSRichard Lowe 			depth(1)
780*10d63b7dSRichard Lowe 		{}
781*10d63b7dSRichard Lowe 
782*10d63b7dSRichard Lowe 		Name		name;
783*10d63b7dSRichard Lowe 
784*10d63b7dSRichard Lowe 		entry		*parent;
785*10d63b7dSRichard Lowe 		entry		*left;
786*10d63b7dSRichard Lowe 		entry		*right;
787*10d63b7dSRichard Lowe 		unsigned	depth;
788*10d63b7dSRichard Lowe 
789*10d63b7dSRichard Lowe 		void setup_depth() {
790*10d63b7dSRichard Lowe 			unsigned rdepth = (right != 0) ? right->depth : 0;
791*10d63b7dSRichard Lowe 			unsigned ldepth = (left != 0) ? left->depth : 0;
792*10d63b7dSRichard Lowe 			depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth);
793*10d63b7dSRichard Lowe 		}
794*10d63b7dSRichard Lowe 	};
795*10d63b7dSRichard Lowe 
796*10d63b7dSRichard Lowe public:
797*10d63b7dSRichard Lowe 	// make iterator a friend of Name_set to have access to struct entry
798*10d63b7dSRichard Lowe 	struct iterator;
799*10d63b7dSRichard Lowe 	friend struct Name_set::iterator;
800*10d63b7dSRichard Lowe 
801*10d63b7dSRichard Lowe 	// iterator over tree nodes
802*10d63b7dSRichard Lowe 	struct iterator {
803*10d63b7dSRichard Lowe 	public:
804*10d63b7dSRichard Lowe 		// constructors
805*10d63b7dSRichard Lowe 		iterator() : node(0) {}
806*10d63b7dSRichard Lowe 		iterator(entry *node_) : node(node_) {}
807*10d63b7dSRichard Lowe 
808*10d63b7dSRichard Lowe 		// dereference operator
809*10d63b7dSRichard Lowe 		Name operator->() const { return node->name; }
810*10d63b7dSRichard Lowe 
811*10d63b7dSRichard Lowe 		// conversion operator
812*10d63b7dSRichard Lowe 		operator Name() { return node->name; }
813*10d63b7dSRichard Lowe 
814*10d63b7dSRichard Lowe 		// assignment operator
815*10d63b7dSRichard Lowe 		iterator& operator=(const iterator &o) { node = o.node; return *this; }
816*10d63b7dSRichard Lowe 
817*10d63b7dSRichard Lowe 		// equality/inequality operators
818*10d63b7dSRichard Lowe 		int operator==(const iterator &o) const { return (node == o.node); }
819*10d63b7dSRichard Lowe 		int operator!=(const iterator &o) const { return (node != o.node); }
820*10d63b7dSRichard Lowe 
821*10d63b7dSRichard Lowe 		// pre/post increment operators
822*10d63b7dSRichard Lowe 		iterator& operator++();
823*10d63b7dSRichard Lowe 		iterator  operator++(int) { iterator it = *this; ++*this; return it; }
824*10d63b7dSRichard Lowe 
825*10d63b7dSRichard Lowe 	private:
826*10d63b7dSRichard Lowe 		// the node iterator points to
827*10d63b7dSRichard Lowe 		entry *node;
828*10d63b7dSRichard Lowe 	};
829*10d63b7dSRichard Lowe 
830*10d63b7dSRichard Lowe public:
831*10d63b7dSRichard Lowe 	// constructor
832*10d63b7dSRichard Lowe 	Name_set() : root(0) {}
833*10d63b7dSRichard Lowe 
834*10d63b7dSRichard Lowe 	// lookup, insert and remove operations
835*10d63b7dSRichard Lowe 	Name lookup(const char *key);
836*10d63b7dSRichard Lowe 	Name insert(const char *key, Boolean &found);
837*10d63b7dSRichard Lowe 	void insert(Name name);
838*10d63b7dSRichard Lowe 
839*10d63b7dSRichard Lowe 	// begin/end iterators
840*10d63b7dSRichard Lowe 	iterator begin() const;
841*10d63b7dSRichard Lowe 	iterator end() const { return iterator(); }
842*10d63b7dSRichard Lowe 
843*10d63b7dSRichard Lowe private:
844*10d63b7dSRichard Lowe 	// rebalance given node
845*10d63b7dSRichard Lowe 	void	rebalance(entry *node);
846*10d63b7dSRichard Lowe 
847*10d63b7dSRichard Lowe private:
848*10d63b7dSRichard Lowe 	// tree root
849*10d63b7dSRichard Lowe 	entry	*root;
850*10d63b7dSRichard Lowe };
851*10d63b7dSRichard Lowe 
852*10d63b7dSRichard Lowe /*
853*10d63b7dSRichard Lowe  *	extern declarations for all global variables.
854*10d63b7dSRichard Lowe  *	The actual declarations are in globals.cc
855*10d63b7dSRichard Lowe  */
856*10d63b7dSRichard Lowe extern char		char_semantics[];
857*10d63b7dSRichard Lowe extern wchar_t		char_semantics_char[];
858*10d63b7dSRichard Lowe extern Macro_list	cond_macro_list;
859*10d63b7dSRichard Lowe extern Boolean		conditional_macro_used;
860*10d63b7dSRichard Lowe extern Boolean		do_not_exec_rule;		/* `-n' */
861*10d63b7dSRichard Lowe extern Boolean		dollarget_seen;
862*10d63b7dSRichard Lowe extern Boolean		dollarless_flag;
863*10d63b7dSRichard Lowe extern Name		dollarless_value;
864*10d63b7dSRichard Lowe extern char		**environ;
865*10d63b7dSRichard Lowe extern Envvar		envvar;
866*10d63b7dSRichard Lowe extern int		exit_status;
867*10d63b7dSRichard Lowe extern wchar_t		*file_being_read;
868*10d63b7dSRichard Lowe /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */
869*10d63b7dSRichard Lowe extern Boolean		gnu_style;
870*10d63b7dSRichard Lowe extern Name_set		hashtab;
871*10d63b7dSRichard Lowe extern Name		host_arch;
872*10d63b7dSRichard Lowe extern Name		host_mach;
873*10d63b7dSRichard Lowe extern int		line_number;
874*10d63b7dSRichard Lowe extern char		*make_state_lockfile;
875*10d63b7dSRichard Lowe extern Boolean		make_word_mentioned;
876*10d63b7dSRichard Lowe extern Makefile_type	makefile_type;
877*10d63b7dSRichard Lowe extern char		mbs_buffer[];
878*10d63b7dSRichard Lowe extern Name		path_name;
879*10d63b7dSRichard Lowe extern Boolean		posix;
880*10d63b7dSRichard Lowe extern Name		query;
881*10d63b7dSRichard Lowe extern Boolean		query_mentioned;
882*10d63b7dSRichard Lowe extern Name		hat;
883*10d63b7dSRichard Lowe extern Boolean		reading_environment;
884*10d63b7dSRichard Lowe extern Name		shell_name;
885*10d63b7dSRichard Lowe extern Boolean		svr4;
886*10d63b7dSRichard Lowe extern Name		target_arch;
887*10d63b7dSRichard Lowe extern Name		target_mach;
888*10d63b7dSRichard Lowe extern Boolean		tilde_rule;
889*10d63b7dSRichard Lowe extern wchar_t		wcs_buffer[];
890*10d63b7dSRichard Lowe extern Boolean		working_on_targets;
891*10d63b7dSRichard Lowe extern Name		virtual_root;
892*10d63b7dSRichard Lowe extern Boolean		vpath_defined;
893*10d63b7dSRichard Lowe extern Name		vpath_name;
894*10d63b7dSRichard Lowe extern Boolean		make_state_locked;
895*10d63b7dSRichard Lowe extern Boolean		out_err_same;
896*10d63b7dSRichard Lowe extern pid_t		childPid;
897*10d63b7dSRichard Lowe 
898*10d63b7dSRichard Lowe /*
899*10d63b7dSRichard Lowe  * RFE 1257407: make does not use fine granularity time info available from stat.
900*10d63b7dSRichard Lowe  * High resolution time comparison.
901*10d63b7dSRichard Lowe  */
902*10d63b7dSRichard Lowe 
903*10d63b7dSRichard Lowe inline int
904*10d63b7dSRichard Lowe operator==(const timestruc_t &t1, const timestruc_t &t2) {
905*10d63b7dSRichard Lowe 	return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec));
906*10d63b7dSRichard Lowe }
907*10d63b7dSRichard Lowe 
908*10d63b7dSRichard Lowe inline int
909*10d63b7dSRichard Lowe operator!=(const timestruc_t &t1, const timestruc_t &t2) {
910*10d63b7dSRichard Lowe 	return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec));
911*10d63b7dSRichard Lowe }
912*10d63b7dSRichard Lowe 
913*10d63b7dSRichard Lowe inline int
914*10d63b7dSRichard Lowe operator>(const timestruc_t &t1, const timestruc_t &t2) {
915*10d63b7dSRichard Lowe 	if (t1.tv_sec == t2.tv_sec) {
916*10d63b7dSRichard Lowe 		return (t1.tv_nsec > t2.tv_nsec);
917*10d63b7dSRichard Lowe 	}
918*10d63b7dSRichard Lowe 	return (t1.tv_sec > t2.tv_sec);
919*10d63b7dSRichard Lowe }
920*10d63b7dSRichard Lowe 
921*10d63b7dSRichard Lowe inline int
922*10d63b7dSRichard Lowe operator>=(const timestruc_t &t1, const timestruc_t &t2) {
923*10d63b7dSRichard Lowe 	if (t1.tv_sec == t2.tv_sec) {
924*10d63b7dSRichard Lowe 		return (t1.tv_nsec >= t2.tv_nsec);
925*10d63b7dSRichard Lowe 	}
926*10d63b7dSRichard Lowe 	return (t1.tv_sec > t2.tv_sec);
927*10d63b7dSRichard Lowe }
928*10d63b7dSRichard Lowe 
929*10d63b7dSRichard Lowe inline int
930*10d63b7dSRichard Lowe operator<(const timestruc_t &t1, const timestruc_t &t2) {
931*10d63b7dSRichard Lowe 	if (t1.tv_sec == t2.tv_sec) {
932*10d63b7dSRichard Lowe 		return (t1.tv_nsec < t2.tv_nsec);
933*10d63b7dSRichard Lowe 	}
934*10d63b7dSRichard Lowe 	return (t1.tv_sec < t2.tv_sec);
935*10d63b7dSRichard Lowe }
936*10d63b7dSRichard Lowe 
937*10d63b7dSRichard Lowe inline int
938*10d63b7dSRichard Lowe operator<=(const timestruc_t &t1, const timestruc_t &t2) {
939*10d63b7dSRichard Lowe 	if (t1.tv_sec == t2.tv_sec) {
940*10d63b7dSRichard Lowe 		return (t1.tv_nsec <= t2.tv_nsec);
941*10d63b7dSRichard Lowe 	}
942*10d63b7dSRichard Lowe 	return (t1.tv_sec < t2.tv_sec);
943*10d63b7dSRichard Lowe }
944*10d63b7dSRichard Lowe 
945*10d63b7dSRichard Lowe #endif
946