Annotation of cci/usr/src/ucb/error/errorpi.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)errorpi.c   1.3 (Berkeley) 7/2/83";
                      2: #include <stdio.h>
                      3: #include <ctype.h>
                      4: #include "error.h"
                      5: 
                      6: extern char    *currentfilename;
                      7: static char    *c_linenumber;
                      8: static char    *unk_hdr[] = {"In", "program", "???"};
                      9: static char    **c_header = &unk_hdr[0];
                     10: 
                     11: /*
                     12:  *     Attempt to handle error messages produced by pi (and by pc)
                     13:  *
                     14:  *     problem #1:     There is no file name available when a file does not
                     15:  *                     use a #include; this will have to be given to error
                     16:  *                     in the command line.
                     17:  *     problem #2:     pi doesn't always tell you what line number
                     18:  *                     a error refers to; for example during the tree
                     19:  *                     walk phase of code generation and error detection,
                     20:  *                     an error can refer to "variable foo in procedure bletch"
                     21:  *                     without giving a line number
                     22:  *     problem #3:     line numbers, when available, are attached to
                     23:  *                     the source line, along with the source line itself
                     24:  *                     These line numbers must be extracted, and
                     25:  *                     the source line thrown away.
                     26:  *     problem #4:     Some error messages produce more than one line number
                     27:  *                     on the same message.
                     28:  *                     There are only two (I think):
                     29:  *                             %s undefined on line%s
                     30:  *                             %s improperly used on line%s
                     31:  *                     here, the %s makes line plural or singular.
                     32:  *
                     33:  *     Here are the error strings used in pi version 1.2 that can refer
                     34:  *     to a file name or line number:
                     35:  *
                     36:  *             Multiply defined label in case, lines %d and %d
                     37:  *             Goto %s from line %d is into a structured statement
                     38:  *             End matched %s on line %d
                     39:  *             Inserted keyword end matching %s on line %d
                     40:  *
                     41:  *     Here are the general pi patterns recognized:
                     42:  *     define piptr == -.*^-.*
                     43:  *     define msg = .*
                     44:  *     define digit = [0-9]
                     45:  *     definename = .*
                     46:  *     define date_format letter*3 letter*3 (digit | (digit digit)) 
                     47:  *                     (digit | (digit digit)):digit*2 digit*4
                     48:  *
                     49:  *     {e,E} (piptr) (msg)     Encounter an error during textual scan
                     50:  *     E {digit}* - (msg)      Have an error message that refers to a new line
                     51:  *     E - msg                 Have an error message that refers to current
                     52:  *                                     function, program or procedure
                     53:  *     (date_format) (name):   When switch compilation files
                     54:  *     ... (msg)               When refer to the previous line
                     55:  *     'In' ('procedure'|'function'|'program') (name):
                     56:  *                             pi is now complaining about 2nd pass errors.
                     57:  *     
                     58:  *     Here is the output from a compilation
                     59:  *
                     60:  *
                     61:  *          2          var     i:integer;
                     62:  *     e --------------^--- Inserted ';'
                     63:  *     E 2 - All variables must be declared in one var part
                     64:  *     E 5 - Include filename must end in .i
                     65:  *     Mon Apr 21 15:56 1980  test.h:
                     66:  *          2  begin
                     67:  *     e ------^--- Inserted ';'
                     68:  *     Mon Apr 21 16:06 1980  test.p:
                     69:  *     E 2 - Function type must be specified
                     70:  *          6  procedure foo(var x:real);
                     71:  *     e ------^--- Inserted ';'
                     72:  *     In function bletch:
                     73:  *       E - No assignment to the function variable
                     74:  *       w - variable x is never used
                     75:  *     E 6 - foo is already defined in this block
                     76:  *     In procedure foo:
                     77:  *       w - variable x is neither used nor set
                     78:  *          9          z : = 23;
                     79:  *     E --------------^--- Undefined variable
                     80:  *         10          y = [1];
                     81:  *     e ----------------^--- Inserted ':'
                     82:  *         13          z := 345.;
                     83:  *     e -----------------------^--- Digits required after decimal point
                     84:  *     E 10 - Constant set involved in non set context
                     85:  *     E 11 - Type clash: real is incompatible with integer
                     86:  *        ... Type of expression clashed with type of variable in assignment
                     87:  *     E 12 - Parameter type not identical to type of var parameter x of foo
                     88:  *     In program mung:
                     89:  *       w - variable y is never used
                     90:  *       w - type foo is never used
                     91:  *       w - function bletch is never used
                     92:  *       E - z undefined on lines 9 13
                     93:  */
                     94: char *Months[] = {
                     95:        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                     96:        "Jul", "Aug", "Sep", "Oct","Nov", "Dec",
                     97:        0
                     98: };
                     99: char *Days[] = {
                    100:        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 0
                    101: };
                    102: char *Piroutines[] = {
                    103:                "program", "function", "procedure", 0
                    104: };
                    105: 
                    106: 
                    107: static boolean structured, multiple;
                    108: 
                    109: char *pi_Endmatched[] = {"End", "matched"};
                    110: char *pi_Inserted[] = {"Inserted", "keyword", "end", "matching"};
                    111: 
                    112: char *pi_multiple[] = {"Mutiply", "defined", "label", "in", "case,", "line"};
                    113: char *pi_structured[] = {"is", "into", "a", "structured", "statement"};
                    114: 
                    115: char *pi_und1[] = {"undefined", "on", "line"};
                    116: char *pi_und2[] = {"undefined", "on", "lines"};
                    117: char *pi_imp1[] = {"improperly", "used", "on", "line"};
                    118: char *pi_imp2[] = {"improperly", "used", "on", "lines"};
                    119: 
                    120: boolean alldigits(string)
                    121:        reg     char    *string;
                    122: {
                    123:        for (; *string && isdigit(*string); string++)
                    124:                continue;
                    125:        return(*string == '\0');
                    126: }
                    127: boolean instringset(member, set)
                    128:                char    *member;
                    129:        reg     char    **set;
                    130: {
                    131:        for(; *set; set++){
                    132:                if (strcmp(*set, member) == 0)
                    133:                        return(TRUE);
                    134:        }
                    135:        return(FALSE);
                    136: }
                    137: 
                    138: boolean isdateformat(wordc, wordv)
                    139:        int     wordc;
                    140:        char    **wordv;
                    141: {
                    142:        return(
                    143:                (wordc == 5)
                    144:             && (instringset(wordv[0], Days))
                    145:             && (instringset(wordv[1], Months))
                    146:             && (alldigits(wordv[2]))
                    147:             && (alldigits(wordv[4])) );
                    148: }
                    149: 
                    150: boolean piptr(string)
                    151:        reg     char    *string;
                    152: {
                    153:        if (*string != '-')
                    154:                return(FALSE);
                    155:        while (*string && *string == '-')
                    156:                string++;
                    157:        if (*string != '^')
                    158:                return(FALSE);
                    159:        string++;
                    160:        while (*string && *string == '-')
                    161:                string++;
                    162:        return(*string == '\0');
                    163: }
                    164: 
                    165: extern int     wordc;
                    166: extern char    **wordv;
                    167: 
                    168: Errorclass pi()
                    169: {
                    170:        char    **nwordv;
                    171: 
                    172:        if (wordc < 2)
                    173:                return (C_UNKNOWN);
                    174:        if (   ( strlen(wordv[1]) == 1)
                    175:            && ( (wordv[1][0] == 'e') || (wordv[1][0] == 'E') )
                    176:            && ( piptr(wordv[2]) )
                    177:        ) {
                    178:                boolean longpiptr = 0;
                    179:                /*
                    180:                 *      We have recognized a first pass error of the form:
                    181:                 *      letter ------^---- message
                    182:                 *
                    183:                 *      turn into an error message of the form:
                    184:                 *
                    185:                 *      file line 'pascal errortype' letter \n |---- message
                    186:                 *      or of the form:
                    187:                 *      file line letter |---- message
                    188:                 *              when there are strlen("(*[pi]") or more
                    189:                 *              preceding '-' on the error pointer.
                    190:                 *
                    191:                 *      Where the | is intended to be a down arrow, so that
                    192:                 *      the pi error messages can be inserted above the
                    193:                 *      line in error, instead of below.  (All of the other
                    194:                 *      langauges put thier messages before the source line,
                    195:                 *      instead of after it as does pi.)
                    196:                 *
                    197:                 *      where the pointer to the error has been truncated
                    198:                 *      by 6 characters to account for the fact that
                    199:                 *      the pointer points into a tab preceded input line.
                    200:                 */
                    201:                language = INPI;
                    202:                (void)substitute(wordv[2], '^', '|');
                    203:                longpiptr = position(wordv[2],'|') > (6+8&�&���2��$&�
                    204: �_Gs辿_Gs��&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/*
                    205:  * C object code impr-- third part
                    206:  */
                    207: 
                    208: #include "c2.h"
                    209: #include <stdio.h>
                    210: #include <ctype.h>
                    211: 
                    212: #define NUSE 6
                    213: struct node *uses[NUSE]; /* for backwards flow analysis */
                    214: char *lastrand; /* last operand of instruction */
                    215: char *findcon();
                    216: 
                    217: ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
                    218:        register int log;
                    219:        if (n==0 || n&(n-1)) return(-1); log=0;
                    220:        for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
                    221: }
                    222: 
                    223: equop(p1, p2)
                    224: register struct node *p1, *p2;
                    225: {
                    226:        register char *cp1, *cp2;
                    227: 
                    228:        if (p1->op != p2->op || p1->subop != p2->subop)
                    229:                return(0);
                    230:        if (p1->op>0 && p1->op<MOV)
                    231:                return(0);
                    232:        if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
                    233:        cp1 = p1->code;
                    234:        cp2 = p2->code;
                    235:        if (cp1==0 && cp2==0)
                    236:                return(1);
                    237:        if (cp1==0 || cp2==0)
                    238:                return(0);
                    239:        while (*cp1 == *cp2++)
                    240:                if (*cp1++ == 0)
                    241:                        return(1);
                    242:        return(0);
                    243: }
                    244: 
                    245: delnode(p) register struct node *p; {
                    246:        p->back->forw = p->forw;
                    247:        p->forw->back = p->back;
                    248: }
                    249: 
                    250: decref(p)
                    251: register struct node *p;
                    252: {
                    253:        if (p && --p->refc <= 0) {
                    254:                nrlab++; nchange++;
                    255:                delnod;
                    256:        }
                    257: }
                    258: 
                    259: struct node *
                    260: nonlab(ap)
                    261: struct node *ap;
                    262: {
                    263:        register struct node *p;
                    264: 
                    265:        p = ap;
                    266:        while (p && p->op==LABEL)
                    267:                p = p->forw;
                    268:        return(p);
                    269: }
                    270: 
                    271: clearuse() {
                    272:        register struct node **i;
                    273:        for (i=uses+NUSE; i>uses;) *--i=0;
                    274: }
                    275: 
                    276: clearreg() {
                    277:        register char **i;
                    278:        for (i=regs+NREG; i>regs;){ **--i=0; **i=0; }
                    279:        conloc[0] = 0; ccloc[0] = 0;
                    280: }
                    281: 
                    282: savereg(ai, s, type)
                    283: register char *s;
                    284: {
                    285:        register char *p, *sp;
                    286: 
                    287:        sp = p = regs[ai];
                    288:        /* if any indexing, must be parameter or local */
                    289:        /* indirection (as in "*-4(fp)") is ok, however */
                    290:        *p++ = type;
                    291:        while (*p++ = *s)
                    292:                if (*s=='[' || *s++=='(' && *s!='f') {*sp = 0; return;}
                    293: }
                    294: 
                    295: dest(s,type, ccflg)
                    296: register char *s;
                    297: {
                    298:        register int i;
                    299: 
                    300:        if ((i = isreg(s)) >= 0) {
                    301:                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
                    302:        }
                    303:        for (i=NREG; --i>=0;)
                    304:                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
                    305:                        *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
                    306:        while ((i = findrand(s,0)) >= 0) /* previous values (wordc == 6) && (wordvcmp(wordv+1, 2, pi_Endmatched) == 0))
                    307:            || ( (wordc == 8) && (wordvcmp(wordv+1, 4, pi_Inserted) == 0))
                    308:            || ( multiple = ((wordc == 9) && (wordvcmp(wordv+1,6, pi_multiple) == 0) ) )
                    309:            || ( structured = ((wordc == 10) && (wordvcmp(wordv+6,5, pi_structured) == 0 ) ))
                    310:        ){
                    311:                language = INPI;
                    312:                nwordv = wordvsplice(2, wordc, wordv+1);
                    313:                nwordv[0] = strsave(currentfilename);
                    314:                nwordv[1] = structured ? wordv [5] : wordv[wordc];
                    315:                wordc += 2;
                    316:                wordv = nwordv - 1;
                    317:                if (!multiple)
                    318:                        return(C_TRUE);
                    319:                erroradd(wordc, nwordv, C_TRUE, C_UNKNOWN);
                    320:                nwordv = wordvsplice(0, wordc, nwordv);
                    321:                nwordv[1] = wordv[wordc - 2];
                    322:                return(C_TRUE);
                    323:        }
                    324:        return(C_UNKNOWN);
                    325: }

unix.superglobalmegacorp.com

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