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

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid = "@(#)ptx.c       4.3 (Berkeley) 12/2/87";
        !             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 /usr/lib/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: #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:        if(sortfile)
        !           249:                unlink(sortfile);
        !           250:        exit(0);
        !           251: }
        !           252: 
        !           253: msg(s,arg)
        !           254: char *s;
        !           255: char *arg;
        !           256: {
        !           257:        fprintf(stderr,"%s %s\n",s,arg);
        !           258:        return;
        !           259: }
        !           260: diag(s,arg)
        !           261: char *s, *arg;
        !           262: {
        !           263: 
        !           264:        msg(s,arg);
        !           265:        exit(1);
        !           266: }
        !           267: 
        !           268: 
        !           269: char *getline()
        !           270: {
        !           271: 
        !           272:        register c;
        !           273:        register char *linep;
        !           274:        char *endlinep;
        !           275: 
        !           276: 
        !           277:        endlinep= line + mlen;
        !           278:        linep = line;
        !           279:        /* Throw away leading white space */
        !           280: 
        !           281:        while(isspace(c=getc(inptr)))
        !           282:                ;
        !           283:        if(c==EOF)
        !           284:                return(0);
        !           285:        ungetc(c,inptr);
        !           286:        while(( c=getc(inptr)) != EOF) {
        !           287:                switch (c) {
        !           288: 
        !           289:                        case '\t':
        !           290:                                if(linep<endlinep)
        !           291:                                        *linep++ = ' ';
        !           292:                                break;
        !           293:                        case '\n':
        !           294:                                while(isspace(*--linep));
        !           295:                                *++linep = '\n';
        !           296:                                return(linep);
        !           297:                        default:
        !           298:                                if(linep < endlinep)
        !           299:                                        *linep++ = c;
        !           300:                }
        !           301:        }
        !           302:        return(0);
        !           303: }
        !           304: 
        !           305: cmpline(pend)
        !           306: char *pend;
        !           307: {
        !           308: 
        !           309:        char *pstrt, *pchar, *cp;
        !           310:        char **hp;
        !           311:        int flag;
        !           312: 
        !           313:        pchar = line;
        !           314:        if(rflag)
        !           315:                while(pchar<pend&&!isspace(*pchar))
        !           316:                        pchar++;
        !           317:        while(pchar<pend){
        !           318:        /* eliminate white space */
        !           319:                if(isabreak(*pchar++))
        !           320:                        continue;
        !           321:                pstrt = --pchar;
        !           322: 
        !           323:                flag = 1;
        !           324:                while(flag){
        !           325:                        if(isabreak(*pchar)) {
        !           326:                                hp = &hasht[hash(pstrt,pchar)];
        !           327:                                pchar--;
        !           328:                                while(cp = *hp++){
        !           329:                                        if(hp == &hasht[MAXT])
        !           330:                                                hp = hasht;
        !           331:        /* possible match */
        !           332:                                        if(cmpword(pstrt,pchar,cp)){
        !           333:        /* exact match */
        !           334:                                                if(!ignore && only)
        !           335:                                                        putline(pstrt,pend);
        !           336:                                                flag = 0;
        !           337:                                                break;
        !           338:                                        }
        !           339:                                }
        !           340:        /* no match */
        !           341:                                if(flag){
        !           342:                                        if(ignore || !only)
        !           343:                                                putline(pstrt,pend);
        !           344:                                        flag = 0;
        !           345:                                }
        !           346:                        }
        !           347:                pchar++;
        !           348:                }
        !           349:        }
        !           350: }
        !           351: 
        !           352: cmpword(cpp,pend,hpp)
        !           353: char *cpp, *pend, *hpp;
        !           354: {
        !           355:        char c;
        !           356: 
        !           357:        while(*hpp != '\0'){
        !           358:                c = *cpp++;
        !           359:                if((isupper(c)?tolower(c):c) != *hpp++)
        !           360:                        return(0);
        !           361:        }
        !           362:        if(--cpp == pend) return(1);
        !           363:        return(0);
        !           364: }
        !           365: 
        !           366: putline(strt, end)
        !           367: char *strt, *end;
        !           368: {
        !           369:        char *cp;
        !           370: 
        !           371:        for(cp=strt; cp<end; cp++)
        !           372:                putc(*cp, sortptr);
        !           373:        /* Add extra blank before TILDE to sort correctly
        !           374:           with -fd option */
        !           375:        putc(' ',sortptr);
        !           376:        putc(TILDE,sortptr);
        !           377:        for (cp=line; cp<strt; cp++)
        !           378:                putc(*cp,sortptr);
        !           379:        putc('\n',sortptr);
        !           380: }
        !           381: 
        !           382: getsort()
        !           383: {
        !           384:        register c;
        !           385:        register char *tilde, *linep, *ref;
        !           386:        char *p1a,*p1b,*p2a,*p2b,*p3a,*p3b,*p4a,*p4b;
        !           387:        int w;
        !           388:        char *rtrim(), *ltrim();
        !           389: 
        !           390:        if((sortptr = fopen(sortfile,"r")) == NULL)
        !           391:                diag("Cannot open sorted data:",sortfile);
        !           392: 
        !           393:        halflen = (llen-gutter)/2;
        !           394:        linep = line;
        !           395:        while((c = getc(sortptr)) != EOF) {
        !           396:                switch(c) {
        !           397: 
        !           398:                case TILDE:
        !           399:                        tilde = linep;
        !           400:                        break;
        !           401: 
        !           402:                case '\n':
        !           403:                        while(isspace(linep[-1]))
        !           404:                                linep--;
        !           405:                        ref = tilde;
        !           406:                        if(rflag) {
        !           407:                                while(ref<linep&&!isspace(*ref))
        !           408:                                        ref++;
        !           409:                                *ref++ = 0;
        !           410:                        }
        !           411:                /* the -1 is an overly conservative test to leave
        !           412:                   space for the / that signifies truncation*/
        !           413:                        p3b = rtrim(p3a=line,tilde,halflen-1);
        !           414:                        if(p3b-p3a>halflen-1)
        !           415:                                p3b = p3a+halflen-1;
        !           416:                        p2a = ltrim(ref,p2b=linep,halflen-1);
        !           417:                        if(p2b-p2a>halflen-1)
        !           418:                                p2a = p2b-halflen-1;
        !           419:                        p1b = rtrim(p1a=p3b+(isspace(p3b[0])!=0),tilde,
        !           420:                                w=halflen-(p2b-p2a)-gap);
        !           421:                        if(p1b-p1a>w)
        !           422:                                p1b = p1a;
        !           423:                        p4a = ltrim(ref,p4b=p2a-(isspace(p2a[-1])!=0),
        !           424:                                w=halflen-(p3b-p3a)-gap);
        !           425:                        if(p4b-p4a>w)
        !           426:                                p4a = p4b;
        !           427:                        fprintf(outptr,".xx \"");
        !           428:                        putout(p1a,p1b);
        !           429:        /* tilde-1 to account for extra space before TILDE */
        !           430:                        if(p1b!=(tilde-1) && p1a!=p1b)
        !           431:                                fprintf(outptr,"/");
        !           432:                        fprintf(outptr,"\" \"");
        !           433:                        if(p4a==p4b && p2a!=ref && p2a!=p2b)
        !           434:                                fprintf(outptr,"/");
        !           435:                        putout(p2a,p2b);
        !           436:                        fprintf(outptr,"\" \"");
        !           437:                        putout(p3a,p3b);
        !           438:        /* ++p3b to account for extra blank after TILDE */
        !           439:        /* ++p3b to account for extra space before TILDE */
        !           440:                        if(p1a==p1b && ++p3b!=tilde)
        !           441:                                fprintf(outptr,"/");
        !           442:                        fprintf(outptr,"\" \"");
        !           443:                        if(p1a==p1b && p4a!=ref && p4a!=p4b)
        !           444:                                fprintf(outptr,"/");
        !           445:                        putout(p4a,p4b);
        !           446:                        if(rflag)
        !           447:                                fprintf(outptr,"\" %s\n",tilde);
        !           448:                        else
        !           449:                                fprintf(outptr,"\"\n");
        !           450:                        linep = line;
        !           451:                        break;
        !           452: 
        !           453:                case '"':
        !           454:        /* put double " for "  */
        !           455:                        *linep++ = c;
        !           456:                default:
        !           457:                        *linep++ = c;
        !           458:                }
        !           459:        }
        !           460: }
        !           461: 
        !           462: char *rtrim(a,c,d)
        !           463: char *a,*c;
        !           464: {
        !           465:        char *b,*x;
        !           466:        b = c;
        !           467:        for(x=a+1; x<=c&&x-a<=d; x++)
        !           468:                if((x==c||isspace(x[0]))&&!isspace(x[-1]))
        !           469:                        b = x;
        !           470:        if(b<c&&!isspace(b[0]))
        !           471:                b++;
        !           472:        return(b);
        !           473: }
        !           474: 
        !           475: char *ltrim(c,b,d)
        !           476: char *c,*b;
        !           477: {
        !           478:        char *a,*x;
        !           479:        a = c;
        !           480:        for(x=b-1; x>=c&&b-x<=d; x--)
        !           481:                if(!isspace(x[0])&&(x==c||isspace(x[-1])))
        !           482:                        a = x;
        !           483:        if(a>c&&!isspace(a[-1]))
        !           484:                a--;
        !           485:        return(a);
        !           486: }
        !           487: 
        !           488: putout(strt,end)
        !           489: char *strt, *end;
        !           490: {
        !           491:        char *cp;
        !           492: 
        !           493:        cp = strt;
        !           494: 
        !           495:        for(cp=strt; cp<end; cp++) {
        !           496:                putc(*cp,outptr);
        !           497:        }
        !           498: }
        !           499: 
        !           500: onintr()
        !           501: {
        !           502: 
        !           503:        if(sortfile)
        !           504:                unlink(sortfile);
        !           505:        exit(1);
        !           506: }
        !           507: 
        !           508: hash(strtp,endp)
        !           509: char *strtp, *endp;
        !           510: {
        !           511:        char *cp, c;
        !           512:        int i, j, k;
        !           513: 
        !           514:        /* Return zero hash number for single letter words */
        !           515:        if((endp - strtp) == 1)
        !           516:                return(0);
        !           517: 
        !           518:        cp = strtp;
        !           519:        c = *cp++;
        !           520:        i = (isupper(c)?tolower(c):c);
        !           521:        c = *cp;
        !           522:        j = (isupper(c)?tolower(c):c);
        !           523:        i = i*j;
        !           524:        cp = --endp;
        !           525:        c = *cp--;
        !           526:        k = (isupper(c)?tolower(c):c);
        !           527:        c = *cp;
        !           528:        j = (isupper(c)?tolower(c):c);
        !           529:        j = k*j;
        !           530: 
        !           531:        k = (i ^ (j>>2)) & MASK;
        !           532:        return(k);
        !           533: }
        !           534: 
        !           535: storeh(num,strtp)
        !           536: int num;
        !           537: char *strtp;
        !           538: {
        !           539:        int i;
        !           540: 
        !           541:        for(i=num; i<MAXT; i++) {
        !           542:                if(hasht[i] == 0) {
        !           543:                        hasht[i] = strtp;
        !           544:                        return(0);
        !           545:                }
        !           546:        }
        !           547:        for(i=0; i<num; i++) {
        !           548:                if(hasht[i] == 0) {
        !           549:                        hasht[i] = strtp;
        !           550:                        return(0);
        !           551:                }
        !           552:        }
        !           553:        return(1);
        !           554: }

unix.superglobalmegacorp.com

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