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
main(int argc,char * argv[])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