1: static  char *sccsid = "@(#)errortouch.c	1.5 (Berkeley) 11/20/82";
   2: #include <stdio.h>
   3: #include <ctype.h>
   4: #include <sys/types.h>
   5: #include <sys/stat.h>
   6: #include <signal.h>
   7: #include "error.h"
   8: 
   9: /*
  10:  *	Iterate through errors
  11:  */
  12: #define EITERATE(p, fv, i)  for (p = fv[i]; p < fv[i+1]; p++)
  13: #define ECITERATE(ei, p, lb)    for (ei = lb; p = errors[ei],ei < nerrors; ei++)
  14: 
  15: #define FILEITERATE(fi, lb) for (fi = lb; fi <= nfiles; fi++)
  16: int touchstatus = Q_YES;
  17: 
  18: findfiles(nerrors, errors, r_nfiles, r_files)
  19:         int nerrors;
  20:     Eptr    *errors;
  21:         int *r_nfiles;
  22:     Eptr    ***r_files;
  23: {
  24:         int nfiles;
  25:     Eptr    **files;
  26: 
  27:         char    *name;
  28:     reg int ei;
  29:         int fi;
  30:     reg Eptr    errorp;
  31: 
  32:     nfiles = countfiles(errors);
  33: 
  34:     files = (Eptr**)Calloc(nfiles + 3, sizeof (Eptr*));
  35:     touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean));
  36:     /*
  37: 	 *	Now, partition off the error messages
  38: 	 *	into those that are synchronization, discarded or
  39: 	 *	not specific to any file, and those that were
  40: 	 *	nulled or true errors.
  41: 	 */
  42:     files[0] = &errors[0];
  43:     ECITERATE(ei, errorp, 0){
  44:         if ( ! (NOTSORTABLE(errorp->error_e_class)))
  45:             break;
  46:     }
  47:     /*
  48: 	 *	Now, and partition off all error messages
  49: 	 *	for a given file.
  50: 	 */
  51:     files[1] = &errors[ei];
  52:     touchedfiles[0] = touchedfiles[1] = FALSE;
  53:     name = "\1";
  54:     fi = 1;
  55:     ECITERATE(ei, errorp, ei){
  56:         if (   (errorp->error_e_class == C_NULLED)
  57:             || (errorp->error_e_class == C_TRUE) ){
  58:             if (strcmp(errorp->error_text[0], name) != 0){
  59:                 name = errorp->error_text[0];
  60:                 touchedfiles[fi] = FALSE;
  61:                 files[fi] = &errors[ei];
  62:                 fi++;
  63:             }
  64:         }
  65:     }
  66:     files[fi] = &errors[nerrors];
  67:     *r_nfiles = nfiles;
  68:     *r_files = files;
  69: }
  70: 
  71: int countfiles(errors)
  72:     Eptr    *errors;
  73: {
  74:     char    *name;
  75:     int ei;
  76:     reg Eptr    errorp;
  77: 
  78:     int nfiles;
  79:     nfiles = 0;
  80:     name = "\1";
  81:     ECITERATE(ei, errorp, 0){
  82:         if (SORTABLE(errorp->error_e_class)){
  83:             if (strcmp(errorp->error_text[0],name) != 0){
  84:                 nfiles++;
  85:                 name = errorp->error_text[0];
  86:             }
  87:         }
  88:     }
  89:     return(nfiles);
  90: }
  91: char    *class_table[] = {
  92:     /*C_UNKNOWN	0	*/    "Unknown",
  93:     /*C_IGNORE	1	*/ "ignore",
  94:     /*C_SYNC	2	*/   "synchronization",
  95:     /*C_DISCARD	3	*/    "discarded",
  96:     /*C_NONSPEC	4	*/    "non specific",
  97:     /*C_THISFILE	5	*/   "specific to this file",
  98:     /*C_NULLED	6	*/ "nulled",
  99:     /*C_TRUE	7	*/   "true",
 100:     /*C_DUPL	8	*/   "duplicated"
 101: };
 102: 
 103: int class_count[C_LAST - C_FIRST] = {0};
 104: 
 105: filenames(nfiles, files)
 106:     int nfiles;
 107:     Eptr    **files;
 108: {
 109:     reg int fi;
 110:         char    *sep = " ";
 111:     extern  char    *class_table[];
 112:         int someerrors;
 113: 
 114:     /*
 115: 	 *	first, simply dump out errors that
 116: 	 *	don't pertain to any file
 117: 	 */
 118:     someerrors = nopertain(files);
 119: 
 120:     if (nfiles){
 121:         someerrors++;
 122:         fprintf(stdout, terse
 123:             ? "%d file%s"
 124:             : "%d file%s contain%s errors",
 125:             nfiles, plural(nfiles), verbform(nfiles));
 126:         if (!terse){
 127:             FILEITERATE(fi, 1){
 128:                 fprintf(stdout, "%s\"%s\" (%d)",
 129:                     sep, (*files[fi])->error_text[0],
 130:                     files[fi+1] - files[fi]);
 131:                 sep = ", ";
 132:             }
 133:         }
 134:         fprintf(stdout, "\n");
 135:     }
 136:     if (!someerrors)
 137:         fprintf(stdout, "No errors.\n");
 138: }
 139: 
 140: /*
 141:  *	Dump out errors that don't pertain to any file
 142:  */
 143: int nopertain(files)
 144:     Eptr    **files;
 145: {
 146:     int type;
 147:     int someerrors = 0;
 148:     reg Eptr    *erpp;
 149:     reg Eptr    errorp;
 150: 
 151:     if (files[1] - files[0] <= 0)
 152:         return(0);
 153:     for(type = C_UNKNOWN; NOTSORTABLE(type); type++){
 154:         if (class_count[type] <= 0)
 155:             continue;
 156:         if (type > C_SYNC)
 157:             someerrors++;
 158:         if (terse){
 159:             fprintf(stdout, "\t%d %s errors NOT PRINTED\n",
 160:                 class_count[type], class_table[type]);
 161:         } else {
 162:             fprintf(stdout, "\n\t%d %s errors follow\n",
 163:                 class_count[type], class_table[type]);
 164:             EITERATE(erpp, files, 0){
 165:                 errorp = *erpp;
 166:                 if (errorp->error_e_class == type){
 167:                     errorprint(stdout, errorp, TRUE);
 168:                 }
 169:             }
 170:         }
 171:     }
 172:     return(someerrors);
 173: }
 174: 
 175: extern  boolean notouch;
 176: 
 177: boolean touchfiles(nfiles, files, r_edargc, r_edargv)
 178:     int nfiles;
 179:     Eptr    **files;
 180:     int *r_edargc;
 181:     char    ***r_edargv;
 182: {
 183:         char    *name;
 184:     reg Eptr    errorp;
 185:     reg int fi;
 186:     reg Eptr    *erpp;
 187:         int     ntrueerrors;
 188:         boolean     scribbled;
 189:         int     n_pissed_on;    /* # of file touched*/
 190:         int spread;
 191: 
 192:     FILEITERATE(fi, 1){
 193:         name = (*files[fi])->error_text[0];
 194:         spread = files[fi+1] - files[fi];
 195:         fprintf(stdout, terse
 196:             ? "\"%s\" has %d error%s, "
 197:             : "\nFile \"%s\" has %d error%s.\n"
 198:             , name ,spread ,plural(spread));
 199:         /*
 200: 		 *	First, iterate through all error messages in this file
 201: 		 *	to see how many of the error messages really will
 202: 		 *	get inserted into the file.
 203: 		 */
 204:         ntrueerrors = 0;
 205:         EITERATE(erpp, files, fi){
 206:             errorp = *erpp;
 207:             if (errorp->error_e_class == C_TRUE)
 208:                 ntrueerrors++;
 209:         }
 210:         fprintf(stdout, terse
 211:           ? "insert %d\n"
 212:           : "\t%d of these errors can be inserted into the file.\n",
 213:             ntrueerrors);
 214: 
 215:         hackfile(name, files, fi, ntrueerrors);
 216:     }
 217:     scribbled = FALSE;
 218:     n_pissed_on = 0;
 219:     FILEITERATE(fi, 1){
 220:         scribbled |= touchedfiles[fi];
 221:         n_pissed_on++;
 222:     }
 223:     if (scribbled){
 224:         /*
 225: 		 *	Construct an execv argument
 226: 		 */
 227:         execvarg(n_pissed_on, r_edargc, r_edargv);
 228:         return(TRUE);
 229:     } else {
 230:         if (!terse)
 231:             fprintf(stdout, "You didn't touch any files.\n");
 232:         return(FALSE);
 233:     }
 234: }
 235: 
 236: hackfile(name, files, ix, nerrors)
 237:     char    *name;
 238:     Eptr    **files;
 239:     int ix;
 240: {
 241:     boolean seen;
 242:     int errordest;  /* where errors go*/
 243: 
 244:     seen = preview(name, nerrors, files, ix);
 245: 
 246:     errordest = settotouch(name);
 247: 
 248:     if (errordest != TOSTDOUT)
 249:         touchedfiles[ix] = TRUE;
 250: 
 251:     if (seen && (errordest == TOSTDOUT))
 252:         return;
 253: 
 254:     diverterrors(name, errordest, files, ix, seen, nerrors);
 255: 
 256:     if (errordest == TOTHEFILE){
 257:         /*
 258: 		 *	overwrite the original file
 259: 		 */
 260:         writetouched(1);
 261:     }
 262: }
 263: 
 264: boolean preview(name, nerrors, files, ix)
 265:     char    *name;
 266:     int nerrors;
 267:     Eptr    **files;
 268:     int ix;
 269: {
 270:     int back;
 271:     reg Eptr    *erpp;
 272: 
 273:     if (!oktotouch(name))
 274:         return(false);
 275:     if (nerrors <= 0)
 276:         return(false);
 277:     back = false;
 278:     if(query){
 279:         switch(inquire(terse
 280:             ? "Preview? "
 281:             : "Do you want to preview the errors first? ")){
 282:         case Q_YES:
 283:         case Q_yes:
 284:             back = true;
 285:             EITERATE(erpp, files, ix){
 286:                 errorprint(stdout, *erpp, TRUE);
 287:             }
 288:             if (!terse)
 289:                 fprintf(stdout, "\n");
 290:         default:
 291:             break;
 292:         }
 293:     }
 294:     return(back);
 295: }
 296: 
 297: int settotouch(name)
 298:     char    *name;
 299: {
 300:     int dest = TOSTDOUT;
 301: 
 302:     if (query){
 303:         switch(touchstatus = inquire(terse
 304:             ? "Touch? "
 305:             : "Do you want to touch file \"%s\"? ",
 306:             name)){
 307:         case Q_NO:
 308:         case Q_no:
 309:             return(dest);
 310:         default:
 311:             break;
 312:         }
 313:     }
 314: 
 315:     switch(probethisfile(name)){
 316:     case F_NOTREAD:
 317:         dest = TOSTDOUT;
 318:         fprintf(stdout, terse
 319:             ? "\"%s\" unreadable\n"
 320:             : "File \"%s\" is unreadable\n",
 321:             name);
 322:         break;
 323:     case F_NOTWRITE:
 324:         dest = TOSTDOUT;
 325:         fprintf(stdout, terse
 326:             ? "\"%s\" unwritable\n"
 327:             : "File \"%s\" is unwritable\n",
 328:             name);
 329:         break;
 330:     case F_NOTEXIST:
 331:         dest = TOSTDOUT;
 332:         fprintf(stdout, terse
 333:             ? "\"%s\" not found\n"
 334:             : "Can't find file \"%s\" to insert error messages into.\n",
 335:             name);
 336:         break;
 337:     default:
 338:         dest = edit(name) ? TOSTDOUT : TOTHEFILE;
 339:         break;
 340:     }
 341:     return(dest);
 342: }
 343: 
 344: diverterrors(name, dest, files, ix, seen, nterrors)
 345:     char    *name;
 346:     int dest;
 347:     Eptr    **files;
 348:     int ix;
 349:     boolean seen;
 350:     int nterrors;
 351: {
 352:     int nerrors;
 353:     reg Eptr    *erpp;
 354:     reg Eptr    errorp;
 355: 
 356:     nerrors = files[ix+1] - files[ix];
 357: 
 358:     if (   (nerrors != nterrors)
 359:         && (!seen) ){
 360:         fprintf(stdout, terse
 361:             ? "Uninserted errors\n"
 362:             : ">>Uninserted errors for file \"%s\" follow.\n",
 363:             name);
 364:     }
 365: 
 366:     EITERATE(erpp, files, ix){
 367:         errorp = *erpp;
 368:         if (errorp->error_e_class != C_TRUE){
 369:             if (seen || touchstatus == Q_NO)
 370:                 continue;
 371:             errorprint(stdout, errorp, TRUE);
 372:             continue;
 373:         }
 374:         switch (dest){
 375:         case TOSTDOUT:
 376:             if (seen || touchstatus == Q_NO)
 377:                 continue;
 378:             errorprint(stdout,errorp, TRUE);
 379:             break;
 380:         case TOTHEFILE:
 381:             insert(errorp->error_line);
 382:             text(errorp, FALSE);
 383:             break;
 384:         }
 385:     }
 386: }
 387: 
 388: int oktotouch(filename)
 389:     char    *filename;
 390: {
 391:     extern      char    *suffixlist;
 392:     reg char    *src;
 393:     reg char    *pat;
 394:             char    *osrc;
 395: 
 396:     pat = suffixlist;
 397:     if (pat == 0)
 398:         return(0);
 399:     if (*pat == '*')
 400:         return(1);
 401:     while (*pat++ != '.')
 402:         continue;
 403:     --pat;      /* point to the period */
 404: 
 405:     for (src = &filename[strlen(filename)], --src;
 406:          (src > filename) && (*src != '.'); --src)
 407:         continue;
 408:     if (*src != '.')
 409:         return(0);
 410: 
 411:     for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++){
 412:         for (;   *src           /* not at end of the source */
 413:               && *pat           /* not off end of pattern */
 414:               && *pat != '.'        /* not off end of sub pattern */
 415:               && *pat != '*'        /* not wild card */
 416:               && *src == *pat;      /* and equal... */
 417:               src++, pat++)
 418:             continue;
 419:         if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*'))
 420:             return(1);
 421:         if (*src != 0 && *pat == '*')
 422:             return(1);
 423:         while (*pat && *pat != '.')
 424:             pat++;
 425:         if (! *pat)
 426:             return(0);
 427:     }
 428:     return(0);
 429: }
 430: /*
 431:  *	Construct an execv argument
 432:  *	We need 1 argument for the editor's name
 433:  *	We need 1 argument for the initial search string
 434:  *	We need n_pissed_on arguments for the file names
 435:  *	We need 1 argument that is a null for execv.
 436:  *	The caller fills in the editor's name.
 437:  *	We fill in the initial search string.
 438:  *	We fill in the arguments, and the null.
 439:  */
 440: execvarg(n_pissed_on, r_argc, r_argv)
 441:     int n_pissed_on;
 442:     int *r_argc;
 443:     char    ***r_argv;
 444: {
 445:     Eptr    p;
 446:     char    *sep;
 447:     int fi;
 448: 
 449:     (*r_argv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *));
 450:     (*r_argc) =  n_pissed_on + 2;
 451:     (*r_argv)[1] = "+1;/###/";
 452:     n_pissed_on = 2;
 453:     if (!terse){
 454:         fprintf(stdout, "You touched file(s):");
 455:         sep = " ";
 456:     }
 457:     FILEITERATE(fi, 1){
 458:         if (!touchedfiles[fi])
 459:             continue;
 460:         p = *(files[fi]);
 461:         if (!terse){
 462:             fprintf(stdout,"%s\"%s\"", sep, p->error_text[0]);
 463:             sep = ", ";
 464:         }
 465:         (*r_argv)[n_pissed_on++] = p->error_text[0];
 466:     }
 467:     if (!terse)
 468:         fprintf(stdout, "\n");
 469:     (*r_argv)[n_pissed_on] = 0;
 470: }
 471: 
 472: FILE    *o_touchedfile; /* the old file */
 473: FILE    *n_touchedfile; /* the new file */
 474: char    *o_name;
 475: char    n_name[64];
 476: char    *canon_name = "/tmp/ErrorXXXXXX";
 477: int o_lineno;
 478: int n_lineno;
 479: boolean tempfileopen = FALSE;
 480: /*
 481:  *	open the file; guaranteed to be both readable and writable
 482:  *	Well, if it isn't, then return TRUE if something failed
 483:  */
 484: boolean edit(name)
 485:     char    *name;
 486: {
 487:     o_name = name;
 488:     if ( (o_touchedfile = fopen(name, "r")) == NULL){
 489:         fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n",
 490:             processname, name);
 491:         return(TRUE);
 492:     }
 493:     (void)strcpy(n_name, canon_name);
 494:     (void)mktemp(n_name);
 495:     if ( (n_touchedfile = fopen(n_name, "w")) == NULL){
 496:         fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n",
 497:             processname, name);
 498:         return(TRUE);
 499:     }
 500:     tempfileopen = TRUE;
 501:     n_lineno = 0;
 502:     o_lineno = 0;
 503:     return(FALSE);
 504: }
 505: /*
 506:  *	Position to the line (before, after) the line given by place
 507:  */
 508: char    edbuf[BUFSIZ];
 509: insert(place)
 510:     int place;
 511: {
 512:     --place;    /* always insert messages before the offending line*/
 513:     for(; o_lineno < place; o_lineno++, n_lineno++){
 514:         if(fgets(edbuf, BUFSIZ, o_touchedfile) == NULL)
 515:             return;
 516:         fputs(edbuf, n_touchedfile);
 517:     }
 518: }
 519: 
 520: text(p, use_all)
 521:     reg Eptr    p;
 522:         boolean use_all;
 523: {
 524:     int offset = use_all ? 0 : 2;
 525: 
 526:     fputs(lang_table[p->error_language].lang_incomment, n_touchedfile);
 527:     fprintf(n_touchedfile, "%d [%s] ",
 528:         p->error_line,
 529:         lang_table[p->error_language].lang_name);
 530:     wordvprint(n_touchedfile, p->error_lgtext-offset, p->error_text+offset);
 531:     fputs(lang_table[p->error_language].lang_outcomment,n_touchedfile);
 532:     n_lineno++;
 533: }
 534: 
 535: /*
 536:  *	write the touched file to its temporary copy,
 537:  *	then bring the temporary in over the local file
 538:  */
 539: writetouched(overwrite)
 540:     int overwrite;
 541: {
 542:     reg int nread;
 543:     reg FILE    *localfile;
 544:     reg FILE    *tmpfile;
 545:         int botch;
 546:         int oktorm;
 547: 
 548:     botch = 0;
 549:     oktorm = 1;
 550:     while((nread = fread(edbuf, 1, sizeof(edbuf), o_touchedfile)) != NULL){
 551:         if (nread != fwrite(edbuf, 1, nread, n_touchedfile)){
 552:             /*
 553: 			 *	Catastrophe in temporary area: file system full?
 554: 			 */
 555:             botch = 1;
 556:             fprintf(stderr,
 557:               "%s: write failure: No errors inserted in \"%s\"\n",
 558:               processname, o_name);
 559:         }
 560:     }
 561:     fclose(n_touchedfile);
 562:     fclose(o_touchedfile);
 563:     /*
 564: 	 *	Now, copy the temp file back over the original
 565: 	 *	file, thus preserving links, etc
 566: 	 */
 567:     if (botch == 0 && overwrite){
 568:         botch = 0;
 569:         localfile = NULL;
 570:         tmpfile = NULL;
 571:         if ((localfile = fopen(o_name, "w")) == NULL){
 572:             fprintf(stderr,
 573:                 "%s: Can't open file \"%s\" to overwrite.\n",
 574:                 processname, o_name);
 575:             botch++;
 576:         }
 577:         if ((tmpfile = fopen(n_name, "r")) == NULL){
 578:             fprintf(stderr, "%s: Can't open file \"%s\" to read.\n",
 579:                 processname, n_name);
 580:             botch++;
 581:         }
 582:         if (!botch)
 583:             oktorm = mustoverwrite(localfile, tmpfile);
 584:         if (localfile != NULL)
 585:             fclose(localfile);
 586:         if (tmpfile != NULL)
 587:             fclose(tmpfile);
 588:     }
 589:     if (oktorm == 0){
 590:         fprintf(stderr, "%s: Catastrophe: A copy of \"%s\: was saved in \"%s\"\n",
 591:             processname, o_name, n_name);
 592:         exit(1);
 593:     }
 594:     /*
 595: 	 *	Kiss the temp file good bye
 596: 	 */
 597:     unlink(n_name);
 598:     tempfileopen = FALSE;
 599:     return(TRUE);
 600: }
 601: /*
 602:  *	return 1 if the tmpfile can be removed after writing it out
 603:  */
 604: int mustoverwrite(preciousfile, tmpfile)
 605:     FILE    *preciousfile;
 606:     FILE    *tmpfile;
 607: {
 608:     int nread;
 609: 
 610:     while((nread = fread(edbuf, 1, sizeof(edbuf), tmpfile)) != NULL){
 611:         if (mustwrite(edbuf, nread, preciousfile) == 0)
 612:             return(0);
 613:     }
 614:     return(1);
 615: }
 616: /*
 617:  *	return 0 on catastrophe
 618:  */
 619: mustwrite(base, n, preciousfile)
 620:     char    *base;
 621:     int n;
 622:     FILE    *preciousfile;
 623: {
 624:     int nwrote;
 625: 
 626:     if (n <= 0)
 627:         return(1);
 628:     nwrote = fwrite(base, 1, n, preciousfile);
 629:     if (nwrote == n)
 630:         return(1);
 631:     perror(processname);
 632:     switch(inquire(terse
 633:         ? "Botch overwriting: retry? "
 634:         : "Botch overwriting the source file: retry? ")){
 635:     case Q_YES:
 636:     case Q_yes:
 637:         mustwrite(base + nwrote, n - nwrote, preciousfile);
 638:         return(1);
 639:     case Q_NO:
 640:     case Q_no:
 641:         switch(inquire("Are you sure? ")){
 642:         case Q_YES:
 643:         case Q_yes:
 644:             return(0);
 645:         case Q_NO:
 646:         case Q_no:
 647:             mustwrite(base + nwrote, n - nwrote, preciousfile);
 648:             return(1);
 649:         }
 650:     }
 651: }
 652: 
 653: onintr()
 654: {
 655:     switch(inquire(terse
 656:         ? "\nContinue? "
 657:         : "\nInterrupt: Do you want to continue? ")){
 658:     case Q_YES:
 659:     case Q_yes:
 660:         signal(SIGINT, onintr);
 661:         return;
 662:     default:
 663:         if (tempfileopen){
 664:             /*
 665: 			 *	Don't overwrite the original file!
 666: 			 */
 667:             writetouched(0);
 668:         }
 669:         exit(1);
 670:     }
 671:     /*NOTREACHED*/
 672: }
 673: 
 674: errorprint(place, errorp, print_all)
 675:     FILE    *place;
 676:     Eptr    errorp;
 677:     boolean print_all;
 678: {
 679:     int offset = print_all ? 0 : 2;
 680: 
 681:     if (errorp->error_e_class == C_IGNORE)
 682:         return;
 683:     fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name);
 684:     wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset);
 685:     putc('\n', place);
 686: }
 687: 
 688: int inquire(fmt, a1, a2)
 689:     char    *fmt;
 690:     /*VARARGS1*/
 691: {
 692:     char    buffer[128];
 693:     for(;;){
 694:         do{
 695:             fflush(stdout);
 696:             fprintf(stderr, fmt, a1, a2);
 697:             fflush(stderr);
 698:         } while (fgets(buffer, 127, queryfile) == NULL);
 699:         switch(buffer[0]){
 700:         case 'Y':   return(Q_YES);
 701:         case 'y':   return(Q_yes);
 702:         case 'N':   return(Q_NO);
 703:         case 'n':   return(Q_no);
 704:         default:    fprintf(stderr, "Yes or No only!\n");
 705:         }
 706:     }
 707: }
 708: 
 709: int probethisfile(name)
 710:     char    *name;
 711: {
 712:     struct stat statbuf;
 713:     if (stat(name, &statbuf) < 0)
 714:         return(F_NOTEXIST);
 715:     if((statbuf.st_mode & S_IREAD) == 0)
 716:         return(F_NOTREAD);
 717:     if((statbuf.st_mode & S_IWRITE) == 0)
 718:         return(F_NOTWRITE);
 719:     return(F_TOUCHIT);
 720: }

