Annotation of 43BSDTahoe/ucb/error/errorpi.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that the above copyright notice and this paragraph are
        !             7:  * duplicated in all such forms and that any documentation,
        !             8:  * advertising materials, and other materials related to such
        !             9:  * distribution and use acknowledge that the software was developed
        !            10:  * by the University of California, Berkeley.  The name of the
        !            11:  * University may not be used to endorse or promote products derived
        !            12:  * from this software without specific prior written permission.
        !            13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            16:  */
        !            17: 
        !            18: #ifndef lint
        !            19: static char sccsid[] = "@(#)errorpi.c  5.3 (Berkeley) 6/29/88";
        !            20: #endif /* not lint */
        !            21: 
        !            22: #include <stdio.h>
        !            23: #include <ctype.h>
        !            24: #include "error.h"
        !            25: 
        !            26: extern char    *currentfilename;
        !            27: static char    *c_linenumber;
        !            28: static char    *unk_hdr[] = {"In", "program", "???"};
        !            29: static char    **c_header = &unk_hdr[0];
        !            30: 
        !            31: /*
        !            32:  *     Attempt to handle error messages produced by pi (and by pc)
        !            33:  *
        !            34:  *     problem #1:     There is no file name available when a file does not
        !            35:  *                     use a #include; this will have to be given to error
        !            36:  *                     in the command line.
        !            37:  *     problem #2:     pi doesn't always tell you what line number
        !            38:  *                     a error refers to; for example during the tree
        !            39:  *                     walk phase of code generation and error detection,
        !            40:  *                     an error can refer to "variable foo in procedure bletch"
        !            41:  *                     without giving a line number
        !            42:  *     problem #3:     line numbers, when available, are attached to
        !            43:  *                     the source line, along with the source line itself
        !            44:  *                     These line numbers must be extracted, and
        !            45:  *                     the source line thrown away.
        !            46:  *     problem #4:     Some error messages produce more than one line number
        !            47:  *                     on the same message.
        !            48:  *                     There are only two (I think):
        !            49:  *                             %s undefined on line%s
        !            50:  *                             %s improperly used on line%s
        !            51:  *                     here, the %s makes line plural or singular.
        !            52:  *
        !            53:  *     Here are the error strings used in pi version 1.2 that can refer
        !            54:  *     to a file name or line number:
        !            55:  *
        !            56:  *             Multiply defined label in case, lines %d and %d
        !            57:  *             Goto %s from line %d is into a structured statement
        !            58:  *             End matched %s on line %d
        !            59:  *             Inserted keyword end matching %s on line %d
        !            60:  *
        !            61:  *     Here are the general pi patterns recognized:
        !            62:  *     define piptr == -.*^-.*
        !            63:  *     define msg = .*
        !            64:  *     define digit = [0-9]
        !            65:  *     definename = .*
        !            66:  *     define date_format letter*3 letter*3 (digit | (digit digit)) 
        !            67:  *                     (digit | (digit digit)):digit*2 digit*4
        !            68:  *
        !            69:  *     {e,E} (piptr) (msg)     Encounter an error during textual scan
        !            70:  *     E {digit}* - (msg)      Have an error message that refers to a new line
        !            71:  *     E - msg                 Have an error message that refers to current
        !            72:  *                                     function, program or procedure
        !            73:  *     (date_format) (name):   When switch compilation files
        !            74:  *     ... (msg)               When refer to the previous line
        !            75:  *     'In' ('procedure'|'function'|'program') (name):
        !            76:  *                             pi is now complaining about 2nd pass errors.
        !            77:  *     
        !            78:  *     Here is the output from a compilation
        !            79:  *
        !            80:  *
        !            81:  *          2          var     i:integer;
        !            82:  *     e --------------^--- Inserted ';'
        !            83:  *     E 2 - All variables must be declared in one var part
        !            84:  *     E 5 - Include filename must end in .i
        !            85:  *     Mon Apr 21 15:56 1980  test.h:
        !            86:  *          2  begin
        !            87:  *     e ------^--- Inserted ';'
        !            88:  *     Mon Apr 21 16:06 1980  test.p:
        !            89:  *     E 2 - Function type must be specified
        !            90:  *          6  procedure foo(var x:real);
        !            91:  *     e ------^--- Inserted ';'
        !            92:  *     In function bletch:
        !            93:  *       E - No assignment to the function variable
        !            94:  *       w - variable x is never used
        !            95:  *     E 6 - foo is already defined in this block
        !            96:  *     In procedure foo:
        !            97:  *       w - variable x is neither used nor set
        !            98:  *          9          z : = 23;
        !            99:  *     E --------------^--- Undefined variable
        !           100:  *         10          y = [1];
        !           101:  *     e ----------------^--- Inserted ':'
        !           102:  *         13          z := 345.;
        !           103:  *     e -----------------------^--- Digits required after decimal point
        !           104:  *     E 10 - Constant set involved in non set context
        !           105:  *     E 11 - Type clash: real is incompatible with integer
        !           106:  *        ... Type of expression clashed with type of variable in assignment
        !           107:  *     E 12 - Parameter type not identical to type of var parameter x of foo
        !           108:  *     In program mung:
        !           109:  *       w - variable y is never used
        !           110:  *       w - type foo is never used
        !           111:  *       w - function bletch is never used
        !           112:  *       E - z undefined on lines 9 13
        !           113:  */
        !           114: char *Months[] = {
        !           115:        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        !           116:        "Jul", "Aug", "Sep", "Oct","Nov", "Dec",
        !           117:        0
        !           118: };
        !           119: char *Days[] = {
        !           120:        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 0
        !           121: };
        !           122: char *Piroutines[] = {
        !           123:                "program", "function", "procedure", 0
        !           124: };
        !           125: 
        !           126: 
        !           127: static boolean structured, multiple;
        !           128: 
        !           129: char *pi_Endmatched[] = {"End", "matched"};
        !           130: char *pi_Inserted[] = {"Inserted", "keyword", "end", "matching"};
        !           131: 
        !           132: char *pi_multiple[] = {"Mutiply", "defined", "label", "in", "case,", "line"};
        !           133: char *pi_structured[] = {"is", "into", "a", "structured", "statement"};
        !           134: 
        !           135: char *pi_und1[] = {"undefined", "on", "line"};
        !           136: char *pi_und2[] = {"undefined", "on", "lines"};
        !           137: char *pi_imp1[] = {"improperly", "used", "on", "line"};
        !           138: char *pi_imp2[] = {"improperly", "used", "on", "lines"};
        !           139: 
        !           140: boolean alldigits(string)
        !           141:        reg     char    *string;
        !           142: {
        !           143:        for (; *string && isdigit(*string); string++)
        !           144:                continue;
        !           145:        return(*string == '\0');
        !           146: }
        !           147: boolean instringset(member, set)
        !           148:                char    *member;
        !           149:        reg     char    **set;
        !           150: {
        !           151:        for(; *set; set++){
        !           152:                if (strcmp(*set, member) == 0)
        !           153:                        return(TRUE);
        !           154:        }
        !           155:        return(FALSE);
        !           156: }
        !           157: 
        !           158: boolean isdateformat(wordc, wordv)
        !           159:        int     wordc;
        !           160:        char    **wordv;
        !           161: {
        !           162:        return(
        !           163:                (wordc == 5)
        !           164:             && (instringset(wordv[0], Days))
        !           165:             && (instringset(wordv[1], Months))
        !           166:             && (alldigits(wordv[2]))
        !           167:             && (alldigits(wordv[4])) );
        !           168: }
        !           169: 
        !           170: boolean piptr(string)
        !           171:        reg     char    *string;
        !           172: {
        !           173:        if (*string != '-')
        !           174:                return(FALSE);
        !           175:        while (*string && *string == '-')
        !           176:                string++;
        !           177:        if (*string != '^')
        !           178:                return(FALSE);
        !           179:        string++;
        !           180:        while (*string && *string == '-')
        !           181:                string++;
        !           182:        return(*string == '\0');
        !           183: }
        !           184: 
        !           185: extern int     wordc;
        !           186: extern char    **wordv;
        !           187: 
        !           188: Errorclass pi()
        !           189: {
        !           190:        char    **nwordv;
        !           191: 
        !           192:        if (wordc < 2)
        !           193:                return (C_UNKNOWN);
        !           194:        if (   ( strlen(wordv[1]) == 1)
        !           195:            && ( (wordv[1][0] == 'e') || (wordv[1][0] == 'E') )
        !           196:            && ( piptr(wordv[2]) )
        !           197:        ) {
        !           198:                boolean longpiptr = 0;
        !           199:                /*
        !           200:                 *      We have recognized a first pass error of the form:
        !           201:                 *      letter ------^---- message
        !           202:                 *
        !           203:                 *      turn into an error message of the form:
        !           204:                 *
        !           205:                 *      file line 'pascal errortype' letter \n |---- message
        !           206:                 *      or of the form:
        !           207:                 *      file line letter |---- message
        !           208:                 *              when there are strlen("(*[pi]") or more
        !           209:                 *              preceding '-' on the error pointer.
        !           210:                 *
        !           211:                 *      Where the | is intended to be a down arrow, so that
        !           212:                 *      the pi error messages can be inserted above the
        !           213:                 *      line in error, instead of below.  (All of the other
        !           214:                 *      langauges put thier messages before the source line,
        !           215:                 *      instead of after it as does pi.)
        !           216:                 *
        !           217:                 *      where the pointer to the error has been truncated
        !           218:                 *      by 6 characters to account for the fact that
        !           219:                 *      the pointer points into a tab preceded input line.
        !           220:                 */
        !           221:                language = INPI;
        !           222:                (void)substitute(wordv[2], '^', '|');
        !           223:                longpiptr = position(wordv[2],'|') > (6+8);
        !           224:                nwordv = wordvsplice(longpiptr ? 2 : 4, wordc, wordv+1);
        !           225:                nwordv[0] = strsave(currentfilename);
        !           226:                nwordv[1] = strsave(c_linenumber);
        !           227:                if (!longpiptr){
        !           228:                        nwordv[2] = "pascal errortype";
        !           229:                        nwordv[3] = wordv[1];
        !           230:                        nwordv[4] = strsave("%%%\n");
        !           231:                        if (strlen(nwordv[5]) > (8-2))  /* this is the pointer */
        !           232:                                nwordv[5] += (8-2);     /* bump over 6 characters */
        !           233:                }
        !           234:                wordv = nwordv - 1;             /* convert to 1 based */
        !           235:                wordc += longpiptr ? 2 : 4;
        !           236:                return(C_TRUE);
        !           237:        }
        !           238:        if (   (wordc >= 4)
        !           239:            && (strlen(wordv[1]) == 1)
        !           240:            && ( (*wordv[1] == 'E') || (*wordv[1] == 'w') || (*wordv[1] == 'e') )
        !           241:            && (alldigits(wordv[2]))
        !           242:            && (strlen(wordv[3]) == 1)
        !           243:            && (wordv[3][0] == '-')
        !           244:        ){
        !           245:                /*
        !           246:                 *      Message of the form: letter linenumber - message
        !           247:                 *      Turn into form: filename linenumber letter - message
        !           248:                 */
        !           249:                language = INPI;
        !           250:                nwordv = wordvsplice(1, wordc, wordv + 1);
        !           251:                nwordv[0] = strsave(currentfilename);
        !           252:                nwordv[1] = wordv[2];
        !           253:                nwordv[2] = wordv[1];
        !           254:                c_linenumber = wordv[2];
        !           255:                wordc += 1;
        !           256:                wordv = nwordv - 1;
        !           257:                return(C_TRUE);
        !           258:        }
        !           259:        if (   (wordc >= 3)
        !           260:            && (strlen(wordv[1]) == 1)
        !           261:            && ( (*(wordv[1]) == 'E') || (*(wordv[1]) == 'w') || (*(wordv[1]) == 'e') )
        !           262:            && (strlen(wordv[2]) == 1)
        !           263:            && (wordv[2][0] == '-')
        !           264:        ) {
        !           265:                /*
        !           266:                 *      Message of the form: letter - message
        !           267:                 *      This happens only when we are traversing the tree
        !           268:                 *      during the second pass of pi, and discover semantic
        !           269:                 *      errors.
        !           270:                 *
        !           271:                 *      We have already (presumably) saved the header message
        !           272:                 *      and can now construct a nulled error message for the
        !           273:                 *      current file.
        !           274:                 *
        !           275:                 *      Turns into a message of the form:
        !           276:                 *      filename (header) letter - message
        !           277:                 *      
        !           278:                 *      First, see if it is a message referring to more than
        !           279:                 *      one line number.  Only of the form:
        !           280:                 *              %s undefined on line%s
        !           281:                 *              %s improperly used on line%s
        !           282:                 */
        !           283:                boolean undefined = 0;
        !           284:                int     wordindex;
        !           285: 
        !           286:                language = INPI;
        !           287:                if (    (undefined = (wordvcmp(wordv+2, 3, pi_und1) == 0) )
        !           288:                     || (undefined = (wordvcmp(wordv+2, 3, pi_und2) == 0) )
        !           289:                     || (wordvcmp(wordv+2, 4, pi_imp1) == 0)
        !           290:                     || (wordvcmp(wordv+2, 4, pi_imp2) == 0)
        !           291:                ){
        !           292:                        for (wordindex = undefined ? 5 : 6; wordindex <= wordc;
        !           293:                            wordindex++){
        !           294:                                nwordv = wordvsplice(2, undefined ? 2 : 3, wordv+1);
        !           295:                                nwordv[0] = strsave(currentfilename);
        !           296:                                nwordv[1] = wordv[wordindex];
        !           297:                                if (wordindex != wordc)
        !           298:                                        erroradd(undefined ? 4 : 5, nwordv,
        !           299:                                                C_TRUE, C_UNKNOWN);
        !           300:                        }
        !           301:                        wordc = undefined ? 4 : 5;
        !           302:                        wordv = nwordv - 1;
        !           303:                        return(C_TRUE);
        !           304:                }
        !           305: 
        !           306:                nwordv = wordvsplice(1+3, wordc, wordv+1);
        !           307:                nwordv[0] = strsave(currentfilename);
        !           308:                nwordv[1] = strsave(c_header[0]);
        !           309:                nwordv[2] = strsave(c_header[1]);
        !           310:                nwordv[3] = strsave(c_header[2]);
        !           311:                wordv = nwordv - 1;
        !           312:                wordc += 1 + 3;
        !           313:                return(C_THISFILE);
        !           314:        }
        !           315:        if (strcmp(wordv[1], "...") == 0){
        !           316:                /*
        !           317:                 *      have a continuation error message
        !           318:                 *      of the form: ... message
        !           319:                 *      Turn into form : filename linenumber message
        !           320:                 */
        !           321:                language = INPI;
        !           322:                nwordv = wordvsplice(1, wordc, wordv+1);
        !           323:                nwordv[0] = strsave(currentfilename);
        !           324:                nwordv[1] = strsave(c_linenumber);
        !           325:                wordv = nwordv - 1;
        !           326:                wordc += 1;
        !           327:                return(C_TRUE);
        !           328:        }
        !           329:        if(   (wordc == 6)
        !           330:           && (lastchar(wordv[6]) == ':')
        !           331:           && (isdateformat(5, wordv + 1))
        !           332:        ){
        !           333:                /*
        !           334:                 *      Have message that tells us we have changed files
        !           335:                 */
        !           336:                language = INPI;
        !           337:                currentfilename = strsave(wordv[6]);
        !           338:                clob_last(currentfilename, '\0');
        !           339:                return(C_SYNC);
        !           340:        }
        !           341:        if(   (wordc == 3)
        !           342:           && (strcmp(wordv[1], "In") == 0)
        !           343:           && (lastchar(wordv[3]) == ':')
        !           344:           && (instringset(wordv[2], Piroutines))
        !           345:        ) {
        !           346:                language = INPI;
        !           347:                c_header = wordvsplice(0, wordc, wordv+1);
        !           348:                return(C_SYNC);
        !           349:        }
        !           350:        /*
        !           351:         *      now, check for just the line number followed by the text
        !           352:         */
        !           353:        if (alldigits(wordv[1])){
        !           354:                language = INPI;
        !           355:                c_linenumber = wordv[1];
        !           356:                return(C_IGNORE);
        !           357:        }
        !           358:        /*
        !           359:         *      Attempt to match messages refering to a line number
        !           360:         *
        !           361:         *      Multiply defined label in case, lines %d and %d
        !           362:         *      Goto %s from line %d is into a structured statement
        !           363:         *      End matched %s on line %d
        !           364:         *      Inserted keyword end matching %s on line %d
        !           365:         */
        !           366:        multiple = structured = 0;
        !           367:        if (
        !           368:               ( (wordc == 6) && (wordvcmp(wordv+1, 2, pi_Endmatched) == 0))
        !           369:            || ( (wordc == 8) && (wordvcmp(wordv+1, 4, pi_Inserted) == 0))
        !           370:            || ( multiple = ((wordc == 9) && (wordvcmp(wordv+1,6, pi_multiple) == 0) ) )
        !           371:            || ( structured = ((wordc == 10) && (wordvcmp(wordv+6,5, pi_structured) == 0 ) ))
        !           372:        ){
        !           373:                language = INPI;
        !           374:                nwordv = wordvsplice(2, wordc, wordv+1);
        !           375:                nwordv[0] = strsave(currentfilename);
        !           376:                nwordv[1] = structured ? wordv [5] : wordv[wordc];
        !           377:                wordc += 2;
        !           378:                wordv = nwordv - 1;
        !           379:                if (!multiple)
        !           380:                        return(C_TRUE);
        !           381:                erroradd(wordc, nwordv, C_TRUE, C_UNKNOWN);
        !           382:                nwordv = wordvsplice(0, wordc, nwordv);
        !           383:                nwordv[1] = wordv[wordc - 2];
        !           384:                return(C_TRUE);
        !           385:        }
        !           386:        return(C_UNKNOWN);
        !           387: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.