xref: /illumos-gate/usr/src/cmd/fm/eversholt/esc/common/escmain.c (revision 10a4fa49f51ed9ae1c857a626de6ce9ebf41661a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * escmain.c -- main routine for esc, the eversholt compiler
27  *
28  * argument processing and the general flow through all the other
29  * modules is driven by this file.
30  */
31 
32 #pragma ident	"%Z%%M%	%I%	%E% SMI"
33 
34 #include <stdio.h>
35 #include <string.h>
36 #ifdef sun
37 #include <stdlib.h>
38 #else
39 #include <getopt.h>
40 #endif /* sun */
41 #include "out.h"
42 #include "stats.h"
43 #include "alloc.h"
44 #include "stable.h"
45 #include "literals.h"
46 #include "lut.h"
47 #include "esclex.h"
48 #include "eftwrite.h"
49 #include "ptree.h"
50 #include "tree.h"
51 #include "check.h"
52 #include "version.h"
53 
54 /* stuff exported by yacc-generated parsers */
55 extern void yyparse(void);
56 extern int yydebug;
57 
58 /*
59  * This external definition has to be here.  If we put it in literals.h
60  * lint complains about the declaration not being used within the block
61  * when compiling literals.c.
62  */
63 extern void literals_init(void);
64 
65 static const char *Usage =
66 "[-SYdghpqvy] [-Dname[=def]] [-I dir] [-Uname] [-o outfile] esc-files...";
67 static const char *Help =
68 "\tinput files are run through cpp and concatenated.\n"
69 "\t-D name[=def] Pass to cpp\n"
70 "\t-I dir        Pass to cpp\n"
71 "\t-S            Print stats for compiler memory usage, etc.\n"
72 "\t-U name       Pass to cpp\n"
73 "\t-Y            Enable parser debug output\n"
74 "\t-d            Enable general debug output\n"
75 "\t-g            Print generated iterators (use with -p)\n"
76 "\t-h            Print this help message\n"
77 "\t-o outfile    Emit compiled EFT to \"outfile\"\n"
78 "\t-p            Print complete parse tree\n"
79 "\t-q            Quiet mode: suppress warnings\n"
80 "\t-v            Enable verbose output\n"
81 "\t-y            Enable lexer debug output";
82 
83 int Debug;
84 int Verbose;
85 int Warn = 1;	/* the esc compiler should issue language warnings */
86 
87 extern int Pchildgen;	/* flag to ptree for printing generated iterators */
88 
89 #define	MAXARGS 8192
90 char Args[MAXARGS];
91 
92 #define	MAXCPPARGS 4000
93 static char Cppargs[MAXCPPARGS];
94 
95 int
96 main(int argc, char *argv[])
97 {
98 	char flagbuf[] = " -D";
99 	char **av;
100 	int c;
101 	int stats = 0;
102 	int lexecho = 0;
103 	const char *outfile = NULL;
104 	int count;
105 	int i;
106 	int pflag = 0;
107 
108 	alloc_init();
109 	out_init(argv[0]);
110 	stats_init(1);		/* extended stats always enabled for esc */
111 	stable_init(0);
112 	literals_init();
113 	lut_init();
114 	tree_init();
115 	eftwrite_init();
116 
117 	/* built a best effort summary of args for eftwrite() */
118 	count = 0;
119 	for (i = 1; i < argc; i++) {
120 		char *ptr = argv[i];
121 
122 		if (count < MAXARGS - 1)
123 			Args[count++] = ' ';
124 
125 		while (count < MAXARGS - 1 && *ptr)
126 			Args[count++] = *ptr++;
127 
128 	}
129 	Args[count] = '\0';
130 
131 
132 
133 	while ((c = getopt(argc, argv, "D:I:SU:Ydgho:pqvy")) != EOF) {
134 		switch (c) {
135 		case 'D':
136 		case 'I':
137 		case 'U':
138 			if (strlen(optarg) + strlen(Cppargs) + 4 >= MAXCPPARGS)
139 				out(O_DIE, "cpp args too long (max %d bytes)",
140 				    MAXCPPARGS);
141 			flagbuf[2] = c;
142 			(void) strcat(Cppargs, flagbuf);
143 			(void) strcat(Cppargs, optarg);
144 			break;
145 
146 		case 'S':
147 			stats++;
148 			break;
149 
150 		case 'Y':
151 			yydebug++;
152 			break;
153 
154 		case 'd':
155 			Debug++;
156 			break;
157 
158 		case 'g':
159 			Pchildgen++;
160 			break;
161 
162 		case 'h':
163 		case '?':
164 			out(O_PROG, "eversholt compiler version %d.%d",
165 			    VERSION_MAJOR, VERSION_MINOR);
166 			out(O_DIE|O_USAGE, "%s\n%s", Usage, Help);
167 			/*NOTREACHED*/
168 
169 		case 'o':
170 			outfile = optarg;
171 			break;
172 
173 		case 'p':
174 			pflag++;
175 			break;
176 
177 		case 'q':
178 			Warn = 0;
179 			break;
180 
181 		case 'v':
182 			Verbose++;
183 			break;
184 
185 		case 'y':
186 			lexecho++;
187 			break;
188 
189 		default:
190 			out(O_DIE|O_USAGE, Usage);
191 			/*NOTREACHED*/
192 		}
193 	}
194 
195 	out(O_PROG|O_VERB, "eversholt compiler version %d.%d",
196 	    VERSION_MAJOR, VERSION_MINOR);
197 
198 	argc -= optind;
199 	av = &argv[optind];
200 
201 	if (argc < 1) {
202 		out(O_ERR, "no esc source files given");
203 		out(O_DIE|O_USAGE, Usage);
204 		/*NOTREACHED*/
205 	}
206 
207 	lex_init(av, Cppargs, lexecho);
208 	check_init();
209 	yyparse();
210 	(void) lex_fini();
211 
212 	tree_report();
213 
214 	if (count = out_errcount())
215 		out(O_DIE, "%d language error%s encountered, exiting.",
216 		    OUTS(count));
217 
218 	if (outfile)
219 		eftwrite(outfile);
220 
221 	if (pflag)
222 		ptree_name_iter(O_OK, tree_root(NULL));
223 
224 	if (stats) {
225 		out(O_OK, "Stats:");
226 		stats_publish();
227 	}
228 
229 	out_exit(0);
230 	/*NOTREACHED*/
231 	return (0);
232 }
233