[BACK]Return to subr.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / error

Annotation of src/usr.bin/error/subr.c, Revision 1.7

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