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

📄 sed.c

📁 minix软件源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if ((rp->name != NULL) && (strcmp(rp->name, ptr->name) == 0))		return(rp);  return(NULL);}static void resolve(){				/* uses global lablst */  /* Write label links into the compiled-command space */  register label *lptr;  register sedcmd *rptr, *trptr;  /* Loop through the label table */  for (lptr = lablst; lptr < lab; lptr++)	if (lptr->address == NULL) {	/* barf if not defined */		fprintf(stderr, ULABL, lptr->name);		quit(2);	} else if (lptr->last) {/* if last is non-null */		rptr = lptr->last;	/* chase it */		while (trptr = rptr->u.link) {	/* resolve refs */			rptr->u.link = lptr->address;			rptr = trptr;		}		rptr->u.link = lptr->address;	}}static char *ycomp(ep, delim)/* Compile a y (transliterate) command */register char *ep;		/* where to compile to */char delim;			/* end delimiter to look for */{  register char *tp, *sp;  register int c;  /* Scan the 'from' section for invalid chars */  for (sp = tp = cp; *tp != delim; tp++) {	if (*tp == '\\') tp++;	if ((*tp == '\n') || (*tp == '\0')) return (BAD);  }  tp++;				/* tp now points at first char of 'to'			 * section */  /* Now rescan the 'from' section */  while ((c = *sp++ & 0x7F) != delim) {	if (c == '\\' && *sp == 'n') {		sp++;		c = '\n';	}	if ((ep[c] = *tp++) == '\\' && *tp == 'n') {		ep[c] = '\n';		tp++;	}	if ((ep[c] == delim) || (ep[c] == '\0')) return(BAD);  }  if (*tp != delim)		/* 'to', 'from' parts have unequal lengths */	return(BAD);  cp = ++tp;			/* point compile ptr past translit */  for (c = 0; c < 128; c++)	/* fill in self-map entries in table */	if (ep[c] == 0) ep[c] = c;  return(ep + 0x80);		/* return first free location past table end */}void quit(n)int n;{/* Flush buffers and exit.  Now a historical relic.  Rely on exit to flush * the buffers. */  exit(n);}/*+++++++++++++++*//*   sedexec.c -- execute compiled form of stream editor commands   The single entry point of this module is the function execute(). It   may take a string argument (the name of a file to be used as text)  or   the argument NULL which tells it to filter standard input. It executes   the compiled commands in cmds[] on each line in turn.   The function command() does most of the work. Match() and advance()   are used for matching text against precompiled regular expressions and   dosub() does right-hand-side substitution.  Getline() does text input;   readout() and Memcmp() are output and string-comparison utilities.*//* #include <stdio.h>	*//* #include <ctype.h>	*//* #include "sed.h"	*//***** shared variables imported from the main ******//* Main data areas */extern char linebuf[];		/* current-line buffer */extern sedcmd cmds[];		/* hold compiled commands */extern long linenum[];		/* numeric-addresses table *//* Miscellaneous shared variables */extern int nflag;		/* -n option flag */extern int eargc;		/* scratch copy of argument count */extern char **eargv;		/* scratch copy of argument list */extern char bits[];		/* the bits table *//***** end of imported stuff *****/#define MAXHOLD	 MAXBUF		/* size of the hold space */#define GENSIZ	 MAXBUF		/* maximum genbuf size */#define TRUE	 1#define FALSE	 0static char LTLMSG[] = "sed: line too long\n";static char *spend;		/* current end-of-line-buffer pointer */static long lnum = 0L;		/* current source line number *//* Append buffer maintenance */static sedcmd *appends[MAXAPPENDS];	/* array of ptrs to a,i,c commands */static sedcmd **aptr = appends;	/* ptr to current append *//* Genbuf and its pointers */static char genbuf[GENSIZ];static char *loc1;static char *loc2;static char *locs;/* Command-logic flags */static int lastline;		/* do-line flag */static int jump;		/* jump to cmd's link address if set */static int delete;		/* delete command flag *//* Tagged-pattern tracking */static char *bracend[MAXTAGS];	/* tagged pattern start pointers */static char *brastart[MAXTAGS];	/* tagged pattern end pointers */static int anysub;		/* true if any s on current line succeeded */void execute()/* Execute the compiled commands in cmds[] */{  register char *p1;		/* dummy copy ptrs */  register sedcmd *ipc;		/* ptr to current command */  char *execp;			/* ptr to source */  initget();  /* Here's the main command-execution loop */  for (;;) {	/* Get next line to filter */	if ((execp = getline(linebuf)) == BAD) return;	spend = execp;	anysub = FALSE;	/* Loop through compiled commands, executing them */	for (ipc = cmds; ipc->command;) {		if (!selected(ipc)) {			ipc++;			continue;		}		command(ipc);	/* execute the command pointed at */		if (delete)	/* if delete flag is set */			break;	/* don't exec rest of compiled cmds */		if (jump) {	/* if jump set, follow cmd's link */			jump = FALSE;			if ((ipc = ipc->u.link) == 0) {				ipc = cmds;				break;			}		} else		/* normal goto next command */			ipc++;	}	/* We've now done all modification commands on the line */	/* Here's where the transformed line is output */	if (!nflag && !delete) {		for (p1 = linebuf; p1 < spend; p1++) putc(*p1, stdout);		putc('\n', stdout);	}	/* If we've been set up for append, emit the text from it */	if (aptr > appends) readout();	delete = FALSE;		/* clear delete flag; about to get next cmd */  }}static int selected(ipc)/* Is current command selected */sedcmd *ipc;{  register char *p1 = ipc->addr1;	/* point p1 at first address */  register char *p2 = ipc->addr2;	/* and p2 at second */  int c;  int sel = TRUE;		/* select by default */  if (!p1)			/* No addresses: always selected */	;  else if (ipc->flags.inrange) {	if (*p2 == CEND);	else if (*p2 == CLNUM) {		c = p2[1] & CMASK;		if (lnum >= linenum[c]) {			ipc->flags.inrange = FALSE;			if (lnum > linenum[c]) sel = FALSE;		}	} else if (match(p2, 0))		ipc->flags.inrange = FALSE;  } else if (*p1 == CEND) {	if (!lastline) sel = FALSE;  } else if (*p1 == CLNUM) {	c = p1[1] & CMASK;	if (lnum != linenum[c])		sel = FALSE;	else if (p2)		ipc->flags.inrange = TRUE;  } else if (match(p1, 0)) {	if (p2) ipc->flags.inrange = TRUE;  } else	sel = FALSE;  return ipc->flags.allbut ? !sel : sel;}static int match(expbuf, gf)	/* uses genbuf */ /* Match RE at expbuf against linebuf; if gf set, copy linebuf from genbuf */char *expbuf;int gf;{  register char *p1, *p2, c;  if (gf) {	if (*expbuf) return(FALSE);	p1 = linebuf;	p2 = genbuf;	while (*p1++ = *p2++);	locs = p1 = loc2;  } else {	p1 = linebuf;	locs = FALSE;  }  p2 = expbuf;  if (*p2++) {	loc1 = p1;	if (*p2 == CCHR && p2[1] != *p1)	/* 1st char is wrong */		return(FALSE);	/* so fail */	return(advance(p1, p2));/* else try to match rest */  }  /* Quick check for 1st character if it's literal */  if (*p2 == CCHR) {	c = p2[1];		/* pull out character to search for */	do {		if (*p1 != c) continue;	/* scan the source string */		if (advance(p1, p2))	/* found it, match the rest */			return(loc1 = p1, 1);	} while		(*p1++);	return(FALSE);		/* didn't find that first char */  }  /* Else try for unanchored match of the pattern */  do {	if (advance(p1, p2)) return(loc1 = p1, 1);  } while	(*p1++);  /* If got here, didn't match either way */  return(FALSE);}static int advance(lp, ep)/* Attempt to advance match pointer by one pattern element */register char *lp;		/* source (linebuf) ptr */register char *ep;		/* regular expression element ptr */{  register char *curlp;		/* save ptr for closures */  char c;			/* scratch character holder */  char *bbeg;  int ct;  for (;;) switch (*ep++) {	    case CCHR:		/* literal character */		if (*ep++ == *lp++)	/* if chars are equal */			continue;	/* matched */		return(FALSE);	/* else return false */	    case CDOT:		/* anything but newline */		if (*lp++)	/* first NUL is at EOL */			continue;	/* keep going if didn't find */		return(FALSE);	/* else return false */	    case CNL:		/* start-of-line */	    case CDOL:		/* end-of-line */		if (*lp == 0)	/* found that first NUL? */			continue;	/* yes, keep going */		return(FALSE);	/* else return false */	    case CEOF:		/* end-of-address mark */		loc2 = lp;	/* set second loc */		return(TRUE);	/* return true */	    case CCL:		/* a closure */		c = *lp++ & 0177;		if (ep[c >> 3] & bits[c & 07]) {	/* is char in set? */			ep += 16;	/* then skip rest of bitmask */			continue;	/* and keep going */		}		return(FALSE);	/* else return false */	    case CBRA:		/* start of tagged pattern */		brastart[*ep++] = lp;	/* mark it */		continue;	/* and go */	    case CKET:		/* end of tagged pattern */		bracend[*ep++] = lp;	/* mark it */		continue;	/* and go */	    case CBACK:		bbeg = brastart[*ep];		ct = bracend[*ep++] - bbeg;		if (Memcmp(bbeg, lp, ct)) {			lp += ct;			continue;		}		return(FALSE);	    case CBACK | STAR:		bbeg = brastart[*ep];		ct = bracend[*ep++] - bbeg;		curlp = lp;		while (Memcmp(bbeg, lp, ct)) lp += ct;		while (lp >= curlp) {			if (advance(lp, ep)) return(TRUE);			lp -= ct;		}		return(FALSE);	    case CDOT | STAR:	/* match .* */		curlp = lp;	/* save closure start loc */		while (*lp++);	/* match anything */		goto star;	/* now look for followers */	    case CCHR | STAR:	/* match <literal char>* */		curlp = lp;	/* save closure start loc */		while (*lp++ == *ep);	/* match many of that char */		ep++;		/* to start of next element */		goto star;	/* match it and followers */	    case CCL | STAR:	/* match [...]* */		curlp = lp;	/* save closure start loc */		do {			c = *lp++ & 0x7F;	/* match any in set */		} while			(ep[c >> 3] & bits[c & 07]);		ep += 16;	/* skip past the set */		goto star;	/* match followers */  star:				/* the recursion part of a * or + match */		if (--lp == curlp)	/* 0 matches */			continue;		if (*ep == CCHR) {			c = ep[1];			do {				if (*lp != c) continue;				if (advance(lp, ep)) return (TRUE);			} while				(lp-- > curlp);			return(FALSE);		}		if (*ep == CBACK) {			c = *(brastart[ep[1]]);			do {				if (*lp != c) continue;				if (advance(lp, ep)) return (TRUE);			} while				(lp-- > curlp);			return(FALSE);		}		do {			if (lp == locs) break;			if (advance(lp, ep)) return (TRUE);		} while			(lp-- > curlp);		return(FALSE);	    default:		fprintf(stderr, "sed: RE error, %o\n", *--ep);		quit(2);

⌨️ 快捷键说明

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