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