Article View: comp.bugs.sys5
Article #642Re: fgrep bug
From: Guy Harris
Date: Fri, 06 Nov 1987 08:42
Date: Fri, 06 Nov 1987 08:42
357 lines
7826 bytes
7826 bytes
> Anyone have a fix?
Yes. Also:
A significant speedup - don't do case-mapping in a subroutine, do it
in-line (yes, I know, there are lots of faster scanner programs, don't
waste people's time asking "why bother fixing 'fgrep'");
Don't allow more than one "-f" option;
Print slightly better error messages;
Check for errors when reading files;
Fix a bug where "%d" was used to print a "long";
Drop in a bug fix that came from an addendum to V7, put out by AT&T,
but that never appeared in a USG release.
*** /arch/s5r2/usr/src/cmd/fgrep.c Mon Jul 25 14:23:18 1983
--- ./fgrep.c Fri Nov 6 00:34:04 1987
***************
*** 9,14 ****
--- 9,15 ----
*/
#include <stdio.h>
+ #include <ctype.h>
#define MAXSIZ 6000
#define QSIZE 400
***************
*** 30,38 ****
--- 31,41 ----
int nsucc;
long tln;
FILE *wordf;
+ char *wordfname;
char *argptr;
extern char *optarg;
extern int optind;
+ void exit();
main(argc, argv)
char **argv;
***************
*** 63,74 ****
continue;
case 'f':
! fflag++;
! wordf = fopen(optarg, "r");
! if (wordf==NULL) {
! fprintf(stderr, "fgrep: can't open %s\n", optarg);
exit(2);
}
continue;
case 'l':
--- 66,77 ----
continue;
case 'f':
! if (fflag) {
! fprintf(stderr, "fgrep: Only one \"-f\" option allowed\n");
exit(2);
}
+ fflag++;
+ wordfname = optarg;
continue;
case 'l':
***************
*** 92,106 ****
}
argc -= optind;
! if (errflg || ((argc <= 0) && !fflag)) {
printf("usage: fgrep %s\n",usage);
exit(2);
}
! if ( !eflag && !fflag ) {
! argptr = argv[optind];
! optind++;
! argc--;
}
cgotofn();
cfail();
nfile = argc;
--- 95,119 ----
}
argc -= optind;
! if (errflg || ((argc <= 0) && !fflag && !eflag)) {
printf("usage: fgrep %s\n",usage);
exit(2);
}
! if (fflag) {
! wordf = fopen(wordfname, "r");
! if (wordf==NULL) {
! fprintf(stderr, "fgrep: ");
! perror(wordfname);
! exit(2);
! }
! } else {
! if (!eflag) {
! argptr = argv[optind];
! optind++;
! argc--;
! }
}
+
cgotofn();
cfail();
nfile = argc;
***************
*** 117,122 ****
--- 130,137 ----
exit(retcode != 0 ? retcode : nsucc == 0);
}
+ # define ccomp(a,b) (iflag ? lca(a)==lca(b) : a==b)
+ # define lca(x) (isupper(x) ? _tolower(x) : x)
execute(file)
char *file;
{
***************
*** 128,134 ****
char *nlp;
if (file) {
if ((fptr = fopen(file, "r")) == NULL) {
! fprintf(stderr, "fgrep: can't open %s\n", file);
retcode = 2;
return;
}
--- 143,150 ----
char *nlp;
if (file) {
if ((fptr = fopen(file, "r")) == NULL) {
! fprintf(stderr, "fgrep: ");
! perror(file);
retcode = 2;
return;
}
***************
*** 153,159 ****
blkno += ccount;
}
nstate:
! if (same(c->inp,*p)) {
c = c->nst;
}
else if (c->link != 0) {
--- 169,175 ----
blkno += ccount;
}
nstate:
! if (ccomp(c->inp,*p)) {
c = c->nst;
}
else if (c->link != 0) {
***************
*** 166,172 ****
if (c==0) {
c = w;
istate:
! if (same(c->inp,*p)) {
c = c->nst;
}
else if (c->link != 0) {
--- 182,188 ----
if (c==0) {
c = w;
istate:
! if (ccomp(c->inp,*p)) {
c = c->nst;
}
else if (c->link != 0) {
***************
*** 187,192 ****
--- 203,210 ----
blkno += ccount;
}
}
+ if (ccount < 0)
+ goto done;
if ( (vflag && (failed == 0 || xflag == 0)) || (vflag == 0 && xflag && failed) )
goto nomatch;
succeed: nsucc = 1;
***************
*** 198,204 ****
}
else {
if (nfile > 1) printf("%s:", file);
! if (bflag) printf("%d:", (blkno-ccount-1)/BUFSIZ);
if (nflag) printf("%ld:", lnum);
if (p <= nlp) {
while (nlp < &buf[2*BUFSIZ]) putchar(*nlp++);
--- 216,222 ----
}
else {
if (nfile > 1) printf("%s:", file);
! if (bflag) printf("%ld:", (blkno-ccount-1)/BUFSIZ);
if (nflag) printf("%ld:", lnum);
if (p <= nlp) {
while (nlp < &buf[2*BUFSIZ]) putchar(*nlp++);
***************
*** 221,226 ****
--- 239,252 ----
failed = 0;
}
}
+ done:
+ if (ccount < 0) {
+ fprintf(stderr, "fgrep: Read error on ");
+ perror(file ? file : "standard input");
+ retcode = 2;
+ fclose(fptr);
+ return;
+ }
fclose(fptr);
if (cflag) {
if (nfile > 1)
***************
*** 232,241 ****
getargc()
{
register c;
! if (wordf)
! return(getc(wordf));
! if ((c = *argptr++) == '\0')
! return(EOF);
return(c);
}
--- 258,277 ----
getargc()
{
register c;
! if (wordf) {
! c = getc(wordf);
! if (c == EOF) {
! if (ferror(wordf)) {
! fprintf(stderr, "fgrep: Read error on ");
! perror(wordfname);
! exit(1);
! }
! fclose(wordf);
! }
! } else {
! if ((c = *argptr++) == '\0')
! return(EOF);
! }
return(c);
}
***************
*** 303,309 ****
}
overflo() {
! fprintf(stderr, "wordlist too large\n");
exit(2);
}
cfail() {
--- 339,345 ----
}
overflo() {
! fprintf(stderr, "fgrep: wordlist too large\n");
exit(2);
}
cfail() {
***************
*** 310,315 ****
--- 346,352 ----
struct words *queue[QSIZE];
struct words **front, **rear;
struct words *state;
+ int bstart;
register char c;
register struct words *s;
s = w;
***************
*** 328,333 ****
--- 365,371 ----
front = queue;
else front++;
cloop: if ((c = s->inp) != 0) {
+ bstart = 0;
*rear = (q = s->nst);
if (front < rear)
if (rear >= &queue[QSIZE-1])
***************
*** 337,343 ****
else
if (++rear == front) overflo();
state = s->fail;
! floop: if (state == 0) state = w;
if (state->inp == c) {
qloop: q->fail = state->nst;
if ((state->nst)->out == 1) q->out = 1;
--- 375,384 ----
else
if (++rear == front) overflo();
state = s->fail;
! floop: if (state == 0) {
! state = w;
! bstart = 1;
! }
if (state->inp == c) {
qloop: q->fail = state->nst;
if ((state->nst)->out == 1) q->out = 1;
***************
*** 345,370 ****
}
else if ((state = state->link) != 0)
goto floop;
}
if ((s = s->link) != 0)
goto cloop;
}
- }
-
- /* The following functions were inserted to allow for the "-i" option */
-
- same(a, b)
- register int a, b;
- {
- return (a == b || iflag && (a ^ b) == ' ' && letter(a) == letter(b));
- }
-
- letter(c)
- register int c;
- {
- if (c >= 'a' && c <= 'z')
- return (c);
- if (c >= 'A' && c <= 'z')
- return (c + 'a' - 'A');
- return(0);
}
--- 386,397 ----
}
else if ((state = state->link) != 0)
goto floop;
+ else if(bstart == 0){
+ state = 0;
+ goto floop;
+ }
}
if ((s = s->link) != 0)
goto cloop;
}
}
Guy Harris
{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
guy@sun.com
Technical Details
Message-ID:
<33168@sun.uucp>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!gorodish!guyReferences:
<2715@ncrcae.Columbia.NCR.COM>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!gorodish!guy From: guy@gorodish.Sun.COM (Guy Harris) Newsgroups: comp.bugs.sys5 Subject: Re: fgrep bug Message-ID: <33168@sun.uucp> Date: Fri, 6-Nov-87 03:42:31 EST Article-I.D.: sun.33168 Posted: Fri Nov 6 03:42:31 1987 Date-Received: Sun, 8-Nov-87 12:06:20 EST References: <2715@ncrcae.Columbia.NCR.COM> Sender: news@sun.uucp Lines: 357