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 >
Text File  |  2000-06-30  |  5KB  |  186 lines

  1. /*        Find Pattern
  2.  *
  3.  *    This is a program which prints out all lines in a file with a
  4.  * given pattern.  It can be conditionally compiled for either CP/M or
  5.  * Unix.  In either case, it is invoked by:
  6.  *
  7.  *        fp <pattern> <file(s)>
  8.  *
  9.  *    The <file(s)> specification can use normal file widcards, as
  10.  * defined by wildexp in CP/M and the shell in Unix.
  11.  *    The <pattern> is a string of characters, some of which have special
  12.  * meanings:
  13.  *
  14.  *        <char> - any character not listed below matches exactly that
  15.  *             character.
  16.  *        ? - matches any single character.
  17.  *        * - matches zero or more of any character.
  18.  *        [...] - matches one of any of the characters included between
  19.  *            the brackets; character ranges can also be indicated
  20.  *            by <char>-<char>.  E.g., [a-z0-9] will match any
  21.  *            letter or digit.
  22.  *        [-...] - matches one of any of the characters not included
  23.  *             between the brackets.
  24.  *
  25.  *    Also, backslash (\) can be used to quote characters (i.e., keep them
  26.  * from being interpreted specially).
  27.  *
  28.  *    To compile and load the program, make sure that one of UNIX or CPM
  29.  * is defined (not both!) in fp.c, and that you have pat.h and pat.c (and
  30.  * wildexp.crl).  On CP/M, then do:
  31.  *
  32.  *        cc1 pat.c
  33.  *        cc1 fp.c
  34.  *        clink fp pat wildexp
  35.  *
  36.  *    On Unix, then do:
  37.  *
  38.  *        cc -O -o fp fp.c pat.c
  39.  *
  40.  *    Note: On Unix, fp runs about three times slower than grep, so it's
  41.  * not clear why you'd want to use it.  This is probably because I use
  42.  * recursion.  Maybe I'll do a non-recursive version later, but this way
  43.  * is much simpler.
  44.  *
  45.  *
  46.  *    Initial coding 8/18/82 by Harry R. Chesley.
  47.  *
  48.  *
  49.  *    Copyright 1982 by Harry R. Chesley.
  50.  *    Unlimited permission granted for non-profit use only.
  51.  */
  52.  
  53. #include "pat.h"
  54.  
  55. /* UNIX - defined for use on Unix.
  56.  * CPM - defined for use on CP/M (with BDS-C).
  57.  *
  58.  * MAXBSZ - max size of text buffer (big to minimize IO); should be a multiple
  59.  *        of 128 for CPM, but doesn't really have to be.  One more char is
  60.  *        allocated so that a zero byte can be appended when printing
  61.  *        strings.
  62.  * MAXPSZ - max size of pattern string.
  63.  */
  64.  
  65. #define UNIX
  66. /*#define CPM*/
  67.  
  68. #define MAXBSZ 10240+1
  69. #define MAXPSZ 100
  70.  
  71. /*    main()
  72.  *
  73.  *    Function: Invoked by "fp <pattern> <files>".  Prints every line in
  74.  * each file containing the pattern.
  75.  *
  76.  *    Algorithm: Use srchpat() to locate each subsequent line to be output.
  77.  *
  78.  *    Comments: The only tricky things here are: (1) The search pattern is
  79.  * surrounded with "*"s because srchpat() will only do exact matches;
  80.  * inserting the "*"s makes it match the pattern anywhere on the line.  And
  81.  * (2) when we find outselves at the end of a buffer, we read in a new buffer
  82.  * of text, but keep any partial lines to concatenate with the next buffer
  83.  * load.
  84.  *    I use puts() in the CP/M version because BDS-C printf breaks on long
  85.  * lines.  I don't use it in the Unix version because Unix puts() appends
  86.  * newlines to the string.
  87.  */
  88.  
  89. main(argc,argv)
  90.  
  91. int argc;
  92. char *argv[];
  93.  
  94. {
  95.     int fd;            /* File descriptor. */
  96.     char tbuf[MAXBSZ];    /* Input buffer. */
  97.     char pat[MAXPSZ];    /* Search pattern. */
  98.     char *pptr;        /* Pattern string pointer. */
  99.     char *aptr;        /* Argv pattern pointer. */
  100.     char *nptr;        /* New pointer (in copying partials). */
  101.     char *tptr;        /* Text pointer (while searching). */
  102.     char *retstr;        /* Srchpat() return value. */
  103.     char *eosret;        /* EOS pointer return from srchpat(). */
  104.     char ctmp;        /* Temp storage. */
  105.     int sz, osz;        /* Bytes remaining sizes. */
  106.  
  107. #ifdef CPM
  108.     /* Fake command name. */
  109.     argv[0] = "FP";
  110. #endif
  111.  
  112.     /* Verify proper calling procedure: */
  113.     if (argc < 3) {
  114.         printf("Usage: %s <pattern> <file(s)>\n",argv[0]);
  115.         exit(1);
  116.     };
  117.  
  118.     /* Copy search pattern, prepend and postpend "*". */
  119.     pptr = pat;
  120.     *pptr++ = '*';
  121.     for (aptr = argv[1]; *aptr != 0; *pptr++ = *aptr++);
  122.     *pptr++ = '*';
  123.     *pptr = 0;
  124.  
  125.     /* Compile search pattern; normal EOL, ignore case. */
  126.     comppat(pat,'\n',TRUE);
  127.  
  128. #ifdef CPM
  129.     /* Remove search pattern from argv, and expand file names. */
  130.     argv[1] = "NOARG";
  131.     wildexp(&argc, &argv);
  132. #endif
  133.  
  134.     /* Go thru the files one by one. */
  135.     argc--; argv++; argc--; argv++;    /* Skip command name and pattern. */
  136.     while (argc-- > 0) {
  137.         if ((fd = open(argv[0],0)) == -1) {
  138.             printf("Bad file name: %s!\n",argv[0]);
  139.             argv++;
  140.             continue;
  141.         };
  142.         
  143.         /* Read & write, read & write, ... */
  144.         osz = 0;
  145. #ifdef UNIX
  146.         while ((sz = read(fd,tbuf+osz,(MAXBSZ-1)-osz)) > 0) {
  147. #endif
  148. #ifdef CPM
  149.         while ((sz = 128*read(fd,tbuf+osz,((MAXBSZ-1)-osz)/128)) > 0){
  150. #endif
  151.             osz += sz;
  152.             tptr = tbuf;
  153.  
  154.             /* While there's something worth printing. */
  155.             while ((retstr = srchpat(tptr,osz,&eosret)) != 0) {
  156.                 ctmp = *eosret;
  157.                 *eosret = 0;
  158. #ifdef UNIX
  159.                 printf("%s: %s",argv[0],retstr);
  160. #endif
  161. #ifdef CPM
  162.                 puts(argv[0]); puts(": "); puts(retstr);
  163. #endif
  164.                 *eosret = ctmp;
  165.                 osz -= eosret - tptr;
  166.                 tptr = eosret;
  167.             };
  168.  
  169.             /* Find partial line at end. */
  170.             tptr += osz-1;
  171.             for (sz = 0; sz != osz; sz++) {
  172.                 if (*tptr == '\n') break;
  173.                 tptr--;
  174.             };
  175.  
  176.             /* Copy partial. */
  177.             tptr++;
  178.             osz = sz;
  179.             for (nptr = tbuf; sz != 0; sz--) *nptr++ = *tptr++;
  180.         };
  181.  
  182.         close(fd);
  183.         argv++;
  184.     };
  185. }
  186.