Defined functions

countfiles defined in line 71; used 1 times
  • in line 32
diverterrors defined in line 344; used 1 times
edit defined in line 484; used 1 times
errorprint defined in line 674; used 4 times
execvarg defined in line 440; used 1 times
filenames defined in line 105; used 1 times
findfiles defined in line 18; used 1 times
hackfile defined in line 236; used 1 times
inquire defined in line 688; used 7 times
insert defined in line 509; used 1 times
mustoverwrite defined in line 604; used 1 times
mustwrite defined in line 619; used 3 times
nopertain defined in line 143; used 1 times
oktotouch defined in line 388; used 1 times
onintr defined in line 653; used 4 times
preview defined in line 264; used 1 times
probethisfile defined in line 709; used 2 times
settotouch defined in line 297; used 1 times
text defined in line 520; used 1 times
touchfiles defined in line 177; used 1 times
writetouched defined in line 539; used 2 times

Defined variables

canon_name defined in line 476; used 1 times
class_count defined in line 103; used 15 times
class_table defined in line 91; used 7 times
edbuf defined in line 508; used 8 times
n_lineno defined in line 478; used 3 times
n_name defined in line 475; used 7 times
o_lineno defined in line 477; used 3 times
o_name defined in line 474; used 5 times
sccsid defined in line 1; never used
tempfileopen defined in line 479; used 3 times
touchstatus defined in line 16; used 3 times

Defined macros

ECITERATE defined in line 13; used 3 times
EITERATE defined in line 12; used 4 times
FILEITERATE defined in line 15; used 4 times
Last modified: 1983-06-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1924
Valid CSS Valid XHTML 1.0 Strict