Annotation of coherent/d/bin/look.c, revision 1.1

1.1     ! root        1: /*     look.c - look for matching lines of text in a sorted file.
        !             2:  */
        !             3: #include       <stdio.h>
        !             4: #include       <ctype.h>
        !             5: 
        !             6: #define        TRUE    1
        !             7: #define        FALSE   0
        !             8: #define        EQ      1
        !             9: #define        LESS    0
        !            10: #define        GREATER 2
        !            11: #define        TAB     '       '
        !            12: #define        BSIZ    512
        !            13: 
        !            14: extern long    ftell() ;
        !            15: 
        !            16: /*     Globals
        !            17:  */
        !            18: 
        !            19: int    d_mode, f_mode ;
        !            20: long   top, bottom ;
        !            21: long   fsiz ;
        !            22: FILE   *fildes ;
        !            23: char   stbuf[BSIZ], rbuf[BSIZ] ;
        !            24: char   *rbufp ;
        !            25: 
        !            26: /*     getx -  Get the nex character from the character buffer.
        !            27:  *             If the buffer is empty get the next block.
        !            28:  */
        !            29: 
        !            30: /*  getx()
        !            31:  *  {
        !            32:  *     if (rbufp < &rbuf[BSIZ])
        !            33:  *             return(*rbufp++) ;
        !            34:  *     else {
        !            35:  *             gnb() ;
        !            36:  *             return(getx()) ;
        !            37:  *     }
        !            38:  *  }
        !            39:  */
        !            40: 
        !            41: #ifdef FIXED /* Bug in 8086 compiler */
        !            42: #define        getx()  ((rbuf < &rbuf[BSIZ]) ? *rbufp++ : (gnb(), *rbufp++))
        !            43: #else
        !            44: getx()
        !            45: {
        !            46:        if (rbufp >= &rbuf[BSIZ])
        !            47:                gnb();
        !            48:        return (*rbufp++);
        !            49: }
        !            50: #endif
        !            51: 
        !            52: /*     order - Order relation for characters. Returns GREATER, LESS or EQ.
        !            53:  */
        !            54: 
        !            55: /*  order(a, b)
        !            56:  *  {
        !            57:  *     if (a > b)
        !            58:  *             return(GREATER) ;
        !            59:  *     else if (a < b)
        !            60:  *             return(LESS) ;
        !            61:  *     return(EQ) ;
        !            62:  *  }
        !            63:  */
        !            64: 
        !            65: #define        order(a, b)     ((a > b) ? GREATER : ((a < b) ? LESS : EQ))
        !            66: 
        !            67: /*     isdict - Test for a dictionary character. From the class :
        !            68:  *              [a-zA-Z0-9 ].
        !            69:  */
        !            70: 
        !            71: /* isdict(ch)
        !            72:  * {
        !            73:  *     if (isalnum(ch) || (ch == ' '))
        !            74:  *             return(1) ;
        !            75:  *     return(0) ;
        !            76:  * }
        !            77:  */
        !            78: 
        !            79: #define        isdict(ch)      ((isalnum(ch) || (ch == ' ')) ? 1 : 0)
        !            80: 
        !            81: /*     main    - Get args, set flags and get the ball rolling.
        !            82:  */
        !            83: 
        !            84: main(argc, argv)
        !            85: register char  *argv[] ;
        !            86: {
        !            87:        ++argv ;
        !            88:        switch (argc) {
        !            89: 
        !            90:        case 4 :
        !            91:        case 3 :
        !            92:                        if (setop(argv[0])) {
        !            93:                                ++argv ;
        !            94:                                --argc ;
        !            95:                        } else
        !            96:                                if (argc == 4) {
        !            97:                                        form() ;
        !            98:                                        break ;
        !            99:                                }
        !           100:        case 2 :
        !           101:                        if (argc == 3)
        !           102:                                gfile(argv[1]) ;
        !           103:                        else
        !           104:                                gfile(NULL) ;
        !           105:                        if (gstring(argv[0])) {
        !           106:                                look() ;
        !           107:                                exit(0) ;
        !           108:                                break ;
        !           109:                        }
        !           110:        default :
        !           111:                        form() ;
        !           112:        }
        !           113:        exit(1) ;
        !           114: }
        !           115: 
        !           116: /*     setop - set option flags d_mode and f_mode. d_mode marks an occurance
        !           117:  *             of -d[f] or -[f]d and f_mode marks an occurance of -f[d] or
        !           118:  *             -[d]f.
        !           119:  */
        !           120: 
        !           121: setop(fp)
        !           122: register char  *fp ;
        !           123: {
        !           124:        register int    i ;
        !           125: 
        !           126:        d_mode = FALSE ;
        !           127:        f_mode = FALSE ;
        !           128: 
        !           129:        if (*fp++ != '-')
        !           130:                return(0) ;
        !           131:        else {
        !           132:                for (i = 0; i < 2; i++) {
        !           133:                        switch (*fp++) {
        !           134: 
        !           135:                        case 'd' :
        !           136:                                        d_mode = TRUE ;
        !           137:                                        break ;
        !           138:                        case 'f' :
        !           139:                                        f_mode = TRUE ;
        !           140:                                        break ;
        !           141:                        case '\0' :
        !           142:                                        --fp ;
        !           143:                                        return(1) ;
        !           144:                        default :
        !           145:                                        return(0) ;
        !           146:                        }
        !           147:                }
        !           148:                if (*fp != '\0')
        !           149:                        return(0) ;
        !           150:                return(1) ;
        !           151:        }
        !           152: }
        !           153: 
        !           154: /*     gstring - gets the match string <string> and places it in the 
        !           155:  *               stbuf buffer after conforming it to the d_mode and
        !           156:  *               f_mode options (That will make the compare routine 
        !           157:  *               faster). Returns the number of characters in stbuf.
        !           158:  */
        !           159: 
        !           160: gstring(fp)
        !           161: register char  *fp ;
        !           162: {
        !           163:        register int    nc ;
        !           164:        register char   *st ;
        !           165: 
        !           166:        nc = 0 ;
        !           167:        st = stbuf ;
        !           168:        while ((nc++ < BSIZ) && (*fp != '\0')) {
        !           169:                if (d_mode && !isdict(*fp)) {
        !           170:                        fp++ ;
        !           171:                        nc-- ;
        !           172:                        continue ;
        !           173:                }
        !           174:                if (f_mode && islower(*fp)) {
        !           175:                        *st++ = toupper(*fp++) ;
        !           176:                        continue ;
        !           177:                }
        !           178:                *st++ = *fp++ ;
        !           179:        }
        !           180:        if (nc >= BSIZ)
        !           181:                return(0) ;
        !           182:        return(nc) ;
        !           183: }
        !           184: 
        !           185: 
        !           186: /*     gfile - Gets the specified file and opens it for reading.
        !           187:  *             If no file is specified /usr/dict/words is opened.
        !           188:  */
        !           189: 
        !           190: gfile(fp)
        !           191: register char  *fp ;
        !           192: {
        !           193:        register char   *file ;
        !           194: 
        !           195:        if (fp == NULL) {
        !           196:                file = "/usr/dict/words" ;
        !           197:                d_mode = TRUE ;
        !           198:                f_mode = TRUE ;
        !           199:        } else
        !           200:                file = fp ;
        !           201:        
        !           202:        if ((fildes = fopen(file, "r")) == NULL) {
        !           203:                aww("look : Cannot open file") ;
        !           204:                exit(1) ;
        !           205:        }
        !           206: 
        !           207:        bottom = 0 ;
        !           208:        if (fseek(fildes, 0L, 2) == -1) {
        !           209:                aww("look : Cannot seek on file") ;
        !           210:                exit(1) ;
        !           211:        }
        !           212: 
        !           213:        top = ftell(fildes) ;
        !           214:        top -= 2 ;
        !           215:        fsiz = top ;
        !           216: 
        !           217: 
        !           218:        return(1) ;
        !           219: }
        !           220: 
        !           221: /*     aww - Error condition. Prints out the passed string.
        !           222:  */
        !           223: 
        !           224: aww(sp)
        !           225: char   *sp ;
        !           226: {
        !           227:        fprintf(stderr, "%s\n", sp) ;
        !           228: }
        !           229: 
        !           230: /*     form - Prints out a Usage message.
        !           231:  */
        !           232: 
        !           233: form()
        !           234: {
        !           235:        fprintf(stderr, "Usage : look [-df] string [file]\n") ;
        !           236: }
        !           237: 
        !           238: /*     look - Binary search looking for a string match. If a match
        !           239:  *            is found (the EQ case) all the strings that match
        !           240:  *            are printed and then we quit else the window is 
        !           241:  *            decreased and the test goes on.
        !           242:  */
        !           243: 
        !           244: look()
        !           245: {
        !           246:        register int    nmove ;
        !           247:        long    mid1, mid2 ;
        !           248:        long    gll() ;
        !           249:        long    gteol() ;
        !           250: 
        !           251:        while (top != bottom) {
        !           252:                mid1 = (top - bottom)/2 + bottom ;
        !           253:                mid2 = gll(mid1) ;
        !           254:                nmove = comstr() ;
        !           255:                switch (nmove) {
        !           256: 
        !           257:                case EQ :
        !           258:                                wstr(mid2) ;
        !           259:                                return(1) ;
        !           260:                case GREATER :
        !           261:                                bottom = gteol(mid1) ;
        !           262:                                break ;
        !           263:                case LESS :
        !           264:                                top = mid2 - 2 ;
        !           265:                                break ;
        !           266:                }
        !           267:                if (top < bottom)
        !           268:                        top = bottom ;
        !           269:        }
        !           270: }
        !           271: 
        !           272: 
        !           273: /*     wstr -  We found a string that matches but we are not sure that
        !           274:  *             this is the only occurance of a matched string and hence
        !           275:  *             we must back up until we find a non match and print 
        !           276:  *             forward till we find a non match in the other direction.
        !           277:  */
        !           278: 
        !           279: wstr(seek)
        !           280: long   seek ;
        !           281: {
        !           282:        long    temp1, temp2 ;
        !           283:        long    gll() ;
        !           284: 
        !           285:        if (seek != 0) {
        !           286:                temp2 = seek ;
        !           287:                temp1 = gll(seek - 2) ;
        !           288:                while (comstr() == EQ) {
        !           289:                        temp2 = temp1 ;
        !           290:                        if (temp1 == 0)
        !           291:                                break ;
        !           292:                        else
        !           293:                                temp1 = gll(temp1 - 2) ;
        !           294:                }
        !           295:        } else
        !           296:                temp2 = 0 ;
        !           297:        fseek(fildes, temp2, 0) ;
        !           298:        while (ftell(fildes) <= seek) {
        !           299:                fgets(rbuf, BSIZ, fildes) ;
        !           300:                fputs(rbuf, stdout) ;
        !           301:        }
        !           302:        fgets(rbuf, BSIZ, fildes) ;
        !           303:        rbufp = rbuf ;
        !           304:        while (comstr() == EQ) {
        !           305:                fputs(rbuf, stdout) ;
        !           306:                fgets(rbuf, BSIZ, fildes) ;
        !           307:                rbufp = rbuf ;
        !           308:        }
        !           309:        return(1) ;
        !           310: }
        !           311: 
        !           312: /*     comstr - Compare the base string to the input line.
        !           313:  *              Returns a stat telling what the difference between the
        !           314:  *              two strings is. EQ is equal, GREATER implies the base string
        !           315:  *              is greater then the input string and LESS is vice versa.
        !           316:  */
        !           317: 
        !           318: comstr()
        !           319: {
        !           320:        register int    state ;
        !           321:        register int    ch ;
        !           322:        register char   *sp ;
        !           323: 
        !           324:        sp = stbuf ;
        !           325:        while (*sp != '\0') {
        !           326:                ch = getx() ;
        !           327:                if (ch == '\n')
        !           328:                        return(GREATER) ;
        !           329:                if (d_mode && !isdict(ch)) {
        !           330:                        continue ;
        !           331:                }
        !           332:                if (f_mode && islower(ch))
        !           333:                        ch = toupper(ch) ;
        !           334:                if ((state = order(*sp, ch)) != EQ) {
        !           335:                        return(state) ;
        !           336:                }
        !           337:                ++sp ;
        !           338:        }
        !           339:        return(EQ) ;
        !           340: }
        !           341: 
        !           342: /*     gll -   Get last line. Using the seek variable, returns a pointer to
        !           343:  *             the beginning of the last line of text. If neccesary
        !           344:  *             gll will wind back seek a block at a time looking for
        !           345:  *             the last line.
        !           346:  */
        !           347: 
        !           348: long
        !           349: gll(seek)
        !           350: long   seek ;
        !           351: {
        !           352:        register char   *cp ;
        !           353:        register int    tmp ;
        !           354: 
        !           355:        if (seek == 0) {
        !           356:                rbufp = rbuf ;
        !           357:                return(0) ;
        !           358:        }
        !           359: 
        !           360:        if (seek < BSIZ) {
        !           361:                cp = &rbuf[(int) seek] ;
        !           362:                seek = 0 ;
        !           363:                fseek(fildes, 0L, 0) ;
        !           364:        } else {
        !           365:                cp = &rbuf[BSIZ - 1] ;
        !           366:                seek -= BSIZ ;
        !           367:                fseek(fildes, seek, 0) ;
        !           368:        }
        !           369:        fread(rbuf, sizeof(*cp), BSIZ, fildes) ;
        !           370: 
        !           371:        while (cp >= rbuf) {
        !           372:                if (*cp == '\n')
        !           373:                        break ;
        !           374:                --cp ;
        !           375:        }
        !           376: 
        !           377:        if (*cp == '\n') {
        !           378:                rbufp = ++cp ;
        !           379:                tmp = cp - rbuf ;
        !           380:                seek += (long) tmp ;
        !           381:                if (seek > fsiz)
        !           382:                        return(-1) ;
        !           383:                fseek(fildes, seek, 0) ;
        !           384:                fread(rbuf, sizeof(*rbufp), BSIZ, fildes) ;
        !           385:                rbufp = rbuf ;
        !           386:                return(seek) ;
        !           387:        } else
        !           388:                return(gll(seek)) ;
        !           389: }
        !           390: 
        !           391: /*     gnb -   Get the next block from the file and adjust the 
        !           392:  *             character buffer pointer.
        !           393:  */
        !           394: 
        !           395: gnb()
        !           396: {
        !           397:        fseek(fildes, 512L, 1) ;
        !           398:        fread(rbuf, sizeof(*rbufp), BSIZ, fildes) ;
        !           399:        rbufp = rbuf ;
        !           400:        return(1) ;
        !           401: }
        !           402: 
        !           403: /*     gteol - Go to end of line. Returns the seek adress of the end of line.
        !           404:  */
        !           405: 
        !           406: long
        !           407: gteol(seek)
        !           408: long   seek ;
        !           409: {
        !           410:        if (seek >= fsiz)
        !           411:                return(fsiz) ;
        !           412:        fseek(fildes, seek, 0) ;
        !           413:        while (fgetc(fildes) != '\n')
        !           414:                ;
        !           415:        return(ftell(fildes)) ;
        !           416: }
        !           417: 

unix.superglobalmegacorp.com

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