Annotation of os2sdk/demos/apps/cpgrep/cpgrep.c, revision 1.1

1.1     ! root        1: /* cpgrep
        !             2: *
        !             3: * HISTORY:
        !             4: * 23-Mar-87     danl    exit(x) -> DOSEXIT(1, x)
        !             5: *
        !             6: */
        !             7: 
        !             8: #include               <stdio.h>
        !             9: #include               <fcntl.h>
        !            10: #include               <ctype.h>
        !            11: 
        !            12: int far pascal         DOSCREATETHREAD(void (far *)(),int far *,int far *);
        !            13: int far pascal         DOSGETMACHINEMODE(char far *);
        !            14: int far pascal         DOSQHANDTYPE(int,int far *,int far *);
        !            15: int far pascal         DOSREAD(int,char far *,int,int far *);
        !            16: int far pascal         DOSSEMCLEAR(long far *);
        !            17: int far pascal         DOSSEMREQUEST(long far *,long);
        !            18: int far pascal         DOSSEMSET(long far *);
        !            19: int far pascal         DOSSEMWAIT(long far *,long);
        !            20: int far pascal         DOSSLEEP(long);
        !            21: int far pascal         DOSWRITE(int,char far *,int,int far *);
        !            22: int far pascal         DOSEXIT(int, int);
        !            23: 
        !            24: #define        BEGLINE         0x40
        !            25: #define        DEBUG           0x08
        !            26: #define        ENDLINE         0x80
        !            27: #define        FILBUFLEN       (SECTORLEN*30)
        !            28: #define        FILNAMLEN       80
        !            29: #define        INVERT          0x10
        !            30: #define        ISCOT           0x0002
        !            31: #define        LG2SECLEN       9
        !            32: #define        LINELEN         128
        !            33: #define        LINENOS         0x04
        !            34: #define        LNOLEN          8
        !            35: #define        MAXSTRLEN       128
        !            36: #define        NAMEONLY        0x02
        !            37: #define        OUTBUFLEN       (SECTORLEN*4)
        !            38: #define        SECTORLEN       (1 << LG2SECLEN)
        !            39: #define        SHOWNAME        0x01
        !            40: #define        STKLEN          256
        !            41: #define        TIMER           0x20
        !            42: #define        TRTABLEN        256
        !            43: #define        s_text(x)       (((char *)(x)) - ((x)->s_must))
        !            44: 
        !            45: typedef struct stringnode
        !            46:   {
        !            47:     struct stringnode  *s_alt;         /* List of alternates */
        !            48:     struct stringnode  *s_suf;         /* List of suffixes */
        !            49:     int                        s_must;         /* Length of portion that must match */
        !            50:   }
        !            51:                        STRINGNODE;
        !            52: 
        !            53: char                   filbuf[(FILBUFLEN + 2)*2];
        !            54: char                   *bufptr[] = { filbuf, filbuf + FILBUFLEN + 2 };
        !            55: char                   outbuf[OUTBUFLEN*2];
        !            56: char                   *obuf[] = { outbuf, outbuf + OUTBUFLEN };
        !            57: char                   *optr[] = { outbuf, outbuf + OUTBUFLEN };
        !            58: int                    ocnt[] = { OUTBUFLEN, OUTBUFLEN };
        !            59: int                    oi = 0;
        !            60: char                   transtab[TRTABLEN] = { 0 };
        !            61: STRINGNODE             *stringlist[TRTABLEN/2];
        !            62: int                    arrc;           /* I/O return code for DOSREAD */
        !            63: int                    awrc;           /* I/O return code for DOSWRITE */
        !            64: int                    casesen = 1;    /* Assume case-sensitivity */
        !            65: int                    cbread;         /* Bytes read by DOSREAD */
        !            66: int                    cbwrite;        /* Bytes written by DOSWRITE */
        !            67: int                    clists = 1;     /* One is first available index */
        !            68: int                    flags;          /* Flags */
        !            69: int                    lineno;         /* Current line number */
        !            70: char                   pmode;          /* Protected mode flag */
        !            71: long                   readdone;       /* Async read done semaphore */
        !            72: long                   readpending;    /* Async read pending semaphore */
        !            73: int                    status = 1;     /* Assume failure */
        !            74: char                   *t2buf;         /* Async read buffer */
        !            75: int                    t2buflen;       /* Async read buffer length */
        !            76: int                    t2fd;           /* Async read file */
        !            77: char                   *t3buf;         /* Async write buffer */
        !            78: int                    t3buflen;       /* Async write buffer length */
        !            79: int                    t3fd;           /* Async write file */
        !            80: long                   writedone;      /* Async write done semaphore */
        !            81: long                   writepending;   /* Async write pending semaphore */
        !            82: char                   target[MAXSTRLEN];
        !            83:                                        /* Last string added */
        !            84: int                    targetlen;      /* Length of last string added */
        !            85: 
        !            86: int                    countlines();   /* See CPGREPSB.ASM */
        !            87: int                    countmatched(); /* See CPGREPSB.ASM */
        !            88: char                   *findlist();    /* See CPGREPSB.ASM */
        !            89: char                   *findone();     /* See CPGREPSB.ASM */
        !            90: void                   flush1buf();    /* See below */
        !            91: int                    grepbuffer();   /* See below */
        !            92: int                    revfind();      /* See CPGREPSB.ASM */
        !            93: void                   write1buf();    /* See below */
        !            94: char                   *(*find)() = findlist;
        !            95: void                   (*flush1)() = flush1buf;
        !            96: int                    (*grep)() = grepbuffer;
        !            97: void                   (*write1)() = write1buf;
        !            98: 
        !            99: void                   freenode(x)
        !           100: register STRINGNODE    *x;             /* Pointer to node to free */
        !           101:   {
        !           102:     register STRINGNODE        *y;             /* Pointer to next node in list */
        !           103: 
        !           104:     while(x != NULL)                   /* While not at end of list */
        !           105:       {
        !           106:        if(x->s_suf != NULL) freenode(x->s_suf);
        !           107:                                        /* Free suffix list */
        !           108:        y = x;                          /* Save pointer */
        !           109:        x = x->s_alt;                   /* Move down the list */
        !           110:        free(y);                        /* Free the node */
        !           111:       }
        !           112:   }
        !           113: 
        !           114: 
        !           115: STRINGNODE             *newnode(s,n)
        !           116: char                   *s;             /* String */
        !           117: int                    n;              /* Length of string */
        !           118:   {
        !           119:     register STRINGNODE        *new;           /* Pointer to new node */
        !           120:     char               *t;             /* String pointer */
        !           121:     char               *malloc();      /* Storage allocator */
        !           122: 
        !           123:     if((t = malloc(sizeof(STRINGNODE) + n + (n & 1))) == NULL)
        !           124:       {                                        /* If allocation fails */
        !           125:        fprintf(stderr,"Out of memory\n");
        !           126:        DOSEXIT(1, 2);                        /* Print error message and die */
        !           127:       }
        !           128:     if(n & 1) ++t;                     /* END of string word-aligned */
        !           129:     strncpy(t,s,n);                    /* Copy string text */
        !           130:     new = (STRINGNODE *)(t + n);       /* Set pointer to node */
        !           131:     new->s_alt = NULL;                 /* No alternates yet */
        !           132:     new->s_suf = NULL;                 /* No suffixes yet */
        !           133:     new->s_must = n;                   /* Set string length */
        !           134:     return(new);                       /* Return pointer to new node */
        !           135:   }
        !           136: 
        !           137: 
        !           138: void                   reallocnode(node,s,n)
        !           139: register STRINGNODE    *node;          /* Pointer to node */
        !           140: char                   *s;             /* String */
        !           141: register int           n;              /* Length of string */
        !           142:   {
        !           143:     if(n > node->s_must)               /* If node must grow */
        !           144:       {
        !           145:        fprintf(stderr,"Internal error\n");
        !           146:                                        /* Error message */
        !           147:        DOSEXIT(1, 2);                        /* Error exit */
        !           148:       }
        !           149:     node->s_must = n;                  /* Set new length */
        !           150:     memcpy(s_text(node),s,n);          /* Copy new text */
        !           151:   }
        !           152: 
        !           153: 
        !           154: void                   addstring(s,n)
        !           155: char                   *s;             /* String to add */
        !           156: int                    n;              /* Length of string */
        !           157:   {
        !           158:     register STRINGNODE        *cur;           /* Current string */
        !           159:     register STRINGNODE        **pprev;        /* Pointer to previous link */
        !           160:     STRINGNODE         *new;           /* New string */
        !           161:     int                        i;              /* Index */
        !           162:     int                        j;              /* Count */
        !           163:     int                        k;              /* Count */
        !           164: 
        !           165:     if(n <= 0 || n > 127) return;      /* Should never happen */
        !           166:     i = transtab[*s];                  /* Get current index */
        !           167:     if(i == 0)                         /* If no existing list */
        !           168:       {
        !           169:        /*
        !           170:         *  We have to start a new list
        !           171:         */
        !           172:        if((i = clists++) >= TRTABLEN/2)
        !           173:          {                             /* If too many string lists */
        !           174:            fprintf(stderr,"Too many string lists\n");
        !           175:                                        /* Error message */
        !           176:            DOSEXIT(1, 2);                    /* Die */
        !           177:          }
        !           178:        stringlist[i] = NULL;           /* Initialize */
        !           179:        transtab[*s] = i;               /* Set pointer to new list */
        !           180:        if(!casesen && isalpha(*s)) transtab[*s ^ '\x20'] = i;
        !           181:                                        /* Set pointer for other case */
        !           182:       }
        !           183:     else if(stringlist[i] == NULL) return;
        !           184:                                        /* Check for existing 1-byte string */
        !           185:     if(--n == 0)                       /* If 1-byte string */
        !           186:       {
        !           187:        freenode(stringlist[i]);        /* Free any existing stuff */
        !           188:        stringlist[i] = NULL;           /* No record here */
        !           189:        return;                         /* Done */
        !           190:       }
        !           191:     ++s;                               /* Skip first char */
        !           192:     pprev = stringlist + i;            /* Get pointer to link */
        !           193:     cur = *pprev;                      /* Get pointer to node */
        !           194:     while(cur != NULL)                 /* Loop to traverse match tree */
        !           195:       {
        !           196:        i = (n > cur->s_must)? cur->s_must: n;
        !           197:                                        /* Find minimum of string lengths */
        !           198:        matchstrings(s,s_text(cur),i,&j,&k);
        !           199:                                        /* Compare the strings */
        !           200:        if(j == 0)                      /* If complete mismatch */
        !           201:          {
        !           202:            if(k < 0) break;            /* Break if insertion point found */
        !           203:            pprev = &(cur->s_alt);      /* Get pointer to alternate link */
        !           204:            cur = *pprev;               /* Follow the link */
        !           205:          }
        !           206:        else if(i == j)                 /* Else if strings matched */
        !           207:          {
        !           208:            if(i == n)                  /* If new is prefix of current */
        !           209:              {
        !           210:                reallocnode(cur,s_text(cur),n);
        !           211:                                        /* Shorten text of node */
        !           212:                if(cur->s_suf != NULL)  /* If there are suffixes */
        !           213:                  {
        !           214:                    freenode(cur->s_suf);
        !           215:                                        /* Suffixes no longer needed */
        !           216:                    cur->s_suf = NULL;
        !           217:                  }
        !           218:                return;                 /* All done */
        !           219:              }
        !           220:            pprev = &(cur->s_suf);      /* Get pointer to suffix link */
        !           221:            if((cur = *pprev) == NULL) return;
        !           222:                                        /* Done if current is prefix of new */
        !           223:            s += i;                     /* Skip matched portion */
        !           224:            n -= i;
        !           225:          }
        !           226:        else                            /* Else partial match */
        !           227:          {
        !           228:            /*
        !           229:             *  We must split an existing node.
        !           230:             *  This is the trickiest case.
        !           231:             */
        !           232:            new = newnode(s_text(cur) + j,cur->s_must - j);
        !           233:                                        /* Unmatched part of current string */
        !           234:            reallocnode(cur,s_text(cur),j);
        !           235:                                        /* Set length to matched portion */
        !           236:            new->s_suf = cur->s_suf;    /* Current string's suffixes */
        !           237:            if(k < 0)                   /* If new preceded current */
        !           238:              {
        !           239:                cur->s_suf = newnode(s + j,n - j);
        !           240:                                        /* FIrst suffix is new string */
        !           241:                cur->s_suf->s_alt = new;/* Alternate is part of current */
        !           242:              }
        !           243:            else                        /* Else new followed current */
        !           244:              {
        !           245:                new->s_alt = newnode(s + j,n - j);
        !           246:                                        /* Unmatched new string is alternate */
        !           247:                cur->s_suf = new;       /* New suffix list */
        !           248:              }
        !           249:            return;
        !           250:          }
        !           251:       }
        !           252:     *pprev = newnode(s,n);             /* Set pointer to new node */
        !           253:     (*pprev)->s_alt = cur;             /* Attach alternates */
        !           254:   }
        !           255: 
        !           256: 
        !           257: int                    addfancy(buffer,buflen,seplist)
        !           258: register char          *buffer;        /* Buffer */
        !           259: int                    buflen;         /* Length of buffer */
        !           260: char                   *seplist;       /* List of separators */
        !           261:   {
        !           262:     register char      *bufend;        /* Pointer to end of buffer */
        !           263:     int                        strcnt = 0;     /* String count */
        !           264:     int                        len;            /* String length */
        !           265:     char               c;              /* One char buffer */
        !           266: 
        !           267:     bufend = buffer + buflen;          /* Set end pointer */
        !           268:     while(buffer < bufend)             /* Loop through all strings */
        !           269:       {
        !           270:        len = strncspn(buffer,seplist,bufend - buffer);
        !           271:                                        /* Length of string */
        !           272:        if(flags & ENDLINE)             /* If match must be at end of line */
        !           273:          {
        !           274:            c = buffer[len];            /* Save 1st character past string */
        !           275:            buffer[len++] = '\r';       /* Carriage return marks end of line */
        !           276:          }
        !           277:        if(findlist(buffer,buffer + len) == NULL)
        !           278:          {                             /* If no match within string */
        !           279:            addstring(buffer,len);      /* Add string to list */
        !           280:            if(strcnt++ == 0)           /* If first string */
        !           281:              {
        !           282:                memcpy(target,buffer,len);
        !           283:                                        /* Save first string in buffer */
        !           284:                targetlen = len;        /* Remember length */
        !           285:              }
        !           286:          }
        !           287:        buffer += len;                  /* Skip over string */
        !           288:        if(flags & ENDLINE) (--buffer)[0] = c;
        !           289:                                        /* Restore saved character */
        !           290:        buffer += strnspn(buffer,seplist,bufend - buffer);
        !           291:                                        /* Skip over trailing separators */
        !           292:       }
        !           293:     return(strcnt);                    /* Return string count */
        !           294:   }
        !           295: 
        !           296: 
        !           297: int                    addplain(buffer,buflen,seplist)
        !           298: register char          *buffer;        /* String list buffer */
        !           299: int                    buflen;         /* Buffer length */
        !           300: char                   *seplist;       /* List of separators */
        !           301:   {
        !           302:     int                        strcnt;         /* String count */
        !           303:     register int       len;            /* String length */
        !           304:     char               c;              /* One char buffer */
        !           305: 
        !           306:     strcnt = 0;
        !           307:     while((len = strncspn(buffer,seplist,buflen)) > 0)
        !           308:       {                                        /* While not at end of input list */
        !           309:        if(flags & ENDLINE)             /* If match must be at end of line */
        !           310:          {
        !           311:            c = buffer[len];            /* Save 1st character past string */
        !           312:            buffer[len++] = '\r';       /* Carriage return marks end of line */
        !           313:          }
        !           314:        if(strcnt == 0)                 /* Save first string */
        !           315:          {
        !           316:            strncpy(target,buffer,len); /* Save string in buffer */
        !           317:            targetlen = len;            /* Save string length */
        !           318:          }
        !           319:        addstring(buffer,len);          /* Add the string to the table */
        !           320:        if(flags & ENDLINE) buffer[--len] = c;
        !           321:                                        /* Restore saved character */
        !           322:        buffer += len;                  /* Skip the string */
        !           323:        buflen -= len;
        !           324:        len = strnspn(buffer,seplist,buflen);
        !           325:                                        /* Skip separators */
        !           326:        buffer += len;
        !           327:        buflen -= len;
        !           328:        ++strcnt;                       /* Increment string count */
        !           329:       }
        !           330:     return(strcnt);                    /* Return string count */
        !           331:   }
        !           332: 
        !           333: 
        !           334: void                   dumplist(node,indent)
        !           335: register STRINGNODE    *node;          /* Pointer to list to dump */
        !           336: int                    indent;         /* Current length of buffer */
        !           337:   {
        !           338:     int                        i;              /* Counter */
        !           339: 
        !           340:     while(node != NULL)                        /* While not at end of list */
        !           341:       {
        !           342:        for(i = 0; i < indent; ++i) fputc(' ',stderr);
        !           343:        fwrite(s_text(node),sizeof(char),node->s_must,stderr);
        !           344:        fprintf(stderr,"\n");
        !           345:        if(node->s_suf != NULL)
        !           346:          dumplist(node->s_suf,indent + node->s_must);
        !           347:                                        /* Recurse to do suffixes */
        !           348:        node = node->s_alt;             /* Do next alternate in list */
        !           349:       }
        !           350:   }
        !           351: 
        !           352: 
        !           353: void                   dumpstrings()
        !           354:   {
        !           355:     int                        i;              /* Index */
        !           356: 
        !           357:     for(i = 0; i < TRTABLEN; ++i)      /* Loop through translation table */
        !           358:       {
        !           359:        if(transtab[i] == 0) continue;  /* Skip null entries */
        !           360:        fprintf(stderr,"%c\n",i);       /* Print the first byte */
        !           361:        dumplist(stringlist[transtab[i]],1);
        !           362:                                        /* Dump the list */
        !           363:       }
        !           364:   }
        !           365: 
        !           366: 
        !           367: int                    openfile(name)
        !           368: char                   *name;          /* File name */
        !           369:   {
        !           370:     int                        fd;             /* File descriptor */
        !           371: 
        !           372:     if((fd = open(name,0)) == -1)      /* If error opening file */
        !           373:       {
        !           374:        fprintf(stderr,"Cannot open %s\r\n",name);
        !           375:                                        /* Print error message */
        !           376:       }
        !           377:     return(fd);                                /* Return file descriptor */
        !           378:   }
        !           379: 
        !           380: 
        !           381: void far               thread2()       /* Read thread */
        !           382:   {
        !           383:     while(DOSSEMREQUEST((long far *) &readpending,-1L) == 0)
        !           384:       {                                        /* While there is work to do */
        !           385:        arrc = DOSREAD(t2fd,(char far *) t2buf,t2buflen,(int far *) &cbread);
        !           386:                                        /* Do the read */
        !           387:        DOSSEMCLEAR((long far *) &readdone);
        !           388:                                        /* Signal read completed */
        !           389:       }
        !           390:     fprintf(stderr,"Thread 2: DOSSEMREQUEST failed\n");
        !           391:                                        /* Print error message */
        !           392:     DOSEXIT(1, 2);                           /* Die */
        !           393:   }
        !           394: 
        !           395: 
        !           396: void far               thread3()       /* Write thread */
        !           397:   {
        !           398:     while(DOSSEMREQUEST((long far *) &writepending,-1L) == 0)
        !           399:       {                                        /* While there is work to do */
        !           400:        awrc = DOSWRITE(t3fd,(char far *) t3buf,t3buflen,(int far *) &cbwrite);
        !           401:                                        /* Do the write */
        !           402:        DOSSEMCLEAR((long far *) &writedone);
        !           403:                                        /* Signal write completed */
        !           404:       }
        !           405:     fprintf(stderr,"Thread 3: DOSSEMREQUEST failed\n");
        !           406:                                        /* Print error message */
        !           407:     DOSEXIT(1, 2);                           /* Die */
        !           408:   }
        !           409: 
        !           410: 
        !           411: void                   startread(fd,buffer,buflen)
        !           412: int                    fd;             /* File handle */
        !           413: char                   *buffer;        /* Buffer */
        !           414: int                    buflen;         /* Buffer length */
        !           415:   {
        !           416:     if(pmode)                          /* If protected mode */
        !           417:       {
        !           418:        if(DOSSEMREQUEST((long far *) &readdone,-1L) != 0)
        !           419:          {                             /* If we fail to get the semaphore */
        !           420:            fprintf(stderr,"DOSSEMREQUEST failed\n");
        !           421:                                        /* Error message */
        !           422:            DOSEXIT(1, 2);                    /* Die */
        !           423:          }
        !           424:        t2fd = fd;                      /* Set parameters for read */
        !           425:        t2buf = buffer;
        !           426:        t2buflen = buflen;
        !           427:        DOSSEMCLEAR((long far *) &readpending);
        !           428:                                        /* Wake thread 2 for read */
        !           429:        DOSSLEEP(0L);                   /* Yield the CPU */
        !           430:       }
        !           431:     else arrc = DOSREAD(fd,(char far *) buffer,buflen,(int far *) &cbread);
        !           432:   }
        !           433: 
        !           434: 
        !           435: int                    finishread()
        !           436:   {
        !           437:     if(pmode && DOSSEMWAIT((long far *) &readdone,-1L) != 0)
        !           438:       {                                        /* If protected mode and wait fails */
        !           439:        fprintf(stderr,"DOSSEMWAIT failed\n");
        !           440:                                        /* Print error message */
        !           441:        DOSEXIT(1, 2);                        /* Die */
        !           442:       }
        !           443:     return((arrc == 0)? cbread: -1);   /* Return number of bytes read */
        !           444:   }
        !           445: 
        !           446: 
        !           447: void                   startwrite(fd,buffer,buflen)
        !           448: int                    fd;             /* File handle */
        !           449: char                   *buffer;        /* Buffer */
        !           450: int                    buflen;         /* Buffer length */
        !           451:   {
        !           452:     if(pmode)                          /* If protected mode */
        !           453:       {
        !           454:        if(DOSSEMREQUEST((long far *) &writedone,-1L) != 0)
        !           455:          {                             /* If we fail to get the semaphore */
        !           456:            fprintf(stderr,"DOSSEMREQUEST failed\n");
        !           457:                                        /* Error message */
        !           458:            DOSEXIT(1, 2);                    /* Die */
        !           459:          }
        !           460:        t3fd = fd;                      /* Set parameters for write */
        !           461:        t3buf = buffer;
        !           462:        t3buflen = buflen;
        !           463:        DOSSEMCLEAR((long far *) &writepending);
        !           464:                                        /* Wake thread 3 for read */
        !           465:        DOSSLEEP(0L);                   /* Yield the CPU */
        !           466:       }
        !           467:     else awrc = DOSWRITE(fd,(char far *) buffer,buflen,(int far *) &cbwrite);
        !           468:   }
        !           469: 
        !           470: 
        !           471: int                    finishwrite()
        !           472:   {
        !           473:     if(pmode && DOSSEMWAIT((long far *) &writedone,-1L) != 0)
        !           474:       {                                        /* If protected mode and wait fails */
        !           475:        fprintf(stderr,"DOSSEMWAIT failed\n");
        !           476:                                        /* Print error message */
        !           477:        DOSEXIT(1, 2);                        /* Die */
        !           478:       }
        !           479:     return((awrc == 0)? cbwrite: -1);  /* Return number of bytes written */
        !           480:   }
        !           481: 
        !           482: 
        !           483: void                   write1nobuf(buffer,buflen)
        !           484: char                   *buffer;        /* Buffer */
        !           485: register int           buflen;         /* Buffer length */
        !           486:   {
        !           487:     int                        cb;             /* Count of bytes written */
        !           488: 
        !           489:     if(DOSWRITE(1,(char far *) buffer,buflen,(int far *) &cb) != 0 ||
        !           490:       cb != buflen)                    /* If write fails */
        !           491:       {
        !           492:        fprintf(stderr,"write error %d\n",awrc);
        !           493:                                        /* Print error message */
        !           494:        DOSEXIT(1, 2);                        /* Die */
        !           495:       }
        !           496:   }
        !           497: 
        !           498: 
        !           499: void                   write1buf(buffer,buflen)
        !           500: char                   *buffer;        /* Buffer */
        !           501: register int           buflen;         /* Buffer length */
        !           502:   {
        !           503:     register int       cb;             /* Byte count */
        !           504: 
        !           505:     while(buflen > 0)                  /* While bytes remain */
        !           506:       {
        !           507:        if(awrc != 0)                   /* If previous write failed */
        !           508:          {
        !           509:            fprintf(stderr,"write error %d\n",awrc);
        !           510:                                        /* Print error message */
        !           511:            DOSEXIT(1, 2);                    /* Die */
        !           512:          }
        !           513:        if((cb = ocnt[oi]) == 0)        /* If buffer full */
        !           514:          {
        !           515:            startwrite(1,obuf[oi],OUTBUFLEN);
        !           516:                                        /* Write the buffer */
        !           517:            ocnt[oi] = OUTBUFLEN;       /* Reset count and pointer */
        !           518:            optr[oi] = obuf[oi];
        !           519:            oi ^= 1;                    /* Switch buffers */
        !           520:            cb = ocnt[oi];              /* Get space remaining */
        !           521:          }
        !           522:        if(cb > buflen) cb = buflen;    /* Get minimum */
        !           523:        memcpy(optr[oi],buffer,cb);     /* Copy bytes to buffer */
        !           524:        ocnt[oi] -= cb;                 /* Update buffer length and pointers */
        !           525:        optr[oi] += cb;
        !           526:        buflen -= cb;
        !           527:        buffer += cb;
        !           528:       }
        !           529:   }
        !           530: 
        !           531: 
        !           532: void                   flush1nobuf()
        !           533:   {
        !           534:   }
        !           535: 
        !           536: 
        !           537: void                   flush1buf()
        !           538:   {
        !           539:     int                        cb;             /* Byte count */
        !           540: 
        !           541:     if((cb = OUTBUFLEN - ocnt[oi]) > 0)        /* If buffer not empty */
        !           542:       {
        !           543:        startwrite(1,obuf[oi],cb);      /* Start write */
        !           544:        if(finishwrite() != cb)         /* If write failed */
        !           545:          {
        !           546:            fprintf(stderr,"write error %d\n",awrc);
        !           547:                                        /* Print error message */
        !           548:            DOSEXIT(1, 2);                    /* Die */
        !           549:          }
        !           550:       }
        !           551:   }
        !           552: 
        !           553: 
        !           554: int                    grepnull(cp,endbuf,name)
        !           555: register char          *cp;            /* Buffer pointer */
        !           556: char                   *endbuf;        /* End of buffer */
        !           557: char                   *name;          /* File name */
        !           558:   {
        !           559:     return(0);                         /* Do nothing */
        !           560:   }
        !           561: 
        !           562: 
        !           563: int                    grepbuffer(startbuf,endbuf,name)
        !           564: char                   *startbuf;      /* Start of buffer */
        !           565: char                   *endbuf;        /* End of buffer */
        !           566: char                   *name;          /* File name */
        !           567:   {
        !           568:     register char      *cp;            /* Buffer pointer */
        !           569:     char               *lastmatch;     /* Last matching line */
        !           570:     int                        linelen;        /* Line length */
        !           571:     int                        namlen = 0;     /* Length of name */
        !           572:     char               lnobuf[LNOLEN]; /* Line number buffer */
        !           573:     char               nambuf[LINELEN];/* Name buffer */
        !           574: 
        !           575:     cp = startbuf;                     /* Initialize to start of buffer */
        !           576:     lastmatch = cp;                    /* No previous match yet */
        !           577:     while((cp = (*find)(cp,endbuf)) != NULL)
        !           578:       {                                        /* While matches are found */
        !           579:        if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)
        !           580:          {                             /* If begin line conditions not met */
        !           581:            ++cp;                       /* Skip first char of match */
        !           582:            continue;                   /* Keep looking */
        !           583:          }
        !           584:        status = 0;                     /* Match found */
        !           585:        if(flags & NAMEONLY)            /* If filename only wanted */
        !           586:          {
        !           587:            (*write1)(nambuf,sprintf(nambuf,"%s\r\n",name));
        !           588:                                        /* Print the name */
        !           589:            return(1);                  /* Punt remainder of buffer */
        !           590:          }
        !           591:        cp -= revfind(cp,'\n',cp - startbuf);
        !           592:                                        /* Point at last linefeed */
        !           593:        if(*cp == '\n') ++cp;           /* Point at start of line */
        !           594:        if(flags & SHOWNAME)            /* If name wanted */
        !           595:          {
        !           596:            if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);
        !           597:                                        /* Format name if not done already */
        !           598:            (*write1)(nambuf,namlen);   /* Show name */
        !           599:          }
        !           600:        if(flags & LINENOS)             /* If line number wanted */
        !           601:          {
        !           602:            lineno += countlines(lastmatch,cp);
        !           603:                                        /* Count lines since last match */
        !           604:            (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno));
        !           605:                                        /* Print line number */
        !           606:            lastmatch = cp;             /* New last match */
        !           607:          }
        !           608:        linelen = strncspn(cp,"\n",endbuf - cp) + 1;
        !           609:                                        /* Calculate line length */
        !           610:        (*write1)(cp,linelen);          /* Print the line */
        !           611:        cp += linelen;                  /* Skip the line */
        !           612:       }
        !           613:     if(flags & LINENOS) lineno += countlines(lastmatch,endbuf);
        !           614:                                        /* Count remaining lines in buffer */
        !           615:     return(0);                         /* Keep searching */
        !           616:   }
        !           617: 
        !           618: 
        !           619: void                   showv(name,lastmatch,thismatch)
        !           620: char                   *name;
        !           621: register char          *lastmatch;
        !           622: char                   *thismatch;
        !           623:   {
        !           624:     register int       linelen;
        !           625:     int                        namlen = 0;     /* Length of name */
        !           626:     char               lnobuf[LNOLEN]; /* Line number buffer */
        !           627:     char               nambuf[LINELEN];/* Name buffer */
        !           628: 
        !           629:     if(flags & (SHOWNAME | LINENOS))
        !           630:       {
        !           631:        while(lastmatch < thismatch)
        !           632:          {
        !           633:            if(flags & SHOWNAME)        /* If name wanted */
        !           634:              {
        !           635:                if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);
        !           636:                                        /* Format name if not done already */
        !           637:                (*write1)(nambuf,namlen);
        !           638:                                        /* Write the name */
        !           639:              }
        !           640:            if(flags & LINENOS)
        !           641:              {
        !           642:                (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno++));
        !           643:              }
        !           644:            linelen = strncspn(lastmatch,"\n",thismatch - lastmatch) + 1;
        !           645:            (*write1)(lastmatch,linelen);
        !           646:            lastmatch += linelen;
        !           647:          }
        !           648:       }
        !           649:     else (*write1)(lastmatch,thismatch - lastmatch);
        !           650:   }
        !           651: 
        !           652: 
        !           653: int                    grepvbuffer(startbuf,endbuf,name)
        !           654: char                   *startbuf;      /* Start of buffer */
        !           655: char                   *endbuf;        /* End of buffer */
        !           656: char                   *name;          /* File name */
        !           657:   {
        !           658:     register char      *cp;            /* Buffer pointer */
        !           659:     register char      *lastmatch;     /* Pointer to line after last match */
        !           660: 
        !           661:     cp = startbuf;                     /* Initialize to start of buffer */
        !           662:     lastmatch = cp;
        !           663:     while((cp = (*find)(cp,endbuf)) != NULL)
        !           664:       {
        !           665:        if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)
        !           666:          {                             /* If begin line conditions not met */
        !           667:            ++cp;                       /* Skip first char of match */
        !           668:            continue;                   /* Keep looking */
        !           669:          }
        !           670:        status = 1;                     /* Match found */
        !           671:        if(flags & NAMEONLY) return(1); /* Skip rest of file if NAMEONLY */
        !           672:        cp -= revfind(cp,'\n',cp - startbuf);
        !           673:                                        /* Point at last linefeed */
        !           674:        if(*cp == '\n') ++cp;           /* Point at start of line */
        !           675:        showv(name,lastmatch,cp);       /* Show from last match to this */
        !           676:        cp += strncspn(cp,"\n",endbuf - cp) + 1;
        !           677:                                        /* Skip over line with match */
        !           678:        lastmatch = cp;                 /* New "last" match */
        !           679:        ++lineno;                       /* Increment line count */
        !           680:       }
        !           681:     if(!(flags & NAMEONLY)) showv(name,lastmatch,endbuf);
        !           682:                                        /* Show buffer tail if not NAMEONLY */
        !           683:     return(0);                         /* Keep searching file */
        !           684:   }
        !           685: 
        !           686: 
        !           687: void                   qgrep(name,fd)
        !           688: char                   *name;          /* File name */
        !           689: int                    fd;             /* File descriptor */
        !           690:   {
        !           691:     register int       cb;             /* Byte count */
        !           692:     register char      *cp;            /* Buffer pointer */
        !           693:     char               *endbuf;        /* End of buffer */
        !           694:     int                        taillen;        /* Length of buffer tail */
        !           695:     int                        bufi;           /* Buffer index */
        !           696:     char               line[LINELEN];  /* Line buffer */
        !           697: 
        !           698:     lineno = 1;                                /* File starts on line 1 */
        !           699:     taillen = 0;                       /* No buffer tail yet */
        !           700:     bufi = 0;                          /* Initialize buffer index */
        !           701:     cp = bufptr[0];                    /* Initialize to start of buffer */
        !           702:     finishread();                      /* Make sure no I/O activity */
        !           703:     arrc = DOSREAD(fd,(char far *) cp,FILBUFLEN,(int far *) &cbread);
        !           704:                                        /* Do first read synchronously */
        !           705:     while((cb = finishread()) + taillen > 0)
        !           706:       {                                        /* While search incomplete */
        !           707:        if(cb == 0)                     /* If buffer tail is all that's left */
        !           708:          {
        !           709:            taillen = 0;                /* Set tail length to zero */
        !           710:            *cp++ = '\r';               /* Add end of line sequence */
        !           711:            *cp++ = '\n';
        !           712:            endbuf = cp;                /* Note end of buffer */
        !           713:          }
        !           714:        else                            /* Else start next read */
        !           715:          {
        !           716:            taillen = revfind(cp + cb - 1,'\n',cb);
        !           717:                                        /* Find length of partial line */
        !           718:            endbuf = cp + cb - taillen; /* Get pointer to end of buffer */
        !           719:            cp = bufptr[bufi ^ 1];      /* Pointer to other buffer */
        !           720:            memcpy(cp,endbuf,taillen);  /* Copy tail to head of other buffer */
        !           721:            cp += taillen;              /* Skip over tail */
        !           722:            startread(fd,cp,(FILBUFLEN - taillen) & (~0 << LG2SECLEN));
        !           723:                                        /* Start next read */
        !           724:          }
        !           725:        if((*grep)(bufptr[bufi],endbuf,name)) return;
        !           726:                                        /* Done if NAMEONLY and match found */
        !           727:        bufi ^= 1;                      /* Switch buffers */
        !           728:       }
        !           729:     if((flags & (NAMEONLY | INVERT)) == (NAMEONLY | INVERT))
        !           730:       (*write1)(line,sprintf(line,"%s\r\n",name));
        !           731:                                        /* Write name if -lv */
        !           732:   }
        !           733: 
        !           734: 
        !           735: void                   usage(verbose)
        !           736: int                    verbose;        /* Verbose message flag */
        !           737:   {
        !           738:     static char                *opts[] =
        !           739:       {
        !           740:        "-? - print this message",
        !           741:        "-B - match pattern if at beginning of line",
        !           742:        "-E - match pattern if at end of line",
        !           743:        "-l - print only file name if file contains match",
        !           744:        "-n - print line number before each matching line",
        !           745:        "-v - print only lines not containing a match",
        !           746:        "-x - print lines that match exactly (-BE)",
        !           747:        "-y - treat upper and lower case as equivalent",
        !           748:        "-e - treat next argument as the search string",
        !           749:        "-f - read search strings from file named by next argument",
        !           750:        "-i - read file list from file named by next argument",
        !           751:        0
        !           752:       };
        !           753:     register char      **opt = opts;   /* Option list */
        !           754: 
        !           755:     fprintf(stderr,"usage: CPGREP [-?BElnvxy][-e][-f <file>][-i <file>][<strings>][<files>]\n");
        !           756:     if(verbose)                                /* If verbose message wanted */
        !           757:       {
        !           758:        while(*opt != 0) fprintf(stderr,"%s\n",*opt++);
        !           759:                                        /* Print option list */
        !           760:       }
        !           761:     DOSEXIT(1, 2);                           /* Error exit */
        !           762:   }
        !           763: 
        !           764: 
        !           765: void                   main(argc,argv)
        !           766: int                    argc;
        !           767: char                   **argv;
        !           768:   {
        !           769:     register char      *cp;
        !           770:     int                        fd;
        !           771:     FILE               *fi;
        !           772:     char               filnam[FILNAMLEN];
        !           773:     int                        i;
        !           774:     char               *inpfile = NULL;
        !           775:     int                        j;
        !           776:     char               *seplist = " \t";
        !           777:     int                        strcnt;
        !           778:     char               *strfile = NULL;
        !           779:     long               start;          /* Start time */
        !           780:     int                        (*add)();
        !           781:     int                        t2stk[STKLEN];  /* Read thread stack */
        !           782:     int                        t3stk[STKLEN];  /* Write thread stack */
        !           783:     long               time();         /* Time and date in seconds */
        !           784: 
        !           785:     DOSGETMACHINEMODE((char far *) &pmode);
        !           786:     flags = 0;
        !           787:     for(i = 1; i < argc && argv[i][0] == '-'; ++i)
        !           788:       {
        !           789:        switch(argv[i][1])
        !           790:          {
        !           791:            case 'f':
        !           792:            case 'i':
        !           793:              if(i == argc - 1)
        !           794:                {
        !           795:                  fprintf(stderr,"File name missing after -%c\n",argv[i][1]);
        !           796:                  DOSEXIT(1, 2);
        !           797:                }
        !           798:              if(argv[i++][1] == 'i') inpfile = argv[i];
        !           799:              else strfile = argv[i];
        !           800:              break;
        !           801: 
        !           802:            case '?':
        !           803:            case 'B':
        !           804:            case 'E':
        !           805:            case 'N':
        !           806:            case 'S':
        !           807:            case 'd':
        !           808:            case 'l':
        !           809:            case 'n':
        !           810:            case 't':
        !           811:            case 'v':
        !           812:            case 'x':
        !           813:            case 'y':
        !           814:              for(cp = &argv[i][1]; *cp != '\0'; ++cp)
        !           815:                {
        !           816:                  switch(*cp)
        !           817:                    {
        !           818:                      case '?':
        !           819:                        usage(1);       /* Verbose usage message */
        !           820: 
        !           821:                      case 'B':
        !           822:                        flags |= BEGLINE;
        !           823:                        break;
        !           824: 
        !           825:                      case 'E':
        !           826:                        flags |= ENDLINE;
        !           827:                        break;
        !           828: 
        !           829:                      case 'N':
        !           830:                        grep = grepnull;
        !           831:                        break;
        !           832: 
        !           833:                      case 'S':
        !           834:                        pmode = 0;      /* Force synchronous I/O */
        !           835:                        break;
        !           836: 
        !           837:                      case 'd':
        !           838:                        flags |= DEBUG;
        !           839:                        break;
        !           840: 
        !           841:                      case 'l':
        !           842:                        flags |= NAMEONLY;
        !           843:                        break;
        !           844: 
        !           845:                      case 'n':
        !           846:                        flags |= LINENOS;
        !           847:                        break;
        !           848: 
        !           849:                      case 't':
        !           850:                        flags |= TIMER;
        !           851:                        break;
        !           852: 
        !           853:                      case 'v':
        !           854:                        status = 0;     /* Assume success */
        !           855:                        flags |= INVERT;
        !           856:                        grep = grepvbuffer;
        !           857:                        break;
        !           858: 
        !           859:                      case 'x':
        !           860:                        flags |= BEGLINE | ENDLINE;
        !           861:                        break;
        !           862: 
        !           863:                      case 'y':
        !           864:                        casesen = 0;
        !           865:                        break;
        !           866: 
        !           867:                      default:
        !           868:                        fprintf(stderr,"-%c ignored\n",*cp);
        !           869:                        break;
        !           870:                    }
        !           871:                }
        !           872:              break;
        !           873: 
        !           874:            case 'e':
        !           875:              if(strfile == NULL)
        !           876:                {
        !           877:                  ++i;
        !           878:                  seplist = "";         /* Allow anything in string */
        !           879:                  goto endfor0;
        !           880:                }
        !           881:              /* Drop through to "default" */
        !           882: 
        !           883:            default:
        !           884:              fprintf(stderr,"%s ignored\n",argv[i]);
        !           885:              break;
        !           886:          }
        !           887:       }
        !           888:     endfor0:
        !           889: 
        !           890:     if(i == argc && strfile == NULL) usage(0);
        !           891:                                        /* Simple usage message if arg error */
        !           892:     if(flags & TIMER) start = time(NULL);
        !           893:                                        /* Get start time if timer on */
        !           894:     if(pmode)                          /* Initialize semaphores and threads */
        !           895:       {
        !           896:        DOSSEMCLEAR((long far *) &readdone);
        !           897:        DOSSEMCLEAR((long far *) &writedone);
        !           898:        DOSSEMSET((long far *) &readpending);
        !           899:        DOSSEMSET((long far *) &writepending);
        !           900:        if(DOSCREATETHREAD(thread2,(int far *) &fd,
        !           901:          (int far *) t2stk + STKLEN) != 0 ||
        !           902:          DOSCREATETHREAD(thread3,(int far *) &fd,
        !           903:          (int far *) t3stk + STKLEN) != 0)
        !           904:          {                             /* If thread creation fails */
        !           905:            fprintf(stderr,"Failed to create child threads\n");
        !           906:                                        /* Print error message */
        !           907:            DOSEXIT(1, 2);                    /* Die */
        !           908:          }
        !           909:       }
        !           910:     setmode(fileno(stdout),O_BINARY);
        !           911:     add = addplain;                    /* Assume plain string adds */
        !           912:     if(strfile != NULL)                        /* If strings from file */
        !           913:       {
        !           914:        if(!(flags & BEGLINE)) add = addfancy;
        !           915:                                        /* Try to add intelligently */
        !           916:        if((fd = open(strfile,0)) == -1)
        !           917:          {                             /* If open fails */
        !           918:            fprintf(stderr,"Cannot read strings from %s\n",strfile);
        !           919:            DOSEXIT(1, 2);                    /* Print message and die */
        !           920:          }
        !           921:        for(cp = filbuf, j = 0; (j = read(fd,cp,FILBUFLEN*2 - j)) > 0; cp += j);
        !           922:                                        /* Read strings file into buffer */
        !           923:        j = cp - filbuf;                /* Get total length of buffer */
        !           924:        close(fd);                      /* Close strings file */
        !           925:        filbuf[j] = '\0';               /* Null-terminate the buffer */
        !           926:        cp = filbuf;                    /* Set pointer to string list */
        !           927:        seplist = "\r\n";               /* Only '\r' and '\n' are separators */
        !           928:       }
        !           929:     else                               /* Else strings on command line */
        !           930:       {
        !           931:        cp = argv[i++];                 /* Set pointer to strings */
        !           932:        j = strlen(cp);                 /* Get length of strings */
        !           933:       }
        !           934:     if((strcnt = (*add)(cp,j,seplist)) == 0)
        !           935:       {                                        /* If no strings */
        !           936:        fprintf(stderr,"No search strings\n");
        !           937:        DOSEXIT(1, 2);                        /* Print error message and die */
        !           938:       }
        !           939: 
        !           940:     /*
        !           941:      *  Check type of handle for std. out.
        !           942:      */
        !           943:     if(DOSQHANDTYPE(fileno(stdout),(int far *) &j,(int far *) &fd) != 0)
        !           944:       {                                        /* If error */
        !           945:        fprintf(stderr,"Standard output bad handle\n");
        !           946:                                        /* Print error message */
        !           947:        DOSEXIT(1, 2);                        /* Die */
        !           948:       }
        !           949:     if(j != 0 && (fd & ISCOT))         /* If handle is console output */
        !           950:       {
        !           951:        write1 = write1nobuf;           /* Use unbuffered output */
        !           952:        flush1 = flush1nobuf;
        !           953:       }
        !           954: 
        !           955:     if(strcnt > 1)                     /* If more than one string */
        !           956:       {
        !           957:        if(flags & DEBUG)               /* Print debug info maybe */
        !           958:          {
        !           959:            fprintf(stderr,"Here are the strings:\n");
        !           960:            dumpstrings();
        !           961:          }
        !           962:       }
        !           963:     else if(casesen) find = findone;   /* Else use findone() */
        !           964:     if(inpfile != NULL)                        /* If file list from file */
        !           965:       {
        !           966:        flags |= SHOWNAME;              /* Always show name of file */
        !           967:        if((fi = fopen(inpfile,"r")) == NULL)
        !           968:          {                             /* If open fails */
        !           969:            fprintf(stderr,"Cannot read file list from %s\r\n",inpfile);
        !           970:                                        /* Error message */
        !           971:            DOSEXIT(1, 2);                    /* Error exit */
        !           972:          }
        !           973:        while(fgets(filnam,FILNAMLEN,fi) != NULL)
        !           974:          {                             /* While there are names */
        !           975:            filnam[strcspn(filnam,"\r\n")] = '\0';
        !           976:                                        /* Null-terminate the name */
        !           977:            if((fd = openfile(filnam)) == -1) continue;
        !           978:                                        /* Skip file if it cannot be opened */
        !           979:            qgrep(filnam,fd);           /* Do the work */
        !           980:            close(fd);                  /* Close the file */
        !           981:          }
        !           982:        fclose(fi);                     /* Close the list file */
        !           983:       }
        !           984:     else if(i == argc)
        !           985:       {
        !           986:        flags &= ~(NAMEONLY | SHOWNAME);
        !           987:        setmode(fileno(stdin),O_BINARY);
        !           988:        qgrep(NULL,fileno(stdin));
        !           989:       }
        !           990:     if(argc > i + 1) flags |= SHOWNAME;
        !           991:     for(; i < argc; ++i)
        !           992:       {
        !           993:        if((fd = openfile(argv[i])) == -1) continue;
        !           994:        qgrep(argv[i],fd);
        !           995:        close(fd);
        !           996:       }
        !           997:     (*flush1)();
        !           998:     if(flags & TIMER) fprintf(stderr,"%ld seconds\n",time(NULL) - start);
        !           999:                                        /* Print elapsed time if timer on */
        !          1000:     DOSEXIT(1, status);
        !          1001:   }

unix.superglobalmegacorp.com

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