# 2.11BSD#431 - /usr/src/ucb/error/errorpi.c

##### Functions

    alldigits         X
    instringset       X
    isdateformat      X
    pi                X
    piptr             X

##### Variables

    Days              X
    Months            X
    Piroutines        X
    pi_Endmatched     X
    pi_Inserted       X
    pi_imp1           X
    pi_imp2           X
    pi_multiple       X
    pi_structured     X
    pi_und1           X
    pi_und2           X

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

#### Defined functions

alldigits defined in line 129; used 4 times

- in line 155-156(2), 230, 342

instringset defined in line 136; used 3 times

- in line 153-154(2), 333

isdateformat defined in line 147; used 1 times

- in line 320

pi defined in line 177; used 2 times

- in /usr/src/ucb/error/errorinput.c line 31, 68

piptr defined in line 159; used 1 times

- in line 185

#### Defined variables

Days defined in line 108; used 1 times

- in line 153

Months defined in line 103; used 1 times

- in line 154

Piroutines defined in line 111; used 1 times

- in line 333

c_header defined in line 18; used 4 times

- in line 297-299(3), 336

c_linenumber defined in line 16; used 4 times

- in line 215, 243, 313, 344

multiple defined in line 116; used 3 times

- in line 355-359(2), 368

pi_Endmatched defined in line 118; used 1 times

- in line 357

pi_Inserted defined in line 119; used 1 times

- in line 358

pi_imp1 defined in line 126; used 1 times

- in line 278

pi_imp2 defined in line 127; used 1 times

- in line 279

pi_multiple defined in line 121; used 1 times

- in line 359

pi_structured defined in line 122; used 1 times

- in line 360

pi_und1 defined in line 124; used 1 times

- in line 276

pi_und2 defined in line 125; used 1 times

- in line 277

sccsid defined in line 8; never used
structured defined in line 116; used 3 times

- in line 355-365(3)

unk_hdr defined in line 17; used 1 times

- in line 18

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1528 |