Annotation of 43BSDReno/usr.bin/ptx/ptx.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid = "@(#)ptx.c       4.5 (Berkeley) 5/11/89";
        !             3: #endif /* not lint */
        !             4: 
        !             5: /*     permuted title index
        !             6:        ptx [-t] [-i ignore] [-o only] [-w num] [-f] [input] [output]
        !             7:        Ptx reads the input file and permutes on words in it.
        !             8:        It excludes all words in the ignore file.
        !             9:        Alternately it includes words in the only file.
        !            10:        if neither is given it excludes the words in _PATH_EIGN.
        !            11: 
        !            12:        The width of the output line can be changed to num
        !            13:        characters.  If omitted 72 is default unless troff than 100.
        !            14:        the -f flag tells the program to fold the output
        !            15:        the -t flag says the output is for troff and the
        !            16:        output is then wider.
        !            17: 
        !            18:        */
        !            19: 
        !            20: #include <stdio.h>
        !            21: #include <ctype.h>
        !            22: #include <signal.h>
        !            23: #include "pathnames.h"
        !            24: 
        !            25: #define TILDE 0177
        !            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[] = _PATH_TMP;           /* 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 = _PATH_EIGN;
        !            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:        mktemp(sortfile);
        !           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(_PATH_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:        unlink(sortfile);
        !           249:        exit(0);
        !           250: }
        !           251: 
        !           252: msg(s,arg)
        !           253: char *s;
        !           254: char *arg;
        !           255: {
        !           256:        fprintf(stderr,"%s %s\n",s,arg);
        !           257:        return;
        !           258: }
        !           259: diag(s,arg)
        !           260: char *s, *arg;
        !           261: {
        !           262: 
        !           263:        msg(s,arg);
        !           264:        exit(1);
        !           265: }
        !           266: 
        !           267: 
        !           268: char *getline()
        !           269: {
        !           270: 
        !           271:        register c;
        !           272:        register char *linep;
        !           273:        char *endlinep;
        !           274: 
        !           275: 
        !           276:        endlinep= line + mlen;
        !           277:        linep = line;
        !           278:        /* Throw away leading white space */
        !           279: 
        !           280:        while(isspace(c=getc(inptr)))
        !           281:                ;
        !           282:        if(c==EOF)
        !           283:                return(0);
        !           284:        ungetc(c,inptr);
        !           285:        while(( c=getc(inptr)) != EOF) {
        !           286:                switch (c) {
        !           287: 
        !           288:                        case '\t':
        !           289:                                if(linep<endlinep)
        !           290:                                        *linep++ = ' ';
        !           291:                                break;
        !           292:                        case '\n':
        !           293:                                while(isspace(*--linep));
        !           294:                                *++linep = '\n';
        !           295:                                return(linep);
        !           296:                        default:
        !           297:                                if(linep < endlinep)
        !           298:                                        *linep++ = c;
        !           299:                }
        !           300:        }
        !           301:        return(0);
        !           302: }
        !           303: 
        !           304: cmpline(pend)
        !           305: char *pend;
        !           306: {
        !           307: 
        !           308:        char *pstrt, *pchar, *cp;
        !           309:        char **hp;
        !           310:        int flag;
        !           311: 
        !           312:        pchar = line;
        !           313:        if(rflag)
        !           314:                while(pchar<pend&&!isspace(*pchar))
        !           315:                        pchar++;
        !           316:        while(pchar<pend){
        !           317:        /* eliminate white space */
        !           318:                if(isabreak(*pchar++))
        !           319:                        continue;
        !           320:                pstrt = --pchar;
        !           321: 
        !           322:                flag = 1;
        !           323:                while(flag){
        !           324:                        if(isabreak(*pchar)) {
        !           325:                                hp = &hasht[hash(pstrt,pchar)];
        !           326:                                pchar--;
        !           327:                                while(cp = *hp++){
        !           328:                                        if(hp == &hasht[MAXT])
        !           329:                                                hp = hasht;
        !           330:        /* possible match */
        !           331:                                        if(cmpword(pstrt,pchar,cp)){
        !           332:        /* exact match */
        !           333:                                                if(!ignore && only)
        !           334:                                                        putline(pstrt,pend);
        !           335:                                                flag = 0;
        !           336:                                                break;
        !           337:                                        }
        !           338:                                }
        !           339:        /* no match */
        !           340:                                if(flag){
        !           341:                                        if(ignore || !only)
        !           342:                                                putline(pstrt,pend);
        !           343:                                        flag = 0;
        !           344:                                }
        !           345:                        }
        !           346:                pchar++;
        !           347:                }
        !           348:        }
        !           349: }
        !           350: 
        !           351: cmpword(cpp,pend,hpp)
        !           352: char *cpp, *pend, *hpp;
        !           353: {
        !           354:        char c;
        !           355: 
        !           356:        while(*hpp != '\0'){
        !           357:                c = *cpp++;
        !           358:                if((isupper(c)?tolower(c):c) != *hpp++)
        !           359:                        return(0);
        !           360:        }
        !           361:        if(--cpp == pend) return(1);
        !           362:        return(0);
        !           363: }
        !           364: 
        !           365: putline(strt, end)
        !           366: char *strt, *end;
        !           367: {
        !           368:        char *cp;
        !           369: 
        !           370:        for(cp=strt; cp<end; cp++)
        !           371:                putc(*cp, sortptr);
        !           372:        /* Add extra blank before TILDE to sort correctly
        !           373:           with -fd option */
        !           374:        putc(' ',sortptr);
        !           375:        putc(TILDE,sortptr);
        !           376:        for (cp=line; cp<strt; cp++)
        !           377:                putc(*cp,sortptr);
        !           378:        putc('\n',sortptr);
        !           379: }
        !           380: 
        !           381: getsort()
        !           382: {
        !           383:        register c;
        !           384:        register char *tilde, *linep, *ref;
        !           385:        char *p1a,*p1b,*p2a,*p2b,*p3a,*p3b,*p4a,*p4b;
        !           386:        int w;
        !           387:        char *rtrim(), *ltrim();
        !           388: 
        !           389:        if((sortptr = fopen(sortfile,"r")) == NULL)
        !           390:                diag("Cannot open sorted data:",sortfile);
        !           391: 
        !           392:        halflen = (llen-gutter)/2;
        !           393:        linep = line;
        !           394:        while((c = getc(sortptr)) != EOF) {
        !           395:                switch(c) {
        !           396: 
        !           397:                case TILDE:
        !           398:                        tilde = linep;
        !           399:                        break;
        !           400: 
        !           401:                case '\n':
        !           402:                        while(isspace(linep[-1]))
        !           403:                                linep--;
        !           404:                        ref = tilde;
        !           405:                        if(rflag) {
        !           406:                                while(ref<linep&&!isspace(*ref))
        !           407:                                        ref++;
        !           408:                                *ref++ = 0;
        !           409:                        }
        !           410:                /* the -1 is an overly conservative test to leave
        !           411:                   space for the / that signifies truncation*/
        !           412:                        p3b = rtrim(p3a=line,tilde,halflen-1);
        !           413:                        if(p3b-p3a>halflen-1)
        !           414:                                p3b = p3a+halflen-1;
        !           415:                        p2a = ltrim(ref,p2b=linep,halflen-1);
        !           416:                        if(p2b-p2a>halflen-1)
        !           417:                                p2a = p2b-halflen-1;
        !           418:                        p1b = rtrim(p1a=p3b+(isspace(p3b[0])!=0),tilde,
        !           419:                                w=halflen-(p2b-p2a)-gap);
        !           420:                        if(p1b-p1a>w)
        !           421:                                p1b = p1a;
        !           422:                        p4a = ltrim(ref,p4b=p2a-(isspace(p2a[-1])!=0),
        !           423:                                w=halflen-(p3b-p3a)-gap);
        !           424:                        if(p4b-p4a>w)
        !           425:                                p4a = p4b;
        !           426:                        fprintf(outptr,".xx \"");
        !           427:                        putout(p1a,p1b);
        !           428:        /* tilde-1 to account for extra space before TILDE */
        !           429:                        if(p1b!=(tilde-1) && p1a!=p1b)
        !           430:                                fprintf(outptr,"/");
        !           431:                        fprintf(outptr,"\" \"");
        !           432:                        if(p4a==p4b && p2a!=ref && p2a!=p2b)
        !           433:                                fprintf(outptr,"/");
        !           434:                        putout(p2a,p2b);
        !           435:                        fprintf(outptr,"\" \"");
        !           436:                        putout(p3a,p3b);
        !           437:        /* ++p3b to account for extra blank after TILDE */
        !           438:        /* ++p3b to account for extra space before TILDE */
        !           439:                        if(p1a==p1b && ++p3b!=tilde)
        !           440:                                fprintf(outptr,"/");
        !           441:                        fprintf(outptr,"\" \"");
        !           442:                        if(p1a==p1b && p4a!=ref && p4a!=p4b)
        !           443:                                fprintf(outptr,"/");
        !           444:                        putout(p4a,p4b);
        !           445:                        if(rflag)
        !           446:                                fprintf(outptr,"\" %s\n",tilde);
        !           447:                        else
        !           448:                                fprintf(outptr,"\"\n");
        !           449:                        linep = line;
        !           450:                        break;
        !           451: 
        !           452:                case '"':
        !           453:        /* put double " for "  */
        !           454:                        *linep++ = c;
        !           455:                default:
        !           456:                        *linep++ = c;
        !           457:                }
        !           458:        }
        !           459: }
        !           460: 
        !           461: char *rtrim(a,c,d)
        !           462: char *a,*c;
        !           463: {
        !           464:        char *b,*x;
        !           465:        b = c;
        !           466:        for(x=a+1; x<=c&&x-a<=d; x++)
        !           467:                if((x==c||isspace(x[0]))&&!isspace(x[-1]))
        !           468:                        b = x;
        !           469:        if(b<c&&!isspace(b[0]))
        !           470:                b++;
        !           471:        return(b);
        !           472: }
        !           473: 
        !           474: char *ltrim(c,b,d)
        !           475: char *c,*b;
        !           476: {
        !           477:        char *a,*x;
        !           478:        a = c;
        !           479:        for(x=b-1; x>=c&&b-x<=d; x--)
        !           480:                if(!isspace(x[0])&&(x==c||isspace(x[-1])))
        !           481:                        a = x;
        !           482:        if(a>c&&!isspace(a[-1]))
        !           483:                a--;
        !           484:        return(a);
        !           485: }
        !           486: 
        !           487: putout(strt,end)
        !           488: char *strt, *end;
        !           489: {
        !           490:        char *cp;
        !           491: 
        !           492:        cp = strt;
        !           493: 
        !           494:        for(cp=strt; cp<end; cp++) {
        !           495:                putc(*cp,outptr);
        !           496:        }
        !           497: }
        !           498: 
        !           499: onintr()
        !           500: {
        !           501: 
        !           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.