home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #define MAXLINE 1024
- #define MAXNAME 100
- #define BIGBUF 8192 /* Read buffer size */
-
- #define andc '+' /* and character */
- #define orch '|' /* or character */
- #define arbc '@' /* arbitrary ch */
- #define swch '?' /* single wild */
- #define lbch '^' /* Line begin ch */
- #define lech '$' /* Line End char */
- #define lwch '{' /* Left word ch */
- #define rwch '}' /* right word ch */
-
- /* Public domain program written by Hern Chen 10/86 304-776-8336 */
- /* To get a brief description, type "pgrep" at DOS prompt. */
- /* This is a variation of fgrep/egrep program */
- /* . Multiple filespecs are allowed. */
- /* . Multiple patterns allowed. (and, or, pat followed by pat) */
- /* . Line begin/end, word boundaries, and single wild char. */
- /* . Search binary files as well as text files. */
- /* . Patterns can be placed in a file. */
- /* . Generate simple batch file exec.bat for matching files. */
- /* */
- /* This program contains some Lattice specific codes: */
- /* . Open file in binary mode. */
- /* . dfind/dnext for finding files match a filespec. */
- /* */
-
- int _fmode; /* Lattice C; 0x0000=text, 0x8000=binary */
-
- main (argc,argv)
- int argc;
- char *argv[];
- {
- register int ch;
- register char *se;
- int msize;
- int invert;
- int linef;
- int countf;
- int mixedc;
- int talkf;
- int batch, batchx, batchy;
- int number;
- int nlines;
- int nmatch;
- int nfiles;
- char *pat, *patfile;
- char *p;
- char *bigbuf;
- char *src;
- char *src2;
- char fname[MAXNAME];
- int i;
- char *sb;
- int karg;
- FILE *fp;
- FILE *fptr;
- char *patmatch();
- char *malloc();
- char *strcpy();
- int atoi();
- int printf();
- int fprintf();
- int invalid, more;
-
- countf = linef = number = 1;
- mixedc = invert = talkf = batch = msize = invalid = 0;
- batchx = batchy = 2;
- patfile = pat = NULL;
- for (karg=0; ++karg<argc; )
- if ((p=argv[karg])!=NULL)
- {
- if (*p=='-' || *p=='/' || *p=='+')
- while (ch = *++p)
- switch (ch)
- {
- case 'M': if (*(p+1))
- {
- msize = atoi(p+1);
- while (*++p);
- p--;
- }
- else if (++karg<argc)
- {
- msize = atoi(argv[karg]);
- argv[karg] = NULL;
- };
- break;
- case 'b': batch = 1;
- if (isdigit(*(p+1)))
- batchx = *(++p) - '0';
- if (isdigit(*(p+1)))
- batchy = *(++p) - '0';
- break;
- case 'f': if (*(p+1))
- {
- patfile = p++;
- while (*++p);
- p--;
- }
- else if (++karg<argc)
- {
- patfile = argv[karg];
- argv[karg] = NULL;
- };
- break;
- case 'c': countf = 1-countf;
- break;
- case 'l': linef = 1-linef;
- break;
- case 'm': mixedc = 1-mixedc;
- break;
- case 'n': number = 1-number;
- break;
- case 'v': invert = 1-invert;
- break;
- case 't': talkf = 1-talkf;
- break;
- default: invalid = 1;
- }
- else if (patfile==NULL && pat==NULL)
- {
- pat = argv[karg];
- argv[karg] = NULL;
- };
- };
-
- if ((pat==NULL && patfile==NULL) || (pat!=NULL && patfile!=NULL) || invalid)
- {
- fprintf(stderr,"\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
- "pgrep 1.10 (1986) by Hern Chen for text and binary files",
- "Usage: pgrep [-mvnlct] [-bxy] {-f pat_file | pattern} file1 file2 ...",
- " -m, Mixed, force match to be case sensitive",
- " -v, inVert, print lines that does not match pattern",
- " -bxy,Btach, create exec.bat with %1 .. %x file %x+1 .. %x+y",
- " -n, Number, don't print line number",
- " -l, Line, don't print the line",
- " -c, Count, don't print match count",
- " -t, Trace, print name before search\n",
- "pattern ::= token [{+, @, |, CR} pattern]",
- "token ::= [^, {] string [$, }]",
- " ^ = line begin, $ = line end,",
- " { = word boundary, } = word boundary",
- " + = and, @ = zero or more chars (followed by)",
- " | = or, CR in pat_file = or, ? = any single char\n",
- "Example: pgrep \"pgrep|quote+blank|dos}@command\" pgrep.*",
- " pgrep subroutine *.f \abc\*.f",
- " pgrep \"objfcn@=\" *.f\n",
- "Note: Enclose blank, |, <, and > in double quotes",
- " Quote \" by preceeding it with a backslash",
- " MSDOS removes & from the command line");
- exit (1);
- };
-
- if (patfile!=NULL)
- {
- if ((fp = fopen(patfile,"r"))==NULL)
- {
- fprintf(stderr,"%s: invalid -f spec\n",argv[0]);
- exit (2);
- };
- if (msize==0) msize = 4000;
- pat = malloc(msize);
- for (p=pat; (ch = getc(fp))!=EOF; *p++ = ch);
- *p = '\0';
- fclose(fp);
- };
-
- /* if ignore case then upcase the pattern */
- if (mixedc!=1)
- for (p=pat-1; *++p; *p = toupper(*p));
-
- if (batch && (fp = fopen("exec.bat","w"))==NULL)
- {
- fprintf(stderr,"%s: cannot open 'exec.bat' for output\n",argv[0]);
- exit (3);
- };
-
- nfiles = 0;
- _fmode = 0x8000; /* Binary mode for LATTICE */
- if ((bigbuf = malloc(BIGBUF))==NULL ||
- (src = malloc(MAXLINE+2))==NULL || (src2 = malloc(MAXLINE+2))==NULL)
- {
- fprintf(stderr,"%s: cannot allocate working buffers\n",argv[0]);
- exit (4);
- };
-
- fptr = stdin;
- while (((more=morefile(argc,argv,00,fname))==0 && nfiles==0) ||
- (more==1 && (fptr=fopen(fname,"r"))!=NULL))
- {
- if (talkf) printf("==> Searching file %s\n",fname);
- setvbuf(fptr,bigbuf,_IOFBF,BIGBUF);
- nfiles++;
- nmatch = 0;
- nlines = 0;
- do
- {
- while ((ch=getc(fptr))=='\0');
- for (se=src,p=se+MAXLINE; se<p && ch && ch!=EOF && ch!='\n';
- *se++ = ch, ch=getc(fptr));
- if (ch=='\n' && *(se-1)=='\015') se--;
- *se = '\0';
- nlines++;
-
- if (mixedc==1)
- sb = src;
- else
- {
- sb = src2;
- for (p=src-1, se=src2; *(++p); *se++ = toupper(*p));
- *se = '\0';
- };
-
- if ((((p = patmatch(pat, sb, se))==NULL && invert==1) ||
- (p!=NULL && invert==0)) && ch!=EOF)
- {
- nmatch++;
- if (linef)
- {
- for (se=src; *se; se++)
- if (*se!='\t' && *se!='\014' && iscntrl(*se)) *se='~';
- if (number==1)
- printf("%4d: %s\n", nlines, src);
- else
- printf("%s\n",src);
- };
- };
- }
- while (ch!=EOF);
- fclose(fptr);
- if (nmatch>0)
- {
- if (countf) printf("----- %d lines from file < %s > -----\n",
- nmatch, fname);
- if (batch)
- {
- for (i=1; i<=batchx; i++) fprintf(fp," %%%d",i);
- fprintf(fp," %s",fname);
- while (i<=(batchx+batchy)) fprintf(fp," %%%d",i++);
- fprintf(fp,"\n");
- }
- };
- };
- if (batch) fclose(fp);
- }
-
- #include <dos.h>
- int morefile (argc, argv, mode, fname) /* 1=yes, 0=no, -1=bad spec */
- int argc;
- char *argv[];
- int mode; /* file attributes to look for e.g. read_only, ... */
- char *fname; /* filename may include drive/path */
- {
- static int karg = 0;
- static struct FILEINFO fileinfo;
- static int wild = 0;
- int more;
- char ch, *f, *p, *t;
-
- more = 1;
- if (wild!=1 || dnext(&fileinfo)!=0)
- {
- while (++karg<argc && (argv[karg]==NULL || (ch=*argv[karg])=='-'
- || ch=='+' || ch=='/'));
- if (karg>=argc)
- {
- more = 0;
- strcpy(fname,"stdin");
- }
- else if (dfind(&fileinfo,argv[karg],mode)!=0)
- {
- fprintf(stderr,"%s: no file match <%s>\n", argv[0], argv[karg]);
- more = -1;
- };
- };
-
- if (more==1)
- {
- wild = 0;
- for (f=fname,p=fname,t=argv[karg]; (*f++ = *t); ++t)
- {
- if (*t==':' || *t=='\\') p = f;
- if (*t=='*' || *t=='?') wild = 1;
- };
- for (t=fileinfo.name; (*p++ = *t++); );
- };
- return (more);
- }
-
- char *patmatch(pat, src, se)
- char *pat;
- char *src;
- char *se;
-
- /* */
- /* patmatch tries to decide whether there is a match of pat in src */
- /* The pattern is defined as */
- /* pat := pat op pat */
- /* Allowed op's are */
- /* + = and, @ = zero or more characters, | or \n = or */
- /* */
- /* pat11+pat12+pat13|pat21|pat31+pat32\0 will match lines contains */
- /* a. pat11 and pat12 followed by pat13 or */
- /* b. pat21 or */
- /* c. pat31 followed by pat32 or */
- /* other special characters: */
- /* ^: begin of a line */
- /* $: end of a line */
- /* {: word boundary */
- /* }: word boundary */
- /* */
-
- {
- register char ch;
- char *pb;
- register char *pe;
- char *pt;
- char *sb;
- char *sn;
- int lpat;
- int match;
- int matchi;
- char lch;
- char rch;
- char *strmatch();
-
- match = 0;
- pe = pat-1;
- sb = src;
-
- do
- {
- for (pb = ++pe; (ch = *pe) && ch!=orch && ch!='\n' && ch!=andc
- && ch!=arbc; pe++);
- /* check for begining special symbols '^' and '{' */
- if ((lch = *pb)==lbch || lch==lwch) pb++;
-
- /* check for endng special symbols '$' and '}' */
- if ((rch = *(pt=pe-1))!=lech && rch!=rwch) pt++;
-
-
- matchi = 0;
- if ((lpat=pt-pb)<=(se-sb))
- {
- if (lpat>0)
- {
- do
- {
- if ((sn=strmatch(pb, lpat, sb, se))!=NULL)
- {
- matchi = 1;
- if ((pt = sn-lpat-1)>=src && (lch==lbch || (lch==lwch
- && isalnum(*pt)))) matchi = 0;
- if (sn<se && (rch==lech || (rch==rwch && isalnum(*sn))))
- matchi = 0;
- sb = sn;
- }
- }
- while (sn!=NULL && matchi==0);
- }
- else
- {
- matchi = (sb==se);
- sn = se;
- };
- };
-
- if (matchi==1)
- {
- if ((ch = *pe)=='\0' || ch=='\n' || ch==orch)
- match = 1;
- else if (ch==andc)
- sb = src;
- else if (ch==arbc)
- sb = sn;
- }
- else
- {
- while ((ch = *pe) && ch!='\n' && ch!=orch)
- pe++;
- sb = src;
- }
- }
- while (match==0 && *pe);
-
- if (match==0) sn = NULL;
- return (sn);
- }
-
- char *strmatch(pat, lpat, src, slast)
- char *pat;
- int lpat;
- char *src;
- char *slast;
-
- /* */
- /* strmatch tries to find the first exact match of 'pat' in 'src'. */
- /* */
-
- {
- register char *sb;
- register char *pb;
- char *plast;
- char *sl;
- register char *s;
-
-
- sl = slast-lpat;
- plast = pat+lpat;
- sb = src;
- do
- {
- if (*(pb=pat)!=swch)
- while(sb<sl && *sb!=*pb) sb++;
-
- if (*sb++==*pb || *pb==swch)
- for (s=sb; ++pb<plast && (*pb==*s++ || *pb==swch); );
- }
- while (sb<=sl && pb<plast);
-
- return ((pb<plast) ? NULL : s);
- }