Annotation of 42BSD/usr.bin/ptx.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)ptx.c       4.1 (Berkeley) 10/1/80";
        !             2: #
        !             3: 
        !             4: /*     permuted title index
        !             5:        ptx [-t] [-i ignore] [-o only] [-w num] [-f] [input] [output]
        !             6:        Ptx reads the input file and permutes on words in it.
        !             7:        It excludes all words in the ignore file.
        !             8:        Alternately it includes words in the only file.
        !             9:        if neither is given it excludes the words in /usr/lib/eign.
        !            10: 
        !            11:        The width of the output line can be changed to num
        !            12:        characters.  If omitted 72 is default unless troff than 100.
        !            13:        the -f flag tells the program to fold the output
        !            14:        the -t flag says the output is for troff and the
        !            15:        output is then wider.
        !            16: 
        !            17:       make: cc ptx.c -lS
        !            18:        */
        !            19: 
        !            20: #include <stdio.h>
        !            21: #include <ctype.h>
        !            22: #include <signal.h>
        !            23: #define DEFLTX "/usr/lib/eign"
        !            24: #define TILDE 0177
        !            25: #define SORT "/usr/bin/sort"
        !            26: #define        N 30
        !            27: #define        MAX     N*BUFSIZ
        !            28: #define LMAX   200
        !            29: #define MAXT   2048
        !            30: #define MASK   03777
        !            31: #define SET    1
        !            32: 
        !            33: #define isabreak(c) (btable[c])
        !            34: 
        !            35: extern char *calloc(), *mktemp();
        !            36: extern char *getline();
        !            37: int status;
        !            38: 
        !            39: 
        !            40: char *hasht[MAXT];
        !            41: char line[LMAX];
        !            42: char btable[128];
        !            43: int ignore;
        !            44: int only;
        !            45: int llen = 72;
        !            46: int gap = 3;
        !            47: int gutter = 3;
        !            48: int mlen = LMAX;
        !            49: int wlen;
        !            50: int rflag;
        !            51: int halflen;
        !            52: char *strtbufp, *endbufp;
        !            53: char *empty = "";
        !            54: 
        !            55: char *infile;
        !            56: FILE *inptr = stdin;
        !            57: 
        !            58: char *outfile;
        !            59: FILE *outptr = stdout;
        !            60: 
        !            61: char *sortfile;        /* output of sort program */
        !            62: char nofold[] = {'-', 'd', 't', TILDE, 0};
        !            63: char fold[] = {'-', 'd', 'f', 't', TILDE, 0};
        !            64: char *sortopt = nofold;
        !            65: FILE *sortptr;
        !            66: 
        !            67: char *bfile;   /*contains user supplied break chars */
        !            68: FILE *bptr;
        !            69: 
        !            70: main(argc,argv)
        !            71: int argc;
        !            72: char **argv;
        !            73: {
        !            74:        register int c;
        !            75:        register char *bufp;
        !            76:        int pid;
        !            77:        char *pend;
        !            78:        extern onintr();
        !            79: 
        !            80:        char *xfile;
        !            81:        FILE *xptr;
        !            82: 
        !            83:        if(signal(SIGHUP,onintr)==SIG_IGN)
        !            84:                signal(SIGHUP,SIG_IGN);
        !            85:        if(signal(SIGINT,onintr)==SIG_IGN)
        !            86:                signal(SIGINT,SIG_IGN);
        !            87:        signal(SIGPIPE,onintr);
        !            88:        signal(SIGTERM,onintr);
        !            89: 
        !            90: /*     argument decoding       */
        !            91: 
        !            92:        xfile = DEFLTX;
        !            93:        argv++;
        !            94:        while(argc>1 && **argv == '-') {
        !            95:                switch (*++*argv){
        !            96: 
        !            97:                case 'r':
        !            98:                        rflag++;
        !            99:                        break;
        !           100:                case 'f':
        !           101:                        sortopt = fold;
        !           102:                        break;
        !           103: 
        !           104:                case 'w':
        !           105:                        if(argc >= 2) {
        !           106:                                argc--;
        !           107:                                wlen++;
        !           108:                                llen = atoi(*++argv);
        !           109:                                if(llen == 0)
        !           110:                                        diag("Wrong width:",*argv);
        !           111:                                if(llen > LMAX) {
        !           112:                                        llen = LMAX;
        !           113:                                        msg("Lines truncated to 200 chars.",empty);
        !           114:                                }
        !           115:                                break;
        !           116:                        }
        !           117: 
        !           118:                case 't':
        !           119:                        if(wlen == 0)
        !           120:                                llen = 100;
        !           121:                        break;
        !           122:                case 'g':
        !           123:                        if(argc >=2) {
        !           124:                                argc--;
        !           125:                                gap = gutter = atoi(*++argv);
        !           126:                        }
        !           127:                        break;
        !           128: 
        !           129:                case 'i':
        !           130:                        if(only) 
        !           131:                                diag("Only file already given.",empty);
        !           132:                        if (argc>=2){
        !           133:                                argc--;
        !           134:                                ignore++;
        !           135:                                xfile = *++argv;
        !           136:                        }
        !           137:                        break;
        !           138: 
        !           139:                case 'o':
        !           140:                        if(ignore)
        !           141:                                diag("Ignore file already given",empty);
        !           142:                        if (argc>=2){
        !           143:                                only++;
        !           144:                                argc--;
        !           145:                                xfile = *++argv;
        !           146:                        }
        !           147:                        break;
        !           148: 
        !           149:                case 'b':
        !           150:                        if(argc>=2) {
        !           151:                                argc--;
        !           152:                                bfile = *++argv;
        !           153:                        }
        !           154:                        break;
        !           155: 
        !           156:                default:
        !           157:                        msg("Illegal argument:",*argv);
        !           158:                }
        !           159:                argc--;
        !           160:                argv++;
        !           161:        }
        !           162: 
        !           163:        if(argc>3)
        !           164:                diag("Too many filenames",empty);
        !           165:        else if(argc==3){
        !           166:                infile = *argv++;
        !           167:                outfile = *argv;
        !           168:                if((outptr = fopen(outfile,"w")) == NULL)
        !           169:                        diag("Cannot open output file:",outfile);
        !           170:        } else if(argc==2) {
        !           171:                infile = *argv;
        !           172:                outfile = 0;
        !           173:        }
        !           174: 
        !           175: 
        !           176:        /* Default breaks of blank, tab and newline */
        !           177:        btable[' '] = SET;
        !           178:        btable['\t'] = SET;
        !           179:        btable['\n'] = SET;
        !           180:        if(bfile) {
        !           181:                if((bptr = fopen(bfile,"r")) == NULL)
        !           182:                        diag("Cannot open break char file",bfile);
        !           183: 
        !           184:                while((c = getc(bptr)) != EOF)
        !           185:                        btable[c] = SET;
        !           186:        }
        !           187: 
        !           188: /*     Allocate space for a buffer.  If only or ignore file present
        !           189:        read it into buffer. Else read in default ignore file
        !           190:        and put resulting words in buffer.
        !           191:        */
        !           192: 
        !           193: 
        !           194:        if((strtbufp = calloc(N,BUFSIZ)) == NULL)
        !           195:                diag("Out of memory space",empty);
        !           196:        bufp = strtbufp;
        !           197:        endbufp = strtbufp+MAX;
        !           198: 
        !           199:        if((xptr = fopen(xfile,"r")) == NULL)
        !           200:                diag("Cannot open  file",xfile);
        !           201: 
        !           202:        while(bufp < endbufp && (c = getc(xptr)) != EOF) {
        !           203:                if(isabreak(c)) {
        !           204:                        if(storeh(hash(strtbufp,bufp),strtbufp))
        !           205:                                diag("Too many words",xfile);
        !           206:                        *bufp++ = '\0';
        !           207:                        strtbufp = bufp;
        !           208:                }
        !           209:                else {
        !           210:                        *bufp++ = (isupper(c)?tolower(c):c);
        !           211:                }
        !           212:        }
        !           213:        if (bufp >= endbufp)
        !           214:                diag("Too many words in file",xfile);
        !           215:        endbufp = --bufp;
        !           216: 
        !           217:        /* open output file for sorting */
        !           218: 
        !           219:        sortfile = mktemp("/tmp/ptxsXXXXX");
        !           220:        if((sortptr = fopen(sortfile, "w")) == NULL)
        !           221:                diag("Cannot open output for sorting:",sortfile);
        !           222: 
        !           223: /*     get a line of data and compare each word for
        !           224:        inclusion or exclusion in the sort phase
        !           225: */
        !           226: 
        !           227:        if (infile!=0 && (inptr = fopen(infile,"r")) == NULL)
        !           228:                diag("Cannot open data: ",infile);
        !           229:        while(pend=getline())
        !           230:                cmpline(pend);
        !           231:        fclose(sortptr);
        !           232: 
        !           233:        switch (pid = fork()){
        !           234: 
        !           235:        case -1:        /* cannot fork */
        !           236:                diag("Cannot fork",empty);
        !           237: 
        !           238:        case 0:         /* child */
        !           239:                execl(SORT, SORT, sortopt, "+0", "-1", "+1",
        !           240:                        sortfile, "-o", sortfile, 0);
        !           241: 
        !           242:        default:        /* parent */
        !           243:                while(wait(&status) != pid);
        !           244:        }
        !           245: 
        !           246: 
        !           247:        getsort();
        !           248:        onintr();
        !           249: }
        !           250: 
        !           251: msg(s,arg)
        !           252: char *s;
        !           253: char *arg;
        !           254: {
        !           255:        fprintf(stderr,"%s %s\n",s,arg);
        !           256:        return;
        !           257: }
        !           258: diag(s,arg)
        !           259: char *s, *arg;
        !           260: {
        !           261: 
        !           262:        msg(s,arg);
        !           263:        exit(1);
        !           264: }
        !           265: 
        !           266: 
        !           267: char *getline()
        !           268: {
        !           269: 
        !           270:        register c;
        !           271:        register char *linep;
        !           272:        char *endlinep;
        !           273: 
        !           274: 
        !           275:        endlinep= line + mlen;
        !           276:        linep = line;
        !           277:        /* Throw away leading white space */
        !           278: 
        !           279:        while(isspace(c=getc(inptr)))
        !           280:                ;
        !           281:        if(c==EOF)
        !           282:                return(0);
        !           283:        ungetc(c,inptr);
        !           284:        while(( c=getc(inptr)) != EOF) {
        !           285:                switch (c) {
        !           286: 
        !           287:                        case '\t':
        !           288:                                if(linep<endlinep)
        !           289:                                        *linep++ = ' ';
        !           290:                                break;
        !           291:                        case '\n':
        !           292:                                while(isspace(*--linep));
        !           293:                                *++linep = '\n';
        !           294:                                return(linep);
        !           295:                        default:
        !           296:                                if(linep < endlinep)
        !           297:                                        *linep++ = c;
        !           298:                }
        !           299:        }
        !           300:        return(0);
        !           301: }
        !           302: 
        !           303: cmpline(pend)
        !           304: char *pend;
        !           305: {
        !           306: 
        !           307:        char *pstrt, *pchar, *cp;
        !           308:        char **hp;
        !           309:        int flag;
        !           310: 
        !           311:        pchar = line;
        !           312:        if(rflag)
        !           313:                while(pchar<pend&&!isspace(*pchar))
        !           314:                        pchar++;
        !           315:        while(pchar<pend){
        !           316:        /* eliminate white space */
        !           317:                if(isabreak(*pchar++))
        !           318:                        continue;
        !           319:                pstrt = --pchar;
        !           320: 
        !           321:                flag = 1;
        !           322:                while(flag){
        !           323:                        if(isabreak(*pchar)) {
        !           324:                                hp = &hasht[hash(pstrt,pchar)];
        !           325:                                pchar--;
        !           326:                                while(cp = *hp++){
        !           327:                                        if(hp == &hasht[MAXT])
        !           328:                                                hp = hasht;
        !           329:        /* possible match */
        !           330:                                        if(cmpword(pstrt,pchar,cp)){
        !           331:        /* exact match */
        !           332:                                                if(!ignore && only)
        !           333:                                                        putline(pstrt,pend);
        !           334:                                                flag = 0;
        !           335:                                                break;
        !           336:                                        }
        !           337:                                }
        !           338:        /* no match */
        !           339:                                if(flag){
        !           340:                                        if(ignore || !only)
        !           341:                                                putline(pstrt,pend);
        !           342:                                        flag = 0;
        !           343:                                }
        !           344:                        }
        !           345:                pchar++;
        !           346:                }
        !           347:        }
        !           348: }
        !           349: 
        !           350: cmpword(cpp,pend,hpp)
        !           351: char *cpp, *pend, *hpp;
        !           352: {
        !           353:        char c;
        !           354: 
        !           355:        while(*hpp != '\0'){
        !           356:                c = *cpp++;
        !           357:                if((isupper(c)?tolower(c):c) != *hpp++)
        !           358:                        return(0);
        !           359:        }
        !           360:        if(--cpp == pend) return(1);
        !           361:        return(0);
        !           362: }
        !           363: 
        !           364: putline(strt, end)
        !           365: char *strt, *end;
        !           366: {
        !           367:        char *cp;
        !           368: 
        !           369:        for(cp=strt; cp<end; cp++)
        !           370:                putc(*cp, sortptr);
        !           371:        /* Add extra blank before TILDE to sort correctly
        !           372:           with -fd option */
        !           373:        putc(' ',sortptr);
        !           374:        putc(TILDE,sortptr);
        !           375:        for (cp=line; cp<strt; cp++)
        !           376:                putc(*cp,sortptr);
        !           377:        putc('\n',sortptr);
        !           378: }
        !           379: 
        !           380: getsort()
        !           381: {
        !           382:        register c;
        !           383:        register char *tilde, *linep, *ref;
        !           384:        char *p1a,*p1b,*p2a,*p2b,*p3a,*p3b,*p4a,*p4b;
        !           385:        int w;
        !           386:        char *rtrim(), *ltrim();
        !           387: 
        !           388:        if((sortptr = fopen(sortfile,"r")) == NULL)
        !           389:                diag("Cannot open sorted data:",sortfile);
        !           390: 
        !           391:        halflen = (llen-gutter)/2;
        !           392:        linep = line;
        !           393:        while((c = getc(sortptr)) != EOF) {
        !           394:                switch(c) {
        !           395: 
        !           396:                case TILDE:
        !           397:                        tilde = linep;
        !           398:                        break;
        !           399: 
        !           400:                case '\n':
        !           401:                        while(isspace(linep[-1]))
        !           402:                                linep--;
        !           403:                        ref = tilde;
        !           404:                        if(rflag) {
        !           405:                                while(ref<linep&&!isspace(*ref))
        !           406:                                        ref++;
        !           407:                                *ref++ = 0;
        !           408:                        }
        !           409:                /* the -1 is an overly conservative test to leave
        !           410:                   space for the / that signifies truncation*/
        !           411:                        p3b = rtrim(p3a=line,tilde,halflen-1);
        !           412:                        if(p3b-p3a>halflen-1)
        !           413:                                p3b = p3a+halflen-1;
        !           414:                        p2a = ltrim(ref,p2b=linep,halflen-1);
        !           415:                        if(p2b-p2a>halflen-1)
        !           416:                                p2a = p2b-halflen-1;
        !           417:                        p1b = rtrim(p1a=p3b+(isspace(p3b[0])!=0),tilde,
        !           418:                                w=halflen-(p2b-p2a)-gap);
        !           419:                        if(p1b-p1a>w)
        !           420:                                p1b = p1a;
        !           421:                        p4a = ltrim(ref,p4b=p2a-(isspace(p2a[-1])!=0),
        !           422:                                w=halflen-(p3b-p3a)-gap);
        !           423:                        if(p4b-p4a>w)
        !           424:                                p4a = p4b;
        !           425:                        fprintf(outptr,".xx \"");
        !           426:                        putout(p1a,p1b);
        !           427:        /* tilde-1 to account for extra space before TILDE */
        !           428:                        if(p1b!=(tilde-1) && p1a!=p1b)
        !           429:                                fprintf(outptr,"/");
        !           430:                        fprintf(outptr,"\" \"");
        !           431:                        if(p4a==p4b && p2a!=ref && p2a!=p2b)
        !           432:                                fprintf(outptr,"/");
        !           433:                        putout(p2a,p2b);
        !           434:                        fprintf(outptr,"\" \"");
        !           435:                        putout(p3a,p3b);
        !           436:        /* ++p3b to account for extra blank after TILDE */
        !           437:        /* ++p3b to account for extra space before TILDE */
        !           438:                        if(p1a==p1b && ++p3b!=tilde)
        !           439:                                fprintf(outptr,"/");
        !           440:                        fprintf(outptr,"\" \"");
        !           441:                        if(p1a==p1b && p4a!=ref && p4a!=p4b)
        !           442:                                fprintf(outptr,"/");
        !           443:                        putout(p4a,p4b);
        !           444:                        if(rflag)
        !           445:                                fprintf(outptr,"\" %s\n",tilde);
        !           446:                        else
        !           447:                                fprintf(outptr,"\"\n");
        !           448:                        linep = line;
        !           449:                        break;
        !           450: 
        !           451:                case '"':
        !           452:        /* put double " for "  */
        !           453:                        *linep++ = c;
        !           454:                default:
        !           455:                        *linep++ = c;
        !           456:                }
        !           457:        }
        !           458: }
        !           459: 
        !           460: char *rtrim(a,c,d)
        !           461: char *a,*c;
        !           462: {
        !           463:        char *b,*x;
        !           464:        b = c;
        !           465:        for(x=a+1; x<=c&&x-a<=d; x++)
        !           466:                if((x==c||isspace(x[0]))&&!isspace(x[-1]))
        !           467:                        b = x;
        !           468:        if(b<c&&!isspace(b[0]))
        !           469:                b++;
        !           470:        return(b);
        !           471: }
        !           472: 
        !           473: char *ltrim(c,b,d)
        !           474: char *c,*b;
        !           475: {
        !           476:        char *a,*x;
        !           477:        a = c;
        !           478:        for(x=b-1; x>=c&&b-x<=d; x--)
        !           479:                if(!isspace(x[0])&&(x==c||isspace(x[-1])))
        !           480:                        a = x;
        !           481:        if(a>c&&!isspace(a[-1]))
        !           482:                a--;
        !           483:        return(a);
        !           484: }
        !           485: 
        !           486: putout(strt,end)
        !           487: char *strt, *end;
        !           488: {
        !           489:        char *cp;
        !           490: 
        !           491:        cp = strt;
        !           492: 
        !           493:        for(cp=strt; cp<end; cp++) {
        !           494:                putc(*cp,outptr);
        !           495:        }
        !           496: }
        !           497: 
        !           498: onintr()
        !           499: {
        !           500: 
        !           501:        if(*sortfile)
        !           502:                unlink(sortfile);
        !           503:        exit(1);
        !           504: }
        !           505: 
        !           506: hash(strtp,endp)
        !           507: char *strtp, *endp;
        !           508: {
        !           509:        char *cp, c;
        !           510:        int i, j, k;
        !           511: 
        !           512:        /* Return zero hash number for single letter words */
        !           513:        if((endp - strtp) == 1)
        !           514:                return(0);
        !           515: 
        !           516:        cp = strtp;
        !           517:        c = *cp++;
        !           518:        i = (isupper(c)?tolower(c):c);
        !           519:        c = *cp;
        !           520:        j = (isupper(c)?tolower(c):c);
        !           521:        i = i*j;
        !           522:        cp = --endp;
        !           523:        c = *cp--;
        !           524:        k = (isupper(c)?tolower(c):c);
        !           525:        c = *cp;
        !           526:        j = (isupper(c)?tolower(c):c);
        !           527:        j = k*j;
        !           528: 
        !           529:        k = (i ^ (j>>2)) & MASK;
        !           530:        return(k);
        !           531: }
        !           532: 
        !           533: storeh(num,strtp)
        !           534: int num;
        !           535: char *strtp;
        !           536: {
        !           537:        int i;
        !           538: 
        !           539:        for(i=num; i<MAXT; i++) {
        !           540:                if(hasht[i] == 0) {
        !           541:                        hasht[i] = strtp;
        !           542:                        return(0);
        !           543:                }
        !           544:        }
        !           545:        for(i=0; i<num; i++) {
        !           546:                if(hasht[i] == 0) {
        !           547:                        hasht[i] = strtp;
        !           548:                        return(0);
        !           549:                }
        !           550:        }
        !           551:        return(1);
        !           552: }

unix.superglobalmegacorp.com

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