⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgrep.c

📁 操作系统源代码
💻 C
字号:
/* cgrep - grep and display context	Author: Mark Mallet *//*        Nov 19 1984     Mark Mallett   (mem@zinn.MV.COM)mem	860224	Modified to do r/e (regular expression) parsing on unixmem	860324	Added -f, -n; added code to number lines correctly on output.mem	870325	Added support for regcmp()/regex() style regular expression  library; redid some conditionals to provide better mix'n'match.mem	870326	Don't try to print the filename if reading from stdin.  Add -w option.  Fix a small problem which occasionally allowed  the separator to come out between adjacent lines of the file.mem	871119	Fix semantics of call to regcmp(): the NULL terminating the  argument list was missing.  It worked, but probably only  due to some bizarre coincidence.dro	890109  Minor mods to compile under Minix*/#define  OS_UNIX		/* Define this for unix systems */ /* #define	REGEX *//* Define this for re_comp/re_exec library */#define  REGCMP			/* Define this to use regcmp/regex */ /* #define	OS_CPM *//* Define this for CP/M-80 *//* Don't touch these */#define	NOREGEXP		/* Set this for no regular expression */#ifdef	REGEX#undef	NOREGEXP#endif	/* REGEX */#ifdef	REGCMP#undef	NOREGEXP#endif	/* REGCMP */#ifdef OS_CPM#include "stdio.h"#include "ctype.h"#endif /* OS_CPM */#ifdef OS_UNIX#include <sys/types.h>#include <sys/dir.h>		/* Either here or in sys directory - dro */#include <ctype.h>#include <limits.h>		/* should have this                - dro */#include <regexp.h>		/* should have this                - dro */#include <stdlib.h>#include <stdio.h>#endif /* OS_UNIX *//* Local definitions */#ifndef	NULL#define	NULL	((char *)0)#endif	/* NULL */#ifndef NUL#define NUL     '\000'#endif#ifndef TRUE#define TRUE    1#define FALSE   0#endif/* Internal data declared global *//* Internal routines */_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void dosrch, (char *ifnm));_PROTOTYPE(void shwlin, (char *fnm, int linnum, char *line));_PROTOTYPE(int matlin, (char *line));_PROTOTYPE(void regerror, (char *s));/* External data *//* Local data */static int Debug = {FALSE};	/* Debug enabled flag */static int Lcur = {0};		/* Current line (in Lines array) */static char **Lines = {NULL};	/* Lines pointer array */static int Linlen = {100};	/* Line length */static int Lone = {0};		/* Line one (in Lines array) */static int Nmr = {0};		/* Number of matched regions */static char *Pat = {NULL};	/* Pattern */static char Shwfile = {TRUE};	/* Show file name... */static char Shwline = {TRUE};	/* Show line number */static int Waft = {0};		/* Window after */static int Wbef = {0};		/* Window before */static int Wsiz = {0};		/* Window size */regexp *Re;			/* Result from reg compilation */int main(argc, argv)int argc;			/* Argument count */char **argv;			/* Argument values */{  int i;			/* Scratch */  int n;			/* Scratch again */  int c;			/* A character */  char *aptr;			/* Argument pointer */  int nf;			/* number of files on command line */  nf = 0;			/* No files on line */  for (i = 1; i < argc; i++) {	/* Look at args */	if (argv[i][0] != '-') {/* If option */		if (Pat == NULL) {	/* If no pattern yet given */			Pat = argv[i];	/* point here */#ifdef	REGEX			if ((Re = re_comp(Pat)) != NULL) {				fprintf(stderr, "cgrep: %s\n", re);				exit(1);			}#endif	/* REGEX */#ifdef	REGCMP			if ((Re = regcomp(Pat)) == NULL) {				fprintf(stderr, "cgrep: error in regular expression.\n");				exit(1);			}#endif	/* REGCMP */		} else {	/* This must be a file to search */			nf++;	/* Count it */			dosrch(argv[i]);	/* Search */		}	} else {		/* Option char */		c = argv[i][1];	/* Get option char */		if (isupper(c))	/* Trap idiot definition of tolower */			c = tolower(c);	/* Don't care about case */		n = i;		aptr = NULL;	/* Find arg, if any */		if (argv[i][2] != NUL) {			aptr = &argv[i][2];			n = i;	/* Where to set i if we use this arg */		} else if (i < argc - 1) {	/* use next.. */			n = i + 1;			aptr = argv[n];		}		switch (c) {	/* Process the option */		    case 'a':	/* Lines after */			Waft = atoi(aptr);			Lines = NULL;			i = n;			break;		    case 'b':	/* Lines before */			Wbef = atoi(aptr);			Lines = NULL;			i = n;			break;/* Disable debug output                    case 'd':	Debug = TRUE;	                 break;*/		    case 'f':	/* Suppress filename on output */			Shwfile = FALSE;			break;		    case 'l':	/* Line length */			Linlen = atoi(aptr);			Lines = NULL;			i = n;			break;		    case 'n':	/* Suppress line number on output */			Shwline = FALSE;			break;		    case 'w':	/* Window: lines before and after */			Waft = Wbef = atoi(aptr);			Lines = NULL;			i = n;			break;		    default:			fprintf(stderr, "Invalid option %s\n", argv[i]);			exit(1);		}	}  }  if (Pat == NULL) {		/* If no pattern given */	fprintf(stderr,		"Usage: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n");	exit(1);  }  if (nf == 0)			/* No files processed ? */	dosrch((char *)NULL);		/* Do standard input */  return(0);} /* Dosrch (ifnm) Perform the search   * Accepts :  *   * ifn             Input file name  *   *   * Returns :  *   *   */void dosrch(ifnm)char *ifnm;			/* Input filelname */{  FILE *ifp;			/* Input fp */  char *lptr;			/* Line pointer */  int i;			/* Scratch */  int prtaft;			/* Print-after count */  int linnum;			/* Line number */  int nlb;			/* Number of lines buffered */  if (ifnm != NULL) {		/* If file name given */	ifp = fopen(ifnm, "r");	/* Open it for read access */	if (ifp == NULL) {		fprintf(stderr, "Can not open file %s\n", ifnm);		return;	}  } else	ifp = stdin;  if (Lines == NULL) {		/* If no line table allocated.. */	Wsiz = Wbef + 2;	/* Determine total window size */	Lines = (char **) calloc((size_t)Wsiz, sizeof(char *));	/* Allocate pointer table */	for (i = 0; i < Wsiz; i++)	/* Allocate line buffers */		Lines[i] = (char *) calloc((size_t)Linlen, sizeof(char));  }  Lcur = Lone = 0;		/* Setup line pointers */  nlb = 0;			/* No lines buffered */  linnum = 0;			/* Line number is zero */  prtaft = -(Wbef + 1);		/* Make sure separator given first time */  for (;;) {			/* Loop through the file */	lptr = Lines[Lcur];	/* Get pointer to current line */	if (++Lcur == Wsiz)	/* Bump curr pointer and wrap */		Lcur = 0;	/* if hit end */	if (Lone == Lcur)	/* If wrapped to beginning of window */		if (++Lone == Wsiz)	/* Bump beginning */			Lone = 0;	/* and wrap if hit end */	if (fgets(lptr, Linlen, ifp) != lptr) break;	/* if end of file */	linnum++;		/* Count line number */	if (matlin(lptr)) {	/* If matching line */		if (prtaft < (-Wbef))	/* Check for separator needed */			if ((Nmr++ > 0) && ((Wbef > 0) || (Waft > 0)))				printf("----------------------------------------------------------------------------\n");		while (Lone != Lcur) {	/* Until we close the window */			shwlin(ifnm, linnum - nlb, Lines[Lone]);			/* Show the line */			if (++Lone == Wsiz) Lone = 0;			nlb--;		}		nlb = 0;	/* No lines buffered */		prtaft = Waft;	/* Print n lines after */	} else {		/* Didn't match */		if (prtaft-- > 0) {	/* If must print lines after */			shwlin(ifnm, linnum, lptr);			/* Show the line */			Lone = Lcur;	/* Match pointers */		} else if (nlb < Wbef)	/* Count lines buffered */			nlb++;	}  }  if (ifnm != NULL) fclose(ifp);} /* Shwlin (fnm, linnum, line) Show a matching line   *   * Accepts :  *   * fnm             File name  *   * linnum          Line number  *   * line            Line to show  *   *   * Returns :  *   *   */void shwlin(fnm, linnum, line)char *fnm;			/* File name */int linnum;			/* Line number */char *line;			/* Line (with newline at end) to print */{  if (Shwfile && (fnm != NULL)) printf("%s%s", fnm, Shwline ? " " : ":");  if (Shwline) printf("@%05d:", linnum);  printf("%s", line);} /* Matlin (line) Perform match against pattern and line   *   * Accepts :  *   * line            Address of line to match  *   *   * Returns :  *   * <value>         TRUE if match FALSE if not  *   *   */int matlin(line)char *line;			/* Line to match */{  int rtncode;			/* Return value from this routine */#ifdef	NOREGEXP  char *pptr, *lptr, *tlptr;  int c1, c2;#endif /* NOREGEXP */  if (Debug) printf("Matching %s against %s", Pat, line);#ifdef	REGEX  rtncode = re_exec(line);	/* Hand off to r/e evaluator */#endif	/* REGEX */#ifdef	REGCMP  rtncode = (regexec(Re, line, TRUE) != 0);#endif /* REGCMP */#ifdef	NOREGEX			/* Have to do menial comparison.. */  lptr = line;			/* Init line pointer */  for (rtncode = -1; rtncode < 0;) {	tlptr = lptr++;		/* Get temp ptr to line */	pptr = Pat;		/* Get ptr to pattern */	while (TRUE) {		if ((c1 = *pptr++) == NUL) {			rtncode = 1;	/* GOOD return value */			break;		}		if ((c2 = *tlptr++) == NUL) {			rtncode = 0;	/* BAD return value */			break;		}		if (isupper(c1)) c1 = tolower(c1);		if (isupper(c2)) c2 = tolower(c2);		if (c1 != c2) break;	}  }#endif	/* NOREGEX */  if (Debug) printf("matlin returned %s\n", rtncode ? "TRUE" : "FALSE");  return(rtncode);}void regerror(s)char *s;{  printf("%s\n", s);  exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -