Annotation of src/usr.bin/error/subr.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: subr.c,v 1.4 1995/09/10 15:55:15 christos Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1980, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
! 36: #ifndef lint
! 37: #if 0
! 38: static char sccsid[] = "@(#)subr.c 8.1 (Berkeley) 6/6/93";
! 39: #endif
! 40: static char rcsid[] = "$NetBSD: subr.c,v 1.4 1995/09/10 15:55:15 christos Exp $";
! 41: #endif /* not lint */
! 42:
! 43: #include <stdio.h>
! 44: #include <ctype.h>
! 45: #include <stdlib.h>
! 46: #include <string.h>
! 47: #include "error.h"
! 48: /*
! 49: * Arrayify a list of rules
! 50: */
! 51: arrayify(e_length, e_array, header)
! 52: int *e_length;
! 53: Eptr **e_array;
! 54: Eptr header;
! 55: {
! 56: reg Eptr errorp;
! 57: reg Eptr *array;
! 58: reg int listlength;
! 59: reg int listindex;
! 60:
! 61: for (errorp = header, listlength = 0;
! 62: errorp; errorp = errorp->error_next, listlength++)
! 63: continue;
! 64: array = (Eptr*)Calloc(listlength+1, sizeof (Eptr));
! 65: for(listindex = 0, errorp = header;
! 66: listindex < listlength;
! 67: listindex++, errorp = errorp->error_next){
! 68: array[listindex] = errorp;
! 69: errorp->error_position = listindex;
! 70: }
! 71: array[listindex] = (Eptr)0;
! 72: *e_length = listlength;
! 73: *e_array = array;
! 74: }
! 75:
! 76: /*VARARGS1*/
! 77: error(msg, a1, a2, a3)
! 78: char *msg;
! 79: {
! 80: fprintf(stderr, "Error: ");
! 81: fprintf(stderr, msg, a1, a2, a3);
! 82: fprintf(stderr, "\n");
! 83: fflush(stdout);
! 84: fflush(stderr);
! 85: exit(6);
! 86: }
! 87: /*ARGSUSED*/
! 88: char *Calloc(nelements, size)
! 89: int nelements;
! 90: int size;
! 91: {
! 92: char *back;
! 93: if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){
! 94: error("Ran out of memory.\n");
! 95: exit(1);
! 96: }
! 97: return(back);
! 98: }
! 99:
! 100: char *strsave(instring)
! 101: char *instring;
! 102: {
! 103: char *outstring;
! 104: (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1),
! 105: instring);
! 106: return(outstring);
! 107: }
! 108: /*
! 109: * find the position of a given character in a string
! 110: * (one based)
! 111: */
! 112: int position(string, ch)
! 113: reg char *string;
! 114: reg char ch;
! 115: {
! 116: reg int i;
! 117: if (string)
! 118: for (i=1; *string; string++, i++){
! 119: if (*string == ch)
! 120: return(i);
! 121: }
! 122: return(-1);
! 123: }
! 124: /*
! 125: * clobber the first occurance of ch in string by the new character
! 126: */
! 127: char *substitute(string, chold, chnew)
! 128: char *string;
! 129: char chold, chnew;
! 130: {
! 131: reg char *cp = string;
! 132:
! 133: if (cp)
! 134: while (*cp){
! 135: if (*cp == chold){
! 136: *cp = chnew;
! 137: break;
! 138: }
! 139: cp++;
! 140: }
! 141: return(string);
! 142: }
! 143:
! 144: char lastchar(string)
! 145: char *string;
! 146: {
! 147: int length;
! 148: if (string == 0) return('\0');
! 149: length = strlen(string);
! 150: if (length >= 1)
! 151: return(string[length-1]);
! 152: else
! 153: return('\0');
! 154: }
! 155:
! 156: char firstchar(string)
! 157: char *string;
! 158: {
! 159: if (string)
! 160: return(string[0]);
! 161: else
! 162: return('\0');
! 163: }
! 164:
! 165: char next_lastchar(string)
! 166: char *string;
! 167: {
! 168: int length;
! 169: if (string == 0) return('\0');
! 170: length = strlen(string);
! 171: if (length >= 2)
! 172: return(string[length - 2]);
! 173: else
! 174: return('\0');
! 175: }
! 176:
! 177: clob_last(string, newstuff)
! 178: char *string, newstuff;
! 179: {
! 180: int length = 0;
! 181: if (string)
! 182: length = strlen(string);
! 183: if (length >= 1)
! 184: string[length - 1] = newstuff;
! 185: }
! 186:
! 187: /*
! 188: * parse a string that is the result of a format %s(%d)
! 189: * return TRUE if this is of the proper format
! 190: */
! 191: boolean persperdexplode(string, r_perd, r_pers)
! 192: char *string;
! 193: char **r_perd, **r_pers;
! 194: {
! 195: reg char *cp;
! 196: int length = 0;
! 197:
! 198: if (string)
! 199: length = strlen(string);
! 200: if ( (length >= 4)
! 201: && (string[length - 1] == ')' ) ){
! 202: for (cp = &string[length - 2];
! 203: (isdigit(*cp)) && (*cp != '(');
! 204: --cp)
! 205: continue;
! 206: if (*cp == '('){
! 207: string[length - 1] = '\0'; /* clobber the ) */
! 208: *r_perd = strsave(cp+1);
! 209: string[length - 1] = ')';
! 210: *cp = '\0'; /* clobber the ( */
! 211: *r_pers = strsave(string);
! 212: *cp = '(';
! 213: return(TRUE);
! 214: }
! 215: }
! 216: return(FALSE);
! 217: }
! 218: /*
! 219: * parse a quoted string that is the result of a format \"%s\"(%d)
! 220: * return TRUE if this is of the proper format
! 221: */
! 222: boolean qpersperdexplode(string, r_perd, r_pers)
! 223: char *string;
! 224: char **r_perd, **r_pers;
! 225: {
! 226: reg char *cp;
! 227: int length = 0;
! 228:
! 229: if (string)
! 230: length = strlen(string);
! 231: if ( (length >= 4)
! 232: && (string[length - 1] == ')' ) ){
! 233: for (cp = &string[length - 2];
! 234: (isdigit(*cp)) && (*cp != '(');
! 235: --cp)
! 236: continue;
! 237: if (*cp == '(' && *(cp - 1) == '"'){
! 238: string[length - 1] = '\0';
! 239: *r_perd = strsave(cp+1);
! 240: string[length - 1] = ')';
! 241: *(cp - 1) = '\0'; /* clobber the " */
! 242: *r_pers = strsave(string + 1);
! 243: *(cp - 1) = '"';
! 244: return(TRUE);
! 245: }
! 246: }
! 247: return(FALSE);
! 248: }
! 249:
! 250: static char cincomment[] = CINCOMMENT;
! 251: static char coutcomment[] = COUTCOMMENT;
! 252: static char fincomment[] = FINCOMMENT;
! 253: static char foutcomment[] = FOUTCOMMENT;
! 254: static char newline[] = NEWLINE;
! 255: static char piincomment[] = PIINCOMMENT;
! 256: static char pioutcomment[] = PIOUTCOMMENT;
! 257: static char lispincomment[] = LISPINCOMMENT;
! 258: static char riincomment[] = RIINCOMMENT;
! 259: static char rioutcomment[] = RIOUTCOMMENT;
! 260: static char troffincomment[] = TROFFINCOMMENT;
! 261: static char troffoutcomment[] = TROFFOUTCOMMENT;
! 262: static char mod2incomment[] = MOD2INCOMMENT;
! 263: static char mod2outcomment[] = MOD2OUTCOMMENT;
! 264:
! 265: struct lang_desc lang_table[] = {
! 266: /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment,
! 267: /*INCPP 1*/ "cpp", cincomment, coutcomment,
! 268: /*INCC 2*/ "cc", cincomment, coutcomment,
! 269: /*INAS 3*/ "as", ASINCOMMENT, newline,
! 270: /*INLD 4*/ "ld", cincomment, coutcomment,
! 271: /*INLINT 5*/ "lint", cincomment, coutcomment,
! 272: /*INF77 6*/ "f77", fincomment, foutcomment,
! 273: /*INPI 7*/ "pi", piincomment, pioutcomment,
! 274: /*INPC 8*/ "pc", piincomment, pioutcomment,
! 275: /*INFRANZ 9*/ "franz",lispincomment, newline,
! 276: /*INLISP 10*/ "lisp", lispincomment, newline,
! 277: /*INVAXIMA 11*/ "vaxima",lispincomment,newline,
! 278: /*INRATFOR 12*/ "ratfor",fincomment, foutcomment,
! 279: /*INLEX 13*/ "lex", cincomment, coutcomment,
! 280: /*INYACC 14*/ "yacc", cincomment, coutcomment,
! 281: /*INAPL 15*/ "apl", ".lm", newline,
! 282: /*INMAKE 16*/ "make", ASINCOMMENT, newline,
! 283: /*INRI 17*/ "ri", riincomment, rioutcomment,
! 284: /*INTROFF 18*/ "troff",troffincomment,troffoutcomment,
! 285: /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment,
! 286: 0, 0, 0
! 287: };
! 288:
! 289: printerrors(look_at_subclass, errorc, errorv)
! 290: boolean look_at_subclass;
! 291: int errorc;
! 292: Eptr errorv[];
! 293: {
! 294: reg int i;
! 295: reg Eptr errorp;
! 296:
! 297: for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){
! 298: if (errorp->error_e_class == C_IGNORE)
! 299: continue;
! 300: if (look_at_subclass && errorp->error_s_class == C_DUPL)
! 301: continue;
! 302: printf("Error %d, (%s error) [%s], text = \"",
! 303: i,
! 304: class_table[errorp->error_e_class],
! 305: lang_table[errorp->error_language].lang_name);
! 306: wordvprint(stdout,errorp->error_lgtext,errorp->error_text);
! 307: printf("\"\n");
! 308: }
! 309: }
! 310:
! 311: wordvprint(fyle, wordc, wordv)
! 312: FILE *fyle;
! 313: int wordc;
! 314: char *wordv[];
! 315: {
! 316: int i;
! 317: char *sep = "";
! 318:
! 319: for(i = 0; i < wordc; i++)
! 320: if (wordv[i]) {
! 321: fprintf(fyle, "%s%s",sep,wordv[i]);
! 322: sep = " ";
! 323: }
! 324: }
! 325:
! 326: /*
! 327: * Given a string, parse it into a number of words, and build
! 328: * a wordc wordv combination pointing into it.
! 329: */
! 330: wordvbuild(string, r_wordc, r_wordv)
! 331: char *string;
! 332: int *r_wordc;
! 333: char ***r_wordv;
! 334: {
! 335: reg char *cp;
! 336: char **wordv;
! 337: int wordcount;
! 338: int wordindex;
! 339:
! 340: for (wordcount = 0, cp = string; *cp; wordcount++){
! 341: while (*cp && isspace(*cp))
! 342: cp++;
! 343: if (*cp == 0)
! 344: break;
! 345: while (!isspace(*cp))
! 346: cp++;
! 347: }
! 348: wordv = (char **)Calloc(wordcount + 1, sizeof (char *));
! 349: for (cp=string,wordindex=0; wordcount; wordindex++,--wordcount){
! 350: while (*cp && isspace(*cp))
! 351: cp++;
! 352: if (*cp == 0)
! 353: break;
! 354: wordv[wordindex] = cp;
! 355: while(!isspace(*cp))
! 356: cp++;
! 357: *cp++ = '\0';
! 358: }
! 359: if (wordcount != 0)
! 360: error("Initial miscount of the number of words in a line\n");
! 361: wordv[wordindex] = (char *)0;
! 362: #ifdef FULLDEBUG
! 363: for (wordcount = 0; wordcount < wordindex; wordcount++)
! 364: printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]);
! 365: printf("\n");
! 366: #endif
! 367: *r_wordc = wordindex;
! 368: *r_wordv = wordv;
! 369: }
! 370: /*
! 371: * Compare two 0 based wordvectors
! 372: */
! 373: int wordvcmp(wordv1, wordc, wordv2)
! 374: char **wordv1;
! 375: int wordc;
! 376: char **wordv2;
! 377: {
! 378: reg int i;
! 379: int back;
! 380: for (i = 0; i < wordc; i++){
! 381: if (wordv1[i] == 0 || wordv2[i] == 0)
! 382: return(-1);
! 383: if (back = strcmp(wordv1[i], wordv2[i])){
! 384: return(back);
! 385: }
! 386: }
! 387: return(0); /* they are equal */
! 388: }
! 389:
! 390: /*
! 391: * splice a 0 basedword vector onto the tail of a
! 392: * new wordv, allowing the first emptyhead slots to be empty
! 393: */
! 394: char **wordvsplice(emptyhead, wordc, wordv)
! 395: int emptyhead;
! 396: int wordc;
! 397: char **wordv;
! 398: {
! 399: reg char **nwordv;
! 400: int nwordc = emptyhead + wordc;
! 401: reg int i;
! 402:
! 403: nwordv = (char **)Calloc(nwordc, sizeof (char *));
! 404: for (i = 0; i < emptyhead; i++)
! 405: nwordv[i] = 0;
! 406: for(i = emptyhead; i < nwordc; i++){
! 407: nwordv[i] = wordv[i-emptyhead];
! 408: }
! 409: return(nwordv);
! 410: }
! 411: /*
! 412: * plural'ize and verb forms
! 413: */
! 414: static char *S = "s";
! 415: static char *N = "";
! 416: char *plural(n)
! 417: int n;
! 418: {
! 419: return( n > 1 ? S : N);
! 420: }
! 421: char *verbform(n)
! 422: int n;
! 423: {
! 424: return( n > 1 ? N : S);
! 425: }
! 426: