1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte * CDDL HEADER START
3*fcf3ce44SJohn Forte *
4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte *
8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte * and limitations under the License.
12*fcf3ce44SJohn Forte *
13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte *
19*fcf3ce44SJohn Forte * CDDL HEADER END
20*fcf3ce44SJohn Forte */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23*fcf3ce44SJohn Forte * Use is subject to license terms.
24*fcf3ce44SJohn Forte */
25*fcf3ce44SJohn Forte
26*fcf3ce44SJohn Forte /*
27*fcf3ce44SJohn Forte * Read an errgen status resource file (*.err) from standard input and
28*fcf3ce44SJohn Forte * write an SPCS error code C header file (-c), Java resource file (-j),
29*fcf3ce44SJohn Forte * libspcs Java exception class file(-e), error text file (-m) or JNI
30*fcf3ce44SJohn Forte * exception trinket table to standard output. Lines starting with "#"
31*fcf3ce44SJohn Forte * are ignored.
32*fcf3ce44SJohn Forte *
33*fcf3ce44SJohn Forte * Use "errgen -h" to get usage info including module codes and example
34*fcf3ce44SJohn Forte * input and output.
35*fcf3ce44SJohn Forte */
36*fcf3ce44SJohn Forte
37*fcf3ce44SJohn Forte
38*fcf3ce44SJohn Forte #include <stdio.h>
39*fcf3ce44SJohn Forte #include <stdlib.h>
40*fcf3ce44SJohn Forte #include <string.h>
41*fcf3ce44SJohn Forte #include <ctype.h>
42*fcf3ce44SJohn Forte #include <libgen.h>
43*fcf3ce44SJohn Forte #include <limits.h>
44*fcf3ce44SJohn Forte #include <sys/param.h>
45*fcf3ce44SJohn Forte
46*fcf3ce44SJohn Forte /* The public error info header file. */
47*fcf3ce44SJohn Forte
48*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s.h>
49*fcf3ce44SJohn Forte
50*fcf3ce44SJohn Forte /* The private error info header file */
51*fcf3ce44SJohn Forte
52*fcf3ce44SJohn Forte #include <sys/unistat/spcs_s_impl.h>
53*fcf3ce44SJohn Forte
54*fcf3ce44SJohn Forte
55*fcf3ce44SJohn Forte /* locals */
56*fcf3ce44SJohn Forte
57*fcf3ce44SJohn Forte static enum {C_MODE, J_MODE, M_MODE, E_MODE, T_MODE, X_MODE} mode = E_MODE;
58*fcf3ce44SJohn Forte static char key[SPCS_S_MAXKEY];
59*fcf3ce44SJohn Forte static char text[SPCS_S_MAXTEXT];
60*fcf3ce44SJohn Forte static int mod_number;
61*fcf3ce44SJohn Forte
62*fcf3ce44SJohn Forte static char help_path[PATH_MAX];
63*fcf3ce44SJohn Forte
64*fcf3ce44SJohn Forte static int count = 1;
65*fcf3ce44SJohn Forte
66*fcf3ce44SJohn Forte static char key[SPCS_S_MAXKEY];
67*fcf3ce44SJohn Forte static char text[SPCS_S_MAXTEXT];
68*fcf3ce44SJohn Forte static char modname[SPCS_S_MAXMODNAME];
69*fcf3ce44SJohn Forte
70*fcf3ce44SJohn Forte /*
71*fcf3ce44SJohn Forte * Display help info
72*fcf3ce44SJohn Forte */
73*fcf3ce44SJohn Forte
74*fcf3ce44SJohn Forte static void
help()75*fcf3ce44SJohn Forte help()
76*fcf3ce44SJohn Forte {
77*fcf3ce44SJohn Forte char line[SPCS_S_MAXLINE];
78*fcf3ce44SJohn Forte FILE *h = fopen(help_path, "r");
79*fcf3ce44SJohn Forte
80*fcf3ce44SJohn Forte if (h) {
81*fcf3ce44SJohn Forte while (! feof(h)) {
82*fcf3ce44SJohn Forte (void) fgets(line, SPCS_S_MAXLINE, h);
83*fcf3ce44SJohn Forte if (! feof(h))
84*fcf3ce44SJohn Forte (void) fputs(line, stderr);
85*fcf3ce44SJohn Forte }
86*fcf3ce44SJohn Forte } else {
87*fcf3ce44SJohn Forte perror(strcat("could not open: ", help_path));
88*fcf3ce44SJohn Forte exit(1);
89*fcf3ce44SJohn Forte }
90*fcf3ce44SJohn Forte }
91*fcf3ce44SJohn Forte
92*fcf3ce44SJohn Forte /*
93*fcf3ce44SJohn Forte * Put out a message with terse instructions and err out
94*fcf3ce44SJohn Forte */
95*fcf3ce44SJohn Forte
96*fcf3ce44SJohn Forte static void
fatal(char * msg)97*fcf3ce44SJohn Forte fatal(char *msg)
98*fcf3ce44SJohn Forte {
99*fcf3ce44SJohn Forte (void) fprintf(stderr, "%s\n\n", msg);
100*fcf3ce44SJohn Forte (void) fprintf(stderr, "use errgen -h for help\n");
101*fcf3ce44SJohn Forte exit(1);
102*fcf3ce44SJohn Forte }
103*fcf3ce44SJohn Forte
104*fcf3ce44SJohn Forte /*
105*fcf3ce44SJohn Forte * Put out the output file preamble
106*fcf3ce44SJohn Forte */
107*fcf3ce44SJohn Forte
108*fcf3ce44SJohn Forte static void
do_preamble()109*fcf3ce44SJohn Forte do_preamble()
110*fcf3ce44SJohn Forte {
111*fcf3ce44SJohn Forte switch (mode) {
112*fcf3ce44SJohn Forte case M_MODE:
113*fcf3ce44SJohn Forte (void) fprintf(stdout,
114*fcf3ce44SJohn Forte "static\nchar *SPCS_MSG_%s[] = {\n", modname);
115*fcf3ce44SJohn Forte (void) fprintf(stdout, "\t\"\",\n");
116*fcf3ce44SJohn Forte break;
117*fcf3ce44SJohn Forte case T_MODE:
118*fcf3ce44SJohn Forte (void) fprintf(stdout,
119*fcf3ce44SJohn Forte "static\nchar *SPCS_TRNK_%s[] = {\n", modname);
120*fcf3ce44SJohn Forte (void) fprintf(stdout, "\t\"\",\n");
121*fcf3ce44SJohn Forte break;
122*fcf3ce44SJohn Forte }
123*fcf3ce44SJohn Forte }
124*fcf3ce44SJohn Forte
125*fcf3ce44SJohn Forte /*
126*fcf3ce44SJohn Forte * Put out the output file trailer
127*fcf3ce44SJohn Forte */
128*fcf3ce44SJohn Forte
129*fcf3ce44SJohn Forte static void
do_trailer()130*fcf3ce44SJohn Forte do_trailer()
131*fcf3ce44SJohn Forte {
132*fcf3ce44SJohn Forte switch (mode) {
133*fcf3ce44SJohn Forte case M_MODE:
134*fcf3ce44SJohn Forte (void) fprintf(stdout, "};\n");
135*fcf3ce44SJohn Forte (void) fprintf(stdout,
136*fcf3ce44SJohn Forte "#define\tSPCS_MSGLEN_%s %d\t/* total codes */\n",
137*fcf3ce44SJohn Forte modname, count-1);
138*fcf3ce44SJohn Forte break;
139*fcf3ce44SJohn Forte case T_MODE:
140*fcf3ce44SJohn Forte (void) fprintf(stdout, "};\n");
141*fcf3ce44SJohn Forte (void) fprintf(stdout,
142*fcf3ce44SJohn Forte "#define\tSPCS_TRNKLEN_%s %d\t/* total codes */\n",
143*fcf3ce44SJohn Forte modname, count-1);
144*fcf3ce44SJohn Forte break;
145*fcf3ce44SJohn Forte }
146*fcf3ce44SJohn Forte }
147*fcf3ce44SJohn Forte
148*fcf3ce44SJohn Forte /*
149*fcf3ce44SJohn Forte * Process a single input line
150*fcf3ce44SJohn Forte */
151*fcf3ce44SJohn Forte
152*fcf3ce44SJohn Forte static void
do_line()153*fcf3ce44SJohn Forte do_line()
154*fcf3ce44SJohn Forte {
155*fcf3ce44SJohn Forte spcs_s_udata_t c;
156*fcf3ce44SJohn Forte int fc = 0;
157*fcf3ce44SJohn Forte int len = 0;
158*fcf3ce44SJohn Forte char ptext[SPCS_S_MAXTEXT];
159*fcf3ce44SJohn Forte char keystring[SPCS_S_MAXKEY+SPCS_S_MAXPRE];
160*fcf3ce44SJohn Forte char *p = text;
161*fcf3ce44SJohn Forte int tlen;
162*fcf3ce44SJohn Forte char *pt = ptext;
163*fcf3ce44SJohn Forte char havebytestream = 0;
164*fcf3ce44SJohn Forte
165*fcf3ce44SJohn Forte c.i = 0;
166*fcf3ce44SJohn Forte (void) sprintf(keystring, "%s_E%s", modname, key);
167*fcf3ce44SJohn Forte while (*p) {
168*fcf3ce44SJohn Forte if (*p == '%') {
169*fcf3ce44SJohn Forte if (*(p + 1) != 's') {
170*fcf3ce44SJohn Forte (void) fprintf(stderr,
171*fcf3ce44SJohn Forte "ERRGEN: Error in .err file\n");
172*fcf3ce44SJohn Forte (void) fprintf(stderr,
173*fcf3ce44SJohn Forte "%c is an illegal format spec after %%",
174*fcf3ce44SJohn Forte *p);
175*fcf3ce44SJohn Forte (void) fprintf(stderr,
176*fcf3ce44SJohn Forte " at line: %d pos: %d\n", count,
177*fcf3ce44SJohn Forte /* LINTED possible ptrdiff_t overflow */
178*fcf3ce44SJohn Forte (int)(p - text));
179*fcf3ce44SJohn Forte fatal("");
180*fcf3ce44SJohn Forte }
181*fcf3ce44SJohn Forte len = sprintf(pt, "{%d}", fc);
182*fcf3ce44SJohn Forte pt += len;
183*fcf3ce44SJohn Forte p++;
184*fcf3ce44SJohn Forte fc += 1;
185*fcf3ce44SJohn Forte if (fc > SPCS_S_MAXSUPP) {
186*fcf3ce44SJohn Forte (void) fprintf(stderr,
187*fcf3ce44SJohn Forte "ERRGEN: Error in .err file\n");
188*fcf3ce44SJohn Forte (void) fprintf(stderr,
189*fcf3ce44SJohn Forte "SPCS_S_MAXSUPP exceeeded\n");
190*fcf3ce44SJohn Forte fatal("Too many %%s specifiers");
191*fcf3ce44SJohn Forte }
192*fcf3ce44SJohn Forte } else
193*fcf3ce44SJohn Forte *pt++ = *p;
194*fcf3ce44SJohn Forte p++;
195*fcf3ce44SJohn Forte }
196*fcf3ce44SJohn Forte
197*fcf3ce44SJohn Forte /* look for a bytestream indicator */
198*fcf3ce44SJohn Forte
199*fcf3ce44SJohn Forte tlen = strlen(text);
200*fcf3ce44SJohn Forte
201*fcf3ce44SJohn Forte if ((tlen > 2) && (text[tlen - 1] == '@') && (text[tlen - 2] == '@')) {
202*fcf3ce44SJohn Forte if (fc)
203*fcf3ce44SJohn Forte fatal("ERRGEN: cannot have %%s and @@ ending too");
204*fcf3ce44SJohn Forte
205*fcf3ce44SJohn Forte /* bump the item count and set the bytestream flag */
206*fcf3ce44SJohn Forte fc += 1;
207*fcf3ce44SJohn Forte havebytestream = 1;
208*fcf3ce44SJohn Forte }
209*fcf3ce44SJohn Forte
210*fcf3ce44SJohn Forte *pt = 0;
211*fcf3ce44SJohn Forte
212*fcf3ce44SJohn Forte switch (mode) {
213*fcf3ce44SJohn Forte case C_MODE:
214*fcf3ce44SJohn Forte c.f.bytestream = havebytestream;
215*fcf3ce44SJohn Forte c.f.sup_count = fc;
216*fcf3ce44SJohn Forte c.f.module = mod_number;
217*fcf3ce44SJohn Forte c.f.code = count;
218*fcf3ce44SJohn Forte (void) fprintf(stdout, "#define\t%s 0x%x /* %s */\n",
219*fcf3ce44SJohn Forte keystring, c.i, text);
220*fcf3ce44SJohn Forte break;
221*fcf3ce44SJohn Forte case J_MODE:
222*fcf3ce44SJohn Forte (void) fprintf(stdout, "`%s` = %s\n", keystring, ptext);
223*fcf3ce44SJohn Forte break;
224*fcf3ce44SJohn Forte case X_MODE:
225*fcf3ce44SJohn Forte (void) fprintf(stdout,
226*fcf3ce44SJohn Forte "#define\tT_%s \"`%s`\"\n", keystring, keystring);
227*fcf3ce44SJohn Forte break;
228*fcf3ce44SJohn Forte case T_MODE:
229*fcf3ce44SJohn Forte (void) fprintf(stdout, "\t\"`%s`\",\n", keystring);
230*fcf3ce44SJohn Forte break;
231*fcf3ce44SJohn Forte case M_MODE:
232*fcf3ce44SJohn Forte (void) fprintf(stdout, "\t\"%s\",\n", text);
233*fcf3ce44SJohn Forte break;
234*fcf3ce44SJohn Forte case E_MODE:
235*fcf3ce44SJohn Forte (void) fprintf(stdout, " /**\n * %s\n **/\n",
236*fcf3ce44SJohn Forte text);
237*fcf3ce44SJohn Forte (void) fprintf(stdout, " public static final String %s",
238*fcf3ce44SJohn Forte keystring);
239*fcf3ce44SJohn Forte (void) fprintf(stdout, " = `%s`;\n\n", keystring);
240*fcf3ce44SJohn Forte break;
241*fcf3ce44SJohn Forte }
242*fcf3ce44SJohn Forte }
243*fcf3ce44SJohn Forte
244*fcf3ce44SJohn Forte int
main(int argc,char ** argv)245*fcf3ce44SJohn Forte main(int argc, char **argv)
246*fcf3ce44SJohn Forte {
247*fcf3ce44SJohn Forte int i;
248*fcf3ce44SJohn Forte int searching = 1;
249*fcf3ce44SJohn Forte char searchname[SPCS_S_MAXMODNAME];
250*fcf3ce44SJohn Forte char line[SPCS_S_MAXLINE];
251*fcf3ce44SJohn Forte char tline[SPCS_S_MAXLINE];
252*fcf3ce44SJohn Forte char *p, *p2;
253*fcf3ce44SJohn Forte
254*fcf3ce44SJohn Forte (void) strcpy(help_path, dirname(argv[0]));
255*fcf3ce44SJohn Forte (void) strcat(help_path, "/errgen.help");
256*fcf3ce44SJohn Forte if ((argc == 1) || ((argc == 2) && (strcmp(argv[1], "-h") == 0))) {
257*fcf3ce44SJohn Forte help();
258*fcf3ce44SJohn Forte exit(0);
259*fcf3ce44SJohn Forte }
260*fcf3ce44SJohn Forte
261*fcf3ce44SJohn Forte if (argc != 3)
262*fcf3ce44SJohn Forte fatal("Bad number of arguments");
263*fcf3ce44SJohn Forte
264*fcf3ce44SJohn Forte p = argv[2];
265*fcf3ce44SJohn Forte p2 = modname;
266*fcf3ce44SJohn Forte
267*fcf3ce44SJohn Forte while (*p)
268*fcf3ce44SJohn Forte *p2++ = toupper(*p++);
269*fcf3ce44SJohn Forte *p2 = 0;
270*fcf3ce44SJohn Forte
271*fcf3ce44SJohn Forte switch (argv[1][1]) {
272*fcf3ce44SJohn Forte case 'c':
273*fcf3ce44SJohn Forte mode = C_MODE;
274*fcf3ce44SJohn Forte break;
275*fcf3ce44SJohn Forte case 'j':
276*fcf3ce44SJohn Forte mode = J_MODE;
277*fcf3ce44SJohn Forte break;
278*fcf3ce44SJohn Forte case 'e':
279*fcf3ce44SJohn Forte mode = E_MODE;
280*fcf3ce44SJohn Forte break;
281*fcf3ce44SJohn Forte case 'm':
282*fcf3ce44SJohn Forte mode = M_MODE;
283*fcf3ce44SJohn Forte break;
284*fcf3ce44SJohn Forte case 't':
285*fcf3ce44SJohn Forte mode = T_MODE;
286*fcf3ce44SJohn Forte break;
287*fcf3ce44SJohn Forte case 'x':
288*fcf3ce44SJohn Forte mode = X_MODE;
289*fcf3ce44SJohn Forte break;
290*fcf3ce44SJohn Forte default:
291*fcf3ce44SJohn Forte fatal("Unknown option switch");
292*fcf3ce44SJohn Forte }
293*fcf3ce44SJohn Forte
294*fcf3ce44SJohn Forte if (strcmp(modname, "DSW") == 0) {
295*fcf3ce44SJohn Forte (void) strcpy(searchname, "II");
296*fcf3ce44SJohn Forte } else if (strcmp(modname, "RDC") == 0) {
297*fcf3ce44SJohn Forte (void) strcpy(searchname, "SNDR");
298*fcf3ce44SJohn Forte } else if (strcmp(modname, "SDCTL") == 0) {
299*fcf3ce44SJohn Forte (void) strcpy(searchname, "NSCTL");
300*fcf3ce44SJohn Forte } else {
301*fcf3ce44SJohn Forte (void) strcpy(searchname, modname);
302*fcf3ce44SJohn Forte }
303*fcf3ce44SJohn Forte
304*fcf3ce44SJohn Forte i = 0;
305*fcf3ce44SJohn Forte do {
306*fcf3ce44SJohn Forte if (strcmp(module_names[i++], searchname) == 0) {
307*fcf3ce44SJohn Forte searching = 0;
308*fcf3ce44SJohn Forte mod_number = i - 1;
309*fcf3ce44SJohn Forte break;
310*fcf3ce44SJohn Forte }
311*fcf3ce44SJohn Forte } while (module_names[i]);
312*fcf3ce44SJohn Forte
313*fcf3ce44SJohn Forte if (searching) {
314*fcf3ce44SJohn Forte if (i != SPCS_M_MAX)
315*fcf3ce44SJohn Forte (void) fprintf(stderr,
316*fcf3ce44SJohn Forte "NULL in module_names before SPCS_M_MAX\n");
317*fcf3ce44SJohn Forte fatal("Undefined module name");
318*fcf3ce44SJohn Forte }
319*fcf3ce44SJohn Forte
320*fcf3ce44SJohn Forte do_preamble();
321*fcf3ce44SJohn Forte
322*fcf3ce44SJohn Forte while (!feof(stdin)) {
323*fcf3ce44SJohn Forte (void) fgets(line, SPCS_S_MAXLINE, stdin);
324*fcf3ce44SJohn Forte if (feof(stdin)) {
325*fcf3ce44SJohn Forte if (count == 0)
326*fcf3ce44SJohn Forte fatal("errgen file empty");
327*fcf3ce44SJohn Forte
328*fcf3ce44SJohn Forte do_trailer();
329*fcf3ce44SJohn Forte exit(0);
330*fcf3ce44SJohn Forte }
331*fcf3ce44SJohn Forte line[strlen(line)-1] = 0;
332*fcf3ce44SJohn Forte if ((strlen(line) != 0) && (line[0] != '#')) {
333*fcf3ce44SJohn Forte (void) strcpy(tline, line);
334*fcf3ce44SJohn Forte p = strchr(tline, ' ');
335*fcf3ce44SJohn Forte if (p == NULL) {
336*fcf3ce44SJohn Forte (void) fprintf(stderr,
337*fcf3ce44SJohn Forte "blank separator missing at line: %d\n",
338*fcf3ce44SJohn Forte count);
339*fcf3ce44SJohn Forte fatal("");
340*fcf3ce44SJohn Forte }
341*fcf3ce44SJohn Forte *p = 0;
342*fcf3ce44SJohn Forte if (strlen(p) > SPCS_S_MAXKEY) {
343*fcf3ce44SJohn Forte (void) fprintf(stderr,
344*fcf3ce44SJohn Forte "message label too long at line: %d\n", count);
345*fcf3ce44SJohn Forte fatal("");
346*fcf3ce44SJohn Forte }
347*fcf3ce44SJohn Forte (void) strcpy(key, tline);
348*fcf3ce44SJohn Forte if (strlen(key) == 0) {
349*fcf3ce44SJohn Forte (void) fprintf(stderr,
350*fcf3ce44SJohn Forte "leading blank at line: %d\n", count);
351*fcf3ce44SJohn Forte fatal("");
352*fcf3ce44SJohn Forte }
353*fcf3ce44SJohn Forte p++;
354*fcf3ce44SJohn Forte if (*p != '=') {
355*fcf3ce44SJohn Forte (void) fprintf(stderr,
356*fcf3ce44SJohn Forte "= separator missing at line: %d\n", count);
357*fcf3ce44SJohn Forte fatal("");
358*fcf3ce44SJohn Forte }
359*fcf3ce44SJohn Forte p++;
360*fcf3ce44SJohn Forte if (*p != ' ') {
361*fcf3ce44SJohn Forte (void) fprintf(stderr,
362*fcf3ce44SJohn Forte "blank separator missing at line: %d\n", count);
363*fcf3ce44SJohn Forte fatal("");
364*fcf3ce44SJohn Forte }
365*fcf3ce44SJohn Forte p++;
366*fcf3ce44SJohn Forte if (! *p) {
367*fcf3ce44SJohn Forte (void) fprintf(stderr,
368*fcf3ce44SJohn Forte "msg text missing at line:%d\n", count);
369*fcf3ce44SJohn Forte fatal("");
370*fcf3ce44SJohn Forte }
371*fcf3ce44SJohn Forte (void) strcpy(text, p);
372*fcf3ce44SJohn Forte
373*fcf3ce44SJohn Forte do_line();
374*fcf3ce44SJohn Forte count++;
375*fcf3ce44SJohn Forte }
376*fcf3ce44SJohn Forte }
377*fcf3ce44SJohn Forte
378*fcf3ce44SJohn Forte return (0);
379*fcf3ce44SJohn Forte }
380