DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦06c9c08d4⟧ TextFile

    Length: 6739 (0x1a53)
    Types: TextFile
    Notes: UNIX file
    Names: »grep1.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »cmd/grep/grep1.c« 

TextFile

/*
 * Grep - search a file for a pattern
 * This code uses the regexp.c code which is
 * also used by AWK.
 */

#include <stdio.h>
#include <ctype.h>
#include "grep.h"

#define	MAXLINE	400		/* Maximum input line length */
#define	NEXP	50		/* Maximum number of regular expressions */
#define	BSIZE	BUFSIZ		/* Assume block size if buffer size */

char	line[MAXLINE];
struct	exps {
	union {
		char	*u_cp;
		RE	*u_re;
	}	e_un;
	int	(*e_mfun)();
}	exps[NEXP+1];
char	usage[] =
	"Usage: grep [-abchlnsvxy] [-e exp] [-f efile] [expression] [file ...]";
char	mre[] = "Missing regular expression";
char	nospace[] = "Out of space for regular expressions";
char	*fname;		/* Current filename */

int	vflag;		/* Reverse sense of match */
int	cflag;		/* Print only count of lines */
int	lflag;		/* Only filenames with matching lines */
int	nflag;		/* precede lines by line number in file */
int	bflag;		/* print block number of match */
int	sflag;		/* No output, only status */
int	hflag;		/* Never print filenames */
int	xflag;		/* Exact match only */
int	some;		/* non-zero if some matches */
int	outfile;	/* Output filename if match flag */
int	lineno;		/* Input line # */
unsigned blkno;		/* Block number for `-b' */
long	lmatch;		/* Lines matching */
int	yflag;		/* Dual case comparisons */

int	(*mfun)();	/* Match function */
int	rematch();
int	dirmatch();
int	reinterp();
int	ematch();
int	yematch();

main(argc, argv)
char *argv[];
{
	register RE *rp;
	register char *cp;
	register i;
	struct exps *epp;
	FILE *fp;

	mfun = rematch;
	while (argc>1 && *argv[1]=='-') {
		for (cp = &argv[1][1]; *cp; cp++)
			switch (*cp) {
			case 'a':
				refull = 1;
				break;

			case 'b':
				bflag = 1;
				break;

			case 'c':
				cflag = 1;
				break;

			case 'e':
				if (argc < 3)
					err(mre);
				expsave(argv[2]);
				argc--;
				argv++;
				break;

			case 'f':
				if (argc < 3)
					err("Missing expression filename");
				if ((fp = fopen(argv[2], "r")) == NULL)
					err("Cannot open %s", argv[2]);
				argv++;
				argc--;
				while (fgets(line, MAXLINE, fp) != NULL) {
					i = strlen(line);
					line[i-1] = '\0';
					expsave(line);
				}
				fclose(fp);
				break;

			case 'h':
				hflag = 1;
				break;

			case 'l':
				lflag = 1;
				break;

			case 'n':
				nflag = 1;
				break;

			case 's':
				sflag = 1;
				break;

			case 'v':
				vflag = 1;
				break;

			case 'x':
				xflag = 1;
				mfun = dirmatch;
				break;

			case 'y':
				redual = 1;
				yflag = 1;
				break;

			default:
				err(usage);
			}
		argv++;
		argc--;
	}
	if (exps[0].e_un.u_cp == NULL) {
		if (argc-- < 2)
			err(usage);
		expsave(argv[1]);
		argv++;
	}
	expsave(NULL);
	if (!xflag)
		for (epp = &exps[0]; (cp = epp->e_un.u_cp) != NULL; epp++) {
			rp = epp->e_un.u_re = reparse(cp, '\0');
			if (reerror != NULL)
				err(reerror);
			for (; rp != NULL; rp = rp->r_next)
				if (rp->r_op != CONC)
					break;
			if (rp != NULL) {	/* hard RE */
				free(cp);
				epp->e_mfun = reinterp;
			} else {
				rp = epp->e_un.u_re;
				epp->e_un.u_cp = cp;
				epp->e_mfun = yflag ? yematch : ematch;
				for ( ; rp!=NULL; rp = rp->r_next) {
					*cp = rp->r_left.u_ival;
					cp++;
				}
				*cp = '\0';
			}
		}
	if (argc < 3)			/* Fewer than 2 files? */
		hflag = 1;
	if (argc == 1) {
		fname = "(stdin)";
		grep(stdin);
	} else
		for (i=1; i<argc; i++) {
			if ((fp = fopen(argv[i], "r")) == NULL)
				err("Cannot open %s", argv[i]);
			fname = argv[i];
			grep(fp);
			fclose(fp);
		}
	if (cflag)
		printf("%ld\n", lmatch);
	exit(!some);
}

