[comp.os.minix] tc wns newer_head

dono@killer.DALLAS.TX.US (Don OConnell) (01/10/89)

Here are 3 more little programs.

Head	A version with another flag than the one that Andy wrote.

Tc	A program that gives the ability to use termcap commands from
	the commands line or a shell script.

Wns	A windowing version of grep (uses Spencer's regexp)
	Can specify the number of lines of context before and after the 
	found line.

--------------------------------CUT HERE------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  head.c tc.1 tc.c tc.man wns.1 wns.c wns.man wns.sh.hdr
# Wrapped by dono@killer on Tue Jan 10 08:19:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f head.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"head.c\"
else
echo shar: Extracting \"head.c\" \(4938 characters\)
sed "s/^X//" >head.c <<'END_OF_head.c'
X/* head - replace head command */
X/*
X * call: head [ +n ] [ -n ] [ file ... ]
X *
X *       +n = number of lines to skip before starting display
X *            default = 0
X *       -n = number of lines to display, starting with top of file
X *            default = 10
X *       file = any number of files may be present
X *				if name is `-', read from standard input
X */
X#include    <stdio.h>
X
X#define FALSE 0
X#define TRUE 1
X
Xvoid dofile ();
X
Xmain (ac, av)
Xint     ac;
Xchar    **av;
X{
X    register FILE *in = stdin;          /* default is standard input    */
X
X    register int header = FALSE;        /* TRUE if multiple files       */
X
X    register char *cp;                  /* general purpose pointer      */
X
X    register long nlines = 10;          /* number of lines to display   */
X    register long skip = 0;             /* number of lines to skip      */
X
X    register char *pgm;                 /* program name                 */
X
X    if (pgm = strrchr (av[0], '/')) pgm++;
X    else                            pgm = av[0];
X
X    /* ------------------------------------------------------------ */
X    /* Adjust args to skip program name                             */
X    /* ------------------------------------------------------------ */
X
X    av++; ac--;
X
X    /* ------------------------------------------------------------ */
X    /* process arguments/options                                    */
X    /*   it is assumed that the options will precede all file names */
X    /*   on the command line                                        */
X    /* ------------------------------------------------------------ */
X
X    while (ac)
X    {
X        if (*av[0] == '+')              /* lines to skip            */
X        {
X            skip = atoi (&av[0][1]);
X            ac--; av++;
X        }
X        else if (*av[0] == '-')         /* lines to display         */
X        {
X            nlines = atoi (&av[0][1]);
X            ac--; av++;
X        }
X        else break;
X    }
X
X    /* ------------------------------------------------------------ */
X    /* If any files, then process each                              */
X    /* ------------------------------------------------------------ */
X
X    if (ac)
X    {
X    /* ------------------------------------------------------------ */
X    /* If more than one file name specified, display headers        */
X    /* ------------------------------------------------------------ */
X
X        header = ac > 1;
X        while (ac--)
X        {
X            if (!strcmp (*av, "-"))
X            {
X                dofile (stdin, "standard input", skip, nlines, header);
X            }
X            else if (!(in = fopen (*av, "r")))
X            {
X                fprintf (stderr,
X                    "head: cannot read file %s - skipping\n", *av);
X            }
X            else
X            {
X                dofile (in, *av, skip, nlines, header);
X                fclose (in);
X            }
X            av++;
X        }
X    }
X    else dofile (stdin, "standard input", skip, nlines, FALSE);
X
X    exit (0);
X}
X/* ------------------------------------------------------------ */
X/* Process a file, skipping and displaying as necessary         */
X/* ------------------------------------------------------------ */
Xvoid
Xdofile (in, inname, skip, nlines, dohead)
Xregister FILE *in;          /* input stream                         */
Xregister char *inname;      /* input file name                      */
Xregister long skip;         /* number of lines to skip              */
Xregister long nlines;       /* number of lines to display           */
X         int dohead;        /* TRUE if header is to be displayed    */
X{
X    register char *c;           /* convenient local pointer         */
X    register long lineno = 0;   /* line number in file              */
X
X    char    inbuf[1024];        /* line buffer                      */
X
X    /* ------------------------------------------------------------ */
X    /* Print header if necessary                                    */
X    /* ------------------------------------------------------------ */
X
X    if (dohead)
X    {
X        printf ("\
X+-----------------------------------------------------------------+\n\
X+                %-40.40s         +\n\
X+-----------------------------------------------------------------+\n",
X            inname);
X    }
X
X    /* ------------------------------------------------------------ */
X    /* Skip lines                                                   */
X    /* ------------------------------------------------------------ */
X
X    while (lineno++ < skip && fgets (inbuf, sizeof inbuf, in));
X
X    /* ------------------------------------------------------------ */
X    /* Display lines                                                */
X    /* ------------------------------------------------------------ */
X
X    lineno = 0;
X
X    while (lineno++ < nlines && fgets (inbuf, sizeof inbuf, in))
X        fputs (inbuf, stdout);
X    
X    return;
X}
END_OF_head.c
if test 4938 -ne `wc -c <head.c`; then
    echo shar: \"head.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tc.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tc.1\"
else
echo shar: Extracting \"tc.1\" \(1848 characters\)
sed "s/^X//" >tc.1 <<'END_OF_tc.1'
X.TH TC 1 "28 October 1985"
X.SH NAME
Xtc \- supply termcap capabilities to shell scripts
X.SH SYNOPSIS
X.B tc
X[ -a ] [ cap ] ...
X.SH DESCRIPTION
X.I Tc
Xperforms termcap services at the
Xshell level. Each of the arguments
Xconsists of the name of a termcap
Xcapability followed by optional
Xarguments. There may be any number of
Xarguments. The termcaps mentioned in
Xthe arguments are performed left to
Xright until the list is complete or
Xan error occurs.
X.LP
XThe
X.B -a
Xoption specifies that the termcap is
Xto be echoed to the screen in "ascii"
Xmode, where control characters are
Xdisplayed as ^x and escape characters
X(^[) are preceeded by new-lines.
XNumeric capabilities
Xare displayed in this mode as numbers
Xand flags by either "true" or
X"false"; without the
X.B -a
Xflag numeric and flag capabilities
Xare silently skipped.
X.LP
XThe capabilities that require
Xarguments (like cm and ch) check the
Xnext argument(s) for being
Xnumeric, and if so, are used;
Xotherwise an error is displayed and
Xan error exit taken.
X.LP
XA number of defaults are used when
Xcaps are not found in the terminal
Xdefinition. Some of these are spelled out in
Xtermcap(5), some are common sense:
X
X.nf
X.ul
X	cap     default if not found
X	bc      "\\b"
X	pc      "\\0"
X	ta      "\\t"
X	nl      "\\n"
X	cr      "\\r"
X	ff      "\\f"
X	nw      "\\n\\r"
X	ho      direct cursor motion to 0,0
X	ll      direct cursor motion to tgetnum("li")-1, 0
X	rs      is
X	is      rs
X	rf      if
X	if      rf
X	ws      co
X	unknown numbers default to zero
X
X.fi
X.SH "STATUS RETURNS"
XReturns status of 1 if terminal name
Xnot found, 2 if required cap not
Xa legal capability, 3 for argument error.
X.SH "SEE ALSO"
Xtct(1), termcap(3), termcap(5)
X.SH BUGS
XContains an internal database of
Xwhich capabilities exist, require arguments
Xand are numeric and flags. Will
Xrequire updating if list ever
Xchanges.
X.SH AUTHOR
XLyle McElhaney
END_OF_tc.1
if test 1848 -ne `wc -c <tc.1`; then
    echo shar: \"tc.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tc.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tc.c\"
else
echo shar: Extracting \"tc.c\" \(8393 characters\)
sed "s/^X//" >tc.c <<'END_OF_tc.c'
X/*
X *      tc - termcaps for the shell.
X */
X#include <stdio.h>
X#include <ctype.h>
X
Xextern char *tgetdefstr(), *tgetstr(), *tgoto();
Xextern int tgetdefnum(), tgetnum();
X
Xtypedef struct tbl
X{   char *str;
X    short val;
X} lookuptbl;
X
X#define STRING  1
X#define STR1ARG 2
X#define STR2ARG 3
X#define NUMBER  4
X#define FLAG    5
X
Xlookuptbl tcaps[] = {
X	"AL",  STR1ARG,
X	"Bj",  STRING,
X	"Bl",  STRING,
X	"Br",  STRING,
X	"CC",  STRING,
X	"Cj",  STRING,
X	"CM",  STR2ARG,
X	"DC",  STR1ARG,
X	"DL",  STR1ARG,
X	"DO",  STR1ARG,
X	"EP",  FLAG,
X	"Ge",  STRING,
X	"Gs",  STRING,
X	"HD",  FLAG,
X	"Hl",  STRING,
X	"IC",  STR1ARG,
X	"K1",  STRING,
X	"K2",  STRING,
X	"K3",  STRING,
X	"K4",  STRING,
X	"K5",  STRING,
X	"LC",  FLAG,
X	"LE",  STR1ARG,
X	"Lj",  STRING,
X	"NL",  FLAG,
X	"OP",  FLAG,
X	"RI",  STR1ARG,
X	"Rj",  STRING,
X	"SF",  STR1ARG,
X	"SR",  STR1ARG,
X	"Tj",  STRING,
X	"Tl",  STRING,
X	"Tr",  STRING,
X	"UC",  FLAG,
X	"UP",  STR1ARG,
X	"Vl",  STRING,
X	"Xc",  STRING,
X	"ae",  STRING,
X	"al",  STRING,
X	"am",  FLAG,
X	"as",  STRING,
X	"bc",  STRING,
X	"bl",  STRING,
X	"bs",  FLAG,
X	"bt",  STRING,
X	"bw",  FLAG,
X	"cd",  STRING,
X	"ce",  STRING,
X	"ch",  STR1ARG,
X	"cl",  STRING,
X	"cm",  STR2ARG,
X	"co",  NUMBER,
X	"cr",  STRING,
X	"cs",  STR2ARG,
X	"ct",  STRING,
X	"cv",  STR1ARG,
X	"dB",  NUMBER,
X	"dC",  NUMBER,
X	"dF",  NUMBER,
X	"dN",  NUMBER,
X	"dT",  NUMBER,
X	"dV",  NUMBER,
X	"da",  FLAG,
X	"db",  FLAG,
X	"dc",  STRING,
X	"dl",  STRING,
X	"dm",  STRING,
X	"do",  STRING,
X	"ds",  STRING,
X	"ec",  STR1ARG,
X	"ed",  STRING,
X	"ei",  STRING,
X	"eo",  FLAG,
X	"es",  FLAG,
X	"ff",  STRING,
X	"fs",  STRING,
X	"gn",  FLAG,
X	"hc",  FLAG,
X	"hd",  STRING,
X	"ho",  STRING,
X	"hs",  FLAG,
X	"hu",  STRING,
X	"hz",  FLAG,
X	"ic",  STRING,
X	"if",  STRING,
X	"im",  STRING,
X	"in",  FLAG,
X	"ip",  STRING,
X	"is",  STRING,
X	"it",  NUMBER,
X	"k0",  STRING,
X	"k1",  STRING,
X	"k2",  STRING,
X	"k3",  STRING,
X	"k4",  STRING,
X	"k5",  STRING,
X	"k6",  STRING,
X	"k7",  STRING,
X	"k8",  STRING,
X	"k9",  STRING,
X	"kA",  STRING,
X	"kC",  STRING,
X	"kD",  STRING,
X	"kE",  STRING,
X	"kF",  STRING,
X	"kH",  STRING,
X	"kI",  STRING,
X	"kL",  STRING,
X	"kM",  STRING,
X	"kN",  STRING,
X	"kP",  STRING,
X	"kR",  STRING,
X	"kS",  STRING,
X	"kT",  STRING,
X	"ka",  STRING,
X	"kb",  STRING,
X	"kd",  STRING,
X	"ke",  STRING,
X	"kh",  STRING,
X	"kl",  STRING,
X	"km",  FLAG,
X	"kn",  NUMBER,
X	"ko",  STRING,
X	"kr",  STRING,
X	"ks",  STRING,
X	"kt",  STRING,
X	"ku",  STRING,
X	"l0",  STRING,
X	"l1",  STRING,
X	"l2",  STRING,
X	"l3",  STRING,
X	"l4",  STRING,
X	"l5",  STRING,
X	"l6",  STRING,
X	"l7",  STRING,
X	"l8",  STRING,
X	"l9",  STRING,
X	"le",  STRING,
X	"li",  NUMBER,
X	"ll",  STRING,
X	"lm",  NUMBER,
X	"ma",  STRING,
X	"mb",  STRING,
X	"md",  STRING,
X	"me",  STRING,
X	"mh",  STRING,
X	"mi",  FLAG,
X	"mk",  STRING,
X	"ml",  STRING,
X	"mm",  STRING,
X	"mo",  STRING,
X	"mp",  STRING,
X	"mr",  STRING,
X	"ms",  FLAG,
X	"mu",  STRING,
X	"nc",  FLAG,
X	"nd",  STRING,
X	"nl",  STRING,
X	"ns",  FLAG,
X	"nw",  STRING,
X	"os",  FLAG,
X	"pO",  STR1ARG,
X	"pb",  NUMBER,
X	"pc",  STRING,
X	"pf",  STRING,
X	"po",  STRING,
X	"ps",  STRING,
X	"pt",  FLAG,
X	"rP",  STRING,
X	"rc",  STRING,
X	"rf",  STRING,
X	"rp",  STR2ARG,
X	"rs",  STRING,
X	"sa",  STR2ARG,
X	"sc",  STRING,
X	"se",  STRING,
X	"sf",  STRING,
X	"sg",  NUMBER,
X	"so",  STRING,
X	"sr",  STRING,
X	"st",  STRING,
X	"ta",  STRING,
X	"tc",  STRING,
X	"te",  STRING,
X	"ti",  STRING,
X	"ts",  STR1ARG,
X	"uc",  STRING,
X	"ue",  STRING,
X	"ug",  NUMBER,
X	"ul",  FLAG,
X	"up",  STRING,
X	"us",  STRING,
X	"vb",  STRING,
X	"ve",  STRING,
X	"vi",  STRING,
X	"vs",  STRING,
X	"vt",  NUMBER,
X	"wi",  STRING,
X	"ws",  NUMBER,
X	"xb",  FLAG,
X	"xn",  FLAG,
X	"xo",  FLAG,
X	"xr",  FLAG,
X	"xs",  FLAG,
X	"xt",  FLAG,
X	"xv",  FLAG,
X	"xx",  FLAG,
X};
X
Xputx(c) { putchar (c); }
X
Xmain (argc, argv)
X    int argc;
X    char **argv;
X{
X    char tcbuf[1024];
X    char *cp, *arg;
X    int i, tgetnum(), tgetflag();
X    static int aflag = 0;
X
X    if (tgetent(tcbuf, getenv ("TERM")) <= 0) {
X	(void) fprintf (stderr, "tc: cannot find termcap for %s.\n", getenv ("TERM"));
X	exit (1);
X    }
X    cp = (char *) malloc (256);
X    argv++;
X    while (*argv) {
X	arg = *argv++;
X	if (strcmp (arg, "-a") == 0) {
X	    aflag = 1;
X	    continue;
X	}
X	i = lookup (arg, tcaps);
X	if (i < 0) {
X	    (void) fprintf (stderr, "tc: no such termcap: %s\n", arg);
X	    exit (2);
X	}
X	switch (tcaps[i].val & 017) {
X	case STRING:
X	    if (aflag)
X		show (tgetdefstr (arg, &cp));
X	    else
X		tputs (tgetdefstr (arg, &cp), 1, putx);
X	    break;
X	case STR1ARG:
X	    if (aflag)
X		show (tgetstr (arg, &cp));
X	    else
X		if (argv != NULL && isdigit (**argv))
X		    tputs (tgoto (tgetstr (arg, &cp),
X			atoi (*argv++), 0), 1, putx);
X		else {
X		    (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
X		    exit(3);
X		}
X	    break;
X	case STR2ARG:
X	    if (aflag)
X		show (tgetstr (arg, &cp));
X	    else
X		if (argv != NULL && argv[1] != NULL &&
X		    isdigit (**argv) && isdigit (*(argv[1])))
X		    tputs (tgoto (tgetstr (arg, &cp),
X			atoi (*argv++), atoi (*argv++)), 1, putx);
X		else {
X		    (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
X		    exit(3);
X		}
X	    break;
X	case NUMBER:
X	    if (aflag)
X		(void) printf ("%d\n", tgetdefnum (arg));
X	    break;
X	case FLAG:
X	    if (aflag)
X		(void) printf (tgetflag (arg) ? "true\n" : "false\n");
X	    break;
X	}
X    }
X    exit (0);
X}
X
X
X
X#define MAXLUPN 3      /* longer than longest possible name */
X/*  Lookup name in table.  Will take nonambiguous abbreviations.  If you
X    want to insist that a certain table entry must be spelled out, enter
X    it twice in the table.  Table entries must be sorted by name, and a
X    name which is a substring of a longer name comes earlier in the table.
X    Accepts upper or lower case if table entry is lower case.
X    Returns:
X     > 0 table entry index
X      -1 not found
X      -2 ambiguous
X*/
Xint lookup (name, table)
X    char *name;
X    lookuptbl *table;
X{
X    register char  *namptr,
X		   *tblptr;
X    int ind;
X    int value = 0;
X    short length;
X    short longest = 0;
X    int ambig = 0;
X    char lname[MAXLUPN];
X
X    if (name == NULL)
X	return -1;
X    namptr = name;
X    tblptr = lname;
X    for (;;) {
X	if ((*tblptr++ = isupper (*namptr)? tolower (*namptr++): *namptr++)
X	    == '\0')
X	    break;
X	if (tblptr >= &lname[MAXLUPN])
X	    return -1;
X    }
X
X    for (ind = 0; (tblptr = table->str) != 0; table++, ind++) {
X	namptr = lname;
X	for (; *tblptr == *namptr; tblptr++, namptr++) {
X	    if (*tblptr == '\0')
X		break;
X	}
X	if (*namptr == '\0') {  /* end of name or exact match */
X	    length = namptr - lname;
X	    if (longest < length) {
X		longest = length;
X		ambig = 0;
X		value = ind;
X		if (*tblptr == '\0')
X		    break;          /* exact match */
X	    }
X	    else /* longest == length */
X		ambig = 1;
X	}
X	else if ( *namptr < *tblptr )
X	    break;
X    }
X    if (ambig)
X	return -2;
X    if (longest)
X	return value;
X    return -1;
X}
X
X
Xshow (str)
X    char *str;
X{
X    char c;
X
X    if (str == (char *)0) {
X	(void) printf ("NULL\n");
X	return;
X    }
X    while (c = *str++ & 127)
X	if (c < ' ') {
X	    if (c == 27)
X		(void) printf ("\n");
X	    (void) printf ("^%c", c + '@');
X	} else if (c == 127)
X	    (void) printf ("^?");
X	else
X	    (void) printf ("%c", c);
X    (void) printf ("\n");
X    return;
X}
X
Xchar *
Xtgetdefstr (cap, ptr)
X    char *cap, *ptr;
X{
X    char *x;
X    static char *bs = "\b",
X		*ht = "\t",
X		*nl = "\n",
X		*cr = "\r",
X		*ff = "\f",
X		*nu = "\0",
X		*bl = "\007",
X		*nlcr = "\n\r";
X
X    if ((x = tgetstr (cap, ptr)) != (char *) 0)
X	return (x);
X    if (strcmp (cap, "pc") == 0)
X	return (nu);
X    if (strcmp (cap, "bc") == 0)
X	return (bs);
X    if (strcmp (cap, "ta") == 0)
X	return (ht);
X    if (strcmp (cap, "nl") == 0)
X	return (nl);
X    if (strcmp (cap, "cr") == 0)
X	return (cr);
X    if (strcmp (cap, "ff") == 0)
X	return (ff);
X    if (strcmp (cap, "nw") == 0)
X	return (nlcr);
X    if (strcmp (cap, "bl") == 0)
X	return (bl);
X    if (strcmp (cap, "ho") == 0)
X	return (tgoto (tgetstr ("cm", ptr), 0, 0));
X    if (strcmp (cap, "ll") == 0)
X	return (tgoto (tgetstr ("cm", ptr), tgetnum ("li") - 1, 0));
X    if (strcmp (cap, "rs") == 0)
X	return (tgetstr ("is", ptr));
X    if (strcmp (cap, "is") == 0)
X	return (tgetstr ("rs", ptr));
X    if (strcmp (cap, "rf") == 0)
X	return (tgetstr ("if", ptr));
X    if (strcmp (cap, "if") == 0)
X	return (tgetstr ("rf", ptr));
X
X    return ((char *) 0);
X}
X
X
Xtgetdefnum (cap)
X    char *cap;
X{
X    int x;
X
X    if ((x = tgetnum (cap)) != -1)
X	return (x);
X    if (strcmp (cap, "ws") == 0)
X	return (tgetnum ("co"));
X    return (0);
X}
END_OF_tc.c
if test 8393 -ne `wc -c <tc.c`; then
    echo shar: \"tc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tc.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tc.man\"
else
echo shar: Extracting \"tc.man\" \(2653 characters\)
sed "s/^X//" >tc.man <<'END_OF_tc.man'
X
X
X
X     TC(1)              UNIX 5.0 (28 October 1985)               TC(1)
X
X
X
X     NAME
X          tc - supply termcap capabilities to shell scripts
X
X     SYNOPSIS
X          tc [ -a ] [ cap ] ...
X
X     DESCRIPTION
X          Tc performs termcap services at the shell level. Each of the
X          arguments consists of the name of a termcap capability
X          followed by optional arguments. There may be any number of
X          arguments. The termcaps mentioned in the arguments are
X          performed left to right until the list is complete or an
X          error occurs.
X
X          The -a option specifies that the termcap is to be echoed to
X          the screen in "ascii" mode, where control characters are
X          displayed as ^x and escape characters (^[) are preceeded by
X          new-lines.  Numeric capabilities are displayed in this mode
X          as numbers and flags by either "true" or "false"; without
X          the -a flag numeric and flag capabilities are silently
X          skipped.
X
X          The capabilities that require arguments (like cm and ch)
X          check the next argument(s) for being numeric, and if so, are
X          used; otherwise an error is displayed and an error exit
X          taken.
X
X          A number of defaults are used when caps are not found in the
X          terminal definition. Some of these are spelled out in
X          termcap(5), some are common sense:
X
X               cap     default if not found
X               bc      "\b"
X               pc      "\0"
X               ta      "\t"
X               nl      "\n"
X               cr      "\r"
X               ff      "\f"
X               nw      "\n\r"
X               ho      direct cursor motion to 0,0
X               ll      direct cursor motion to tgetnum("li")-1, 0
X               rs      is
X               is      rs
X               rf      if
X               if      rf
X               ws      co
X               unknown numbers default to zero
X
X
X     STATUS RETURNS
X          Returns status of 1 if terminal name not found, 2 if
X          required cap not a legal capability, 3 for argument error.
X
X
X
X     Page 1                                          (printed 1/10/89)
X
X
X
X
X
X
X     TC(1)              UNIX 5.0 (28 October 1985)               TC(1)
X
X
X
X     SEE ALSO
X          tct(1), termcap(3), termcap(5)
X
X     BUGS
X          Contains an internal database of which capabilities exist,
X          require arguments and are numeric and flags. Will require
X          updating if list ever changes.
X
X     AUTHOR
X          Lyle McElhaney
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X     Page 2                                          (printed 1/10/89)
X
X
X
X
END_OF_tc.man
if test 2653 -ne `wc -c <tc.man`; then
    echo shar: \"tc.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wns.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wns.1\"
else
echo shar: Extracting \"wns.1\" \(1655 characters\)
sed "s/^X//" >wns.1 <<'END_OF_wns.1'
X.TH WNS 1
X.SH NAME
Xwns \- windowing search
X.SH SYNOPSIS
X.B wns
X[-a nnn]
X[-b nnn]
X[-l nnn]
X[-w nnn]
Xpattern
X[file ... ]
X.SH DESCRIPTION
X.I wns
Xsearches through a file or list of files for occurances of a particular
Xpattern, and prints a window of lines around each match point.
X.PP
XOptions which may be given are as follows:
X.TP
X.B \-a\ nnn
X(After) specifies that nnn lines following the matching line will be
Xprinted.  default is 0.
X.TP
X.B \-b\ nnn
X(Before) specifies that nnn lines preceding the matching line will be
Xprinted.  default is 0.
X.TP
X.B \-d
XEnables debugging information.  Not a very interesting option.
X.TP
X.B \-f
XSuppress printing of the filename on each output line.
X.TP
X.B \-l\ nnn
XSets the maximum line length to nnn.  Lines longer than this will be
Xtruncated to this length before attempting to match them to the pattern as
Xwell as when printing them.  Default is 100.
X.TP
X.B \-n
XSuppress printing of the line number on each output line.
X.TP
X.B \-w\ nnn
XSets the window size to nnn.  This is the same as -a nnn -b nnn.
X.PP
X.I wns
Xoutputs lines in the following format:
X.PP
Xfilename @nnnnn: text
X.PP
Xwhere
X.I filename
Xis the name of the file containing the matching text and may be suppressed
Xwith the -f option,
X.I lnnnn
Xis the line number of the displayed line and may be suppressed with the
X-n option, and
X.I text
Xis the line from the file.
XAdditionally, if the total window size is greater than 1 (that is, more than
Xzero lines before or after), then non-adjacent text areas are separated by
Xa short dashed line.
X.SH FILES
X/usr/local/bin/wns /usr/local/src/wns/*
X.SH "CREDITS TO"
XM. Mallett  (mem@zinn.MV.COM)
X.SH BUGS
XYou tell me..
END_OF_wns.1
if test 1655 -ne `wc -c <wns.1`; then
    echo shar: \"wns.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wns.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wns.c\"
else
echo shar: Extracting \"wns.c\" \(10857 characters\)
sed "s/^X//" >wns.c <<'END_OF_wns.c'
X/* wns.c - Search for string and print window of lines around it.
X
X        Nov 19 1984     Mark Mallett   (mem@zinn.MV.COM)
X
Xmem	860224	Modified to do r/e (regular expression) parsing on unix
Xmem	860324	Added -f, -n; added code to number lines correctly on
X		output.
Xmem	870325	Added support for regcmp()/regex() style regular expression
X		library; redid some conditionals to provide better mix'n'match.
Xmem	870326	Don't try to print the filename if reading from stdin.
X		Add -w option.  Fix a small problem which occasionally allowed
X		the separator to come out between adjacent lines of the file.
Xmem	871119	Fix semantics of call to regcmp(): the NULL terminating the
X		argument list was missing.  It worked, but probably only
X		due to some bizarre coincidence.
Xdro 890109  Minor mods to compile under Minix
X
X*/
X
X#define  OS_UNIX   /* Define this for unix systems */
X/* #define	REGEX */	/* Define this for re_comp/re_exec library */
X#define  REGCMP    /* Define this to use regcmp/regex */
X/* #define	OS_CPM */	/* Define this for CP/M-80 */
X
X
X/* Don't touch these */
X#define	NOREGEXP		/* Set this for no regular expression */
X#ifdef	REGEX
X#undef	NOREGEXP
X#endif	REGEX
X
X#ifdef	REGCMP
X#undef	NOREGEXP
X#endif	REGCMP
X
X
X#ifdef OS_CPM
X#include "stdio.h"
X#include "ctype.h"
X#endif OS_CPM
X
X#ifdef OS_UNIX
X#include <stdio.h>
X#include <ctype.h>
X
X#include <sys/types.h>
X#include <dir.h>            /* Either here or in sys directory - dro */
X#include <regexp.h>         /* should have this                - dro */
X#endif OS_UNIX
X
X
X/* Local definitions */
X
X#ifndef	NULL
X#define	NULL	((char *)0)
X#endif	NULL
X
X#ifndef NUL
X#define NUL     '\000'
X#endif
X
X#ifndef TRUE
X#define TRUE    1
X#define FALSE   0
X#endif
X
X
X/* Internal data declared global */
X
X
X/* Internal routines */
X
X
X/* External data */
X
X
X/* Local data */
X
Xstatic  int     Debug={FALSE};          /* Debug enabled flag */
Xstatic  int     Lcur = {0};             /* Current line (in Lines array) */
Xstatic  char    **Lines = {(char **)NULL};       /* Lines pointer array */
Xstatic  int     Linlen = {100};         /* Line length */
Xstatic  int     Lone = {0};             /* Line one (in Lines array) */
Xstatic	int	Nmr = {0};		/* Number of matched regions */
Xstatic  char    *Pat = {NULL};          /* Pattern */
Xstatic	char	Shwfile = {TRUE};	/* Show file name... */
Xstatic	char	Shwline = {TRUE};	/* Show line number */
Xstatic  int     Waft = {0};             /* Window after */
Xstatic  int     Wbef = {0};             /* Window before */
Xstatic  int     Wsiz = {0};             /* Window size */
X
Xchar        *Re;        /* Result from reg compilation */
X
Xmain (argc, argv)
X
Xint             argc;           /* Argument count */
Xchar            **argv;         /* Argument values */
X
X{
Xint             i;              /* Scratch */
Xint             n;              /* Scratch again */
Xint             c;              /* A character */
Xchar            *aptr;          /* Argument pointer */
Xint             nf;             /* number of files on command line */
X
Xnf = 0;                         /* No files on line */
X
Xfor (i = 1; i < argc; i++)      /* Look at args */
X    {
X    if (argv[i][0] != '-')      /* If option */
X        {
X        if (Pat == NULL)        /* If no pattern yet given */
X	    {
X            Pat = argv[i];      /*  point here */
X#ifdef	REGEX
X	    if ((Re = re_comp(Pat)) != NULL)
X            {
X		fprintf(stderr, "wns: %s\n", re);
X		exit(1);
X		}
X#endif	REGEX
X
X#ifdef	REGCMP
X        if ((Re = regcomp(Pat)) == NULL)
X	        {
X		fprintf(stderr, "wns: error in regular expression.\n");
X		exit(1);
X		}
X#endif	REGCMP
X
X	    }
X        else                    /* This must be a file to search */
X            {
X            nf++;               /* Count it */
X            dosrch (argv[i]);   /* Search */
X            }
X        }
X
X    else                        /* Option char */
X        {
X        c = argv[i][1];         /* Get option char */
X        if (isupper(c))         /* Trap idiot definition of tolower */
X            c = tolower(c);     /* Don't care about case */
X        n = i;
X        aptr = NULL;            /* Find arg, if any */
X        if (argv[i][2] != NUL)
X            {
X            aptr = &argv[i][2];
X            n = i;              /* Where to set i if we use this arg */
X            }
X        else if (i < argc-1)    /* use next.. */
X            {
X            n = i+1;
X            aptr = argv[n];
X            }
X
X        switch (c)              /* Process the option */
X            {
X            case 'a':           /* Lines after */
X                Waft = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X            case 'b':           /* Lines before */
X                Wbef = atoi (aptr);
X                Lines = (char **)NULL;
X                i = n;
X                break;
X
X            case 'd':           /* Enable debugging */
X                Debug = TRUE;
X                break;
X
X	    case 'f':		/* Suppress filename on output */
X	        Shwfile = FALSE;
X		break;
X
X            case 'l':           /* Line length */
X                Linlen = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X	    case 'n':		/* Suppress line number on output */
X	        Shwline = FALSE;
X		break;
X
X            case 'w':           /* Window: lines before and after */
X                Waft = Wbef = atoi (aptr);
X                Lines = NULL;
X                i = n;
X                break;
X
X            default:
X                fprintf (stderr, "Invalid option %s\n",argv[i]);
X                exit();
X            }
X        }
X    }
X
Xif ( Pat == NULL )		/* If no pattern given */
X    {
X    fprintf(stderr, 
X"usage: wns [-a n] [-b n] [-d] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n");
X    exit(1);
X    }
X
Xif (nf == 0)                    /* No files processed ? */
X    dosrch (NULL);              /* Do standard input */
X}
X/*
X
X*//* dosrch (ifnm)
X
X        Perform the search
X
XAccepts :
X
X        ifn             Input file name
X
X
XReturns :
X
X
X*/
X
Xdosrch (ifnm)
X
Xchar            *ifnm;          /* Input filelname */
X
X{
XFILE            *ifp;           /* Input fp */
Xchar            *lptr;          /* Line pointer */
Xint             i;              /* Scratch */
Xint             prtaft;         /* Print-after count */
Xint             linnum;         /* Line number */
Xint		nlb;		/* Number of lines buffered */
X
Xif (ifnm != NULL)               /* If file name given */
X    {
X    ifp = fopen (ifnm, "r");    /* Open it for read access */
X    if (ifp == NULL)
X        {
X        fprintf (stderr, "Can not open file %s\n", ifnm);
X        return;
X        }
X    }
Xelse
X    ifp = stdin;
X
Xif (Lines == NULL)              /* If no line table allocated.. */
X    {
X    Wsiz = Wbef+2;              /* Determine total window size */
X    Lines = (char **) calloc (Wsiz, sizeof (char *));
X                                /* Allocate pointer table */
X    for (i = 0; i < Wsiz; i++)  /* Allocate line buffers */
X        Lines[i] = (char *) calloc (Linlen, sizeof(char));
X    }
X
XLcur = Lone = 0;                /* Setup line pointers */
Xnlb = 0;			/* No lines buffered */
Xlinnum = 0;                     /* Line number is zero */
Xprtaft = -(Wbef+1);		/* Make sure separator given first time */
X
Xfor (;;)                        /* Loop through the file */
X    {
X    lptr = Lines[Lcur];         /* Get pointer to current line */
X    if (++Lcur == Wsiz)         /* Bump curr pointer and wrap */
X        Lcur = 0;               /*  if hit end */
X    if (Lone == Lcur)           /* If wrapped to beginning of window */
X        if (++Lone == Wsiz)     /*  Bump beginning */
X            Lone = 0;           /*   and wrap if hit end */
X
X    if (fgets (lptr, Linlen, ifp) != lptr)
X        break;                  /*  if end of file */
X
X    linnum++;                   /* Count line number */
X    if (matlin (lptr))          /* If matching line */
X        {
X        if (prtaft < (-Wbef) )  /* Check for separator needed */
X            if ( (Nmr++ > 0 ) && ((Wbef > 0) || (Waft > 0)) )
X                printf ("-------------------\n");
X        while (Lone != Lcur)    /* Until we close the window */
X            {
X            shwlin (ifnm, linnum-nlb, Lines[Lone]);
X                                /* Show the line */
X            if (++Lone == Wsiz)
X                Lone = 0;
X	    nlb--;
X            }
X	nlb = 0;		/* No lines buffered */
X        prtaft = Waft;          /* Print n lines after */
X        }
X
X    else                        /* Didn't match */
X        {
X        if (prtaft-- > 0)       /* If must print lines after */
X            {
X            shwlin (ifnm, linnum, lptr);
X                                /* Show the line */
X            Lone = Lcur;        /* Match pointers */
X            }
X	else if (nlb < Wbef)	/* Count lines buffered */
X	    nlb++;
X        }
X    }
X
Xif (ifnm != NULL)
X    fclose (ifp);
X}
X/*
X
X*//* shwlin (fnm, linnum, line)
X
X        Show a matching line
X
X
XAccepts :
X
X        fnm             File name
X
X        linnum          Line number
X
X        line            Line to show
X
X
XReturns :
X
X
X*/
X
Xshwlin (fnm, linnum, line)
X
Xchar            *fnm;           /* File name */
Xint             linnum;         /* Line number */
Xchar            *line;          /* Line (with newline at end) to print */
X
X{
Xif (Shwfile && ( fnm != NULL) )
X    printf("%s%s", fnm, Shwline?" ":":");
Xif (Shwline)
X    printf("@%05d%:", linnum);
Xprintf ("%s", line);
X}
X/*
X
X*//* matlin (line)
X
X        Perform match against pattern and line
X
X
XAccepts :
X
X        line            Address of line to match
X
X
XReturns :
X
X        <value>         TRUE if match
X                        FALSE if not
X
X
X*/
X
X
Xint matlin (line)
X
Xchar            *line;          /* Line to match */
X
X{
Xint		rtncode;		/* Return value from this routine */
X
X
X#ifdef	NOREGEXP
Xchar            *pptr, *lptr, *tlptr;
Xint             c1,c2;
X#endif	NOREGEXP
X
Xif (Debug)
X    printf ("Matching %s against %s", Pat, line);
X
X#ifdef	REGEX
Xrtncode = re_exec(line);	/* Hand off to r/e evaluator */
X#endif	REGEX
X
X#ifdef	REGCMP
Xrtncode = (regexec(Re, line) != NULL );
X#endif	REGCMP
X
X#ifdef	NOREGEX		/* Have to do menial comparison.. */
Xlptr = line;                    /* Init line pointer */
X
Xfor ( rtncode = -1; rtncode < 0; )
X    {
X    tlptr = lptr++;             /* Get temp ptr to line */
X    pptr = Pat;                 /* Get ptr to pattern */
X    while (TRUE)
X        {
X        if ((c1 = *pptr++) == NUL)
X            {
X	    rtncode = 1;	/* GOOD return value */
X	    break;
X            }
X        if ((c2 = *tlptr++) == NUL)
X            {
X	    rtncode = 0;	/* BAD return value */
X	    break;
X            }
X        if (isupper(c1))
X            c1 = tolower(c1);
X        if (isupper(c2))
X            c2 = tolower(c2);
X        if (c1 != c2)
X            break;
X        }
X    }
X#endif	NOREGEX
X
X
Xif (Debug)
X    printf("matlin returned %s\n", rtncode?"TRUE":"FALSE");
Xreturn(rtncode);
X}
X
X
END_OF_wns.c
if test 10857 -ne `wc -c <wns.c`; then
    echo shar: \"wns.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wns.man -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wns.man\"
else
echo shar: Extracting \"wns.man\" \(2370 characters\)
sed "s/^X//" >wns.man <<'END_OF_wns.man'
X
X
X
X     WNS(1)                      UNIX 5.0                       WNS(1)
X
X
X
X     NAME
X          wns - windowing search
X
X     SYNOPSIS
X          wns [-a nnn] [-b nnn] [-l nnn] [-w nnn] pattern [file ... ]
X
X     DESCRIPTION
X          wns searches through a file or list of files for occurances
X          of a particular pattern, and prints a window of lines around
X          each match point.
X
X          Options which may be given are as follows:
X
X          -a nnn
X               (After) specifies that nnn lines following the matching
X               line will be printed.  default is 0.
X
X          -b nnn
X               (Before) specifies that nnn lines preceding the
X               matching line will be printed.  default is 0.
X
X          -d   Enables debugging information.  Not a very interesting
X               option.
X
X          -f   Suppress printing of the filename on each output line.
X
X          -l nnn
X               Sets the maximum line length to nnn.  Lines longer than
X               this will be truncated to this length before attempting
X               to match them to the pattern as well as when printing
X               them.  Default is 100.
X
X          -n   Suppress printing of the line number on each output
X               line.
X
X          -w nnn
X               Sets the window size to nnn.  This is the same as -a
X               nnn -b nnn.
X
X          wns outputs lines in the following format:
X
X          filename @nnnnn: text
X
X          where filename is the name of the file containing the
X          matching text and may be suppressed with the -f option,
X          lnnnn is the line number of the displayed line and may be
X          suppressed with the -n option, and text is the line from the
X          file.  Additionally, if the total window size is greater
X          than 1 (that is, more than zero lines before or after), then
X          non-adjacent text areas are separated by a short dashed
X          line.
X
X
X
X
X     Page 1                                           (printed 1/9/89)
X
X
X
X
X
X
X     WNS(1)                      UNIX 5.0                       WNS(1)
X
X
X
X     FILES
X          /usr/local/bin/wns /usr/local/src/wns/*
X
X     CREDITS TO
X          M. Mallett  (mem@zinn.MV.COM)
X
X     BUGS
X          You tell me..
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X     Page 2                                           (printed 1/9/89)
X
X
X
X
END_OF_wns.man
if test 2370 -ne `wc -c <wns.man`; then
    echo shar: \"wns.man\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wns.sh.hdr -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wns.sh.hdr\"
else
echo shar: Extracting \"wns.sh.hdr\" \(0 character\)
sed "s/^X//" >wns.sh.hdr <<'END_OF_wns.sh.hdr'
END_OF_wns.sh.hdr
if test 0 -ne `wc -c <wns.sh.hdr`; then
    echo shar: \"wns.sh.hdr\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

tif@cpe.UUCP (01/11/89)

Written  8:26 am  Jan 10, 1989 by killer.UUCP!dono in cpe:comp.os.minix
/* ---------- "tc  wns  newer_head" ---------- */
>register FILE *in = stdin;          /* default is standard input    */
>register int header = FALSE;        /* TRUE if multiple files       */
>register char *cp;                  /* general purpose pointer      */
>register long nlines = 10;          /* number of lines to display   */
>register long skip = 0;             /* number of lines to skip      */
>register char *pgm;                 /* program name                 */
>register FILE *in;          /* input stream                         */
>register char *inname;      /* input file name                      */
>register long skip;         /* number of lines to skip              */
>register long nlines;       /* number of lines to display           */
>register char *c;           /* convenient local pointer         */
>register long lineno = 0;   /* line number in file              */
>register char  *namptr,

You gotta lotta guts expecting the minix compiler to handle registers
right.  :-)  I don't mean to be disrespectful to the minix compiler but
I have had so many compilers screw up with registers declared.  Not to
mention that on an Intel processor register declarations usually cause
worse code than without.

			Paul Chamberlain
			Computer Product Engineering, Tandy Corp.
			{killer | texbell}!cpe!tif