[comp.os.minix] hgrep

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