Annotation of researchv10no/cmd/ptx.c, revision 1.1

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

unix.superglobalmegacorp.com

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