errorsubr.c revision 5846:466857e6771b
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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <stdio.h> 30#include <ctype.h> 31#include <stdlib.h> 32#include <unistd.h> 33#include <stdarg.h> 34#include <string.h> 35#include "error.h" 36 37/* 38 * Arrayify a list of rules 39 */ 40void 41arrayify(int *e_length, Eptr **e_array, Eptr header) 42{ 43 Eptr errorp; 44 Eptr *array; 45 int listlength; 46 int listindex; 47 48 for (errorp = header, listlength = 0; 49 errorp; errorp = errorp->error_next, listlength++) 50 continue; 51 array = Calloc(listlength+1, sizeof (Eptr)); 52 for (listindex = 0, errorp = header; 53 listindex < listlength; 54 listindex++, errorp = errorp->error_next) { 55 array[listindex] = errorp; 56 errorp->error_position = listindex; 57 } 58 array[listindex] = (Eptr)0; 59 *e_length = listlength; 60 *e_array = array; 61} 62 63/*PRINTFLIKE1*/ 64static void 65error(char *format, ...) 66{ 67 va_list args; 68 69 va_start(args, format); 70 (void) fprintf(stderr, "Error: "); 71 (void) vfprintf(stderr, format, args); 72 (void) fprintf(stderr, "\n"); 73 (void) fflush(stdout); 74 (void) fflush(stderr); 75 va_end(args); 76 exit(6); 77} 78 79void * 80Calloc(int nelements, int size) 81{ 82 void *back; 83 if ((back = calloc(nelements, size)) == NULL) { 84 error("Ran out of memory.\n"); 85 exit(1); 86 } 87 return (back); 88} 89 90char * 91strsave(char *instring) 92{ 93 char *outstring; 94 (void) strcpy(outstring = Calloc(1, strlen(instring) + 1), 95 instring); 96 return (outstring); 97} 98/* 99 * find the position of a given character in a string 100 * (one based) 101 */ 102int 103position(char *string, char ch) 104{ 105 int i; 106 if (string) 107 for (i = 1; *string; string++, i++) { 108 if (*string == ch) 109 return (i); 110 } 111 return (-1); 112} 113/* 114 * clobber the first occurance of ch in string by the new character 115 */ 116char * 117substitute(char *string, char chold, char chnew) 118{ 119 char *cp = string; 120 121 if (cp) 122 while (*cp) { 123 if (*cp == chold) { 124 *cp = chnew; 125 break; 126 } 127 cp++; 128 } 129 return (string); 130} 131 132char 133lastchar(char *string) 134{ 135 int length; 136 137 if (string == NULL) 138 return ('\0'); 139 length = strlen(string); 140 if (length >= 1) 141 return (string[length-1]); 142 else 143 return ('\0'); 144} 145 146char 147firstchar(char *string) 148{ 149 if (string) 150 return (string[0]); 151 else 152 return ('\0'); 153} 154 155char 156next_lastchar(char *string) 157{ 158 int length; 159 160 if (string == NULL) 161 return ('\0'); 162 length = strlen(string); 163 if (length >= 2) 164 return (string[length - 2]); 165 else 166 return ('\0'); 167} 168 169void 170clob_last(char *string, char newstuff) 171{ 172 int length = 0; 173 if (string) 174 length = strlen(string); 175 if (length >= 1) 176 string[length - 1] = newstuff; 177} 178 179/* 180 * parse a string that is the result of a format %s(%d) 181 * return TRUE if this is of the proper format 182 */ 183boolean 184persperdexplode(char *string, char **r_perd, char **r_pers) 185{ 186 char *cp; 187 int length = 0; 188 189 if (string) 190 length = strlen(string); 191 if ((length >= 4) && (string[length - 1] == ')')) { 192 for (cp = &string[length - 2]; 193 (isdigit(*cp)) && (*cp != '('); --cp) 194 continue; 195 if (*cp == '(') { 196 string[length - 1] = '\0'; /* clobber the ) */ 197 *r_perd = strsave(cp+1); 198 string[length - 1] = ')'; 199 *cp = '\0'; /* clobber the ( */ 200 *r_pers = strsave(string); 201 *cp = '('; 202 return (TRUE); 203 } 204 } 205 return (FALSE); 206} 207 208static char cincomment[] = CINCOMMENT; 209static char coutcomment[] = COUTCOMMENT; 210static char fincomment[] = FINCOMMENT; 211static char foutcomment[] = FOUTCOMMENT; 212static char newline[] = NEWLINE; 213static char piincomment[] = PIINCOMMENT; 214static char pioutcomment[] = PIOUTCOMMENT; 215static char lispincomment[] = LISPINCOMMENT; 216static char riincomment[] = RIINCOMMENT; 217static char rioutcomment[] = RIOUTCOMMENT; 218static char troffincomment[] = TROFFINCOMMENT; 219static char troffoutcomment[] = TROFFOUTCOMMENT; 220static char mod2incomment[] = MOD2INCOMMENT; 221static char mod2outcomment[] = MOD2OUTCOMMENT; 222 223struct lang_desc lang_table[] = { 224 /* INUNKNOWN 0 */ "unknown", cincomment, coutcomment, 225 /* INCPP 1 */ "cpp", cincomment, coutcomment, 226 /* INCC 2 */ "cc", cincomment, coutcomment, 227 /* INAS 3 */ "as", ASINCOMMENT, newline, 228 /* INLD 4 */ "ld", cincomment, coutcomment, 229 /* INLINT 5 */ "lint", cincomment, coutcomment, 230 /* INF77 6 */ "f77", fincomment, foutcomment, 231 /* INPI 7 */ "pi", piincomment, pioutcomment, 232 /* INPC 8 */ "pc", piincomment, pioutcomment, 233 /* INFRANZ 9 */ "franz", lispincomment, newline, 234 /* INLISP 10 */ "lisp", lispincomment, newline, 235 /* INVAXIMA 11 */ "vaxima", lispincomment, newline, 236 /* INRATFOR 12 */ "ratfor", fincomment, foutcomment, 237 /* INLEX 13 */ "lex", cincomment, coutcomment, 238 /* INYACC 14 */ "yacc", cincomment, coutcomment, 239 /* INAPL 15 */ "apl", ".lm", newline, 240 /* INMAKE 16 */ "make", ASINCOMMENT, newline, 241 /* INRI 17 */ "ri", riincomment, rioutcomment, 242 /* INTROFF 18 */ "troff", troffincomment, troffoutcomment, 243 /* INMOD2 19 */ "mod2", mod2incomment, mod2outcomment, 244 /* INSUNF77 20 */ "Sunf77", fincomment, foutcomment, 245 0, 0, 0 246}; 247 248void 249printerrors(boolean look_at_subclass, int errorc, Eptr errorv[]) 250{ 251 int i; 252 Eptr errorp; 253 254 for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]) { 255 if (errorp->error_e_class == C_IGNORE) 256 continue; 257 if (look_at_subclass && errorp->error_s_class == C_DUPL) 258 continue; 259 (void) printf("Error %d, (%s error) [%s], text = \"", 260 i, 261 class_table[errorp->error_e_class], 262 lang_table[errorp->error_language].lang_name); 263 wordvprint(stdout, errorp->error_lgtext, errorp->error_text); 264 (void) printf("\"\n"); 265 } 266} 267 268void 269wordvprint(FILE *fyle, int wordc, char *wordv[]) 270{ 271 int i; 272 char *sep = ""; 273 274 for (i = 0; i < wordc; i++) 275 if (wordv[i]) { 276 (void) fprintf(fyle, "%s%s", sep, wordv[i]); 277 sep = " "; 278 } 279} 280 281/* 282 * Given a string, parse it into a number of words, and build 283 * a wordc wordv combination pointing into it. 284 */ 285void 286wordvbuild(char *string, int *r_wordc, char ***r_wordv) 287{ 288 char *cp; 289 char *saltedbuffer; 290 char **wordv; 291 int wordcount; 292 int wordindex; 293 294 saltedbuffer = strsave(string); 295 for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++) { 296 while (*cp && isspace(*cp)) 297 cp++; 298 while (*cp && !isspace(*cp)) 299 cp++; 300 } 301 wordv = Calloc(wordcount + 1, sizeof (char *)); 302 for (cp = saltedbuffer, wordindex = 0; wordcount; 303 wordindex++, --wordcount) { 304 while (*cp && isspace(*cp)) 305 cp++; 306 if (*cp == 0) 307 break; 308 wordv[wordindex] = cp; 309 while (*cp && !isspace(*cp)) 310 cp++; 311 *cp++ = '\0'; 312 } 313 if (wordcount != 0) 314 error("Initial miscount of the number of words in a line\n"); 315 wordv[wordindex] = NULL; 316#ifdef FULLDEBUG 317 for (wordcount = 0; wordcount < wordindex; wordcount++) 318 (void) printf("Word %d = \"%s\"\n", wordcount, 319 wordv[wordcount]); 320 (void) printf("\n"); 321#endif 322 *r_wordc = wordindex; 323 *r_wordv = wordv; 324} 325/* 326 * Compare two 0 based wordvectors 327 */ 328int 329wordvcmp(char **wordv1, int wordc, char **wordv2) 330{ 331 int i; 332 int back; 333 334 for (i = 0; i < wordc; i++) { 335 if (wordv1[i] == 0 || wordv2[i] == 0) 336 return (-1); 337 if (back = strcmp(wordv1[i], wordv2[i])) { 338 return (back); 339 } 340 } 341 return (0); /* they are equal */ 342} 343 344/* 345 * splice a 0 basedword vector onto the tail of a 346 * new wordv, allowing the first emptyhead slots to be empty 347 */ 348char ** 349wordvsplice(int emptyhead, int wordc, char **wordv) 350{ 351 char **nwordv; 352 int nwordc = emptyhead + wordc; 353 int i; 354 355 nwordv = Calloc(nwordc, sizeof (char *)); 356 for (i = 0; i < emptyhead; i++) 357 nwordv[i] = 0; 358 for (i = emptyhead; i < nwordc; i++) { 359 nwordv[i] = wordv[i-emptyhead]; 360 } 361 return (nwordv); 362} 363 364/* 365 * plural'ize and verb forms 366 */ 367static char *S = "s"; 368static char *N = ""; 369 370char * 371plural(int n) 372{ 373 return (n > 1 ? S : N); 374} 375 376char * 377verbform(int n) 378{ 379 return (n > 1 ? N : S); 380} 381