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