home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume16 / hgrep / hgrep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-10  |  3.5 KB  |  166 lines

  1. /*
  2. ** hgrep - a front end to grep that highlights the string found
  3. **
  4. ** version of 23oct88
  5. **
  6. ** Copyright (C) 1988 by Jef Poskanzer.
  7. **
  8. ** Permission to use, copy, modify, and distribute this software and its
  9. ** documentation for any purpose and without fee is hereby granted, provided
  10. ** that the above copyright notice appear in all copies and that both that
  11. ** copyright notice and this permission notice appear in supporting
  12. ** documentation.  This software is provided "as is" without express or
  13. ** implied warranty.
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19. #define TBUFSIZE 1024
  20. #define BIGBUFSIZE 20000
  21.  
  22. extern char *getenv();
  23. extern char *tgetstr();
  24. void putch();
  25.  
  26. main( argc, argv )
  27. int argc;
  28. char *argv[];
  29.     {
  30.     char *term, *strptr, *soptr, *septr;
  31.     int dumb = 0;
  32.     int iflag = 0;
  33.     char buf[TBUFSIZE];
  34.     static char strbuf[TBUFSIZE];
  35.     char bigbuf[BIGBUFSIZE];
  36.     char *grepword = NULL;
  37.     FILE *grepstream;
  38.     int i, j, soon, somap[BIGBUFSIZE], grepwordlen;
  39.  
  40.     /* Initialize termcap stuff. */
  41.     if ( ! isatty( fileno( stdout ) ) )
  42.     dumb = 1;
  43.     else
  44.     {
  45.     term = getenv( "TERM" );
  46.     if ( term == 0 )
  47.         dumb = 1;
  48.     else if ( tgetent( buf, term ) <= 0 )
  49.         dumb = 1;
  50.     else
  51.         {
  52.         strptr = strbuf;
  53.         soptr = tgetstr( "so", &strptr );
  54.         septr = tgetstr( "se", &strptr );
  55.         if ( soptr == NULL || septr == NULL )
  56.         dumb = 1;
  57.         }
  58.     }
  59.  
  60.     /* Construct grep command. */
  61.     strcpy( bigbuf, "grep" );
  62.     for ( i = 1; i < argc; i++ )
  63.     {
  64.     strcat( bigbuf, " " );
  65.     /* (Should do some kind of quoting here.) */
  66.     strcat( bigbuf, argv[i] );
  67.  
  68.     /* Check for -i flag. */
  69.     if ( argv[i][0] == '-' && strchr( argv[i], 'i' ) != NULL )
  70.         iflag = 1;
  71.  
  72.     /* Save pointer to word we are grepping for - first non-flag arg. */
  73.     if ( grepword == NULL && argv[i][0] != '-' )
  74.         {
  75.         grepword = argv[i];
  76.         grepwordlen = strlen( grepword );
  77.         }
  78.     }
  79.  
  80.     /* Spawn a grep. */
  81.     grepstream = popen( bigbuf, "r" );
  82.     if ( grepstream == NULL )
  83.     {
  84.     fprintf( stderr, "%s: can't spawn grep\n", argv[0] );
  85.     exit( 1 );
  86.     }
  87.  
  88.     /* Now read and handle results of grep. */
  89.     soon = 0;
  90.     while ( fgets( bigbuf, BIGBUFSIZE, grepstream ) != NULL )
  91.     {
  92.     if ( dumb )
  93.         fputs( bigbuf, stdout );
  94.     else
  95.         {
  96.         /* Figure out what to highlight.  This is fairly inefficient,
  97.         ** but since we are operating on the output of grep and not
  98.         ** the input, it's ok. */
  99.         for ( i = 0; bigbuf[i] != '\0'; i++ )
  100.         somap[i] = 0;
  101.         for ( i = 0; bigbuf[i] != '\0'; i++ )
  102.         if ( iflag )
  103.             {
  104.             if ( cistrncmp( &(bigbuf[i]), grepword, grepwordlen ) == 0 )
  105.             for ( j = i; j < i + grepwordlen; j++ )
  106.                 somap[j] = 1;
  107.             }
  108.         else
  109.             {
  110.             if ( strncmp( &(bigbuf[i]), grepword, grepwordlen ) == 0 )
  111.             for ( j = i; j < i + grepwordlen; j++ )
  112.                 somap[j] = 1;
  113.             }
  114.  
  115.         /* And now do the highlighting. */
  116.         for ( i = 0; bigbuf[i] != '\0'; i++ )
  117.         {
  118.         if ( somap[i] )
  119.             {
  120.             if ( ! soon )
  121.             {
  122.             tputs( soptr, 1, putch );
  123.             soon = 1;
  124.             }
  125.             }
  126.         else
  127.             {
  128.             if ( soon )
  129.             {
  130.             tputs( septr, 1, putch );
  131.             soon = 0;
  132.             }
  133.             }
  134.         putchar( bigbuf[i] );
  135.         }
  136.         }
  137.     }
  138.  
  139.     /* Bye. */
  140.     if ( soon )
  141.     tputs( septr, 1, putch );
  142.     exit( pclose( grepstream ) );
  143.     }
  144.  
  145. void
  146. putch( ch )
  147. char ch;
  148.     {
  149.     putchar( ch );
  150.     }
  151.  
  152.  
  153. /* cistrncmp - case-insensitive version of strncmp */
  154.  
  155. #include <ctype.h>
  156.  
  157. cistrncmp( s1, s2, n )
  158. char *s1, *s2;
  159. int n;
  160.     {
  161.     while ( --n >= 0 && (isupper(*s1)?tolower(*s1):*s1) == (isupper(*s2)?tolower(*s2++):*s2++) )
  162.     if ( *s1++ == '\0' )
  163.         return 0;
  164.     return n < 0 ? 0 : *s1 - *--s2;
  165.     }
  166.