home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
BDSC
/
BDSC-3
/
FP.C
< prev
next >
Wrap
Text File
|
2000-06-30
|
5KB
|
186 lines
/* Find Pattern
*
* This is a program which prints out all lines in a file with a
* given pattern. It can be conditionally compiled for either CP/M or
* Unix. In either case, it is invoked by:
*
* fp <pattern> <file(s)>
*
* The <file(s)> specification can use normal file widcards, as
* defined by wildexp in CP/M and the shell in Unix.
* The <pattern> is a string of characters, some of which have special
* meanings:
*
* <char> - any character not listed below matches exactly that
* character.
* ? - matches any single character.
* * - matches zero or more of any character.
* [...] - matches one of any of the characters included between
* the brackets; character ranges can also be indicated
* by <char>-<char>. E.g., [a-z0-9] will match any
* letter or digit.
* [-...] - matches one of any of the characters not included
* between the brackets.
*
* Also, backslash (\) can be used to quote characters (i.e., keep them
* from being interpreted specially).
*
* To compile and load the program, make sure that one of UNIX or CPM
* is defined (not both!) in fp.c, and that you have pat.h and pat.c (and
* wildexp.crl). On CP/M, then do:
*
* cc1 pat.c
* cc1 fp.c
* clink fp pat wildexp
*
* On Unix, then do:
*
* cc -O -o fp fp.c pat.c
*
* Note: On Unix, fp runs about three times slower than grep, so it's
* not clear why you'd want to use it. This is probably because I use
* recursion. Maybe I'll do a non-recursive version later, but this way
* is much simpler.
*
*
* Initial coding 8/18/82 by Harry R. Chesley.
*
*
* Copyright 1982 by Harry R. Chesley.
* Unlimited permission granted for non-profit use only.
*/
#include "pat.h"
/* UNIX - defined for use on Unix.
* CPM - defined for use on CP/M (with BDS-C).
*
* MAXBSZ - max size of text buffer (big to minimize IO); should be a multiple
* of 128 for CPM, but doesn't really have to be. One more char is
* allocated so that a zero byte can be appended when printing
* strings.
* MAXPSZ - max size of pattern string.
*/
#define UNIX
/*#define CPM*/
#define MAXBSZ 10240+1
#define MAXPSZ 100
/* main()
*
* Function: Invoked by "fp <pattern> <files>". Prints every line in
* each file containing the pattern.
*
* Algorithm: Use srchpat() to locate each subsequent line to be output.
*
* Comments: The only tricky things here are: (1) The search pattern is
* surrounded with "*"s because srchpat() will only do exact matches;
* inserting the "*"s makes it match the pattern anywhere on the line. And
* (2) when we find outselves at the end of a buffer, we read in a new buffer
* of text, but keep any partial lines to concatenate with the next buffer
* load.
* I use puts() in the CP/M version because BDS-C printf breaks on long
* lines. I don't use it in the Unix version because Unix puts() appends
* newlines to the string.
*/
main(argc,argv)
int argc;
char *argv[];
{
int fd; /* File descriptor. */
char tbuf[MAXBSZ]; /* Input buffer. */
char pat[MAXPSZ]; /* Search pattern. */
char *pptr; /* Pattern string pointer. */
char *aptr; /* Argv pattern pointer. */
char *nptr; /* New pointer (in copying partials). */
char *tptr; /* Text pointer (while searching). */
char *retstr; /* Srchpat() return value. */
char *eosret; /* EOS pointer return from srchpat(). */
char ctmp; /* Temp storage. */
int sz, osz; /* Bytes remaining sizes. */
#ifdef CPM
/* Fake command name. */
argv[0] = "FP";
#endif
/* Verify proper calling procedure: */
if (argc < 3) {
printf("Usage: %s <pattern> <file(s)>\n",argv[0]);
exit(1);
};
/* Copy search pattern, prepend and postpend "*". */
pptr = pat;
*pptr++ = '*';
for (aptr = argv[1]; *aptr != 0; *pptr++ = *aptr++);
*pptr++ = '*';
*pptr = 0;
/* Compile search pattern; normal EOL, ignore case. */
comppat(pat,'\n',TRUE);
#ifdef CPM
/* Remove search pattern from argv, and expand file names. */
argv[1] = "NOARG";
wildexp(&argc, &argv);
#endif
/* Go thru the files one by one. */
argc--; argv++; argc--; argv++; /* Skip command name and pattern. */
while (argc-- > 0) {
if ((fd = open(argv[0],0)) == -1) {
printf("Bad file name: %s!\n",argv[0]);
argv++;
continue;
};
/* Read & write, read & write, ... */
osz = 0;
#ifdef UNIX
while ((sz = read(fd,tbuf+osz,(MAXBSZ-1)-osz)) > 0) {
#endif
#ifdef CPM
while ((sz = 128*read(fd,tbuf+osz,((MAXBSZ-1)-osz)/128)) > 0){
#endif
osz += sz;
tptr = tbuf;
/* While there's something worth printing. */
while ((retstr = srchpat(tptr,osz,&eosret)) != 0) {
ctmp = *eosret;
*eosret = 0;
#ifdef UNIX
printf("%s: %s",argv[0],retstr);
#endif
#ifdef CPM
puts(argv[0]); puts(": "); puts(retstr);
#endif
*eosret = ctmp;
osz -= eosret - tptr;
tptr = eosret;
};
/* Find partial line at end. */
tptr += osz-1;
for (sz = 0; sz != osz; sz++) {
if (*tptr == '\n') break;
tptr--;
};
/* Copy partial. */
tptr++;
osz = sz;
for (nptr = tbuf; sz != 0; sz--) *nptr++ = *tptr++;
};
close(fd);
argv++;
};
}