xref: /original-bsd/usr.bin/tn3270/tools/mkmake.y (revision e50d1fc5)
1c10df855Sminshall %{
27f36b3ebSminshall 
3df35f3bcSbostic /*-
4*e50d1fc5Sbostic  * Copyright (c) 1988, 1993
5*e50d1fc5Sbostic  *	The Regents of the University of California.  All rights reserved.
67f36b3ebSminshall  *
7df35f3bcSbostic  * %sccs.include.redist.c%
87f36b3ebSminshall  */
97f36b3ebSminshall 
10df35f3bcSbostic #ifndef lint
11*e50d1fc5Sbostic static char sccsid[] = "@(#)mkmake.y	8.1 (Berkeley) 06/06/93";
12df35f3bcSbostic #endif /* not lint */
13df35f3bcSbostic 
14c10df855Sminshall typedef struct string {
15c10df855Sminshall     int
16c10df855Sminshall 	hashval,
17c10df855Sminshall 	length;
18c10df855Sminshall     char
19c10df855Sminshall 	*string;
20c10df855Sminshall     struct string
21c10df855Sminshall 	*next;
22c10df855Sminshall } string_t;
23c10df855Sminshall 
2484402bf5Sminshall /*
2584402bf5Sminshall  * The deal with these is that they exist on various lists.
2684402bf5Sminshall  *
2784402bf5Sminshall  * First off, they are on a temporary list during the time they
2884402bf5Sminshall  * are in the active focus of the parser.
2984402bf5Sminshall  *
3084402bf5Sminshall  * Secondly, they live on one of three queues:
3184402bf5Sminshall  *	1.  Variables
3284402bf5Sminshall  *	2.  Targets
3384402bf5Sminshall  *	3.  Actions
3484402bf5Sminshall  * (and, we restrict any given one to live on one and only one such list)
3584402bf5Sminshall  *
3684402bf5Sminshall  * Also, they may live on the list of values for someone else's variable,
3784402bf5Sminshall  * or as someone's dependancy.
3884402bf5Sminshall  */
3984402bf5Sminshall 
40c10df855Sminshall typedef struct same {
41c10df855Sminshall     string_t
4284402bf5Sminshall 	*string;			/* My name */
4384402bf5Sminshall     struct same
4484402bf5Sminshall 	*nexttoken,			/* Next pointer */
4584402bf5Sminshall 	*lasttoken,			/* Back pointer */
4684402bf5Sminshall 	*depend_list,			/* If target, dependancies */
4784402bf5Sminshall 	*action_list,			/* If target, actions */
48bbfe3fc0Sminshall 	*value_list,			/* If variable, value list */
49bbfe3fc0Sminshall 	*shell_item;			/* If a shell variable, current value */
50c10df855Sminshall } same_t;
51c10df855Sminshall 
52c10df855Sminshall %}
53c10df855Sminshall 
54c10df855Sminshall %union {
55c10df855Sminshall     string_t *string;
56c10df855Sminshall     same_t *same;
5784402bf5Sminshall     int	intval;
58c10df855Sminshall     }
59c10df855Sminshall 
604788ac1fSminshall %start makefile
6184402bf5Sminshall %token <string> TOKEN QUOTED_STRING
62bbfe3fc0Sminshall %token <intval>	FOR IN DO DONE
63bbfe3fc0Sminshall %token <intval> MACRO_CHAR NL WHITE_SPACE
64bbfe3fc0Sminshall %token <intval> ':' '=' '$' '{' '}' ';' '-' '@' '(' ')' ' ' '\t'
65d70f92ebSminshall %type <same> target target1 assignment assign1 actions action
66f53f6b88Sminshall %type <same> command_list list list_element
67bc7371f7Sminshall %type <same> for_statement maybe_at_minus tokens token
68d70f92ebSminshall %type <same> maybe_white_space
69bbfe3fc0Sminshall %type <intval> white_space macro_char
70c10df855Sminshall %%
7184402bf5Sminshall 
72bbfe3fc0Sminshall makefile : lines;
73c10df855Sminshall 
74c10df855Sminshall lines : line
75c10df855Sminshall     | lines line
76c10df855Sminshall     ;
77c10df855Sminshall 
78bbfe3fc0Sminshall line : NL
7984402bf5Sminshall     | assignment
8084402bf5Sminshall     | target_action
81c10df855Sminshall     ;
82c10df855Sminshall 
83f53f6b88Sminshall assignment : assign1 tokens NL
84c10df855Sminshall     {
85bbfe3fc0Sminshall 	assign($1, $2);
8684402bf5Sminshall     }
87bbfe3fc0Sminshall     | assign1 NL
8884402bf5Sminshall     {
89953a4c02Sminshall 	assign($1, same_copy(null));
90c10df855Sminshall     }
91c10df855Sminshall     ;
92c10df855Sminshall 
934ffc2a5cSminshall assign1: token maybe_white_space '=' maybe_white_space
94bbfe3fc0Sminshall     ;
95bbfe3fc0Sminshall 
9684402bf5Sminshall target_action: target actions
97c10df855Sminshall     {
9884402bf5Sminshall 	add_targets_actions($1, $2);
9984402bf5Sminshall     }
10084402bf5Sminshall     | target
10184402bf5Sminshall     {
102bc7371f7Sminshall 	add_targets_actions($1, 0);
10384402bf5Sminshall     }
10484402bf5Sminshall     ;
10584402bf5Sminshall 
106f53f6b88Sminshall target : target1 tokens NL
10784402bf5Sminshall     {
108d70f92ebSminshall 	$$ = add_depends($1, $2);
10984402bf5Sminshall     }
110d70f92ebSminshall     | target1 NL
111d70f92ebSminshall     {
112d70f92ebSminshall 	$$ = add_depends($1, same_copy(null));
113d70f92ebSminshall     }
114d70f92ebSminshall     ;
115d70f92ebSminshall 
116d70f92ebSminshall target1: tokens maybe_white_space ':' maybe_white_space
117bc7371f7Sminshall     {
118bc7371f7Sminshall 	$$ = ws_merge($1);
119bc7371f7Sminshall     }
120c10df855Sminshall     ;
121c10df855Sminshall 
122c10df855Sminshall actions: action
123c10df855Sminshall     | actions action
124c10df855Sminshall     {
125f53f6b88Sminshall 	$$ = same_cat(same_cat($1, same_copy(newline)), $2);
126c10df855Sminshall     }
127c10df855Sminshall     ;
128c10df855Sminshall 
129bbfe3fc0Sminshall action:	white_space command_list NL
130c10df855Sminshall     {
131c10df855Sminshall 	$$ = $2;
132c10df855Sminshall     }
133bbfe3fc0Sminshall     | white_space for_statement do command_list semi_colon done NL
1347fe218f1Sminshall     {
135486c8420Sminshall 	$$ = do_command($2, $4);
1367fe218f1Sminshall     }
137c10df855Sminshall     ;
138c10df855Sminshall 
139d70f92ebSminshall for_statement: maybe_at_minus FOR white_space token
140bc7371f7Sminshall 		in tokens semi_colon
1417fe218f1Sminshall     {
142e334f66eSminshall 	$$ = for_statement($1, $4, ws_merge(expand_variables($6, 0)));
143bbfe3fc0Sminshall     }
144bbfe3fc0Sminshall     ;
145bbfe3fc0Sminshall 
146d70f92ebSminshall in:	white_space IN white_space
147bbfe3fc0Sminshall do:	white_space DO white_space
148bbfe3fc0Sminshall     ;
149bbfe3fc0Sminshall 
150bbfe3fc0Sminshall done:	white_space DONE
151bbfe3fc0Sminshall     ;
152bbfe3fc0Sminshall 
153d70f92ebSminshall semi_colon:	';'
154bbfe3fc0Sminshall     ;
155bbfe3fc0Sminshall 
156bbfe3fc0Sminshall command_list: list
157bbfe3fc0Sminshall     | '(' list maybe_white_space ')'
158bbfe3fc0Sminshall     {
1594ffc2a5cSminshall 	$$ = same_cat($2, same_copy(cwd_line));
160bbfe3fc0Sminshall     }
161bbfe3fc0Sminshall     ;
162bbfe3fc0Sminshall 
163f53f6b88Sminshall list: token
164f53f6b88Sminshall     | list list_element
165bbfe3fc0Sminshall     {
166f53f6b88Sminshall 	$$ = same_cat($1, $2);
167f53f6b88Sminshall     }
168f53f6b88Sminshall     | list white_space list_element
169f53f6b88Sminshall     {
170f53f6b88Sminshall 	$$ = same_cat($1, same_cat(same_copy(blank), $3));
171bbfe3fc0Sminshall     }
172bbfe3fc0Sminshall     ;
173bbfe3fc0Sminshall 
174f53f6b88Sminshall list_element: token
175f53f6b88Sminshall     | semi_colon
176f53f6b88Sminshall     {
177f53f6b88Sminshall 	$$ = same_copy(newline);
178f53f6b88Sminshall     }
1797fe218f1Sminshall     ;
1807fe218f1Sminshall 
1817fe218f1Sminshall maybe_at_minus: /* empty */
1827fe218f1Sminshall     {
1837fe218f1Sminshall 	$$ = same_copy(null);
1847fe218f1Sminshall     }
1857fe218f1Sminshall     | '@'
1867fe218f1Sminshall     {
1877fe218f1Sminshall 	char buffer[2];
1887fe218f1Sminshall 
1897fe218f1Sminshall 	buffer[0] = $1;
1907fe218f1Sminshall 	buffer[1] = 0;
1917fe218f1Sminshall 	$$ = same_item(string_lookup(buffer));
1927fe218f1Sminshall     }
1937fe218f1Sminshall     | '-'
1947fe218f1Sminshall     {
1957fe218f1Sminshall 	char buffer[2];
1967fe218f1Sminshall 
1977fe218f1Sminshall 	buffer[0] = $1;
1987fe218f1Sminshall 	buffer[1] = 0;
1997fe218f1Sminshall 	$$ = same_item(string_lookup(buffer));
2007fe218f1Sminshall     }
2017fe218f1Sminshall     ;
202bbfe3fc0Sminshall 
203c10df855Sminshall tokens : token
204d70f92ebSminshall     | tokens maybe_white_space token
205c10df855Sminshall     {
206d70f92ebSminshall 	$$ = same_cat($1, same_cat($2, $3));
207c10df855Sminshall     }
208c10df855Sminshall     ;
20984402bf5Sminshall 
210d70f92ebSminshall token: TOKEN
211c10df855Sminshall     {
21284402bf5Sminshall 	$$ = same_item($1);
21384402bf5Sminshall     }
21484402bf5Sminshall     | QUOTED_STRING
21584402bf5Sminshall     {
21684402bf5Sminshall 	$$ = same_item($1);
21784402bf5Sminshall     }
21884402bf5Sminshall     | '$' macro_char
21984402bf5Sminshall     {
22084402bf5Sminshall 	char buffer[3];
22184402bf5Sminshall 
22284402bf5Sminshall 	buffer[0] = '$';
22384402bf5Sminshall 	buffer[1] = $2;
22484402bf5Sminshall 	buffer[2] = 0;
22584402bf5Sminshall 
22684402bf5Sminshall 	$$ = same_item(string_lookup(buffer));
22784402bf5Sminshall     }
228bc7371f7Sminshall     | '$' '$' TOKEN
22984402bf5Sminshall     {
230bc7371f7Sminshall 	$$ = shell_variable(same_item($3));
23184402bf5Sminshall     }
232bbfe3fc0Sminshall     | MACRO_CHAR
233bbfe3fc0Sminshall     {
234bbfe3fc0Sminshall 	$$ = same_char($1);
235bbfe3fc0Sminshall     }
236bc7371f7Sminshall     | '$' '{' TOKEN '}'
23784402bf5Sminshall     {
238bc7371f7Sminshall 	$$ = variable(same_item($3));
239bc7371f7Sminshall     }
240bc7371f7Sminshall     | '$' '(' TOKEN ')'
241bc7371f7Sminshall     {
242bc7371f7Sminshall 	$$ = variable(same_item($3));
243bc7371f7Sminshall     }
244bc7371f7Sminshall     | '$' TOKEN
245bc7371f7Sminshall     {
246bc7371f7Sminshall 	$$ = variable(same_item($2));
247c10df855Sminshall     }
2487fe218f1Sminshall     | '-'
2497fe218f1Sminshall     {
2507fe218f1Sminshall 	$$ = same_char('-');
2517fe218f1Sminshall     }
2527fe218f1Sminshall     | '@'
2537fe218f1Sminshall     {
2547fe218f1Sminshall 	$$ = same_char('@');
2557fe218f1Sminshall     }
256c10df855Sminshall     ;
25784402bf5Sminshall 
25884402bf5Sminshall macro_char: MACRO_CHAR
259bbfe3fc0Sminshall     | '@'
26084402bf5Sminshall     ;
26184402bf5Sminshall 
26284402bf5Sminshall maybe_white_space:
263d70f92ebSminshall     {
264d70f92ebSminshall 	$$ = same_copy(null);
265d70f92ebSminshall     }
266d70f92ebSminshall     | white_space
267d70f92ebSminshall     {
268d70f92ebSminshall 	$$ = same_char($1);
269d70f92ebSminshall     }
270d70f92ebSminshall     ;
27184402bf5Sminshall 
27284402bf5Sminshall white_space : WHITE_SPACE
27384402bf5Sminshall     | white_space WHITE_SPACE
27484402bf5Sminshall     ;
275c10df855Sminshall %%
276c10df855Sminshall #include <stdio.h>
277bc7371f7Sminshall #include <ctype.h>
278c10df855Sminshall 
279c10df855Sminshall static int last_char, last_saved = 0;
280c10df855Sminshall static int column = 0, lineno = 1;
281c10df855Sminshall 
282c10df855Sminshall 
28384402bf5Sminshall static string_t
28484402bf5Sminshall     *strings = 0;
285bbfe3fc0Sminshall 
286c10df855Sminshall static same_t
287bbfe3fc0Sminshall     *shell_variables = 0,
288bbfe3fc0Sminshall     *shell_special = 0,
289ff189d06Sminshall     *variables = 0,
290ff189d06Sminshall     *targets = 0,
291ff189d06Sminshall     *actions = 0;
29284402bf5Sminshall 
29384402bf5Sminshall static same_t
294953a4c02Sminshall     *null,
295953a4c02Sminshall     *blank,
2964ffc2a5cSminshall     *cwd_line,
297953a4c02Sminshall     *newline;
298c10df855Sminshall 
299c10df855Sminshall extern char *malloc();
300c10df855Sminshall 
301953a4c02Sminshall static unsigned int
302953a4c02Sminshall 	clock = -1;
303953a4c02Sminshall 
304953a4c02Sminshall struct {
305953a4c02Sminshall     same_t *first;
306953a4c02Sminshall     int next;
307953a4c02Sminshall } visit_stack[20];		/* 20 maximum */
308953a4c02Sminshall 
309953a4c02Sminshall #define	visit(what,via) \
310953a4c02Sminshall 	(visit_stack[++clock].next = 0, visit_stack[clock].first = via = what)
3114788ac1fSminshall #define	visited(via)	(visitcheck(via) || ((via) == 0) \
312ff189d06Sminshall 	|| (visit_stack[clock].next && (via == visit_stack[clock].first)))
313953a4c02Sminshall #define	visit_next(via)	(visit_stack[clock].next = 1, (via) = (via)->nexttoken)
314953a4c02Sminshall #define	visit_end()	(clock--)
315953a4c02Sminshall 
yyerror(s)316c10df855Sminshall yyerror(s)
317c10df855Sminshall char *s;
318c10df855Sminshall {
31984402bf5Sminshall     fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s);
32084402bf5Sminshall     do_dump();
321c10df855Sminshall }
322c10df855Sminshall 
32384402bf5Sminshall int
visitcheck(same)3244788ac1fSminshall visitcheck(same)
3254788ac1fSminshall same_t *same;
3264788ac1fSminshall {
3274788ac1fSminshall     if (same->string == 0) {
3284788ac1fSminshall 	yyerror("BUG - freed 'same' in use...");
3294788ac1fSminshall 	exit(1);
3304788ac1fSminshall     }
3314788ac1fSminshall     return 0;
3324788ac1fSminshall }
3334788ac1fSminshall 
3344788ac1fSminshall int
string_hashof(string,length)33584402bf5Sminshall string_hashof(string, length)
33684402bf5Sminshall char *string;
33784402bf5Sminshall int length;
338c10df855Sminshall {
33984402bf5Sminshall     register int i = 0;
34084402bf5Sminshall 
34184402bf5Sminshall     while (length--) {
34284402bf5Sminshall 	i = (i<<3) + *string ^ ((i>>28)&0x7);
34384402bf5Sminshall     }
34484402bf5Sminshall     return i;
345c10df855Sminshall }
346c10df855Sminshall 
34784402bf5Sminshall int
string_same(s1,s2)34884402bf5Sminshall string_same(s1, s2)
34984402bf5Sminshall string_t
35084402bf5Sminshall     *s1, *s2;
351c10df855Sminshall {
35284402bf5Sminshall     if ((s1->hashval == s2->hashval) && (s1->length == s2->length)
35384402bf5Sminshall 		&& (memcmp(s1->string, s2->string, s1->length) == 0)) {
35484402bf5Sminshall 	return 1;
35584402bf5Sminshall     } else {
35684402bf5Sminshall 	return 0;
35784402bf5Sminshall     }
358c10df855Sminshall }
359c10df855Sminshall 
36084402bf5Sminshall string_t *
string_lookup(string)36184402bf5Sminshall string_lookup(string)
36284402bf5Sminshall char *string;
36384402bf5Sminshall {
36484402bf5Sminshall     string_t ours;
36584402bf5Sminshall     string_t *ptr;
36684402bf5Sminshall 
36784402bf5Sminshall     ours.length = strlen(string);
36884402bf5Sminshall     ours.hashval = string_hashof(string, ours.length);
36984402bf5Sminshall     ours.string = string;
37084402bf5Sminshall 
37184402bf5Sminshall     for (ptr = strings; ptr; ptr = ptr->next) {
37284402bf5Sminshall 	if (string_same(&ours, ptr)) {
37384402bf5Sminshall 	    return ptr;
37484402bf5Sminshall 	}
37584402bf5Sminshall     }
37684402bf5Sminshall     if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) {
37784402bf5Sminshall 	fprintf(stderr, "No space to add string *%s*!\n", string);
37884402bf5Sminshall 	exit(1);
37984402bf5Sminshall     }
38084402bf5Sminshall     ptr->hashval = ours.hashval;
38184402bf5Sminshall     ptr->length = ours.length;
38284402bf5Sminshall     if ((ptr->string = malloc(ours.length+1)) == 0) {
38384402bf5Sminshall 	fprintf(stderr, "No space to add literal *%s*!\n", string);
38484402bf5Sminshall 	exit(1);
38584402bf5Sminshall     }
38684402bf5Sminshall     memcpy(ptr->string, string, ours.length+1);
38784402bf5Sminshall     ptr->next = strings;
38884402bf5Sminshall     strings = ptr;
38984402bf5Sminshall     return ptr;
39084402bf5Sminshall }
391c10df855Sminshall 
392bc7371f7Sminshall #define	same_singleton(s)	((s)->nexttoken == (s))
393bc7371f7Sminshall 
394c10df855Sminshall same_t *
same_search(list,token)39584402bf5Sminshall same_search(list, token)
396c10df855Sminshall same_t
39784402bf5Sminshall     *list,
398c10df855Sminshall     *token;
399c10df855Sminshall {
400c10df855Sminshall     same_t *ptr;
401c10df855Sminshall 
402953a4c02Sminshall     ptr = list;
403953a4c02Sminshall     for (visit(list, ptr); !visited(ptr); visit_next(ptr)) {
40484402bf5Sminshall 	string_t *string;
40584402bf5Sminshall 
40684402bf5Sminshall 	string = ptr->string;
40784402bf5Sminshall 	if (string_same(string, token->string)) {
408953a4c02Sminshall 	    visit_end();
40984402bf5Sminshall 	    return ptr;
410c10df855Sminshall 	}
411c10df855Sminshall     }
412953a4c02Sminshall     visit_end();
41384402bf5Sminshall     return 0;
414c10df855Sminshall }
415c10df855Sminshall 
416c10df855Sminshall same_t *
same_cat(list,tokens)41784402bf5Sminshall same_cat(list, tokens)
41884402bf5Sminshall same_t
41984402bf5Sminshall     *list,
42084402bf5Sminshall     *tokens;
42184402bf5Sminshall {
42284402bf5Sminshall     same_t *last;
42384402bf5Sminshall 
424bbfe3fc0Sminshall     if (tokens == 0) {
425bbfe3fc0Sminshall 	return list;
426bbfe3fc0Sminshall     }
427ff189d06Sminshall     if (list) {
42884402bf5Sminshall 	last = tokens->lasttoken;
42984402bf5Sminshall 	tokens->lasttoken = list->lasttoken;
43084402bf5Sminshall 	list->lasttoken = last;
43184402bf5Sminshall 	tokens->lasttoken->nexttoken = tokens;
432953a4c02Sminshall 	last->nexttoken = list;
43384402bf5Sminshall 	return list;
434ff189d06Sminshall     } else {
435ff189d06Sminshall 	return tokens;
436ff189d06Sminshall     }
43784402bf5Sminshall }
43884402bf5Sminshall 
43984402bf5Sminshall same_t *
same_item(string)44084402bf5Sminshall same_item(string)
441c10df855Sminshall string_t *string;
442c10df855Sminshall {
443c10df855Sminshall     same_t *ptr;
444c10df855Sminshall 
445c10df855Sminshall     if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) {
446c10df855Sminshall 	fprintf(stderr, "No more space for tokens!\n");
447c10df855Sminshall 	exit(1);
448c10df855Sminshall     }
44984402bf5Sminshall     memset((char *)ptr, 0, sizeof *ptr);
450953a4c02Sminshall     ptr->nexttoken = ptr->lasttoken = ptr;
451c10df855Sminshall     ptr->string = string;
452c10df855Sminshall     return ptr;
453c10df855Sminshall }
454c10df855Sminshall 
45584402bf5Sminshall same_t *
same_copy(same)45684402bf5Sminshall same_copy(same)
45784402bf5Sminshall same_t *same;
45884402bf5Sminshall {
459953a4c02Sminshall     same_t *head, *copy;
46084402bf5Sminshall 
461ff189d06Sminshall     head = 0;
462ff189d06Sminshall     for (visit(same, copy); !visited(copy); visit_next(copy)) {
46384402bf5Sminshall 	same_t *ptr;
46484402bf5Sminshall 
465953a4c02Sminshall 	ptr = same_item(copy->string);
466ff189d06Sminshall 	head = same_cat(head, ptr);
46784402bf5Sminshall     }
468ff189d06Sminshall     visit_end();
46984402bf5Sminshall     return head;
47084402bf5Sminshall }
47184402bf5Sminshall 
472bc7371f7Sminshall 
473bc7371f7Sminshall same_t *
same_merge(t1,t2)474bc7371f7Sminshall same_merge(t1, t2)
475bc7371f7Sminshall same_t
476bc7371f7Sminshall     *t1,
477bc7371f7Sminshall     *t2;
478bc7371f7Sminshall {
479bc7371f7Sminshall     if (same_singleton(t1) && same_singleton(t2)) {
480bc7371f7Sminshall 	int length = strlen(t1->string->string)+strlen(t2->string->string);
481bc7371f7Sminshall 	char *buffer = malloc(length+1);
482bc7371f7Sminshall 	same_t *value;
483bc7371f7Sminshall 
484bc7371f7Sminshall 	if (buffer == 0) {
485bc7371f7Sminshall 	    yyerror("No space to merge strings in same_merge!");
486bc7371f7Sminshall 	    exit(1);
487bc7371f7Sminshall 	}
488bc7371f7Sminshall 	strcpy(buffer, t1->string->string);
489bc7371f7Sminshall 	strcat(buffer, t2->string->string);
490bc7371f7Sminshall 	value = same_item(string_lookup(buffer));
491bc7371f7Sminshall 	free(buffer);
492bc7371f7Sminshall 	return value;
493bc7371f7Sminshall     } else {
494bc7371f7Sminshall 	yyerror("Internal error - same_merge with non-singletons");
495bc7371f7Sminshall 	exit(1);
496bc7371f7Sminshall     }
497bc7371f7Sminshall }
498bc7371f7Sminshall 
499bc7371f7Sminshall 
50084402bf5Sminshall void
same_free(list)501953a4c02Sminshall same_free(list)
502953a4c02Sminshall same_t *list;
50384402bf5Sminshall {
504953a4c02Sminshall     same_t *token, *ptr;
50584402bf5Sminshall 
506bc7371f7Sminshall     if (list == 0) {
507bc7371f7Sminshall 	return;
508bc7371f7Sminshall     }
509bc7371f7Sminshall 
510953a4c02Sminshall     token = list;
511953a4c02Sminshall     do {
51284402bf5Sminshall 	ptr = token->nexttoken;
5134788ac1fSminshall 	token->string = 0;
51484402bf5Sminshall 	(void) free((char *)token);
51584402bf5Sminshall 	token = ptr;
516953a4c02Sminshall     } while (token != list);
51784402bf5Sminshall }
51884402bf5Sminshall 
5197fe218f1Sminshall same_t *
same_unlink(token)520953a4c02Sminshall same_unlink(token)
52184402bf5Sminshall same_t
522953a4c02Sminshall     *token;
52384402bf5Sminshall {
5247fe218f1Sminshall     same_t *tmp;
5257fe218f1Sminshall 
526ff189d06Sminshall     if (token == 0) {
5277fe218f1Sminshall 	return 0;
5287fe218f1Sminshall     }
5297fe218f1Sminshall     if ((tmp = token->nexttoken) == token) {
5307fe218f1Sminshall 	tmp = 0;
531ff189d06Sminshall     }
53284402bf5Sminshall     token->lasttoken->nexttoken = token->nexttoken;
53384402bf5Sminshall     token->nexttoken->lasttoken = token->lasttoken;
534ff189d06Sminshall     token->nexttoken = token->lasttoken = token;
5357fe218f1Sminshall     return tmp;
5367fe218f1Sminshall }
5377fe218f1Sminshall 
5384ffc2a5cSminshall void
same_replace(old,new)5394ffc2a5cSminshall same_replace(old, new)
5404ffc2a5cSminshall same_t
5414ffc2a5cSminshall     *old,
5424ffc2a5cSminshall     *new;
5434ffc2a5cSminshall {
5444ffc2a5cSminshall     new->lasttoken->nexttoken = old->nexttoken;
5454ffc2a5cSminshall     old->nexttoken->lasttoken = new->lasttoken;
5464ffc2a5cSminshall     new->lasttoken = old->lasttoken;
5474ffc2a5cSminshall     /* rather than
5484ffc2a5cSminshall      * old->lasttoken->nexttoken = new
5494ffc2a5cSminshall      * we update in place (for the case where there isn't anything else)
5504ffc2a5cSminshall      */
5514ffc2a5cSminshall     *old = *new;
5524ffc2a5cSminshall }
5534ffc2a5cSminshall 
5544ffc2a5cSminshall 
5557fe218f1Sminshall same_t *
same_char(ch)5567fe218f1Sminshall same_char(ch)
5577fe218f1Sminshall char ch;
5587fe218f1Sminshall {
5597fe218f1Sminshall     char buffer[2];
5607fe218f1Sminshall 
5617fe218f1Sminshall     buffer[0] = ch;
5627fe218f1Sminshall     buffer[1] = 0;
5637fe218f1Sminshall 
5647fe218f1Sminshall     return same_item(string_lookup(buffer));
56584402bf5Sminshall }
56684402bf5Sminshall 
5674ffc2a5cSminshall 
568bc7371f7Sminshall void
add_target(target,actions)569bc7371f7Sminshall add_target(target, actions)
57084402bf5Sminshall same_t
571bc7371f7Sminshall     *target,
572bc7371f7Sminshall     *actions;
57384402bf5Sminshall {
57484402bf5Sminshall     same_t *ptr;
57584402bf5Sminshall 
576953a4c02Sminshall     if ((ptr = same_search(targets, target)) == 0) {
577ff189d06Sminshall 	targets = same_cat(targets, target);
578bc7371f7Sminshall 	ptr = target;
57984402bf5Sminshall     } else {
580ff189d06Sminshall 	ptr->depend_list = same_cat(ptr->depend_list, target->depend_list);
581bc7371f7Sminshall     }
582bc7371f7Sminshall     if (actions) {
583bc7371f7Sminshall 	if (ptr->action_list) {
584bc7371f7Sminshall 	    same_free(ptr->action_list);
585bc7371f7Sminshall 	}
586bc7371f7Sminshall 	ptr->action_list = same_copy(actions);
58784402bf5Sminshall     }
58884402bf5Sminshall }
58984402bf5Sminshall 
5904ffc2a5cSminshall 
59184402bf5Sminshall same_t *
add_targets_actions(target,actions)59284402bf5Sminshall add_targets_actions(target, actions)
59384402bf5Sminshall same_t
59484402bf5Sminshall     *target,
59584402bf5Sminshall     *actions;
59684402bf5Sminshall {
5974788ac1fSminshall     same_t *ptr;
59884402bf5Sminshall 
599ff189d06Sminshall     if (target == 0) {
600ff189d06Sminshall 	return 0;
60184402bf5Sminshall     }
602ff189d06Sminshall     do {
6037fe218f1Sminshall 	ptr = same_unlink(target);
604bc7371f7Sminshall 	add_target(target, actions);
605ff189d06Sminshall 	target = ptr;
6064788ac1fSminshall     } while (target);
607ff189d06Sminshall 
608ff189d06Sminshall     same_free(actions);
60984402bf5Sminshall     return 0;
61084402bf5Sminshall }
61184402bf5Sminshall 
61284402bf5Sminshall same_t *
add_depends(target,depends)61384402bf5Sminshall add_depends(target, depends)
61484402bf5Sminshall same_t
61584402bf5Sminshall     *target,
61684402bf5Sminshall     *depends;
61784402bf5Sminshall {
61884402bf5Sminshall     same_t *original = target;
61984402bf5Sminshall 
620ff189d06Sminshall     depends = same_cat(depends, same_copy(blank));	/* Separator */
62184402bf5Sminshall 
622953a4c02Sminshall     for (visit(original, target); !visited(target); visit_next(target)) {
623ff189d06Sminshall 	target->depend_list = same_cat(target->depend_list, same_copy(depends));
624953a4c02Sminshall     }
625953a4c02Sminshall     visit_end();
626ff189d06Sminshall     same_free(depends);
627953a4c02Sminshall 
62884402bf5Sminshall     return original;
62984402bf5Sminshall }
63084402bf5Sminshall 
63184402bf5Sminshall 
63284402bf5Sminshall /*
63384402bf5Sminshall  * We know that variable is a singleton
63484402bf5Sminshall  */
63584402bf5Sminshall 
63684402bf5Sminshall void
assign(variable,value)63784402bf5Sminshall assign(variable, value)
63884402bf5Sminshall same_t
63984402bf5Sminshall     *variable,
64084402bf5Sminshall     *value;
64184402bf5Sminshall {
64284402bf5Sminshall     same_t *ptr;
64384402bf5Sminshall 
644953a4c02Sminshall     if ((ptr = same_search(variables, variable)) != 0) {
64584402bf5Sminshall 	same_free(ptr->value_list);
646bc7371f7Sminshall 	variables = same_unlink(ptr);
647ff189d06Sminshall 	same_free(ptr);
64884402bf5Sminshall     }
64984402bf5Sminshall     variable->value_list = value;
650ff189d06Sminshall     variables = same_cat(variables, variable);
65184402bf5Sminshall }
65284402bf5Sminshall 
65384402bf5Sminshall same_t *
value_of(variable)65484402bf5Sminshall value_of(variable)
65584402bf5Sminshall same_t *variable;
65684402bf5Sminshall {
657953a4c02Sminshall     same_t *ptr = same_search(variables, variable);
65884402bf5Sminshall 
65984402bf5Sminshall     if (ptr == 0) {
660ff189d06Sminshall 	return same_copy(null);
66184402bf5Sminshall     } else {
662ff189d06Sminshall 	return same_copy(ptr->value_list);
66384402bf5Sminshall     }
66484402bf5Sminshall }
66584402bf5Sminshall 
6667fe218f1Sminshall 
6677fe218f1Sminshall same_t *
expand_variables(token,free)6687fe218f1Sminshall expand_variables(token, free)
6697fe218f1Sminshall same_t *token;
6707fe218f1Sminshall int	free;
6717fe218f1Sminshall {
6727fe218f1Sminshall     same_t *head = 0;
6737fe218f1Sminshall 
6747fe218f1Sminshall     if (!free) {
6757fe218f1Sminshall 	token = same_copy(token);		/* Get our private copy */
6767fe218f1Sminshall     }
6777fe218f1Sminshall 
6787fe218f1Sminshall     while (token) {
6797fe218f1Sminshall 	char *string = token->string->string;
6807fe218f1Sminshall 	same_t *tmp = same_unlink(token);
6817fe218f1Sminshall 
682e334f66eSminshall 	if ((string[0] == '$') && (string[1] == '{')) {	/* Expand time */
6837fe218f1Sminshall 	    int len = strlen(string);
6847fe218f1Sminshall 
6857fe218f1Sminshall 	    string[len-1] = 0;
6867fe218f1Sminshall 	    head = same_cat(head, expand_variables(
6877fe218f1Sminshall 			value_of(same_item(string_lookup(string+2))), 1));
6887fe218f1Sminshall 	    string[len-1] = '}';
689e334f66eSminshall 	} else {
6907fe218f1Sminshall 	    head = same_cat(head, token);
6917fe218f1Sminshall 	}
6927fe218f1Sminshall 	token = tmp;
6937fe218f1Sminshall     }
6947fe218f1Sminshall     return head;
6957fe218f1Sminshall }
6967fe218f1Sminshall 
697bc7371f7Sminshall 
698bc7371f7Sminshall same_t *
ws_merge(list)699bc7371f7Sminshall ws_merge(list)
700bc7371f7Sminshall same_t *list;
701bc7371f7Sminshall {
702bc7371f7Sminshall     same_t *newlist = 0, *item;
703bc7371f7Sminshall     int what = 0;
704bc7371f7Sminshall 
705bc7371f7Sminshall     while (list) {
706bc7371f7Sminshall 	switch (what) {
707bc7371f7Sminshall 	case 0:
708bc7371f7Sminshall 	    if (isspace(list->string->string[0])) {
709bc7371f7Sminshall 		;
710bc7371f7Sminshall 	    } else {
711bc7371f7Sminshall 		item = same_item(list->string);
712bc7371f7Sminshall 		what = 1;
713bc7371f7Sminshall 	    }
714bc7371f7Sminshall 	    break;
715bc7371f7Sminshall 	case 1:
716bc7371f7Sminshall 	    if (isspace(list->string->string[0])) {
717bc7371f7Sminshall 		newlist = same_cat(newlist, item);
718bc7371f7Sminshall 		item = 0;
719bc7371f7Sminshall 		what = 0;
720bc7371f7Sminshall 	    } else {
721bc7371f7Sminshall 		item = same_merge(item, same_item(list->string));
722bc7371f7Sminshall 		what = 1;
723bc7371f7Sminshall 	    }
724bc7371f7Sminshall 	    break;
725bc7371f7Sminshall 	}
726bc7371f7Sminshall 	list = same_unlink(list);
727bc7371f7Sminshall     }
728bc7371f7Sminshall     return same_cat(newlist, item);
729bc7371f7Sminshall }
730bc7371f7Sminshall 
731bc7371f7Sminshall 
732c4695814Sminshall same_t *
variable(var_name)733c4695814Sminshall variable(var_name)
734c4695814Sminshall same_t *var_name;
735c4695814Sminshall {
736c4695814Sminshall     int length = strlen(var_name->string->string);
737c4695814Sminshall     same_t *resolved;
738c4695814Sminshall     char *newname;
739c4695814Sminshall 
740c4695814Sminshall     if ((newname = malloc(length+1+3)) == 0) {
741c4695814Sminshall 	fprintf("Out of space for a variable name.\n");
742c4695814Sminshall 	exit(1);
743c4695814Sminshall     }
744c4695814Sminshall     newname[0] = '$';
745c4695814Sminshall     newname[1] = '{';
746c4695814Sminshall     strcpy(newname+2, var_name->string->string);
747c4695814Sminshall     strcat(newname, "}");
748c4695814Sminshall     resolved = same_item(string_lookup(newname));
749c4695814Sminshall     free(newname);
750c4695814Sminshall 
751c4695814Sminshall     return resolved;
752c4695814Sminshall }
753c4695814Sminshall 
754bbfe3fc0Sminshall 
7557fe218f1Sminshall same_t *
shell_variable(var_name)756486c8420Sminshall shell_variable(var_name)
757486c8420Sminshall same_t *var_name;
758bbfe3fc0Sminshall {
759486c8420Sminshall     int length = strlen(var_name->string->string);
760486c8420Sminshall     same_t *resolved;
761486c8420Sminshall     char *newname;
762bbfe3fc0Sminshall 
763486c8420Sminshall     if ((newname = malloc(length+1+2)) == 0) {
764486c8420Sminshall 	fprintf("Out of space for a variable name.\n");
765bbfe3fc0Sminshall 	exit(1);
766bbfe3fc0Sminshall     }
767486c8420Sminshall     newname[0] = '$';
768486c8420Sminshall     newname[1] = '$';
769486c8420Sminshall     strcpy(newname+2, var_name->string->string);
770486c8420Sminshall     resolved = same_item(string_lookup(newname));
771486c8420Sminshall     free(newname);
772486c8420Sminshall 
773486c8420Sminshall     return resolved;
774bbfe3fc0Sminshall }
775bbfe3fc0Sminshall 
776bbfe3fc0Sminshall same_t *
for_statement(special,variable,list)777bbfe3fc0Sminshall for_statement(special, variable, list)
7787fe218f1Sminshall same_t
7797fe218f1Sminshall     *special,
7807fe218f1Sminshall     *variable,
781bbfe3fc0Sminshall     *list;
7827fe218f1Sminshall {
783486c8420Sminshall     variable->shell_item = special;
784bbfe3fc0Sminshall     variable->value_list = list;
785486c8420Sminshall     return variable;
786486c8420Sminshall }
787486c8420Sminshall 
788486c8420Sminshall same_t *
do_command(forlist,commands)789486c8420Sminshall do_command(forlist, commands)
790486c8420Sminshall same_t
791486c8420Sminshall     *forlist,
792486c8420Sminshall     *commands;
793486c8420Sminshall {
7944ffc2a5cSminshall     same_t
7954ffc2a5cSminshall 	*special,
7964ffc2a5cSminshall 	*command_list = 0,
7974ffc2a5cSminshall 	*new_commands,
7984ffc2a5cSminshall 	*tmp,
7994ffc2a5cSminshall 	*shell_item,
8004ffc2a5cSminshall 	*value_list = forlist->value_list;
8014ffc2a5cSminshall     char
8024ffc2a5cSminshall 	*tmpstr,
8034ffc2a5cSminshall 	*variable_name = forlist->string->string;
8044ffc2a5cSminshall 
8054ffc2a5cSminshall     special = forlist->shell_item;
8064ffc2a5cSminshall     if (same_unlink(forlist->shell_item) != 0) {
8074ffc2a5cSminshall 	yyerror("Unexpected second item in special part of do_command");
8084ffc2a5cSminshall 	exit(1);
8094ffc2a5cSminshall     }
8104ffc2a5cSminshall 
8114ffc2a5cSminshall     while ((shell_item = value_list) != 0) {
8124ffc2a5cSminshall 	value_list = same_unlink(shell_item);
8134ffc2a5cSminshall 	/* Visit each item in commands.  For each shell variable which
8144ffc2a5cSminshall 	 * matches ours, replace it with ours.
8154ffc2a5cSminshall 	 */
8164ffc2a5cSminshall 	new_commands = same_copy(commands);
8174ffc2a5cSminshall 	for (visit(new_commands, tmp); !visited(tmp); visit_next(tmp)) {
8184ffc2a5cSminshall 	    tmpstr = tmp->string->string;
8194ffc2a5cSminshall 	    if ((tmpstr[0] == '$') && (tmpstr[1] == '$')) {
8204ffc2a5cSminshall 		if (strcmp(tmpstr+2, variable_name) == 0) {
8214ffc2a5cSminshall 		    same_replace(tmp, same_copy(shell_item));
8224ffc2a5cSminshall 		}
8234ffc2a5cSminshall 	    }
8244ffc2a5cSminshall 	}
8254ffc2a5cSminshall 	visit_end();
8264ffc2a5cSminshall 	command_list = same_cat(command_list, new_commands);
8274ffc2a5cSminshall     }
8284ffc2a5cSminshall     return same_cat(command_list, same_copy(newline));
8297fe218f1Sminshall }
8307fe218f1Sminshall 
83184402bf5Sminshall 
832c10df855Sminshall int
Getchar()833c10df855Sminshall Getchar()
834c10df855Sminshall {
835c10df855Sminshall     if (last_saved) {
836c10df855Sminshall 	last_saved = 0;
837c10df855Sminshall 	return last_char;
838c10df855Sminshall     } else {
839c10df855Sminshall 	int c;
840c10df855Sminshall 	c = getchar();
841c10df855Sminshall 	switch (c) {
842c10df855Sminshall 	case '\n':
843c10df855Sminshall 	    lineno++;
844c10df855Sminshall 	    column = 0;
845c10df855Sminshall 	    break;
846c10df855Sminshall 	default:
847c10df855Sminshall 	    column++;
848c10df855Sminshall 	}
849c10df855Sminshall 	return c;
850c10df855Sminshall     }
851c10df855Sminshall }
852c10df855Sminshall 
853c10df855Sminshall 
8547fe218f1Sminshall int
token_type(string)8557fe218f1Sminshall token_type(string)
8567fe218f1Sminshall char *string;
8577fe218f1Sminshall {
8587fe218f1Sminshall     switch (string[0]) {
8597fe218f1Sminshall     case 'f':
8607fe218f1Sminshall 	if (strcmp(string, "for") == 0) {
8617fe218f1Sminshall 	    return FOR;
8627fe218f1Sminshall 	}
8637fe218f1Sminshall 	break;
8647fe218f1Sminshall     case 'd':
8657fe218f1Sminshall 	if (string[1] == 'o') {
8667fe218f1Sminshall 	    if (strcmp(string, "do") == 0) {
8677fe218f1Sminshall 		return DO;
8687fe218f1Sminshall 	    } else if (strcmp(string, "done") == 0) {
8697fe218f1Sminshall 		return DONE;
8707fe218f1Sminshall 	    }
8717fe218f1Sminshall 	}
8727fe218f1Sminshall 	break;
8737fe218f1Sminshall     case 'i':
8747fe218f1Sminshall 	if (strcmp(string, "in") == 0) {
8757fe218f1Sminshall 	    return IN;
8767fe218f1Sminshall 	}
8777fe218f1Sminshall 	break;
8787fe218f1Sminshall     default:
8797fe218f1Sminshall 	break;
8807fe218f1Sminshall     }
8817fe218f1Sminshall     return TOKEN;
8827fe218f1Sminshall }
8837fe218f1Sminshall 
8847fe218f1Sminshall 
yylex()885c10df855Sminshall yylex()
886c10df855Sminshall {
887c10df855Sminshall #define	ret_token(c)	if (bufptr != buffer) { \
888c10df855Sminshall 			    save(c); \
889c10df855Sminshall 			    *bufptr = 0; \
890c10df855Sminshall 			    bufptr = buffer; \
89184402bf5Sminshall 			    yylval.string = string_lookup(buffer); \
8927fe218f1Sminshall 			    return token_type(buffer); \
893c10df855Sminshall 			}
894c10df855Sminshall #define	save(c)	{ last_char = c; last_saved = 1; }
89584402bf5Sminshall #if	defined(YYDEBUG)
896c10df855Sminshall #define	Return(c)	if (yydebug) { \
897c10df855Sminshall 			    printf("[%d]", c); \
898c10df855Sminshall 			    fflush(stdout); \
899c10df855Sminshall 			} \
90084402bf5Sminshall 			yyval.intval = c; \
901c10df855Sminshall 			return c;
90284402bf5Sminshall #else	/* defined(YYDEBUG) */
90384402bf5Sminshall #define	Return(y,c)	{ yylval.intval = c; return y; }
90484402bf5Sminshall #endif	/* defined(YYDEBUG) */
905c10df855Sminshall 
90684402bf5Sminshall 
90784402bf5Sminshall     static char buffer[500], *bufptr = buffer;
908c10df855Sminshall     static int eof_found = 0;
909c10df855Sminshall     int c;
910c10df855Sminshall 
911c10df855Sminshall     if (eof_found != 0) {
912c10df855Sminshall 	eof_found++;
913c10df855Sminshall 	if (eof_found > 2) {
914c10df855Sminshall 	    fprintf(stderr, "End of file ignored.\n");
915c10df855Sminshall 	    exit(1);
916c10df855Sminshall 	}
917bbfe3fc0Sminshall 	Return(EOF,0);
918c10df855Sminshall     }
919c10df855Sminshall     while ((c = Getchar()) != EOF) {
920c10df855Sminshall 	switch (c) {
921c10df855Sminshall 	case '#':
922c10df855Sminshall 	    ret_token(c);
923c10df855Sminshall 	    while (((c = Getchar()) != EOF) && (c != '\n')) {
924c10df855Sminshall 		;
925c10df855Sminshall 	    }
926c10df855Sminshall 	    save(c);
927c10df855Sminshall 	    break;
92884402bf5Sminshall 	case '<':
92984402bf5Sminshall 	case '?':
930c10df855Sminshall 	    ret_token(c);
93184402bf5Sminshall 	    Return(MACRO_CHAR, c);
93284402bf5Sminshall 	case '\t':
93384402bf5Sminshall 	case ' ':
93484402bf5Sminshall 	    ret_token(c);
93584402bf5Sminshall 	    Return(WHITE_SPACE, c);
9367fe218f1Sminshall 	case '-':
9377fe218f1Sminshall 	case '@':
938c10df855Sminshall 	case ':':
9397fe218f1Sminshall 	case ';':
940c10df855Sminshall 	case '=':
94184402bf5Sminshall 	case '$':
94284402bf5Sminshall 	case '{':
94384402bf5Sminshall 	case '}':
9447fe218f1Sminshall 	case '(':
9457fe218f1Sminshall 	case ')':
946c10df855Sminshall 	    ret_token(c);
94784402bf5Sminshall 	    Return(c,c);
94884402bf5Sminshall 	case '\'':
94984402bf5Sminshall 	case '"':
950e023e216Sminshall 	    if (bufptr != buffer) {
951e023e216Sminshall 		if (bufptr[-1] == '\\') {
952e023e216Sminshall 		    bufptr[-1] = c;
953e023e216Sminshall 		}
954e023e216Sminshall 		break;
955e023e216Sminshall 	    } else {
95684402bf5Sminshall 		int newc;
95784402bf5Sminshall 
95884402bf5Sminshall 		ret_token(c);
95984402bf5Sminshall 		*bufptr++ = c;
96084402bf5Sminshall 		while (((newc = Getchar()) != EOF) && (newc != c)) {
96184402bf5Sminshall 		    *bufptr++ = newc;
96284402bf5Sminshall 		}
96384402bf5Sminshall 		*bufptr++ = c;
96484402bf5Sminshall 		*bufptr = 0;
96584402bf5Sminshall 		bufptr = buffer;
96684402bf5Sminshall 		yylval.string = string_lookup(buffer);
96784402bf5Sminshall 		return QUOTED_STRING;
96884402bf5Sminshall 	    }
969c10df855Sminshall 	case '\n':
970c10df855Sminshall 	    if (bufptr != buffer) {
971c10df855Sminshall 		if (bufptr[-1] == '\\') {
972c10df855Sminshall 		    bufptr--;
97384402bf5Sminshall 		    if ((c = Getchar()) != '\t') {
97484402bf5Sminshall 			yyerror("continuation line doesn't begin with a tab");
97584402bf5Sminshall 			save(c);
97684402bf5Sminshall 		    }
97784402bf5Sminshall 		    ret_token(c);
97884402bf5Sminshall 		    Return(WHITE_SPACE, c);
979c10df855Sminshall 		}
980c10df855Sminshall 	    }
981c10df855Sminshall 	    ret_token(c);
98284402bf5Sminshall 	    Return(NL, 0);
983c10df855Sminshall 	default:
984c10df855Sminshall 	    *bufptr++ = c;
985c10df855Sminshall 	    break;
986c10df855Sminshall 	}
987c10df855Sminshall     }
988c10df855Sminshall 
989c10df855Sminshall     eof_found = 1;
990c10df855Sminshall 
991c10df855Sminshall     ret_token(' ');
992bbfe3fc0Sminshall     Return(EOF, 0);
993c10df855Sminshall }
99484402bf5Sminshall 
main()99584402bf5Sminshall main()
99684402bf5Sminshall {
99784402bf5Sminshall #define	YYDEBUG
99884402bf5Sminshall     extern int yydebug;
99984402bf5Sminshall 
1000953a4c02Sminshall     null = same_item(string_lookup(""));
1001953a4c02Sminshall     newline = same_item(string_lookup("\n"));
1002953a4c02Sminshall     blank = same_item(string_lookup(" "));
10034ffc2a5cSminshall     cwd_line = same_cat(same_copy(newline),
10044ffc2a5cSminshall 			same_cat(same_item(string_lookup("cd ${CWD}")),
10054ffc2a5cSminshall 				 same_copy(newline)));
100684402bf5Sminshall 
1007d70f92ebSminshall     yyparse();
1008d70f92ebSminshall 
1009d70f92ebSminshall     do_dump();
10104ffc2a5cSminshall 
10114ffc2a5cSminshall     return 0;
101284402bf5Sminshall }
101384402bf5Sminshall 
101484402bf5Sminshall #if	defined(YYDEBUG)
dump_same(same)10154788ac1fSminshall dump_same(same)
10164788ac1fSminshall same_t *same;
10174788ac1fSminshall {
10184788ac1fSminshall     same_t *same2;
10194788ac1fSminshall 
10204788ac1fSminshall     for (visit(same, same2); !visited(same2); visit_next(same2)) {
10214788ac1fSminshall 	printf(same2->string->string);
10224788ac1fSminshall     }
10234788ac1fSminshall     visit_end();
10244788ac1fSminshall }
1025d70f92ebSminshall #endif	/* YYDEBUG */
10264788ac1fSminshall 
do_dump()102784402bf5Sminshall do_dump()
102884402bf5Sminshall {
102984402bf5Sminshall     string_t *string;
103084402bf5Sminshall     same_t *same, *same2;
103184402bf5Sminshall 
103284402bf5Sminshall     if (yydebug > 1) {
103384402bf5Sminshall 	printf("strings...\n");
103484402bf5Sminshall 	for (string = strings; string; string = string->next) {
103584402bf5Sminshall 	    printf("\t%s\n", string->string);
103684402bf5Sminshall 	}
103784402bf5Sminshall     }
103884402bf5Sminshall 
1039d70f92ebSminshall     printf("# variables...\n");
1040ff189d06Sminshall     for (visit(variables, same); !visited(same); visit_next(same)) {
1041d70f92ebSminshall 	printf("%s =\t", same->string->string);
1042953a4c02Sminshall 	for (visit(same->value_list, same2); !visited(same2);
1043953a4c02Sminshall 						visit_next(same2)) {
1044bc7371f7Sminshall 	    printf(same2->string->string);
104584402bf5Sminshall 	}
1046953a4c02Sminshall 	visit_end();
104784402bf5Sminshall 	printf("\n");
104884402bf5Sminshall     }
1049ff189d06Sminshall     visit_end();
105084402bf5Sminshall 
1051f53f6b88Sminshall     printf("\n\n#targets...\n");
1052ff189d06Sminshall     for (visit(targets, same); !visited(same); visit_next(same)) {
1053f53f6b88Sminshall 	printf("\n%s:\t", same->string->string);
1054953a4c02Sminshall 	for (visit(same->depend_list, same2); !visited(same2);
1055953a4c02Sminshall 						visit_next(same2)) {
105684402bf5Sminshall 	    printf(same2->string->string);
105784402bf5Sminshall 	}
1058953a4c02Sminshall 	visit_end();
1059d70f92ebSminshall 	printf("\n\t");
1060953a4c02Sminshall 	for (visit(same->action_list, same2); !visited(same2);
1061953a4c02Sminshall 					    visit_next(same2)) {
106284402bf5Sminshall 	    printf(same2->string->string);
106384402bf5Sminshall 	    if (same2->string->string[0] == '\n') {
1064d70f92ebSminshall 		printf("\t");
106584402bf5Sminshall 	    }
106684402bf5Sminshall 	}
1067953a4c02Sminshall 	visit_end();
106884402bf5Sminshall 	printf("\n");
106984402bf5Sminshall     }
1070ff189d06Sminshall     visit_end();
107184402bf5Sminshall }
1072