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  * eftinfo.c -- main routine for eftinfo command
27  *
28  * argument processing and the general flow through all the other
29  * modules is driven by this file.
30  */
31 
32 #include <stdio.h>
33 #include <string.h>
34 #ifdef sun
35 #include <stdlib.h>
36 #else
37 #include <getopt.h>
38 #endif /* sun */
39 #include "out.h"
40 #include "alloc.h"
41 #include "stats.h"
42 #include "stable.h"
43 #include "literals.h"
44 #include "lut.h"
45 #include "esclex.h"
46 #include "ptree.h"
47 #include "tree.h"
48 #include "check.h"
49 #include "version.h"
50 #include "eftread.h"
51 
52 /* stuff exported by yacc-generated parsers */
53 extern void yyparse(void);
54 extern int yydebug;
55 
56 /*
57  * This external definition has to be here.  If we put it in literals.h
58  * lint complains about the declaration not being used within the block
59  * when compiling literals.c.
60  */
61 extern void literals_init(void);
62 
63 static const char *Usage = "[-DEPghpqvw] eft-files...";
64 static const char *Help =
65 "\t-D            Print dictionaries EFT references.\n"
66 "\t-E            Print ereports EFT will consume.\n"
67 "\t-P            Print problems EFT can diagnose.\n"
68 "\t-g            Print generated iterators (use with -p)\n"
69 "\t-h            Print this help message\n"
70 "\t-p            Print complete propagation tree\n"
71 "\t-q            Quiet mode, no header info printed\n"
72 "\t-v            Enable verbose output\n"
73 "\t-w            Enable language warnings";
74 /*
75  * and some undocumented extras...
76  *	"\t-S            Print stats for compiler memory usage, etc.\n"
77  *	"\t-Y            Enable parser debug output\n"
78  *	"\t-d            Enable general debug output\n"
79  *	"\t-y            Enable lexer debug output\n"
80  *
81  */
82 
83 int Debug;
84 int Verbose;
85 int Warn;
86 
87 extern int Pchildgen;	/* flag to ptree for printing generated interators */
88 
89 extern struct lut *Dicts;
90 
91 /*ARGSUSED*/
92 static void
dictprint(const char * s,void * rhs,void * arg)93 dictprint(const char *s, void *rhs, void *arg)
94 {
95 	static char *sep = "";
96 
97 	out(O_OK|O_NONL, "%s%s", sep, s);
98 	sep = ":";
99 }
100 
101 int
main(int argc,char * argv[])102 main(int argc, char *argv[])
103 {
104 	int c;
105 	int count;
106 	int Dflag = 0;
107 	int Eflag = 0;
108 	int yflag = 0;
109 	int Pflag = 0;
110 	int Sflag = 0;
111 	int pflag = 0;
112 	int qflag = 0;
113 
114 	alloc_init();
115 	out_init(argv[0]);
116 	stats_init(1);		/* extended stats always enabled for eftinfo */
117 	stable_init(0);
118 	literals_init();
119 	lut_init();
120 	tree_init();
121 
122 	while ((c = getopt(argc, argv, "DEPSYdghpqvwy")) != EOF) {
123 		switch (c) {
124 		case 'D':
125 			Dflag++;
126 			break;
127 
128 		case 'E':
129 			Eflag++;
130 			break;
131 
132 		case 'y':
133 			yflag++;
134 			break;
135 
136 		case 'P':
137 			Pflag++;
138 			break;
139 
140 		case 'S':
141 			Sflag++;
142 			break;
143 
144 		case 'Y':
145 			yydebug++;
146 			break;
147 
148 		case 'd':
149 			Debug++;
150 			break;
151 
152 		case 'g':
153 			Pchildgen++;
154 			break;
155 
156 		case 'h':
157 		case '?':
158 			out(O_PROG, "version %d.%d",
159 			    VERSION_MAJOR, VERSION_MINOR);
160 			out(O_DIE|O_USAGE, "%s\n%s", Usage, Help);
161 			/*NOTREACHED*/
162 			break;
163 
164 		case 'p':
165 			pflag++;
166 			break;
167 
168 		case 'q':
169 			qflag++;
170 			break;
171 
172 		case 'v':
173 			Verbose++;
174 			break;
175 
176 		case 'w':
177 			Warn++;
178 			break;
179 
180 		default:
181 			out(O_DIE|O_USAGE, Usage);
182 			/*NOTREACHED*/
183 		}
184 	}
185 
186 	out(O_PROG|O_VERB, "version %d.%d",
187 	    VERSION_MAJOR, VERSION_MINOR);
188 	argc -= optind;
189 
190 	if (argc < 1)
191 		out(O_DIE|O_USAGE, Usage);
192 
193 	if (!qflag)
194 		eftread_showheader(1);
195 
196 	lex_init(&argv[optind], NULL, yflag);
197 	check_init();
198 	yyparse();
199 	(void) lex_fini();
200 
201 	tree_report();
202 
203 	if (count = out_errcount())
204 		out(O_DIE, "%d error%s encountered, exiting.", OUTS(count));
205 
206 	if (Dflag) {
207 		out(O_OK|O_NONL, "Dictionaries: ");
208 		lut_walk(Dicts, (lut_cb)dictprint, (void *)0);
209 		out(O_OK, NULL);
210 	}
211 
212 	if (Eflag)
213 		ptree_ereport(O_OK, NULL);
214 
215 	if (Pflag) {
216 		ptree_fault(O_OK, NULL);
217 		ptree_upset(O_OK, NULL);
218 		ptree_defect(O_OK, NULL);
219 	}
220 
221 	if (pflag)
222 		ptree_name_iter(O_OK, tree_root(NULL));
223 
224 	if (Sflag) {
225 		out(O_OK, "Stats:");
226 		stats_publish();
227 	}
228 
229 	out_exit(0);
230 	/*NOTREACHED*/
231 	return (0);
232 }
233