/*
 * Save regular expression.
 */
expsave(s)
register char *s;
{
	static struct exps *epp;

	if (epp == NULL)
		epp = &exps[0];
	if (epp >= &exps[NEXP-1])
		err("Too many regular expressions");
	if (s == NULL)
		epp->e_un.u_cp = NULL;
	else {
		if ((epp->e_un.u_cp = malloc(strlen(s)+1)) == NULL)
			err(nospace);
		strcpy(epp->e_un.u_cp, s);
	}
	epp++;
}

/*
 * Called for each input file
 * to drive the pattern matches.
 */
grep(ifp)
FILE *ifp;
{
	register unsigned n;
	register c;
	register char *cp;

	outfile = 0;
	blkno = 0;
	n = BSIZE;
	lineno = 0;
	for (cp = line; (c = getc(ifp)) != EOF; ) {
		if (n-- == 0) {
			n = BSIZE;
			blkno++;
		}
		if (c=='\n' || cp>=&line[MAXLINE-1]) {
			*cp = '\0';
			lineno++;
			(*mfun)(cp = line);
		} else
			*cp++ = c;
	}
	if (outfile)
		printf("%s\n", fname);
}

/*
 * Called when a match occurred in input
 */
amatch(s)
char *s;
{
	some = 1;
	if (sflag)
		return;
	if (!lflag && !cflag) {
		if (!hflag)
			printf("%s: ", fname);
		if (bflag)
			printf("%d:\t", blkno);
		else if (nflag)
			printf("%d:\t", lineno);
		printf("%s\n", s);
	} else if (lflag)
		outfile = 1;
	else if (cflag)
		lmatch++;
}

/*
 * try to match each line with all the
 * regular expressions.
 * An attempt is made to make expressions
 * with no metacharacters run faster.
 */
rematch(s)
char *s;
{
	register struct exps *epp;
	register int m;

	m = 0;
	for (epp = &exps[0]; epp->e_un.u_re!=NULL && m==0; epp++)
		if ((*epp->e_mfun)(epp->e_un.u_re, s) != NULL)
			m = 1;
	if (vflag)
		m = !m;
	if (m)
		amatch(s);
	return (m);
}

/*
 * Direct match function (for `-x' option)
 */
dirmatch(s)
char *s;
{
	register struct exps *epp;
	register m;

	m = 0;
	for (epp = &exps[0]; epp->u_cp!=NULL && !m; epp++)
		m = yflag ? yseq(epp->u_cp, s) : seq(epp->u_cp, s);
	if (vflag)
		m = !m;
	if (m)
		amatch(s);
	return (m);
}

/*
 * Easy match
 * For non -y grep.
 */
ematch(p, s)
char *p;
register char *s;
{
	register char *xp, *xs;

	do {
		xp = p;
		xs = s;
		while (*xp != '\0') {
			if (*xs == '\0')
				return (0);
			if (*xp != *xs++)
				break;
			xp++;
		}
		if (*xp == '\0')
			return (1);
	} while (*s++ != '\0');
	return (0);
}

/*
 * Version of `ematch' for `-y' option
 * of grep.
 */
yematch(p, s)
char *p;
register char *s;
{
	register char *xp, *xs;
	register int c;

	do {
		xp = p;
		xs = s;
		while (*xp != '\0') {
			if (*xs == '\0')
				return (0);
			if (islower(*xp) && isupper(*xs))
				c = tolower(*xs++); else
				c = *xs++;
			if (*xp != c)
				break;
			xp++;
		}
		if (*xp == '\0')
			return (1);
	} while (*s++ != '\0');
	return (0);
}

/*
 * String comparison for `-x' option
 * without `-y' (dual) flag.
 */
seq(p, s)
register char *p;
register char *s;
{
	while (*s == *p++)
		if (*s++ == '\0')
			return (1);
	return (0);
}

/*
 * Version of `seq' for the `-y' option.
 * First argument is the pattern, the second
 * is the input string.
 */
yseq(p, s)
register char *p;
register char *s;
{
	register int c;

	while ((c = *s++) != '\0') {
		if (islower(*p) && isupper(c))
			c = tolower(c);
		if (c != *p++)
			return (0);
	}
	if (*p != '\0')
		return (0);
	return (1);
}

err(s)
{
	if (!sflag) {
		fprintf(stderr, "%r", &s);
		fprintf(stderr, "\n");
	}
	exit(2);
}