home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / JGREP.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  182 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  JGREP.C - A utility to search files for text.
  5. **
  6. **  public domain by Jerry Coffin
  7. **
  8. **  Link with wildargs.obj (Borland), setargv.obj (Microsoft), _mainX.obj 
  9. **  (Symantec/Zortech), or wildargX.obj (Watcom) which allows you to pass 
  10. **  wildcards on the command line.
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <limits.h>
  17. #include <ctype.h>
  18. #include "extkword.h"
  19.  
  20. #define LINELEN 1024
  21. #define BUFSIZE 32767
  22.  
  23. #if defined(_QC) || defined(_MSC_VER)
  24.     void CDECL _setenvp(void) {}
  25.     void CDECL _nullcheck(void) {}
  26. #endif
  27.  
  28. enum { FALSE, TRUE };
  29.  
  30. typedef unsigned char uchar;
  31.  
  32. static size_t table[UCHAR_MAX+1];
  33. static size_t len;
  34. static char *string=NULL;
  35.  
  36. void init_find(char *new_string)
  37. {
  38.       size_t i;
  39.  
  40.       if (NULL != string)
  41.             free(string);
  42.       string = strdup(new_string);
  43.       len = strlen(string);
  44.  
  45.       for (i=0;i<=UCHAR_MAX;i++)
  46.             table[i]=len;
  47.       for (i=0;i<len;i++)
  48.             table[string[i]]=len-i-1;
  49. }
  50.  
  51. char *find_case(char *string2)
  52. {
  53.       size_t limit = strlen(string2);
  54.       size_t shift;
  55.       size_t pos=len-1;
  56.       char *here;
  57.  
  58.       while (pos < limit)
  59.       {
  60.             while( pos < limit && (shift=table[(uchar)string2[pos]])>0)
  61.                   pos+=shift;
  62.             if (0==shift)
  63.             {
  64.                   if (!memcmp(string,here=string2+pos-len+1,len))
  65.                         return(here);
  66.                   else  pos++;
  67.             }
  68.       }
  69.       return NULL;
  70. }
  71.  
  72. char *find_no_case(char *string2)
  73. {
  74.       size_t limit = strlen(string2);
  75.       size_t shift;
  76.       size_t pos=len-1;
  77.       char *here;
  78.  
  79.       while (pos < limit)
  80.       {
  81.             while( pos < limit &&
  82.                   (shift=table[(uchar)toupper(string2[pos])])>0)
  83.             {
  84.                   pos+=shift;
  85.             }
  86.             if (0==shift)
  87.             {
  88.                   if (!memicmp(string,here=string2+pos-len+1,len))
  89.                         return(here);
  90.                   else  pos++;
  91.             }
  92.       }
  93.       return NULL;
  94. }
  95.  
  96. char *( *find)    (char *)=find_case;
  97.  
  98. int main(int argc, char **argv)
  99. {
  100.       int         k, first;
  101.       unsigned    line;
  102.       int line_numbers=FALSE, reverse=FALSE, print_file_name=FALSE;
  103.       int no_case = TRUE;
  104.       char line_buffer[LINELEN],*string,c;
  105.       FILE *infile=NULL;
  106.       static char buffer[BUFSIZE];
  107.  
  108.       while (argc > 1 && (c=argv[1][0])=='/' || c=='-')
  109.       {
  110.             switch(tolower(argv[1][1]))
  111.             {
  112.             case 'c':
  113.             case 'y':
  114.                   no_case=FALSE;
  115.                   break;
  116.  
  117.             case 'f':
  118.                   print_file_name=TRUE;
  119.  
  120.             case 'n':
  121.                   line_numbers=TRUE;
  122.                   break;
  123.  
  124.             case 'v':
  125.                   reverse = TRUE;
  126.                   break;
  127.  
  128.             default:
  129.                   fprintf(stderr,"unknown switch -%c",argv[1][1]);
  130.             }
  131.             argv++;
  132.             argc--;
  133.       }
  134.       if (argc < 3)
  135.       {
  136.             fprintf(stderr ,"\nsyntax: find [-c|y][-n][-v][-f] "
  137.                   "string filename ..."
  138.                   "\n\t-c | -y : make case significant ('c' != 'C')"
  139.                   "\n\t-n      : number lines"
  140.                   "\n\t-f      : place file name before lines ( forces -n)"
  141.                   "\n\t-v      : print lines that don't match"
  142.                   "\n - by itself to read from standard input");
  143.             return(1);
  144.       }
  145.  
  146.       string=argv[1];
  147.       if (no_case)
  148.       {
  149.             strupr(string);
  150.             find=find_no_case;
  151.       }
  152.       init_find(string);
  153.       for (k=2;k<argc;k++)
  154.       {
  155.             if (infile != NULL)
  156.                   fclose(infile);
  157.             if ((infile=fopen(argv[k],"r"))==NULL)
  158.                   continue;
  159.             first=TRUE;
  160.             setvbuf(infile,buffer,_IOFBF,BUFSIZE);
  161.             line=0;
  162.             while (fgets(line_buffer,LINELEN,infile)!=NULL)
  163.             {
  164.                   line ++;
  165.                   if ((NULL!=find(line_buffer)) ^ reverse)
  166.                   {
  167.                         if (first && !print_file_name )
  168.                         {
  169.                               printf("\n\t%s:\n",argv[k]);
  170.                               first = FALSE;
  171.                         }
  172.                         if (print_file_name)
  173.                               printf(" %s ",argv[k]);
  174.                         if (line_numbers)
  175.                               printf("%d:",line);
  176.                         printf("%s",line_buffer);
  177.                   }
  178.             }
  179.       }
  180.       return 0;
  181. }
  182.