Annotation of researchv10no/cmd/error/errortouch.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)errortouch.c        1.2 (Berkeley) 10/16/80";
        !             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: findfiles(nerrors, errors, r_nfiles, r_files)
        !            10:        int     nerrors;
        !            11:        struct  error_desc      **errors;
        !            12:        int     *r_nfiles;
        !            13:        struct  error_desc      ****r_files;
        !            14: {
        !            15:                        int     nfiles;
        !            16:        struct  error_desc      ***files;
        !            17: 
        !            18:                        char    *currentfilename;
        !            19:        register        int     errorindex;
        !            20:                        int     fileindex;
        !            21:        register        struct  error_desc      *errorp;
        !            22:        /*
        !            23:         *      First, go through and count all of the filenames
        !            24:         */
        !            25:        for (errorp = errors[errorindex = 0],nfiles = 0, currentfilename = "\1";
        !            26:             errorindex < nerrors;
        !            27:             errorp = errors[++errorindex]){
        !            28:                if (SORTABLE(errorp->error_e_class)){
        !            29:                        if (strcmp(errorp->error_text[0],currentfilename) != 0){
        !            30:                                nfiles++;
        !            31:                                currentfilename = errorp->error_text[0];
        !            32:                        }
        !            33:                }
        !            34:        }
        !            35:        files = (struct error_desc ***)Calloc(nfiles + 3,
        !            36:                sizeof (struct error_desc**));
        !            37:        touchedfiles = (boolean *)Calloc(nfiles+3, sizeof(boolean));
        !            38:        /*
        !            39:         *      Now, go through and partition off the error messages
        !            40:         *      into those that are synchronization, discarded or
        !            41:         *      not specific to any file, and those that were
        !            42:         *      nulled or true errors.
        !            43:         */
        !            44:        files[0] = &errors[0];
        !            45:        for (errorp = errors[errorindex = 0], fileindex = 0;
        !            46:             (errorindex < nerrors) &&
        !            47:                (NOTSORTABLE(errorp->error_e_class));
        !            48:             errorp = errors[++errorindex]){
        !            49:                continue;
        !            50:        }
        !            51:        /*
        !            52:         *      Now, go through and partition off all error messages
        !            53:         *      for a given file.
        !            54:         */
        !            55:        files[1] = &errors[errorindex];
        !            56:        touchedfiles[0] = touchedfiles[1] = FALSE;
        !            57:        for (errorp = errors[errorindex], currentfilename = "\1", fileindex = 1;
        !            58:             errorindex < nerrors; errorp = errors[++errorindex]){
        !            59:                if ( (errorp->error_e_class == C_NULLED) || (errorp->error_e_class == C_TRUE) ){
        !            60:                        if (strcmp(errorp->error_text[0],currentfilename) != 0){
        !            61:                                currentfilename = errorp->error_text[0];
        !            62:                                touchedfiles[fileindex] = FALSE;
        !            63:                                files[fileindex++] = &errors[errorindex];
        !            64:                        }
        !            65:                }
        !            66:        }
        !            67:        files[fileindex] = &errors[nerrors];
        !            68:        *r_nfiles = nfiles;
        !            69:        *r_files = files;
        !            70: }
        !            71: 
        !            72: char   *class_table[] = {
        !            73:        /*C_UNKNOWN     0       */      "Unknown",
        !            74:        /*C_IGNORE      1       */      "ignore",
        !            75:        /*C_SYNC        2       */      "synchronization",
        !            76:        /*C_DISCARD     3       */      "discarded",
        !            77:        /*C_NONSPEC     4       */      "non specific",
        !            78:        /*C_THISFILE    5       */      "specific to this file",
        !            79:        /*C_NULLED      6       */      "nulled",
        !            80:        /*C_TRUE        7       */      "true",
        !            81:        /*C_DUPL        8       */      "duplicated"
        !            82: };
        !            83: 
        !            84: int    class_count[C_LAST - C_FIRST] = {0};
        !            85: 
        !            86: filenames(nfiles, files)
        !            87:        int     nfiles;
        !            88:        struct  error_desc      ***files;
        !            89: {
        !            90:        register        int     fileindex;
        !            91:        register        struct  error_desc      *errorp;
        !            92:        register        struct  error_desc      **erpp;
        !            93:                        char    *sep = " ";
        !            94:        register        int     errortype;
        !            95:        extern          char    *class_table[];
        !            96:                        int     someerrors = 0;
        !            97: 
        !            98:        /*
        !            99:         *      first, go through and simply dump out errors that
        !           100:         *      don't pertain to any file
        !           101:         */
        !           102:        if (files[1] - files[0] > 0){
        !           103:            for(errortype = C_UNKNOWN; NOTSORTABLE(errortype); errortype++){
        !           104:                if (class_count[errortype] > 0){
        !           105:                        if (errortype > C_SYNC)
        !           106:                                someerrors++;
        !           107:                        fprintf(stdout, "\n\t%d %s errors follow:\n",
        !           108:                                class_count[errortype], class_table[errortype]);
        !           109:                        for (errorp = *(erpp = files[0]);
        !           110:                             erpp < files[1];
        !           111:                             errorp = (*++erpp)){
        !           112:                                if (errorp->error_e_class == errortype)
        !           113:                                        errorprint(stdout, errorp, TRUE);
        !           114:                        }
        !           115:                }
        !           116:            }
        !           117:        }
        !           118:        if (nfiles){
        !           119:                someerrors++;
        !           120:                fprintf(stdout, "%d files contain errors:", nfiles);
        !           121:                for (fileindex = 1; fileindex <= nfiles; fileindex++){
        !           122:                        fprintf(stdout, "%s\"%s\" (%d)",
        !           123:                                sep, (*files[fileindex])->error_text[0],
        !           124:                                files[fileindex+1] - files[fileindex]);
        !           125:                        sep = ", ";
        !           126:                }
        !           127:                fprintf(stdout, "\n");
        !           128:        }
        !           129:        if (!someerrors)
        !           130:                fprintf(stdout, "No errors.\n");
        !           131: }
        !           132: 
        !           133: extern boolean notouch;
        !           134: 
        !           135: boolean touchfiles(nfiles, files, r_edargc, r_edargv)
        !           136:        int     nfiles;
        !           137:        struct  error_desc      ***files;
        !           138:        int     *r_edargc;
        !           139:        char    ***r_edargv;
        !           140: {
        !           141:                        char    *currentfilename;
        !           142:        register        struct  error_desc      *errorp;
        !           143:        register        int     fileindex;
        !           144:        register        struct  error_desc      **erpp;
        !           145:                        int             ntrueerrors;
        !           146:                        int             errordest;      /* where errors go*/
        !           147:                        char            *sep;
        !           148:                        boolean         scribbled;
        !           149:                        int             n_pissed_on;    /* # of file touched*/
        !           150:                        int             previewed;
        !           151: 
        !           152:        for (fileindex = 1; fileindex <= nfiles; fileindex++){
        !           153:                fprintf(stdout, "\nFile \"%s\" has %d total error messages.\n",
        !           154:                        currentfilename = (*files[fileindex])->error_text[0],
        !           155:                        files[fileindex+1] - files[fileindex]);
        !           156:                /*
        !           157:                 *      First, iterate through all error messages in this file
        !           158:                 *      to see how many of the error messages really will
        !           159:                 *      get inserted into the file.
        !           160:                 */
        !           161:                for (erpp = files[fileindex], ntrueerrors = 0;
        !           162:                     erpp < files[fileindex+1];
        !           163:                     erpp++){
        !           164:                        errorp = *erpp;
        !           165:                        if (errorp->error_e_class == C_TRUE)
        !           166:                                ntrueerrors++;
        !           167:                }
        !           168:                fprintf(stdout,"\t%d of these errors can be inserted into the file.\n",
        !           169:                        ntrueerrors);
        !           170: 
        !           171:                /*
        !           172:                 *      What does the operator want?
        !           173:                 */
        !           174:                previewed = 0;
        !           175:                errordest = TOSTDOUT;
        !           176:                if (oktotouch(currentfilename) && (ntrueerrors > 0) ){
        !           177:                        if (query && inquire("Do you want to preview the errors first?")){
        !           178:                                previewed = 1;
        !           179:                                for (erpp = files[fileindex];
        !           180:                                     erpp < files[fileindex + 1];
        !           181:                                     erpp++){
        !           182:                                        errorprint(stdout, *erpp, TRUE);
        !           183:                                }
        !           184:                                fprintf(stdout, "\n");
        !           185:                        }
        !           186:                        if (   !query
        !           187:                            || inquire("Do you want to touch file \"%s\"? ",
        !           188:                                        currentfilename)
        !           189:                        ){
        !           190:                                errordest = TOTHEFILE;
        !           191:                                if (!probethisfile(currentfilename)){
        !           192:                                        errordest = TOSTDOUT;
        !           193:                                        fprintf(stdout,
        !           194:                                         "Can't find file \"%s\" to insert error messages into.\n",
        !           195:                                                currentfilename);
        !           196:                                } else {
        !           197:                                        if (edit(currentfilename))
        !           198:                                                errordest = TOSTDOUT;
        !           199:                                        else
        !           200:                                                touchedfiles[fileindex] = TRUE;
        !           201:                                }
        !           202:                        }
        !           203:                }
        !           204:                if (previewed && (errordest == TOSTDOUT))
        !           205:                        continue;               /* with the next file */
        !           206:                /*
        !           207:                 *      go through and print each error message,
        !           208:                 *      diverting to the right place
        !           209:                 */
        !           210:                if ( (files[fileindex+1] - files[fileindex]) != ntrueerrors)
        !           211:                        if (!previewed) fprintf(stdout,
        !           212:                            ">>Uninserted error messages for file \"%s\" follow.\n",
        !           213:                            currentfilename);
        !           214:                for (erpp = files[fileindex];erpp < files[fileindex+1];erpp++){
        !           215:                        errorp = *erpp;
        !           216:                        if (errorp->error_e_class == C_TRUE){
        !           217:                                switch (errordest){
        !           218:                                  case TOSTDOUT:
        !           219:                                        if (!previewed)
        !           220:                                                errorprint(stdout,errorp, TRUE);
        !           221:                                        break;
        !           222:                                  case TOTHEFILE:
        !           223:                                        insert(errorp->error_line);
        !           224:                                        text(errorp, FALSE);
        !           225:                                        break;
        !           226:                                }       /* switch */
        !           227:                        } else {
        !           228:                                if (!previewed)
        !           229:                                        errorprint(stdout, errorp, TRUE);
        !           230:                        }
        !           231:                }       /* end of walking through all errors*/
        !           232:                if (errordest == TOTHEFILE){
        !           233:                        writetouched();
        !           234:                }
        !           235:        }       /* end of walking through all files*/
        !           236:        scribbled = FALSE;
        !           237:        for (n_pissed_on = 0, fileindex = 1; fileindex <= nfiles; fileindex++){
        !           238:                scribbled |= touchedfiles[fileindex];
        !           239:                n_pissed_on++;
        !           240:        }
        !           241:        if (scribbled){
        !           242:                /*
        !           243:                 *      Construct an execv argument
        !           244:                 *      We need 1 argument for the editor's name
        !           245:                 *      We need 1 argument for the initial search string
        !           246:                 *      We need n_pissed_on arguments for the file names
        !           247:                 *      We need 1 argument that is a null for execv.
        !           248:                 *      The caller fills in the editor's name.
        !           249:                 *      We fill in the initial search string.
        !           250:                 *      We fill in the arguments, and the null.
        !           251:                 */
        !           252:                (*r_edargv) = (char **)Calloc(n_pissed_on + 3, sizeof(char *));
        !           253:                (*r_edargc) =  n_pissed_on + 2;
        !           254:                (*r_edargv)[1] = "+/###/";
        !           255:                n_pissed_on = 2;
        !           256:                fprintf(stdout, "You touched file(s):");
        !           257:                sep = " ";
        !           258:                for (fileindex = 1; fileindex <= nfiles; fileindex++){
        !           259:                        if (!touchedfiles[fileindex])
        !           260:                                continue;
        !           261:                        errorp = *(files[fileindex]);
        !           262:                        fprintf(stdout,"%s\"%s\"", sep, errorp->error_text[0]);
        !           263:                        sep = ", ";
        !           264:                        (*r_edargv)[n_pissed_on++] = errorp->error_text[0];
        !           265:                }
        !           266:                fprintf(stdout, "\n");
        !           267:                (*r_edargv)[n_pissed_on] = 0;
        !           268:                return(TRUE);
        !           269:        } else {
        !           270:                fprintf(stdout, "You didn't touch any files.\n");
        !           271:                return(FALSE);
        !           272:        }
        !           273: 
        !           274: }      /* end of touchfiles*/
        !           275: int    oktotouch(filename)
        !           276:        char    *filename;
        !           277: {
        !           278:        extern          char    *suffixlist;
        !           279:        register        char    *src;
        !           280:        register        char    *pat;
        !           281:                        char    *osrc;
        !           282: 
        !           283:        pat = suffixlist;
        !           284:        if (pat == 0)
        !           285:                return(0);
        !           286:        if (*pat == '*')
        !           287:                return(1);
        !           288:        while (*pat++ != '.')
        !           289:                continue;
        !           290:        --pat;          /* point to the period */
        !           291: 
        !           292:        for (src = &filename[strlen(filename)], --src;
        !           293:             (src > filename) && (*src != '.'); --src)
        !           294:                continue;
        !           295:        if (*src != '.')
        !           296:                return(0);
        !           297: 
        !           298:        for (src++, pat++, osrc = src; *src && *pat; src = osrc, pat++){
        !           299:                for (;   *src                   /* not at end of the source */
        !           300:                      && *pat                   /* not off end of pattern */
        !           301:                      && *pat != '.'            /* not off end of sub pattern */
        !           302:                      && *pat != '*'            /* not wild card */
        !           303:                      && *src == *pat;          /* and equal... */
        !           304:                      src++, pat++)
        !           305:                        continue;
        !           306:                if (*src == 0 && (*pat == 0 || *pat == '.' || *pat == '*'))
        !           307:                        return(1);
        !           308:                if (*src != 0 && *pat == '*')
        !           309:                        return(1);
        !           310:                while (*pat && *pat != '.')
        !           311:                        pat++;
        !           312:                if (! *pat)
        !           313:                        return(0);
        !           314:        }
        !           315:        return(0);
        !           316: }
        !           317: 
        !           318: FILE   *o_touchedfile; /* the old file */
        !           319: FILE   *n_touchedfile; /* the new file */
        !           320: char   *o_name;
        !           321: char   n_name[32];
        !           322: char   *canon_name = "ErrorXXXXXX";
        !           323: int    o_lineno;
        !           324: int    n_lineno;
        !           325: boolean        tempfileopen = FALSE;
        !           326: /*
        !           327:  *     open the file; guaranteed to be both readable and writable
        !           328:  *     Well, if it isn't, then return TRUE if something failed
        !           329:  */
        !           330: boolean edit(name)
        !           331:        char    *name;
        !           332: {
        !           333:        o_name = name;
        !           334:        if ( (o_touchedfile = fopen(name, "r")) == NULL){
        !           335:                fprintf(stderr, "%s: Can't open file \"%s\" to touch (read).\n",
        !           336:                        processname, name);
        !           337:                return(TRUE);
        !           338:        }
        !           339:        strcpy(n_name, canon_name);
        !           340:        mktemp(n_name);
        !           341:        if ( (n_touchedfile = fopen(n_name, "w")) == NULL){
        !           342:                fprintf(stderr,"%s: Can't open file \"%s\" to touch (write).\n",
        !           343:                        processname, name);
        !           344:                return(TRUE);
        !           345:        }
        !           346:        tempfileopen = TRUE;
        !           347:        n_lineno = 0;
        !           348:        o_lineno = 0;
        !           349:        return(FALSE);
        !           350: }
        !           351: /*
        !           352:  *     Position to the line (before, after) the line given by place
        !           353:  */
        !           354: char   edbuffer[BUFSIZ];
        !           355: insert(place)
        !           356:        int     place;
        !           357: {
        !           358:        --place;        /* always insert messages before the offending line*/
        !           359:        for(; o_lineno < place; o_lineno++, n_lineno++){
        !           360:                if(fgets(edbuffer, BUFSIZ, o_touchedfile) == NULL)
        !           361:                        return;
        !           362:                fputs(edbuffer, n_touchedfile);
        !           363:        }
        !           364: }
        !           365: 
        !           366: text(errorp, use_all)
        !           367:        register        struct  error_desc      *errorp;
        !           368:        boolean use_all;
        !           369: {
        !           370:        int     offset = use_all ? 0 : 2;
        !           371:        fputs(lang_table[errorp->error_language].lang_incomment, n_touchedfile);
        !           372:        fprintf(n_touchedfile, "%d [%s] ",
        !           373:                errorp->error_line,
        !           374:                lang_table[errorp->error_language].lang_name);
        !           375:        wordvprint(n_touchedfile,
        !           376:                errorp->error_lgtext-offset, errorp->error_text+offset);
        !           377:        fputs(lang_table[errorp->error_language].lang_outcomment,n_touchedfile);
        !           378:        n_lineno++;
        !           379: }
        !           380: 
        !           381: writetouched()
        !           382: {
        !           383:        int     bytes_read;
        !           384:        for(; (bytes_read = fread(edbuffer, 1, sizeof(edbuffer), o_touchedfile))!= NULL; ){
        !           385:                fwrite(edbuffer, 1, bytes_read, n_touchedfile);
        !           386:        }
        !           387:        fclose(n_touchedfile);
        !           388:        fclose(o_touchedfile);
        !           389:        unlink(o_name);
        !           390:        link(n_name, o_name);   
        !           391:        unlink(n_name);
        !           392:        tempfileopen = FALSE;
        !           393: }
        !           394: onintr()
        !           395: {
        !           396:        if (inquire("\nInterrupt: Do you want to continue?")){
        !           397:                signal(SIGINT, onintr);
        !           398:                return;
        !           399:        }
        !           400:        if (tempfileopen)
        !           401:                writetouched();
        !           402:        exit(1);
        !           403: }
        !           404: errorprint(place, errorp, print_all)
        !           405:        FILE    *place;
        !           406:        struct  error_desc      *errorp;
        !           407:        boolean print_all;
        !           408: {
        !           409:        int     offset = print_all ? 0 : 2;
        !           410: 
        !           411:        if (errorp->error_e_class == C_IGNORE)
        !           412:                return;
        !           413:        fprintf(place, "[%s] ", lang_table[errorp->error_language].lang_name);
        !           414:        wordvprint(place,errorp->error_lgtext-offset,errorp->error_text+offset);
        !           415:        putc('\n', place);
        !           416: }
        !           417: 
        !           418: boolean inquire(fmt, a1, a2)
        !           419:        char    *fmt;
        !           420:        /*VARARGS1*/
        !           421: {
        !           422:        char    buffer[128];
        !           423:        char    ch;
        !           424:        for(;;){
        !           425:                do{
        !           426:                        fflush(stdout);
        !           427:                        fprintf(stderr, fmt, a1, a2);
        !           428:                        fflush(stderr);
        !           429:                } while (fgets(buffer, 127, queryfile) == NULL);
        !           430:                ch = buffer[0];
        !           431:                if (ch == 'Y' || ch == 'y')
        !           432:                        return(TRUE);
        !           433:                if (ch == 'N' || ch == 'n')
        !           434:                        return(FALSE);
        !           435:                fprintf(stderr, "Yes or No only!\n");
        !           436:        }
        !           437: }
        !           438: 
        !           439: boolean probethisfile(currentfilename)
        !           440:        char    *currentfilename;
        !           441: {
        !           442:        struct stat statbuf;
        !           443:        if (stat(currentfilename, &statbuf) != 0)
        !           444:                return(FALSE);
        !           445:        if ( (statbuf.st_mode&S_IREAD) && (statbuf.st_mode&S_IWRITE))
        !           446:                return(TRUE);
        !           447:        return(FALSE);
        !           448: }

unix.superglobalmegacorp.com

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