1*0a6a1f1dSLionel Sambuc /*	$NetBSD: slc-gram.y,v 1.1.1.2 2014/04/24 12:45:53 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc %{
4ebfedea0SLionel Sambuc /*
5ebfedea0SLionel Sambuc  * Copyright (c) 2004-2006 Kungliga Tekniska Högskolan
6ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
7ebfedea0SLionel Sambuc  * All rights reserved.
8ebfedea0SLionel Sambuc  *
9ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
10ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
11ebfedea0SLionel Sambuc  * are met:
12ebfedea0SLionel Sambuc  *
13ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
14ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
15ebfedea0SLionel Sambuc  *
16ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
17ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
18ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
19ebfedea0SLionel Sambuc  *
20ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
21ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
22ebfedea0SLionel Sambuc  *    without specific prior written permission.
23ebfedea0SLionel Sambuc  *
24ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
25ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
28ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34ebfedea0SLionel Sambuc  * SUCH DAMAGE.
35ebfedea0SLionel Sambuc  */
36ebfedea0SLionel Sambuc 
37ebfedea0SLionel Sambuc #include <config.h>
38ebfedea0SLionel Sambuc 
39ebfedea0SLionel Sambuc #include <stdio.h>
40ebfedea0SLionel Sambuc #include <stdlib.h>
41ebfedea0SLionel Sambuc #include <err.h>
42ebfedea0SLionel Sambuc #include <ctype.h>
43ebfedea0SLionel Sambuc #include <limits.h>
44ebfedea0SLionel Sambuc #include <getarg.h>
45ebfedea0SLionel Sambuc #include <vers.h>
46ebfedea0SLionel Sambuc #include <roken.h>
47ebfedea0SLionel Sambuc 
48ebfedea0SLionel Sambuc #include "slc.h"
49ebfedea0SLionel Sambuc extern FILE *yyin;
50ebfedea0SLionel Sambuc extern struct assignment *assignment;
51ebfedea0SLionel Sambuc 
52ebfedea0SLionel Sambuc /* Declarations for Bison:
53ebfedea0SLionel Sambuc  */
54ebfedea0SLionel Sambuc #define YYMALLOC        malloc
55ebfedea0SLionel Sambuc #define YYFREE          free
56ebfedea0SLionel Sambuc 
57ebfedea0SLionel Sambuc %}
58ebfedea0SLionel Sambuc 
59ebfedea0SLionel Sambuc %union {
60ebfedea0SLionel Sambuc 	char *string;
61ebfedea0SLionel Sambuc 	struct assignment *assignment;
62ebfedea0SLionel Sambuc }
63ebfedea0SLionel Sambuc 
64ebfedea0SLionel Sambuc %token <string> LITERAL
65ebfedea0SLionel Sambuc %token <string> STRING
66ebfedea0SLionel Sambuc %type <assignment> assignment assignments
67ebfedea0SLionel Sambuc 
68ebfedea0SLionel Sambuc %start start
69ebfedea0SLionel Sambuc 
70ebfedea0SLionel Sambuc %%
71ebfedea0SLionel Sambuc 
72ebfedea0SLionel Sambuc start		: assignments
73ebfedea0SLionel Sambuc 		{
74ebfedea0SLionel Sambuc 			assignment = $1;
75ebfedea0SLionel Sambuc 		}
76ebfedea0SLionel Sambuc 		;
77ebfedea0SLionel Sambuc 
78ebfedea0SLionel Sambuc assignments	: assignment assignments
79ebfedea0SLionel Sambuc 		{
80ebfedea0SLionel Sambuc 			$1->next = $2;
81ebfedea0SLionel Sambuc 			$$ = $1;
82ebfedea0SLionel Sambuc 		}
83ebfedea0SLionel Sambuc 		| assignment
84ebfedea0SLionel Sambuc 		;
85ebfedea0SLionel Sambuc 
86ebfedea0SLionel Sambuc assignment	: LITERAL '=' STRING
87ebfedea0SLionel Sambuc 		{
88ebfedea0SLionel Sambuc 			$$ = malloc(sizeof(*$$));
89ebfedea0SLionel Sambuc 			$$->name = $1;
90ebfedea0SLionel Sambuc 			$$->type = a_value;
91ebfedea0SLionel Sambuc 			$$->lineno = lineno;
92ebfedea0SLionel Sambuc 			$$->u.value = $3;
93ebfedea0SLionel Sambuc 			$$->next = NULL;
94ebfedea0SLionel Sambuc 		}
95ebfedea0SLionel Sambuc 		| LITERAL '=' '{' assignments '}'
96ebfedea0SLionel Sambuc 		{
97ebfedea0SLionel Sambuc 			$$ = malloc(sizeof(*$$));
98ebfedea0SLionel Sambuc 			$$->name = $1;
99ebfedea0SLionel Sambuc 			$$->type = a_assignment;
100ebfedea0SLionel Sambuc 			$$->lineno = lineno;
101ebfedea0SLionel Sambuc 			$$->u.assignment = $4;
102ebfedea0SLionel Sambuc 			$$->next = NULL;
103ebfedea0SLionel Sambuc 		}
104ebfedea0SLionel Sambuc 		;
105ebfedea0SLionel Sambuc 
106ebfedea0SLionel Sambuc %%
107ebfedea0SLionel Sambuc char *filename;
108ebfedea0SLionel Sambuc FILE *cfile, *hfile;
109ebfedea0SLionel Sambuc int error_flag;
110ebfedea0SLionel Sambuc struct assignment *assignment;
111ebfedea0SLionel Sambuc 
112ebfedea0SLionel Sambuc 
113ebfedea0SLionel Sambuc static void
ex(struct assignment * a,const char * fmt,...)114ebfedea0SLionel Sambuc ex(struct assignment *a, const char *fmt, ...)
115ebfedea0SLionel Sambuc {
116ebfedea0SLionel Sambuc     va_list ap;
117ebfedea0SLionel Sambuc     fprintf(stderr, "%s:%d: ", a->name, a->lineno);
118ebfedea0SLionel Sambuc     va_start(ap, fmt);
119ebfedea0SLionel Sambuc     vfprintf(stderr, fmt, ap);
120ebfedea0SLionel Sambuc     va_end(ap);
121ebfedea0SLionel Sambuc     fprintf(stderr, "\n");
122ebfedea0SLionel Sambuc }
123ebfedea0SLionel Sambuc 
124ebfedea0SLionel Sambuc 
125ebfedea0SLionel Sambuc 
126ebfedea0SLionel Sambuc static int
check_option(struct assignment * as)127ebfedea0SLionel Sambuc check_option(struct assignment *as)
128ebfedea0SLionel Sambuc {
129ebfedea0SLionel Sambuc     struct assignment *a;
130ebfedea0SLionel Sambuc     int seen_long = 0;
131ebfedea0SLionel Sambuc     int seen_name = 0;
132ebfedea0SLionel Sambuc     int seen_short = 0;
133ebfedea0SLionel Sambuc     int seen_type = 0;
134ebfedea0SLionel Sambuc     int seen_argument = 0;
135ebfedea0SLionel Sambuc     int seen_help = 0;
136ebfedea0SLionel Sambuc     int seen_default = 0;
137ebfedea0SLionel Sambuc     int ret = 0;
138ebfedea0SLionel Sambuc 
139ebfedea0SLionel Sambuc     for(a = as; a != NULL; a = a->next) {
140ebfedea0SLionel Sambuc 	if(strcmp(a->name, "long") == 0)
141ebfedea0SLionel Sambuc 	    seen_long++;
142ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "short") == 0)
143ebfedea0SLionel Sambuc 	    seen_short++;
144ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "name") == 0)
145ebfedea0SLionel Sambuc 	    seen_name++;
146ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "type") == 0)
147ebfedea0SLionel Sambuc 	    seen_type++;
148ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "argument") == 0)
149ebfedea0SLionel Sambuc 	    seen_argument++;
150ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "help") == 0)
151ebfedea0SLionel Sambuc 	    seen_help++;
152ebfedea0SLionel Sambuc 	else if(strcmp(a->name, "default") == 0)
153ebfedea0SLionel Sambuc 	    seen_default++;
154ebfedea0SLionel Sambuc 	else {
155ebfedea0SLionel Sambuc 	    ex(a, "unknown name %s", a->name);
156ebfedea0SLionel Sambuc 	    ret++;
157ebfedea0SLionel Sambuc 	}
158ebfedea0SLionel Sambuc     }
159ebfedea0SLionel Sambuc     if(seen_long == 0 && seen_short == 0) {
160ebfedea0SLionel Sambuc 	ex(as, "neither long nor short option");
161ebfedea0SLionel Sambuc 	ret++;
162ebfedea0SLionel Sambuc     }
163ebfedea0SLionel Sambuc     if (seen_long == 0 && seen_name == 0) {
164ebfedea0SLionel Sambuc 	ex(as, "either of long or name option must be used");
165ebfedea0SLionel Sambuc 	ret++;
166ebfedea0SLionel Sambuc     }
167ebfedea0SLionel Sambuc     if(seen_long > 1) {
168ebfedea0SLionel Sambuc 	ex(as, "multiple long options");
169ebfedea0SLionel Sambuc 	ret++;
170ebfedea0SLionel Sambuc     }
171ebfedea0SLionel Sambuc     if(seen_short > 1) {
172ebfedea0SLionel Sambuc 	ex(as, "multiple short options");
173ebfedea0SLionel Sambuc 	ret++;
174ebfedea0SLionel Sambuc     }
175ebfedea0SLionel Sambuc     if(seen_type > 1) {
176ebfedea0SLionel Sambuc 	ex(as, "multiple types");
177ebfedea0SLionel Sambuc 	ret++;
178ebfedea0SLionel Sambuc     }
179ebfedea0SLionel Sambuc     if(seen_argument > 1) {
180ebfedea0SLionel Sambuc 	ex(as, "multiple arguments");
181ebfedea0SLionel Sambuc 	ret++;
182ebfedea0SLionel Sambuc     }
183ebfedea0SLionel Sambuc     if(seen_help > 1) {
184ebfedea0SLionel Sambuc 	ex(as, "multiple help strings");
185ebfedea0SLionel Sambuc 	ret++;
186ebfedea0SLionel Sambuc     }
187ebfedea0SLionel Sambuc     if(seen_default > 1) {
188ebfedea0SLionel Sambuc 	ex(as, "multiple default values");
189ebfedea0SLionel Sambuc 	ret++;
190ebfedea0SLionel Sambuc     }
191ebfedea0SLionel Sambuc     return ret;
192ebfedea0SLionel Sambuc }
193ebfedea0SLionel Sambuc 
194ebfedea0SLionel Sambuc static int
check_command(struct assignment * as)195ebfedea0SLionel Sambuc check_command(struct assignment *as)
196ebfedea0SLionel Sambuc {
197ebfedea0SLionel Sambuc 	struct assignment *a;
198ebfedea0SLionel Sambuc 	int seen_name = 0;
199ebfedea0SLionel Sambuc 	int seen_function = 0;
200ebfedea0SLionel Sambuc 	int seen_help = 0;
201ebfedea0SLionel Sambuc 	int seen_argument = 0;
202ebfedea0SLionel Sambuc 	int seen_minargs = 0;
203ebfedea0SLionel Sambuc 	int seen_maxargs = 0;
204ebfedea0SLionel Sambuc 	int ret = 0;
205ebfedea0SLionel Sambuc 	for(a = as; a != NULL; a = a->next) {
206ebfedea0SLionel Sambuc 		if(strcmp(a->name, "name") == 0)
207ebfedea0SLionel Sambuc 			seen_name++;
208ebfedea0SLionel Sambuc 		else if(strcmp(a->name, "function") == 0) {
209ebfedea0SLionel Sambuc 			seen_function++;
210ebfedea0SLionel Sambuc 		} else if(strcmp(a->name, "option") == 0)
211ebfedea0SLionel Sambuc 			ret += check_option(a->u.assignment);
212ebfedea0SLionel Sambuc 		else if(strcmp(a->name, "help") == 0) {
213ebfedea0SLionel Sambuc 			seen_help++;
214ebfedea0SLionel Sambuc 		} else if(strcmp(a->name, "argument") == 0) {
215ebfedea0SLionel Sambuc 			seen_argument++;
216ebfedea0SLionel Sambuc 		} else if(strcmp(a->name, "min_args") == 0) {
217ebfedea0SLionel Sambuc 			seen_minargs++;
218ebfedea0SLionel Sambuc 		} else if(strcmp(a->name, "max_args") == 0) {
219ebfedea0SLionel Sambuc 			seen_maxargs++;
220ebfedea0SLionel Sambuc 		} else {
221ebfedea0SLionel Sambuc 			ex(a, "unknown name: %s", a->name);
222ebfedea0SLionel Sambuc 			ret++;
223ebfedea0SLionel Sambuc 		}
224ebfedea0SLionel Sambuc 	}
225ebfedea0SLionel Sambuc 	if(seen_name == 0) {
226ebfedea0SLionel Sambuc 		ex(as, "no command name");
227ebfedea0SLionel Sambuc 		ret++;
228ebfedea0SLionel Sambuc 	}
229ebfedea0SLionel Sambuc 	if(seen_function > 1) {
230ebfedea0SLionel Sambuc 		ex(as, "multiple function names");
231ebfedea0SLionel Sambuc 		ret++;
232ebfedea0SLionel Sambuc 	}
233ebfedea0SLionel Sambuc 	if(seen_help > 1) {
234ebfedea0SLionel Sambuc 		ex(as, "multiple help strings");
235ebfedea0SLionel Sambuc 		ret++;
236ebfedea0SLionel Sambuc 	}
237ebfedea0SLionel Sambuc 	if(seen_argument > 1) {
238ebfedea0SLionel Sambuc 		ex(as, "multiple argument strings");
239ebfedea0SLionel Sambuc 		ret++;
240ebfedea0SLionel Sambuc 	}
241ebfedea0SLionel Sambuc 	if(seen_minargs > 1) {
242ebfedea0SLionel Sambuc 		ex(as, "multiple min_args strings");
243ebfedea0SLionel Sambuc 		ret++;
244ebfedea0SLionel Sambuc 	}
245ebfedea0SLionel Sambuc 	if(seen_maxargs > 1) {
246ebfedea0SLionel Sambuc 		ex(as, "multiple max_args strings");
247ebfedea0SLionel Sambuc 		ret++;
248ebfedea0SLionel Sambuc 	}
249ebfedea0SLionel Sambuc 
250ebfedea0SLionel Sambuc 	return ret;
251ebfedea0SLionel Sambuc }
252ebfedea0SLionel Sambuc 
253ebfedea0SLionel Sambuc static int
check(struct assignment * as)254ebfedea0SLionel Sambuc check(struct assignment *as)
255ebfedea0SLionel Sambuc {
256ebfedea0SLionel Sambuc     struct assignment *a;
257ebfedea0SLionel Sambuc     int ret = 0;
258ebfedea0SLionel Sambuc     for(a = as; a != NULL; a = a->next) {
259ebfedea0SLionel Sambuc 	if(strcmp(a->name, "command")) {
260ebfedea0SLionel Sambuc 	    fprintf(stderr, "unknown type %s line %d\n", a->name, a->lineno);
261ebfedea0SLionel Sambuc 	    ret++;
262ebfedea0SLionel Sambuc 	    continue;
263ebfedea0SLionel Sambuc 	}
264ebfedea0SLionel Sambuc 	if(a->type != a_assignment) {
265ebfedea0SLionel Sambuc 	    fprintf(stderr, "bad command definition %s line %d\n", a->name, a->lineno);
266ebfedea0SLionel Sambuc 	    ret++;
267ebfedea0SLionel Sambuc 	    continue;
268ebfedea0SLionel Sambuc 	}
269ebfedea0SLionel Sambuc 	ret += check_command(a->u.assignment);
270ebfedea0SLionel Sambuc     }
271ebfedea0SLionel Sambuc     return ret;
272ebfedea0SLionel Sambuc }
273ebfedea0SLionel Sambuc 
274ebfedea0SLionel Sambuc static struct assignment *
find_next(struct assignment * as,const char * name)275ebfedea0SLionel Sambuc find_next(struct assignment *as, const char *name)
276ebfedea0SLionel Sambuc {
277ebfedea0SLionel Sambuc     for(as = as->next; as != NULL; as = as->next) {
278ebfedea0SLionel Sambuc 	if(strcmp(as->name, name) == 0)
279ebfedea0SLionel Sambuc 	    return as;
280ebfedea0SLionel Sambuc     }
281ebfedea0SLionel Sambuc     return NULL;
282ebfedea0SLionel Sambuc }
283ebfedea0SLionel Sambuc 
284ebfedea0SLionel Sambuc static struct assignment *
find(struct assignment * as,const char * name)285ebfedea0SLionel Sambuc find(struct assignment *as, const char *name)
286ebfedea0SLionel Sambuc {
287ebfedea0SLionel Sambuc     for(; as != NULL; as = as->next) {
288ebfedea0SLionel Sambuc 	if(strcmp(as->name, name) == 0)
289ebfedea0SLionel Sambuc 	    return as;
290ebfedea0SLionel Sambuc     }
291ebfedea0SLionel Sambuc     return NULL;
292ebfedea0SLionel Sambuc }
293ebfedea0SLionel Sambuc 
294ebfedea0SLionel Sambuc static void
space(FILE * f,int level)295ebfedea0SLionel Sambuc space(FILE *f, int level)
296ebfedea0SLionel Sambuc {
297ebfedea0SLionel Sambuc     fprintf(f, "%*.*s", level * 4, level * 4, " ");
298ebfedea0SLionel Sambuc }
299ebfedea0SLionel Sambuc 
300ebfedea0SLionel Sambuc static void
cprint(int level,const char * fmt,...)301ebfedea0SLionel Sambuc cprint(int level, const char *fmt, ...)
302ebfedea0SLionel Sambuc {
303ebfedea0SLionel Sambuc     va_list ap;
304ebfedea0SLionel Sambuc     va_start(ap, fmt);
305ebfedea0SLionel Sambuc     space(cfile, level);
306ebfedea0SLionel Sambuc     vfprintf(cfile, fmt, ap);
307ebfedea0SLionel Sambuc     va_end(ap);
308ebfedea0SLionel Sambuc }
309ebfedea0SLionel Sambuc 
310ebfedea0SLionel Sambuc static void
hprint(int level,const char * fmt,...)311ebfedea0SLionel Sambuc hprint(int level, const char *fmt, ...)
312ebfedea0SLionel Sambuc {
313ebfedea0SLionel Sambuc     va_list ap;
314ebfedea0SLionel Sambuc     va_start(ap, fmt);
315ebfedea0SLionel Sambuc     space(hfile, level);
316ebfedea0SLionel Sambuc     vfprintf(hfile, fmt, ap);
317ebfedea0SLionel Sambuc     va_end(ap);
318ebfedea0SLionel Sambuc }
319ebfedea0SLionel Sambuc 
320ebfedea0SLionel Sambuc static void gen_name(char *str);
321ebfedea0SLionel Sambuc 
322ebfedea0SLionel Sambuc static void
gen_command(struct assignment * as)323ebfedea0SLionel Sambuc gen_command(struct assignment *as)
324ebfedea0SLionel Sambuc {
325ebfedea0SLionel Sambuc     struct assignment *a, *b;
326ebfedea0SLionel Sambuc     char *f;
327ebfedea0SLionel Sambuc     a = find(as, "name");
328ebfedea0SLionel Sambuc     f = strdup(a->u.value);
329ebfedea0SLionel Sambuc     gen_name(f);
330ebfedea0SLionel Sambuc     cprint(1, "    { ");
331ebfedea0SLionel Sambuc     fprintf(cfile, "\"%s\", ", a->u.value);
332ebfedea0SLionel Sambuc     fprintf(cfile, "%s_wrap, ", f);
333ebfedea0SLionel Sambuc     b = find(as, "argument");
334ebfedea0SLionel Sambuc     if(b)
335ebfedea0SLionel Sambuc 	fprintf(cfile, "\"%s %s\", ", a->u.value, b->u.value);
336ebfedea0SLionel Sambuc     else
337ebfedea0SLionel Sambuc 	fprintf(cfile, "\"%s\", ", a->u.value);
338ebfedea0SLionel Sambuc     b = find(as, "help");
339ebfedea0SLionel Sambuc     if(b)
340ebfedea0SLionel Sambuc 	fprintf(cfile, "\"%s\"", b->u.value);
341ebfedea0SLionel Sambuc     else
342ebfedea0SLionel Sambuc 	fprintf(cfile, "NULL");
343ebfedea0SLionel Sambuc     fprintf(cfile, " },\n");
344ebfedea0SLionel Sambuc     for(a = a->next; a != NULL; a = a->next)
345ebfedea0SLionel Sambuc 	if(strcmp(a->name, "name") == 0)
346ebfedea0SLionel Sambuc 	    cprint(1, "    { \"%s\" },\n", a->u.value);
347ebfedea0SLionel Sambuc     cprint(0, "\n");
348ebfedea0SLionel Sambuc }
349ebfedea0SLionel Sambuc 
350ebfedea0SLionel Sambuc static void
gen_name(char * str)351ebfedea0SLionel Sambuc gen_name(char *str)
352ebfedea0SLionel Sambuc {
353ebfedea0SLionel Sambuc     char *p;
354ebfedea0SLionel Sambuc     for(p = str; *p != '\0'; p++)
355ebfedea0SLionel Sambuc 	if(!isalnum((unsigned char)*p))
356ebfedea0SLionel Sambuc 	    *p = '_';
357ebfedea0SLionel Sambuc }
358ebfedea0SLionel Sambuc 
359ebfedea0SLionel Sambuc static char *
make_name(struct assignment * as)360ebfedea0SLionel Sambuc make_name(struct assignment *as)
361ebfedea0SLionel Sambuc {
362ebfedea0SLionel Sambuc     struct assignment *lopt;
363ebfedea0SLionel Sambuc     struct assignment *type;
364ebfedea0SLionel Sambuc     char *s;
365ebfedea0SLionel Sambuc 
366ebfedea0SLionel Sambuc     lopt = find(as, "long");
367ebfedea0SLionel Sambuc     if(lopt == NULL)
368ebfedea0SLionel Sambuc 	lopt = find(as, "name");
369ebfedea0SLionel Sambuc     if(lopt == NULL)
370ebfedea0SLionel Sambuc 	return NULL;
371ebfedea0SLionel Sambuc 
372ebfedea0SLionel Sambuc     type = find(as, "type");
373ebfedea0SLionel Sambuc     if(strcmp(type->u.value, "-flag") == 0)
374ebfedea0SLionel Sambuc 	asprintf(&s, "%s_flag", lopt->u.value);
375ebfedea0SLionel Sambuc     else
376ebfedea0SLionel Sambuc 	asprintf(&s, "%s_%s", lopt->u.value, type->u.value);
377ebfedea0SLionel Sambuc     gen_name(s);
378ebfedea0SLionel Sambuc     return s;
379ebfedea0SLionel Sambuc }
380ebfedea0SLionel Sambuc 
381ebfedea0SLionel Sambuc 
defval_int(const char * name,struct assignment * defval)382ebfedea0SLionel Sambuc static void defval_int(const char *name, struct assignment *defval)
383ebfedea0SLionel Sambuc {
384ebfedea0SLionel Sambuc     if(defval != NULL)
385ebfedea0SLionel Sambuc 	cprint(1, "opt.%s = %s;\n", name, defval->u.value);
386ebfedea0SLionel Sambuc     else
387ebfedea0SLionel Sambuc 	cprint(1, "opt.%s = 0;\n", name);
388ebfedea0SLionel Sambuc }
defval_neg_flag(const char * name,struct assignment * defval)389ebfedea0SLionel Sambuc static void defval_neg_flag(const char *name, struct assignment *defval)
390ebfedea0SLionel Sambuc {
391ebfedea0SLionel Sambuc     if(defval != NULL)
392ebfedea0SLionel Sambuc 	cprint(1, "opt.%s = %s;\n", name, defval->u.value);
393ebfedea0SLionel Sambuc     else
394ebfedea0SLionel Sambuc 	cprint(1, "opt.%s = 1;\n", name);
395ebfedea0SLionel Sambuc }
defval_string(const char * name,struct assignment * defval)396ebfedea0SLionel Sambuc static void defval_string(const char *name, struct assignment *defval)
397ebfedea0SLionel Sambuc {
398ebfedea0SLionel Sambuc     if(defval != NULL)
399*0a6a1f1dSLionel Sambuc 	cprint(1, "opt.%s = (char *)(unsigned long)\"%s\";\n", name, defval->u.value);
400ebfedea0SLionel Sambuc     else
401ebfedea0SLionel Sambuc 	cprint(1, "opt.%s = NULL;\n", name);
402ebfedea0SLionel Sambuc }
defval_strings(const char * name,struct assignment * defval)403ebfedea0SLionel Sambuc static void defval_strings(const char *name, struct assignment *defval)
404ebfedea0SLionel Sambuc {
405ebfedea0SLionel Sambuc     cprint(1, "opt.%s.num_strings = 0;\n", name);
406ebfedea0SLionel Sambuc     cprint(1, "opt.%s.strings = NULL;\n", name);
407ebfedea0SLionel Sambuc }
408ebfedea0SLionel Sambuc 
free_strings(const char * name)409ebfedea0SLionel Sambuc static void free_strings(const char *name)
410ebfedea0SLionel Sambuc {
411ebfedea0SLionel Sambuc     cprint(1, "free_getarg_strings (&opt.%s);\n", name);
412ebfedea0SLionel Sambuc }
413ebfedea0SLionel Sambuc 
414ebfedea0SLionel Sambuc struct type_handler {
415ebfedea0SLionel Sambuc     const char *typename;
416ebfedea0SLionel Sambuc     const char *c_type;
417ebfedea0SLionel Sambuc     const char *getarg_type;
418ebfedea0SLionel Sambuc     void (*defval)(const char*, struct assignment*);
419ebfedea0SLionel Sambuc     void (*free)(const char*);
420ebfedea0SLionel Sambuc } type_handlers[] = {
421ebfedea0SLionel Sambuc 	{ "integer",
422ebfedea0SLionel Sambuc 	  "int",
423ebfedea0SLionel Sambuc 	  "arg_integer",
424ebfedea0SLionel Sambuc 	  defval_int,
425ebfedea0SLionel Sambuc 	  NULL
426ebfedea0SLionel Sambuc 	},
427ebfedea0SLionel Sambuc 	{ "string",
428ebfedea0SLionel Sambuc 	  "char*",
429ebfedea0SLionel Sambuc 	  "arg_string",
430ebfedea0SLionel Sambuc 	  defval_string,
431ebfedea0SLionel Sambuc 	  NULL
432ebfedea0SLionel Sambuc 	},
433ebfedea0SLionel Sambuc 	{ "strings",
434ebfedea0SLionel Sambuc 	  "struct getarg_strings",
435ebfedea0SLionel Sambuc 	  "arg_strings",
436ebfedea0SLionel Sambuc 	  defval_strings,
437ebfedea0SLionel Sambuc 	  free_strings
438ebfedea0SLionel Sambuc 	},
439ebfedea0SLionel Sambuc 	{ "flag",
440ebfedea0SLionel Sambuc 	  "int",
441ebfedea0SLionel Sambuc 	  "arg_flag",
442ebfedea0SLionel Sambuc 	  defval_int,
443ebfedea0SLionel Sambuc 	  NULL
444ebfedea0SLionel Sambuc 	},
445ebfedea0SLionel Sambuc 	{ "-flag",
446ebfedea0SLionel Sambuc 	  "int",
447ebfedea0SLionel Sambuc 	  "arg_negative_flag",
448ebfedea0SLionel Sambuc 	  defval_neg_flag,
449ebfedea0SLionel Sambuc 	  NULL
450ebfedea0SLionel Sambuc 	},
451ebfedea0SLionel Sambuc 	{ NULL }
452ebfedea0SLionel Sambuc };
453ebfedea0SLionel Sambuc 
find_handler(struct assignment * type)454ebfedea0SLionel Sambuc static struct type_handler *find_handler(struct assignment *type)
455ebfedea0SLionel Sambuc {
456ebfedea0SLionel Sambuc     struct type_handler *th;
457ebfedea0SLionel Sambuc     for(th = type_handlers; th->typename != NULL; th++)
458ebfedea0SLionel Sambuc 	if(strcmp(type->u.value, th->typename) == 0)
459ebfedea0SLionel Sambuc 	    return th;
460ebfedea0SLionel Sambuc     ex(type, "unknown type \"%s\"", type->u.value);
461ebfedea0SLionel Sambuc     exit(1);
462ebfedea0SLionel Sambuc }
463ebfedea0SLionel Sambuc 
464ebfedea0SLionel Sambuc static void
gen_options(struct assignment * opt1,const char * name)465ebfedea0SLionel Sambuc gen_options(struct assignment *opt1, const char *name)
466ebfedea0SLionel Sambuc {
467ebfedea0SLionel Sambuc     struct assignment *tmp;
468ebfedea0SLionel Sambuc 
469ebfedea0SLionel Sambuc     hprint(0, "struct %s_options {\n", name);
470ebfedea0SLionel Sambuc 
471ebfedea0SLionel Sambuc     for(tmp = opt1;
472ebfedea0SLionel Sambuc 	tmp != NULL;
473ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
474ebfedea0SLionel Sambuc 	struct assignment *type;
475ebfedea0SLionel Sambuc 	struct type_handler *th;
476ebfedea0SLionel Sambuc 	char *s;
477ebfedea0SLionel Sambuc 
478ebfedea0SLionel Sambuc 	s = make_name(tmp->u.assignment);
479ebfedea0SLionel Sambuc 	type = find(tmp->u.assignment, "type");
480ebfedea0SLionel Sambuc 	th = find_handler(type);
481ebfedea0SLionel Sambuc 	hprint(1, "%s %s;\n", th->c_type, s);
482ebfedea0SLionel Sambuc 	free(s);
483ebfedea0SLionel Sambuc     }
484ebfedea0SLionel Sambuc     hprint(0, "};\n");
485ebfedea0SLionel Sambuc }
486ebfedea0SLionel Sambuc 
487ebfedea0SLionel Sambuc static void
gen_wrapper(struct assignment * as)488ebfedea0SLionel Sambuc gen_wrapper(struct assignment *as)
489ebfedea0SLionel Sambuc {
490ebfedea0SLionel Sambuc     struct assignment *name;
491ebfedea0SLionel Sambuc     struct assignment *arg;
492ebfedea0SLionel Sambuc     struct assignment *opt1;
493ebfedea0SLionel Sambuc     struct assignment *function;
494ebfedea0SLionel Sambuc     struct assignment *tmp;
495ebfedea0SLionel Sambuc     char *n, *f;
496ebfedea0SLionel Sambuc     int nargs = 0;
497*0a6a1f1dSLionel Sambuc     int narguments = 0;
498ebfedea0SLionel Sambuc 
499ebfedea0SLionel Sambuc     name = find(as, "name");
500ebfedea0SLionel Sambuc     n = strdup(name->u.value);
501ebfedea0SLionel Sambuc     gen_name(n);
502ebfedea0SLionel Sambuc     arg = find(as, "argument");
503*0a6a1f1dSLionel Sambuc     if (arg)
504*0a6a1f1dSLionel Sambuc         narguments++;
505ebfedea0SLionel Sambuc     opt1 = find(as, "option");
506ebfedea0SLionel Sambuc     function = find(as, "function");
507ebfedea0SLionel Sambuc     if(function)
508ebfedea0SLionel Sambuc 	f = function->u.value;
509ebfedea0SLionel Sambuc     else
510ebfedea0SLionel Sambuc 	f = n;
511ebfedea0SLionel Sambuc 
512ebfedea0SLionel Sambuc 
513ebfedea0SLionel Sambuc     if(opt1 != NULL) {
514ebfedea0SLionel Sambuc 	gen_options(opt1, n);
515ebfedea0SLionel Sambuc 	hprint(0, "int %s(struct %s_options*, int, char **);\n", f, n);
516ebfedea0SLionel Sambuc     } else {
517ebfedea0SLionel Sambuc 	hprint(0, "int %s(void*, int, char **);\n", f);
518ebfedea0SLionel Sambuc     }
519ebfedea0SLionel Sambuc 
520ebfedea0SLionel Sambuc     fprintf(cfile, "static int\n");
521ebfedea0SLionel Sambuc     fprintf(cfile, "%s_wrap(int argc, char **argv)\n", n);
522ebfedea0SLionel Sambuc     fprintf(cfile, "{\n");
523ebfedea0SLionel Sambuc     if(opt1 != NULL)
524ebfedea0SLionel Sambuc 	cprint(1, "struct %s_options opt;\n", n);
525ebfedea0SLionel Sambuc     cprint(1, "int ret;\n");
526ebfedea0SLionel Sambuc     cprint(1, "int optidx = 0;\n");
527ebfedea0SLionel Sambuc     cprint(1, "struct getargs args[] = {\n");
528ebfedea0SLionel Sambuc     for(tmp = find(as, "option");
529ebfedea0SLionel Sambuc 	tmp != NULL;
530ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
531ebfedea0SLionel Sambuc 	struct assignment *type = find(tmp->u.assignment, "type");
532ebfedea0SLionel Sambuc 	struct assignment *lopt = find(tmp->u.assignment, "long");
533ebfedea0SLionel Sambuc 	struct assignment *sopt = find(tmp->u.assignment, "short");
534ebfedea0SLionel Sambuc 	struct assignment *aarg = find(tmp->u.assignment, "argument");
535ebfedea0SLionel Sambuc 	struct assignment *help = find(tmp->u.assignment, "help");
536ebfedea0SLionel Sambuc 
537ebfedea0SLionel Sambuc 	struct type_handler *th;
538ebfedea0SLionel Sambuc 
539ebfedea0SLionel Sambuc 	cprint(2, "{ ");
540ebfedea0SLionel Sambuc 	if(lopt)
541ebfedea0SLionel Sambuc 	    fprintf(cfile, "\"%s\", ", lopt->u.value);
542ebfedea0SLionel Sambuc 	else
543ebfedea0SLionel Sambuc 	    fprintf(cfile, "NULL, ");
544ebfedea0SLionel Sambuc 	if(sopt)
545ebfedea0SLionel Sambuc 	    fprintf(cfile, "'%c', ", *sopt->u.value);
546ebfedea0SLionel Sambuc 	else
547ebfedea0SLionel Sambuc 	    fprintf(cfile, "0, ");
548ebfedea0SLionel Sambuc 	th = find_handler(type);
549ebfedea0SLionel Sambuc 	fprintf(cfile, "%s, ", th->getarg_type);
550ebfedea0SLionel Sambuc 	fprintf(cfile, "NULL, ");
551ebfedea0SLionel Sambuc 	if(help)
552ebfedea0SLionel Sambuc 	    fprintf(cfile, "\"%s\", ", help->u.value);
553ebfedea0SLionel Sambuc 	else
554ebfedea0SLionel Sambuc 	    fprintf(cfile, "NULL, ");
555*0a6a1f1dSLionel Sambuc 	if(aarg) {
556ebfedea0SLionel Sambuc 	    fprintf(cfile, "\"%s\"", aarg->u.value);
557*0a6a1f1dSLionel Sambuc             narguments++;
558*0a6a1f1dSLionel Sambuc 	} else
559ebfedea0SLionel Sambuc 	    fprintf(cfile, "NULL");
560ebfedea0SLionel Sambuc 	fprintf(cfile, " },\n");
561ebfedea0SLionel Sambuc     }
562ebfedea0SLionel Sambuc     cprint(2, "{ \"help\", 'h', arg_flag, NULL, NULL, NULL }\n");
563ebfedea0SLionel Sambuc     cprint(1, "};\n");
564ebfedea0SLionel Sambuc     cprint(1, "int help_flag = 0;\n");
565ebfedea0SLionel Sambuc 
566ebfedea0SLionel Sambuc     for(tmp = find(as, "option");
567ebfedea0SLionel Sambuc 	tmp != NULL;
568ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
569ebfedea0SLionel Sambuc 	char *s;
570ebfedea0SLionel Sambuc 	struct assignment *type = find(tmp->u.assignment, "type");
571ebfedea0SLionel Sambuc 
572ebfedea0SLionel Sambuc 	struct assignment *defval = find(tmp->u.assignment, "default");
573ebfedea0SLionel Sambuc 
574ebfedea0SLionel Sambuc 	struct type_handler *th;
575ebfedea0SLionel Sambuc 
576ebfedea0SLionel Sambuc 	s = make_name(tmp->u.assignment);
577ebfedea0SLionel Sambuc 	th = find_handler(type);
578ebfedea0SLionel Sambuc 	(*th->defval)(s, defval);
579ebfedea0SLionel Sambuc 	free(s);
580ebfedea0SLionel Sambuc     }
581ebfedea0SLionel Sambuc 
582ebfedea0SLionel Sambuc     for(tmp = find(as, "option");
583ebfedea0SLionel Sambuc 	tmp != NULL;
584ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
585ebfedea0SLionel Sambuc 	char *s;
586ebfedea0SLionel Sambuc 	s = make_name(tmp->u.assignment);
587ebfedea0SLionel Sambuc 	cprint(1, "args[%d].value = &opt.%s;\n", nargs++, s);
588ebfedea0SLionel Sambuc 	free(s);
589ebfedea0SLionel Sambuc     }
590ebfedea0SLionel Sambuc     cprint(1, "args[%d].value = &help_flag;\n", nargs++);
591ebfedea0SLionel Sambuc     cprint(1, "if(getarg(args, %d, argc, argv, &optidx))\n", nargs);
592ebfedea0SLionel Sambuc     cprint(2, "goto usage;\n");
593ebfedea0SLionel Sambuc 
594ebfedea0SLionel Sambuc     {
595ebfedea0SLionel Sambuc 	int min_args = -1;
596ebfedea0SLionel Sambuc 	int max_args = -1;
597ebfedea0SLionel Sambuc 	char *end;
598*0a6a1f1dSLionel Sambuc 	if(narguments == 0) {
599ebfedea0SLionel Sambuc 	    max_args = 0;
600ebfedea0SLionel Sambuc 	} else {
601ebfedea0SLionel Sambuc 	    if((tmp = find(as, "min_args")) != NULL) {
602ebfedea0SLionel Sambuc 		min_args = strtol(tmp->u.value, &end, 0);
603ebfedea0SLionel Sambuc 		if(*end != '\0') {
604ebfedea0SLionel Sambuc 		    ex(tmp, "min_args is not numeric");
605ebfedea0SLionel Sambuc 		    exit(1);
606ebfedea0SLionel Sambuc 		}
607ebfedea0SLionel Sambuc 		if(min_args < 0) {
608ebfedea0SLionel Sambuc 		    ex(tmp, "min_args must be non-negative");
609ebfedea0SLionel Sambuc 		    exit(1);
610ebfedea0SLionel Sambuc 		}
611ebfedea0SLionel Sambuc 	    }
612ebfedea0SLionel Sambuc 	    if((tmp = find(as, "max_args")) != NULL) {
613ebfedea0SLionel Sambuc 		max_args = strtol(tmp->u.value, &end, 0);
614ebfedea0SLionel Sambuc 		if(*end != '\0') {
615ebfedea0SLionel Sambuc 		    ex(tmp, "max_args is not numeric");
616ebfedea0SLionel Sambuc 		    exit(1);
617ebfedea0SLionel Sambuc 		}
618ebfedea0SLionel Sambuc 		if(max_args < 0) {
619ebfedea0SLionel Sambuc 		    ex(tmp, "max_args must be non-negative");
620ebfedea0SLionel Sambuc 		    exit(1);
621ebfedea0SLionel Sambuc 		}
622ebfedea0SLionel Sambuc 	    }
623ebfedea0SLionel Sambuc 	}
624ebfedea0SLionel Sambuc 	if(min_args != -1 || max_args != -1) {
625ebfedea0SLionel Sambuc 	    if(min_args == max_args) {
626ebfedea0SLionel Sambuc 		cprint(1, "if(argc - optidx != %d) {\n",
627ebfedea0SLionel Sambuc 		       min_args);
628ebfedea0SLionel Sambuc 		cprint(2, "fprintf(stderr, \"Need exactly %u parameters (%%u given).\\n\\n\", argc - optidx);\n", min_args);
629ebfedea0SLionel Sambuc 		cprint(2, "goto usage;\n");
630ebfedea0SLionel Sambuc 		cprint(1, "}\n");
631ebfedea0SLionel Sambuc 	    } else {
632ebfedea0SLionel Sambuc 		if(max_args != -1) {
633ebfedea0SLionel Sambuc 		    cprint(1, "if(argc - optidx > %d) {\n", max_args);
634ebfedea0SLionel Sambuc 		    cprint(2, "fprintf(stderr, \"Arguments given (%%u) are more than expected (%u).\\n\\n\", argc - optidx);\n", max_args);
635ebfedea0SLionel Sambuc 		    cprint(2, "goto usage;\n");
636ebfedea0SLionel Sambuc 		    cprint(1, "}\n");
637ebfedea0SLionel Sambuc 		}
638ebfedea0SLionel Sambuc 		if(min_args != -1) {
639ebfedea0SLionel Sambuc 		    cprint(1, "if(argc - optidx < %d) {\n", min_args);
640ebfedea0SLionel Sambuc 		    cprint(2, "fprintf(stderr, \"Arguments given (%%u) are less than expected (%u).\\n\\n\", argc - optidx);\n", min_args);
641ebfedea0SLionel Sambuc 		    cprint(2, "goto usage;\n");
642ebfedea0SLionel Sambuc 		    cprint(1, "}\n");
643ebfedea0SLionel Sambuc 		}
644ebfedea0SLionel Sambuc 	    }
645ebfedea0SLionel Sambuc 	}
646ebfedea0SLionel Sambuc     }
647ebfedea0SLionel Sambuc 
648ebfedea0SLionel Sambuc     cprint(1, "if(help_flag)\n");
649ebfedea0SLionel Sambuc     cprint(2, "goto usage;\n");
650ebfedea0SLionel Sambuc 
651ebfedea0SLionel Sambuc     cprint(1, "ret = %s(%s, argc - optidx, argv + optidx);\n",
652ebfedea0SLionel Sambuc 	   f, opt1 ? "&opt": "NULL");
653ebfedea0SLionel Sambuc 
654ebfedea0SLionel Sambuc     /* free allocated data */
655ebfedea0SLionel Sambuc     for(tmp = find(as, "option");
656ebfedea0SLionel Sambuc 	tmp != NULL;
657ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
658ebfedea0SLionel Sambuc 	char *s;
659ebfedea0SLionel Sambuc 	struct assignment *type = find(tmp->u.assignment, "type");
660ebfedea0SLionel Sambuc 	struct type_handler *th;
661ebfedea0SLionel Sambuc 	th = find_handler(type);
662ebfedea0SLionel Sambuc 	if(th->free == NULL)
663ebfedea0SLionel Sambuc 	    continue;
664ebfedea0SLionel Sambuc 	s = make_name(tmp->u.assignment);
665ebfedea0SLionel Sambuc 	(*th->free)(s);
666ebfedea0SLionel Sambuc 	free(s);
667ebfedea0SLionel Sambuc     }
668ebfedea0SLionel Sambuc     cprint(1, "return ret;\n");
669ebfedea0SLionel Sambuc 
670ebfedea0SLionel Sambuc     cprint(0, "usage:\n");
671ebfedea0SLionel Sambuc     cprint(1, "arg_printusage (args, %d, \"%s\", \"%s\");\n", nargs,
672ebfedea0SLionel Sambuc 	   name->u.value, arg ? arg->u.value : "");
673ebfedea0SLionel Sambuc     /* free allocated data */
674ebfedea0SLionel Sambuc     for(tmp = find(as, "option");
675ebfedea0SLionel Sambuc 	tmp != NULL;
676ebfedea0SLionel Sambuc 	tmp = find_next(tmp, "option")) {
677ebfedea0SLionel Sambuc 	char *s;
678ebfedea0SLionel Sambuc 	struct assignment *type = find(tmp->u.assignment, "type");
679ebfedea0SLionel Sambuc 	struct type_handler *th;
680ebfedea0SLionel Sambuc 	th = find_handler(type);
681ebfedea0SLionel Sambuc 	if(th->free == NULL)
682ebfedea0SLionel Sambuc 	    continue;
683ebfedea0SLionel Sambuc 	s = make_name(tmp->u.assignment);
684ebfedea0SLionel Sambuc 	(*th->free)(s);
685ebfedea0SLionel Sambuc 	free(s);
686ebfedea0SLionel Sambuc     }
687ebfedea0SLionel Sambuc     cprint(1, "return 0;\n");
688ebfedea0SLionel Sambuc     cprint(0, "}\n");
689ebfedea0SLionel Sambuc     cprint(0, "\n");
690ebfedea0SLionel Sambuc }
691ebfedea0SLionel Sambuc 
692ebfedea0SLionel Sambuc char cname[PATH_MAX];
693ebfedea0SLionel Sambuc char hname[PATH_MAX];
694ebfedea0SLionel Sambuc 
695ebfedea0SLionel Sambuc static void
gen(struct assignment * as)696ebfedea0SLionel Sambuc gen(struct assignment *as)
697ebfedea0SLionel Sambuc {
698ebfedea0SLionel Sambuc     struct assignment *a;
699ebfedea0SLionel Sambuc     cprint(0, "#include <stdio.h>\n");
700ebfedea0SLionel Sambuc     cprint(0, "#include <krb5/getarg.h>\n");
701ebfedea0SLionel Sambuc     cprint(0, "#include <krb5/sl.h>\n");
702ebfedea0SLionel Sambuc     cprint(0, "#include \"%s\"\n\n", hname);
703ebfedea0SLionel Sambuc 
704ebfedea0SLionel Sambuc     hprint(0, "#include <stdio.h>\n");
705ebfedea0SLionel Sambuc     hprint(0, "#include <krb5/sl.h>\n");
706ebfedea0SLionel Sambuc     hprint(0, "\n");
707ebfedea0SLionel Sambuc 
708ebfedea0SLionel Sambuc 
709ebfedea0SLionel Sambuc     for(a = as; a != NULL; a = a->next)
710ebfedea0SLionel Sambuc 	gen_wrapper(a->u.assignment);
711ebfedea0SLionel Sambuc 
712ebfedea0SLionel Sambuc     cprint(0, "SL_cmd commands[] = {\n");
713ebfedea0SLionel Sambuc     for(a = as; a != NULL; a = a->next)
714ebfedea0SLionel Sambuc 	gen_command(a->u.assignment);
715ebfedea0SLionel Sambuc     cprint(1, "{ NULL }\n");
716ebfedea0SLionel Sambuc     cprint(0, "};\n");
717ebfedea0SLionel Sambuc 
718ebfedea0SLionel Sambuc     hprint(0, "extern SL_cmd commands[];\n");
719ebfedea0SLionel Sambuc }
720ebfedea0SLionel Sambuc 
721ebfedea0SLionel Sambuc int version_flag;
722ebfedea0SLionel Sambuc int help_flag;
723ebfedea0SLionel Sambuc struct getargs args[] = {
724ebfedea0SLionel Sambuc     { "version", 0, arg_flag, &version_flag },
725ebfedea0SLionel Sambuc     { "help", 0, arg_flag, &help_flag }
726ebfedea0SLionel Sambuc };
727ebfedea0SLionel Sambuc int num_args = sizeof(args) / sizeof(args[0]);
728ebfedea0SLionel Sambuc 
729ebfedea0SLionel Sambuc static void
usage(int code)730ebfedea0SLionel Sambuc usage(int code)
731ebfedea0SLionel Sambuc {
732ebfedea0SLionel Sambuc     arg_printusage(args, num_args, NULL, "command-table");
733ebfedea0SLionel Sambuc     exit(code);
734ebfedea0SLionel Sambuc }
735ebfedea0SLionel Sambuc 
736ebfedea0SLionel Sambuc int
main(int argc,char ** argv)737ebfedea0SLionel Sambuc main(int argc, char **argv)
738ebfedea0SLionel Sambuc {
739ebfedea0SLionel Sambuc     char *p;
740ebfedea0SLionel Sambuc 
741ebfedea0SLionel Sambuc     int optidx = 0;
742ebfedea0SLionel Sambuc 
743ebfedea0SLionel Sambuc     setprogname(argv[0]);
744ebfedea0SLionel Sambuc     if(getarg(args, num_args, argc, argv, &optidx))
745ebfedea0SLionel Sambuc 	usage(1);
746ebfedea0SLionel Sambuc     if(help_flag)
747ebfedea0SLionel Sambuc 	usage(0);
748ebfedea0SLionel Sambuc     if(version_flag) {
749ebfedea0SLionel Sambuc 	print_version(NULL);
750ebfedea0SLionel Sambuc 	exit(0);
751ebfedea0SLionel Sambuc     }
752ebfedea0SLionel Sambuc 
753ebfedea0SLionel Sambuc     if(argc == optidx)
754ebfedea0SLionel Sambuc 	usage(1);
755ebfedea0SLionel Sambuc 
756ebfedea0SLionel Sambuc     filename = argv[optidx];
757ebfedea0SLionel Sambuc     yyin = fopen(filename, "r");
758ebfedea0SLionel Sambuc     if(yyin == NULL)
759ebfedea0SLionel Sambuc 	err(1, "%s", filename);
760ebfedea0SLionel Sambuc     p = strrchr(filename, '/');
761ebfedea0SLionel Sambuc     if(p)
762ebfedea0SLionel Sambuc 	strlcpy(cname, p + 1, sizeof(cname));
763ebfedea0SLionel Sambuc     else
764ebfedea0SLionel Sambuc 	strlcpy(cname, filename, sizeof(cname));
765ebfedea0SLionel Sambuc     p = strrchr(cname, '.');
766ebfedea0SLionel Sambuc     if(p)
767ebfedea0SLionel Sambuc 	*p = '\0';
768ebfedea0SLionel Sambuc     strlcpy(hname, cname, sizeof(hname));
769ebfedea0SLionel Sambuc     strlcat(cname, ".c", sizeof(cname));
770ebfedea0SLionel Sambuc     strlcat(hname, ".h", sizeof(hname));
771ebfedea0SLionel Sambuc     yyparse();
772ebfedea0SLionel Sambuc     if(error_flag)
773ebfedea0SLionel Sambuc 	exit(1);
774ebfedea0SLionel Sambuc     if(check(assignment) == 0) {
775ebfedea0SLionel Sambuc 	cfile = fopen(cname, "w");
776ebfedea0SLionel Sambuc 	if(cfile == NULL)
777ebfedea0SLionel Sambuc 	  err(1, "%s", cname);
778ebfedea0SLionel Sambuc 	hfile = fopen(hname, "w");
779ebfedea0SLionel Sambuc 	if(hfile == NULL)
780ebfedea0SLionel Sambuc 	  err(1, "%s", hname);
781ebfedea0SLionel Sambuc 	gen(assignment);
782ebfedea0SLionel Sambuc 	fclose(cfile);
783ebfedea0SLionel Sambuc 	fclose(hfile);
784ebfedea0SLionel Sambuc     }
785ebfedea0SLionel Sambuc     fclose(yyin);
786ebfedea0SLionel Sambuc     return 0;
787ebfedea0SLionel Sambuc }
788