tholm@uvicctr.UUCP (Terrence W. Holm) (12/10/88)
EFTH MINIX report #60 - December 1988 - hgrep(1)
This is Jef Poskanzer's hgrep(1) - a cute front-end to grep(1).
I only made one change from the original:
20c20
< #define BIGBUFSIZE 20000
---
> #define BIGBUFSIZE 2000
----------------------------------------------------------
echo x - hgrep.1
gres '^X' '' > hgrep.1 << '/'
XCOMMANDS
X hgrep(1) - highlight results of a grep
X
XINVOCATION
X hgrep <grep_args>
X
XEXPLANATION
X Hgrep(1) is a trivial, but cute, front-end for grep(1).
X It takes the results of the grep and highlights the word
X that was searched for.
X
XREFERENCES
X grep(1)
X
XPROBLEMS
X Meta-characters are not handled. Quoting is not handled.
/
echo x - hgrep.c
gres '^X' '' > hgrep.c << '/'
X/*
X** hgrep - a front end to grep that highlights the string found
X**
X** version of 23oct88
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X#include <stdio.h>
X#include <string.h>
X
X#define TBUFSIZE 1024
X#define BIGBUFSIZE 2000
X
Xextern char *getenv();
Xextern char *tgetstr();
Xvoid putch();
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X {
X char *term, *strptr, *soptr, *septr;
X int dumb = 0;
X int iflag = 0;
X char buf[TBUFSIZE];
X static char strbuf[TBUFSIZE];
X char bigbuf[BIGBUFSIZE];
X char *grepword = NULL;
X FILE *grepstream;
X int i, j, soon, somap[BIGBUFSIZE], grepwordlen;
X
X /* Initialize termcap stuff. */
X if ( ! isatty( fileno( stdout ) ) )
X dumb = 1;
X else
X {
X term = getenv( "TERM" );
X if ( term == 0 )
X dumb = 1;
X else if ( tgetent( buf, term ) <= 0 )
X dumb = 1;
X else
X {
X strptr = strbuf;
X soptr = tgetstr( "so", &strptr );
X septr = tgetstr( "se", &strptr );
X if ( soptr == NULL || septr == NULL )
X dumb = 1;
X }
X }
X
X /* Construct grep command. */
X strcpy( bigbuf, "grep" );
X for ( i = 1; i < argc; i++ )
X {
X strcat( bigbuf, " " );
X /* (Should do some kind of quoting here.) */
X strcat( bigbuf, argv[i] );
X
X /* Check for -i flag. */
X if ( argv[i][0] == '-' && strchr( argv[i], 'i' ) != NULL )
X iflag = 1;
X
X /* Save pointer to word we are grepping for - first non-flag arg. */
X if ( grepword == NULL && argv[i][0] != '-' )
X {
X grepword = argv[i];
X grepwordlen = strlen( grepword );
X }
X }
X
X /* Spawn a grep. */
X grepstream = popen( bigbuf, "r" );
X if ( grepstream == NULL )
X {
X fprintf( stderr, "%s: can't spawn grep\n", argv[0] );
X exit( 1 );
X }
X
X /* Now read and handle results of grep. */
X soon = 0;
X while ( fgets( bigbuf, BIGBUFSIZE, grepstream ) != NULL )
X {
X if ( dumb )
X fputs( bigbuf, stdout );
X else
X {
X /* Figure out what to highlight. This is fairly inefficient,
X ** but since we are operating on the output of grep and not
X ** the input, it's ok. */
X for ( i = 0; bigbuf[i] != '\0'; i++ )
X somap[i] = 0;
X for ( i = 0; bigbuf[i] != '\0'; i++ )
X if ( iflag )
X {
X if ( cistrncmp( &(bigbuf[i]), grepword, grepwordlen ) == 0 )
X for ( j = i; j < i + grepwordlen; j++ )
X somap[j] = 1;
X }
X else
X {
X if ( strncmp( &(bigbuf[i]), grepword, grepwordlen ) == 0 )
X for ( j = i; j < i + grepwordlen; j++ )
X somap[j] = 1;
X }
X
X /* And now do the highlighting. */
X for ( i = 0; bigbuf[i] != '\0'; i++ )
X {
X if ( somap[i] )
X {
X if ( ! soon )
X {
X tputs( soptr, 1, putch );
X soon = 1;
X }
X }
X else
X {
X if ( soon )
X {
X tputs( septr, 1, putch );
X soon = 0;
X }
X }
X putchar( bigbuf[i] );
X }
X }
X }
X
X /* Bye. */
X if ( soon )
X tputs( septr, 1, putch );
X exit( pclose( grepstream ) );
X }
X
Xvoid
Xputch( ch )
Xchar ch;
X {
X putchar( ch );
X }
X
X
X/* cistrncmp - case-insensitive version of strncmp */
X
X#include <ctype.h>
X
Xcistrncmp( s1, s2, n )
Xchar *s1, *s2;
Xint n;
X {
X while ( --n >= 0 && (isupper(*s1)?tolower(*s1):*s1) == (isupper(*s2)?tolower(*s2++):*s2++) )
X if ( *s1++ == '\0' )
X return 0;
X return n < 0 ? 0 : *s1 - *--s2;
X }
/
----------------------------------------------------------
Terrence W. Holm
uunet!uw-beaver!uvicctr!tholm
tholm%uvunix.bitnet
tholm%sirius.UVic.ca@relay.ubc.ca