Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: Match 1.2 - Fast grep for Vaxen Message-ID: <1600@panda.UUCP> Date: 4 Apr 86 14:57:41 GMT Sender: jpn@panda.UUCP Organization: Bell-Northern Research, Ottawa, Ontario Lines: 905 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 51 Submitted by: genrad!decvax!linus!bnr-vpa!pdbain This contains the same bug fixes as in the latest release of bm. Match is a very fast (faster than bm, much faster than grep) pattern matcher for Vax machines, using the MATCHC instruction. Be warned, though: some Vaxen (such as Microvax I) interpret the MATCHC instruction, and don't achieve the same performance. *********************** cut here ****************************** #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # match.1 # Makefile # Search.s # Execute.c # GetPatFile.c # Global.c # MakeDesc.c # MatchFound.c # MkDescVec.c # MoveResidue.c # PrintLine.c # PutUsage.c # match.c # Extern.h # match.h # This archive created: Fri Apr 4 09:54:35 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'README'" '(1794 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' Match is a fast pattern matching utility, intended to be almost identical in functionality to fgrep (ugh!) but much faster. It uses MATCHC instruction on VAX computers. Apparently, it is faster than BM only on the VAX 780 - on the Microvax it is much slower than bm. *** NOTE *** There are certain system dependencies in the code. Some systems use "index", others "strchr" to find a character in a string: this affects MkDescVec.c. A #ifdef checks this. Please check whether your system uses or . If it uses strings.h, delete "-DSTRINGS" from the line CFLAGS = -O -DSTRINGS -DBCOPY in the Makefile. This affects match.c/bm.c, MkDescVec.c, and PrintLine.c. Also check whether your system has "bcopy". If it uses strings.h, comment out "-DBCOPY" from the line CFLAGS = -O -DSTRINGS -DBCOPY in the Makefile. This affects MoveResidue.c The files are: Execute.c: search a file for the patterns Extern.h: declarations of externs GetPatFile.c: read in patterns from a file and set up a vector of pattern descriptors Global.c: global variables (complement to Extern.h) MakeDesc.c: create a pattern descriptor for one pattern Makefile: you can figure this one out for yourself MatchFound.c: what to do when you actually FIND a pattern - print it, update flags, etc. MkDescVec.c: make a vector of pattern descriptors, given a string of newline-separated patterns MoveResidue.c: when you come to the end of the buffer, move the unsearched "residue" to the beginning and start again PrintLine.c: print the appropriate stuff after finding a match PutUsage.c: mini-man page. README: this file Search.s: the guts. Calls MATCH match.c: mainline. mostly interpreting the command line and tidying up at the end. Calls Execute for each file. match.h: constants match.1: man page SHAR_EOF if test 1794 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 1794 characters)' fi fi echo shar: extracting "'match.1'" '(2712 characters)' if test -f 'match.1' then echo shar: will not over-write existing file "'match.1'" else cat << \SHAR_EOF > 'match.1' .TH MATCH PUBLIC "11 July 1985" .UC 4 .SH NAME match \- search a file for a string .SH SYNOPSIS .B /usr/public/match [ option ] ... [ strings ] [ file ] .SH DESCRIPTION .I Match searches the input .I files (standard input default) for lines matching a string. Normally, each line found is copied to the standard output. It is blindingly fast. .I Match strings are fixed sequences of characters: there are no wildcards, repetitions, or other features of regular expressions. Match is also case sensitive. The following options are recognized. .TP .B \-x (Exact) only lines matched in their entirety are printed .TP .B \-l The names of files with matching lines are listed (once) separated by newlines. .TP .B \-c Only a count of the number of matches is printed .TP .B \-e "string" The string is the next argument after the .B \-e flag. This allows strings beginning with '-'. .TP .B \-h No filenames are printed, even if multiple files are searched. .TP .B \-n Each line is preceded by the number of characters from the beginning of the file to the match. .TP .B \-s Silent mode. Nothing is printed (except error messages). This is useful for checking the error status. .TP .BI \-f " file" The string list is taken from the .I file. .LP Unless the .B \-h option is specified the file name is shown if there is more than one input file. Care should be taken when using the characters $ * [ ^ | ( ) and \\ in the .I strings (listed on the command line) as they are also meaningful to the Shell. It is safest to enclose the entire .I expression argument in single quotes \' \'. .LP .I Match searches for lines that contain one of the (newline-separated) .I strings, using the VAX MATCHC instruction It is far superior in terms of speed to the grep (egrep, fgrep) family of pattern matchers, as well as bm(p) for fixed-pattern searching on a VAX 780. .SH "SEE ALSO" grep(1), bm(p) .SH DIAGNOSTICS Exit status is 0 if any matches are found, 1 if none, 2 for syntax errors or inaccessible files. .SH AUTHOR Peter Bain (pdbain@wateng) .SH BUGS Works slowly on VAXen other than the 780, and doesn't work at all on other architectures. .LP Only 100 patterns are allowed. .LP Patterns may not contain newlines. .LP If a line (delimited by newlines, and the beginning and end of the file) is longer than 8000 charcters (e.g. in a core dump), it will not be completely printed. .LP If multiple patterns are specified, the order of the ouput lines is not necessarily the same as the order of the input lines. .LP A line will be printed once for each different string on that line. .LP The algorithm cannot count lines. .LP The .B -n and .B -c work differently from fgrep. .LP The .B -v, .B -i, and .B -b are not available. SHAR_EOF if test 2712 -ne "`wc -c < 'match.1'`" then echo shar: error transmitting "'match.1'" '(should have been 2712 characters)' fi fi echo shar: extracting "'Makefile'" '(1121 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' CFLAGS = -O -DSTRINGS -DBCOPY SOURCES = Execute.c Extern.h\ GetPatFile.c Global.c MakeDesc.c \ match.h match.c MatchFound.c \ MkDescVec.c MoveResidue.c PrintLine.c PutUsage.c Search.s OBJECTS = Execute.o \ GetPatFile.o Global.o MakeDesc.o \ match.o MatchFound.o \ MkDescVec.o MoveResidue.o Search.o PrintLine.o PutUsage.o BASEFILES = $(SOURCES) Makefile README match.p match: $(OBJECTS) cc -o match $(CFLAGS) $(OBJECTS) shar: shar $(BASEFILES) >match.shar install: match install -c -s match /usr/public/match man: /usr/man/manp/match.p /usr/man/manp/match.p: match.p rm -f /usr/man/manp/match.p cp match.p /usr/man/manp/match.p man match > /dev/null match.o: match.c match.h Extern.h PutUsage.o: PutUsage.c match.h Search.o: Search.s Execute.o: Execute.c match.h MoveResidue.o: MoveResidue.c match.h Extern.h MatchFound.o: MatchFound.c match.h Extern.h PrintLine.o: PrintLine.c Extern.h MkDescVec.o: MkDescVec.c match.h GetPatFile.o: GetPatFile.c match.h MakeDesc.o: MakeDesc.c match.h Global.o: Global.c listing: print -o3 $(BASEFILES) Makefile # print -i3 $(BASEFILES) Makefile clean: rm -f *.o match SHAR_EOF if test 1121 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 1121 characters)' fi fi echo shar: extracting "'Search.s'" '(239 characters)' if test -f 'Search.s' then echo shar: will not over-write existing file "'Search.s'" else cat << \SHAR_EOF > 'Search.s' LL0: .data .text .align 1 .globl _Search _Search: .word L20 matchc 8(ap),*4(ap),16(ap),*12(ap) beql match movl 20(ap),r0 movl r3,8(r0) movl $0,r0 ret match: movl 20(ap),r0 movl r3,8(r0) movl $1,r0 ret .set L20,0xf00 .data SHAR_EOF if test 239 -ne "`wc -c < 'Search.s'`" then echo shar: error transmitting "'Search.s'" '(should have been 239 characters)' fi fi echo shar: extracting "'Execute.c'" '(2733 characters)' if test -f 'Execute.c' then echo shar: will not over-write existing file "'Execute.c'" else cat << \SHAR_EOF > 'Execute.c' #include #include "match.h" #include "Extern.h" Execute(DescVec, NPats, TextFile, Buffer) register struct PattDesc *DescVec[]; /* pointers to status vectors for the different * patterns, including skip tables, position in buffer, etc. */ register int NPats; /* number of patterns */ register char Buffer[]; /* holds text from file */ register int TextFile; /* file to search */ { int NRead, /* number of chars read from file */ NWanted, /* number of chars wanted */ NAvail, /* number of chars actually read */ BuffSize, /* number of chars in buffer */ BuffPos, /* offset of first char in Buffer in TextFile */ BuffEx, /* flag to indicate that buffer has been searched */ ResSize, /* number of characters in the last, incomplete line */ Found, /* flag indicates whether pattern found * completely and all matches printed */ Valid; /* was the match "valid", i.e. if -x used, * did the whole line match? */ register char *BuffEnd; /* pointer to last char of last complete line */ /* misc working variables */ register int i; /* initialize */ ResSize = 0; Found = 0; BuffPos = 0; for (i=0; i < NPats; i++) { DescVec[i] -> Success = 0; DescVec[i] -> Start = Buffer; } /* for */ /* now do the searching */ do { /* first, read a bufferfull and set up the variables */ NWanted = MAXBUFF - ResSize; NRead = 0; do { NAvail = read(TextFile,Buffer + ResSize + NRead, NWanted); if (NAvail == -1) { fprintf(stderr, "bm: error reading from input file\n"); exit(2); } /* if */ NRead += NAvail; NWanted -= NAvail; } while (NAvail && NWanted); BuffEx = 0; BuffSize = ResSize + NRead; BuffEnd = Buffer + BuffSize - 1; /* locate the end of the last complete line */ while (*BuffEnd != '\n' && BuffEnd >= Buffer) --BuffEnd; if (BuffEnd < Buffer) BuffEnd = Buffer + BuffSize - 1; while (!BuffEx) { /* work through one buffer full */ BuffEx = 1; /* set it provisionally, then clear * it if we find the buffer non-empty */ for (i=0; i< NPats; i++) { if (!DescVec[i]->Success) /* if the pattern has not been found */ DescVec[i]-> Success = Search(DescVec[i]->Pattern, DescVec[i]->PatLen, DescVec[i]->Start, BuffEnd - DescVec[i]->Start + 1, DescVec[i]); if (DescVec[i]->Success){ /* if a match occurred */ BuffEx = 0; Valid = MatchFound(DescVec[i],BuffPos, Buffer, BuffEnd); Found |= Valid; if ((sFlag || lFlag) && Found) return(0); } /* if */ } /* for */ } /* while */ if(NRead) { ResSize = MoveResidue(DescVec,NPats,Buffer, Buffer + BuffSize -1); BuffPos += BuffSize - ResSize; } /* if */ } while (NRead); return(!Found); } /* Execute */ SHAR_EOF if test 2733 -ne "`wc -c < 'Execute.c'`" then echo shar: error transmitting "'Execute.c'" '(should have been 2733 characters)' fi fi echo shar: extracting "'GetPatFile.c'" '(1410 characters)' if test -f 'GetPatFile.c' then echo shar: will not over-write existing file "'GetPatFile.c'" else cat << \SHAR_EOF > 'GetPatFile.c' #include #include #include #include "match.h" int GetPatFile(PatFile, DescVec) char *PatFile; struct PattDesc *DescVec[]; /* read patterns from a file and set up a pattern descriptor vector */ { extern char *malloc(); FILE *PFile; struct stat StatBuff; int PatSize; /* the number of chars in all the patterns */ char *PatBuff; /* hold the patterns */ if (!(strlen(PatFile))) { fprintf(stderr,"mathc: no pattern file given\n"); exit(2); } /* if */ if (!(PFile = fopen(PatFile,"r"))) { fprintf(stderr,"match: can't open pattern file %s\n",PatFile); exit(2); } /* if */ /* find out how big the patterns are */ if (fstat(fileno(PFile),&StatBuff) == -1) { fprintf(stderr,"match: can't fstat %s\n",PatFile); exit(2); } /* if */ if (isatty(fileno(PFile))) PatSize = PSIZEDEF; else PatSize = StatBuff.st_size; if (!PatSize) { fprintf(stderr,"match: pattern file is empty\n"); exit(2); } /* if */ if (!(PatBuff = malloc(PatSize + 1))) { fprintf(stderr,"match: insufficient memory to store patterns\n"); exit(2); } /* if */ fread(PatBuff,1,PatSize,PFile); /* get the patterns */ fclose(PFile); /* make sure the patterns are null-terminated. We can't have * nulls in the patterns */ if (PatBuff[PatSize-1] == '\n') PatBuff[PatSize-1] = '\0'; else PatBuff[PatSize] = '\0'; return(MkDescVec(DescVec,PatBuff)); } /* GetPatFile */ SHAR_EOF if test 1410 -ne "`wc -c < 'GetPatFile.c'`" then echo shar: error transmitting "'GetPatFile.c'" '(should have been 1410 characters)' fi fi echo shar: extracting "'Global.c'" '(626 characters)' if test -f 'Global.c' then echo shar: will not over-write existing file "'Global.c'" else cat << \SHAR_EOF > 'Global.c' /* global flags for match */ int cFlag=0, /* true if we want only a count of matching lines */ eFlag=0, /* indicates that next argument is the pattern */ fFlag=0, /* true if the patterns are to come from a file */ lFlag=0, /* true if we want a list of files containing the pattern */ nFlag=0, /* true if we want the character offset of the pattern */ sFlag=0, /* true if we want silent mode */ xFlag=0, /* true if we want only lines which match entirely */ hFlag=0, /* true if we want no filenames in output */ MatchCount=0; /* count of number of times a search string was found * in the text */ char *FileName = 0; SHAR_EOF if test 626 -ne "`wc -c < 'Global.c'`" then echo shar: error transmitting "'Global.c'" '(should have been 626 characters)' fi fi echo shar: extracting "'MakeDesc.c'" '(343 characters)' if test -f 'MakeDesc.c' then echo shar: will not over-write existing file "'MakeDesc.c'" else cat << \SHAR_EOF > 'MakeDesc.c' #include #include "match.h" #include "Extern.h" extern char * malloc(); /* makes a pattern descriptor */ struct PattDesc *MakeDesc(Pattern) char *Pattern; { struct PattDesc *Desc; Desc = (struct PattDesc *) malloc(sizeof(struct PattDesc)); Desc->Pattern=Pattern; Desc->PatLen = strlen(Desc->Pattern); return(Desc); } /* main */ SHAR_EOF if test 343 -ne "`wc -c < 'MakeDesc.c'`" then echo shar: error transmitting "'MakeDesc.c'" '(should have been 343 characters)' fi fi echo shar: extracting "'MatchFound.c'" '(1181 characters)' if test -f 'MatchFound.c' then echo shar: will not over-write existing file "'MatchFound.c'" else cat << \SHAR_EOF > 'MatchFound.c' #include #include "match.h" #include "Extern.h" MatchFound(Desc, BuffPos, Buffer, BuffEnd) struct PattDesc *Desc; /* state info about search for one string */ int BuffPos; /* offset of first char of buffer into the file being searched */ char *Buffer, /* pointer to the first character in the buffer */ *BuffEnd; /* pointer to the last character in the buffer */ { register char *MLineBegin, *MLineEnd; Desc->Success = 0; /* Start points to first character after a successful match */ MLineBegin = MLineEnd = Desc->Start - 1; while(MLineBegin >=Buffer && *MLineBegin != '\n') --MLineBegin; ++MLineBegin; while( MLineEnd <= BuffEnd && *MLineEnd != '\n') ++MLineEnd; if (MLineEnd > BuffEnd) --MLineEnd; /* fixed 25jun85 pdbain. suppress multiple matches of the same * pattern on one line */ Desc->Start = MLineEnd + 1; /* check if exact match */ if (xFlag && !( Desc->PatLen == (*MLineEnd != '\n' ? ((MLineEnd - MLineBegin) + 1) : (MLineEnd - MLineBegin)))) return(0); /* failure */ if (sFlag) return(1); if (cFlag) { ++MatchCount; return(1); } /* if */ PrintLine(BuffPos+(Desc->Start-Buffer),MLineBegin,MLineEnd); return(1); } /* MatchFound */ SHAR_EOF if test 1181 -ne "`wc -c < 'MatchFound.c'`" then echo shar: error transmitting "'MatchFound.c'" '(should have been 1181 characters)' fi fi echo shar: extracting "'MkDescVec.c'" '(831 characters)' if test -f 'MkDescVec.c' then echo shar: will not over-write existing file "'MkDescVec.c'" else cat << \SHAR_EOF > 'MkDescVec.c' #include "match.h" #ifdef STRINGS #include #else /* some systems use , others use */ #include #endif #ifndef index /* some systems use "strchr" instead of "index" */ #define index strchr #endif /* scan a newline-separated string of patterns and set up the * vector of descriptors, one pattern descriptor per pattern. * Return the number of patterns */ int MkDescVec(DescVec, Pats) struct PattDesc *DescVec[]; char *Pats; { int NPats = 0; char *EndPat; extern struct PattDesc *MakeDesc(); while (*Pats && (EndPat = index(Pats,'\n')) && NPats < MAXPATS) { *EndPat = '\0'; DescVec[NPats] = MakeDesc(Pats); Pats = EndPat + 1; ++NPats; } /* while */ if (*Pats && NPats < MAXPATS) { DescVec[NPats] = MakeDesc(Pats); ++NPats; } /* if */ return(NPats); } /* MkDescVec */ SHAR_EOF if test 831 -ne "`wc -c < 'MkDescVec.c'`" then echo shar: error transmitting "'MkDescVec.c'" '(should have been 831 characters)' fi fi echo shar: extracting "'MoveResidue.c'" '(1280 characters)' if test -f 'MoveResidue.c' then echo shar: will not over-write existing file "'MoveResidue.c'" else cat << \SHAR_EOF > 'MoveResidue.c' #include "match.h" /* Moves the text which has not been completely searched at the end of * the buffer to the beginning of the buffer * and returns number of bytes moved */ int MoveResidue(DescVec, NPats,Buffer, BuffEnd) register struct PattDesc **DescVec; int NPats; char *Buffer, *BuffEnd; { char *FirstStart; register char *Residue; /* use this declaration if you don't use "bcopy" */ register char *f, *t; register int i; int ResSize; FirstStart = BuffEnd; /* find the earliest point which has not been * completely searched */ for (i=0; i < NPats; i++) { FirstStart = min(FirstStart, DescVec[i]-> Start ); } /* for */ /* now scan to the beginning of the line containing the * unsearched text */ for (Residue = FirstStart; *Residue != '\n' && Residue >= Buffer; Residue--); if (Residue < Buffer) Residue = FirstStart; else ++Residue; /* now move the residue to the beginning of * the file */ ResSize = BuffEnd - Residue + 1; /* use this if you don't have "bcopy" */ t = Buffer; f = Residue; #ifdef BCOPY bcopy(Residue, Buffer, ResSize); #else for(i=ResSize;i;--i) *t++ = *f++; #endif /* now fix the status vectors */ for (i=0; i < NPats; i++) { DescVec[i]->Start -= (Residue - Buffer); } /* for */ return(ResSize); } /* MoveResidue */ SHAR_EOF if test 1280 -ne "`wc -c < 'MoveResidue.c'`" then echo shar: error transmitting "'MoveResidue.c'" '(should have been 1280 characters)' fi fi echo shar: extracting "'PrintLine.c'" '(968 characters)' if test -f 'PrintLine.c' then echo shar: will not over-write existing file "'PrintLine.c'" else cat << \SHAR_EOF > 'PrintLine.c' #include #ifdef STRINGS /* some systems use , others use */ #include #else #include #endif #include "Extern.h" PrintLine(OffSet,LineStart,LineEnd) int OffSet; /* offset of LineStart from beginning of file */ char *LineStart, *LineEnd; { char OffStr[80]; if (lFlag) { if (strlen(FileName) > 76) { fprintf(stderr,"match: filename too long\n"); exit(2); } /* if */ if (strlen(FileName)) { sprintf(OffStr,"%s\n",FileName); write(1,OffStr,strlen(OffStr)); } /* if */ return; } /* if */ if (FileName && !hFlag) { if (strlen(FileName) > 76) { fprintf(stderr,"match: filename too long\n"); exit(2); } /* if */ sprintf(OffStr,"%s: ",FileName); write(1,OffStr,strlen(OffStr)); } /* if */ if (nFlag) { sprintf(OffStr,"%d: ",OffSet); write(1,OffStr,strlen(OffStr)); } /* if */ write(1,LineStart,LineEnd-LineStart+1); if (*LineEnd != '\n') write (1,"\n",1); } /* PrintLine */ SHAR_EOF if test 968 -ne "`wc -c < 'PrintLine.c'`" then echo shar: error transmitting "'PrintLine.c'" '(should have been 968 characters)' fi fi echo shar: extracting "'PutUsage.c'" '(774 characters)' if test -f 'PutUsage.c' then echo shar: will not over-write existing file "'PutUsage.c'" else cat << \SHAR_EOF > 'PutUsage.c' #include PutUsage() { fprintf(stderr, "match: search for a given string or strings in a file or files\n"); fprintf(stderr, "synopsis: match [option]* [string(s)] [file]*\n"); fprintf(stderr, "options:\n"); fprintf(stderr, "-c print only a count of matching lines \n"); fprintf(stderr, "-e Take next argument as the pattern\n"); fprintf(stderr, "-f PFile read patterns from a file PFile\n"); fprintf(stderr, "-h Do not print file names\n"); fprintf(stderr, "-l print a list of files containing the pattern(s) \n"); fprintf(stderr, "-n print the character offset of the pattern(s) \n"); fprintf(stderr, "-s silent mode. Return only success (0) or failure (1)\n"); fprintf(stderr, "-x print only lines which match entirely \n"); } /*PutUsage */ SHAR_EOF if test 774 -ne "`wc -c < 'PutUsage.c'`" then echo shar: error transmitting "'PutUsage.c'" '(should have been 774 characters)' fi fi echo shar: extracting "'match.c'" '(2504 characters)' if test -f 'match.c' then echo shar: will not over-write existing file "'match.c'" else cat << \SHAR_EOF > 'match.c' #include #include #include #ifdef STRINGS /* some systems use , others use */ #include #else #include #endif #include "match.h" #include "Extern.h" main(argc,argv) int argc; char *argv[]; { /* grep based on VAX MATCHC instruction */ char BigBuff[MAXBUFF + 2]; /* * We leave one extra character at the beginning and end of the buffer, * but don't tell Execute about it. This is so when someone is * scanning the buffer and scans past the end (or beginning) * we are still technically in the buffer (picky, but there ARE * machines which would complain) */ int ret = 1, /* return code from Execute */ NotFound = 0, /* non-zero if file not readable */ NFiles, NPats; /* number of patterns to search for */ char i, *FlagPtr, **OptPtr; /* used to scan command line */ int TextFile /* file to search */; struct PattDesc *DescVec[MAXPATS]; --argc; OptPtr = argv + 1; while ( argc && **OptPtr == '-') { FlagPtr = *OptPtr + 1; while (*FlagPtr) { switch (*FlagPtr) { case 'c': cFlag = 1; break; case 'e': eFlag = 1; /* get the patterns from next arg */ NPats = MkDescVec(DescVec,*++OptPtr); --argc; break; case 'f': fFlag = 1; /* read the patterns from a file */ NPats = GetPatFile(*++OptPtr,DescVec); --argc; break; case 'l': lFlag = 1; break; case 'n': nFlag = 1; break; case 's': sFlag = 1; break; case 'x': xFlag = 1; break; case 'h': hFlag = 1; break; default: fprintf(stderr, "match: invalid option: -%c \n", *FlagPtr); PutUsage(); exit(2); } /* switch */ ++FlagPtr; } /* while */ ++OptPtr; --argc; } /* while */ /* OptPtr now points to patterns */ if (!fFlag && !eFlag) { if (!argc) { fprintf(stderr,"match: no pattern specified\n"); PutUsage(); exit(2); } else NPats = MkDescVec(DescVec,*OptPtr); ++OptPtr; --argc; } /* OptPtr now points to first file */ NFiles = argc; if (!NFiles) ret &= Execute(DescVec,NPats,0,BigBuff+1); else while (argc--) { if ((NFiles > 1) || lFlag) FileName = *OptPtr; if ((TextFile = open(*OptPtr,O_RDONLY,0)) < 0) { fprintf(stderr,"match: can't open %s\n",*OptPtr); NotFound++; } else { ret &= Execute(DescVec,NPats,TextFile,BigBuff+1); if (sFlag && !ret) exit(0); close(TextFile); } /* if */ ++OptPtr; } /* while */ if (cFlag) printf("%d\n",MatchCount); exit(NotFound ? 2 : ret); } /* main */ SHAR_EOF if test 2504 -ne "`wc -c < 'match.c'`" then echo shar: error transmitting "'match.c'" '(should have been 2504 characters)' fi fi echo shar: extracting "'Extern.h'" '(616 characters)' if test -f 'Extern.h' then echo shar: will not over-write existing file "'Extern.h'" else cat << \SHAR_EOF > 'Extern.h' /* global flags for bm */ extern int cFlag, /* true if we want only a count of matching lines */ eFlag, /* indicates that next argument is the pattern */ fFlag, /* true if the patterns arew to come from a file */ lFlag, /* true if we want a list of files containing the pattern */ nFlag, /* true if we want the character offset of the pattern */ sFlag, /* true if we want silent mode */ xFlag, /* true if we want only lines which match entirely */ hFlag, /* true if we want no filenames in output */ MatchCount; /* count of number of times a search string was found * in the text */ extern char *FileName; SHAR_EOF if test 616 -ne "`wc -c < 'Extern.h'`" then echo shar: error transmitting "'Extern.h'" '(should have been 616 characters)' fi fi echo shar: extracting "'match.h'" '(472 characters)' if test -f 'match.h' then echo shar: will not over-write existing file "'match.h'" else cat << \SHAR_EOF > 'match.h' #define FIRSTCHAR ' ' #define MAXCHAR 0377 #define MAXBUFF 8192 #define MAXSIZE 100 #define MAXPATS 100 /* max number of patterns */ #define PSIZEDEF 1024 /* default storage for patterns from a tty */ #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) struct PattDesc { char *Pattern; int PatLen; /* pattern length */ char *Start; /* starting position of search (at beginning of pattern) */ int Success; /* true when pattern found */ }; SHAR_EOF if test 472 -ne "`wc -c < 'match.h'`" then echo shar: error transmitting "'match.h'" '(should have been 472 characters)' fi fi exit 0 # End of shell archive