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

📄 sed.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  fout[0] = stdout;  switch (cchar) {      case '{':			/* start command group */	cmdp->flags.allbut = !cmdp->flags.allbut;	cmpstk[bdepth++] = &(cmdp->u.link);	if (++cmdp >= cmds + MAXCMDS) ABORT(TMCDS);	return(1);      case '}':			/* end command group */	if (cmdp->addr1) ABORT(AD1NG);	/* no addresses allowed */	if (--bdepth < 0) ABORT(TMRBR);	/* too many right braces */	*cmpstk[bdepth] = cmdp;	/* set the jump address */	return(1);      case '=':			/* print current source line number */      case 'q':			/* exit the stream editor */	if (cmdp->addr2) ABORT(AD2NG);	break;      case ':':			/* label declaration */	if (cmdp->addr1) ABORT(AD1NG);	/* no addresses allowed */	fp = gettext(lab->name = fp);	/* get the label name */	if (lpt = search(lab)) {/* does it have a double? */		if (lpt->address) ABORT(DLABL);	/* yes, abort */	} else {		/* check that it doesn't overflow label table */		lab->last = NULL;		lpt = lab;		if (++lab >= labels + MAXLABS) ABORT(TMLAB);	}	lpt->address = cmdp;	return(1);      case 'b':			/* branch command */      case 't':			/* branch-on-succeed command */      case 'T':			/* branch-on-fail command */	SKIPWS(cp);	if (*cp == '\0') {	/* if branch is to start of cmds... */		/* Add current command to end of label last */		if (sp1 = lablst->last) {			while (sp2 = sp1->u.link) sp1 = sp2;			sp1->u.link = cmdp;		} else		/* lablst->last == NULL */			lablst->last = cmdp;		break;	}	fp = gettext(lab->name = fp);	/* else get label into pool */	if (lpt = search(lab)) {/* enter branch to it */		if (lpt->address)			cmdp->u.link = lpt->address;		else {			sp1 = lpt->last;			while (sp2 = sp1->u.link) sp1 = sp2;			sp1->u.link = cmdp;		}	} else {		/* matching named label not found */		lab->last = cmdp;	/* add the new label */		lab->address = NULL;	/* it's forward of here */		if (++lab >= labels + MAXLABS)	/* overflow if last */			ABORT(TMLAB);	}	break;      case 'a':			/* append text */      case 'i':			/* insert text */      case 'r':			/* read file into stream */	if (cmdp->addr2) ABORT(AD2NG);      case 'c':			/* change text */	if ((*cp == '\\') && (*++cp == '\n')) cp++;	fp = gettext(cmdp->u.lhs = fp);	break;      case 'D':			/* delete current line in hold space */	cmdp->u.link = cmds;	break;      case 's':			/* substitute regular expression */	redelim = *cp++;	/* get delimiter from 1st ch */	if ((fp = recomp(cmdp->u.lhs = fp, redelim)) == BAD) ABORT(CGMSG);	if (fp == cmdp->u.lhs)	/* if compiled RE zero len */		cmdp->u.lhs = lastre;	/* use the previous one */	else			/* otherwise */		lastre = cmdp->u.lhs;	/* save the one just found */	if ((cmdp->rhs = fp) > poolend) ABORT(TMTXT);	if ((fp = rhscomp(cmdp->rhs, redelim)) == BAD) ABORT(CGMSG);	if (gflag) cmdp->flags.global ++;	while (*cp == 'g' || *cp == 'p' || *cp == 'P') {		IFEQ(cp, 'g') cmdp->flags.global ++;		IFEQ(cp, 'p') cmdp->flags.print = 1;		IFEQ(cp, 'P') cmdp->flags.print = 2;	}      case 'l':			/* list pattern space */	if (*cp == 'w')		cp++;		/* and execute a w command! */	else		break;		/* s or l is done */      case 'w':			/* write-pattern-space command */      case 'W':			/* write-first-line command */	if (nwfiles >= WFILES) ABORT(TMWFI);	fp = gettext(fname[nwfiles] = fp);	/* filename will be in pool */	for (i = nwfiles - 1; i >= 0; i--)	/* match it in table */		if ((fname[i] != NULL) &&		    (strcmp(fname[nwfiles], fname[i]) == 0)) {			cmdp->fout = fout[i];			return(0);		}	/* If didn't find one, open new out file */	if ((cmdp->fout = fopen(fname[nwfiles], "w")) == NULL) {		fprintf(stderr, CCOFI, fname[nwfiles]);		quit(2);	}	fout[nwfiles++] = cmdp->fout;	break;      case 'y':			/* transliterate text */	fp = ycomp(cmdp->u.lhs = fp, *cp++);	/* compile translit */	if (fp == BAD) ABORT(CGMSG);	/* fail on bad form */	if (fp > poolend) ABORT(TMTXT);	/* fail on overflow */	break;  }  return(0);			/* succeeded in interpreting one command */}static char *rhscomp(rhsp, delim)	/* uses bcount */ /* Generate replacement string for substitute command right hand side */register char *rhsp;		/* place to compile expression to */register char delim;		/* regular-expression end-mark to look for */{  register char *p = cp;	/* strictly for speed */  for (;;)	if ((*rhsp = *p++) == '\\') {	/* copy; if it's a \, */		*rhsp = *p++;	/* copy escaped char */		/* Check validity of pattern tag */		if (*rhsp > bcount + '0' && *rhsp <= '9') return(BAD);		*rhsp++ |= 0x80;/* mark the good ones */		continue;	} else if (*rhsp == delim) {	/* found RE end, hooray... */		*rhsp++ = '\0';	/* cap the expression string */		cp = p;		return(rhsp);	/* pt at 1 past the RE */	} else if (*rhsp++ == '\0')	/* last ch not RE end, help! */		return(BAD);}static char *recomp(expbuf, redelim)	/* uses cp, bcount */ /* Compile a regular expression to internal form */char *expbuf;			/* place to compile it to */char redelim;			/* RE end-marker to look for */{  register char *ep = expbuf;	/* current-compiled-char pointer */  register char *sp = cp;	/* source-character ptr */  register int c;		/* current-character pointer */  char negclass;		/* all-but flag */  char *lastep;			/* ptr to last expr compiled */  char *svclass;		/* start of current char class */  char brnest[MAXTAGS];		/* bracket-nesting array */  char *brnestp;		/* ptr to current bracket-nest */  int classct;			/* class element count */  int tags;			/* # of closed tags */  if (*cp == redelim)		/* if first char is RE endmarker */	return(cp++, expbuf);	/* leave existing RE unchanged */  lastep = NULL;		/* there's no previous RE */  brnestp = brnest;		/* initialize ptr to brnest array */  tags = bcount = 0;		/* initialize counters */  if (*ep++ = (*sp == '^'))	/* check for start-of-line syntax */	sp++;  for (;;) {	if (ep >= expbuf + RELIMIT)	/* match is too large */		return(cp = sp, BAD);	if ((c = *sp++) == redelim) {	/* found the end of the RE */		cp = sp;		if (brnestp != brnest)	/* \(, \) unbalanced */			return(BAD);		*ep++ = CEOF;	/* write end-of-pattern mark */		return(ep);	/* return ptr to compiled RE */	}	if (c != '*')		/* if we're a postfix op */		lastep = ep;	/* get ready to match last */	switch (c) {	    case '\\':		if ((c = *sp++) == '(') {	/* start tagged section */			if (bcount >= MAXTAGS) return(cp = sp, BAD);			*brnestp++ = bcount;	/* update tag stack */			*ep++ = CBRA;	/* enter tag-start */			*ep++ = bcount++;	/* bump tag count */			continue;		} else if (c == ')') {	/* end tagged section */			if (brnestp <= brnest)	/* extra \) */				return(cp = sp, BAD);			*ep++ = CKET;	/* enter end-of-tag */			*ep++ = *--brnestp;	/* pop tag stack */			tags++;	/* count closed tags */			continue;		} else if (c >= '1' && c <= '9') {	/* tag use */			if ((c -= '1') >= tags)	/* too few */				return(BAD);			*ep++ = CBACK;	/* enter tag mark */			*ep++ = c;	/* and the number */			continue;		} else if (c == '\n')	/* escaped newline no good */			return(cp = sp, BAD);		else if (c == 'n')	/* match a newline */			c = '\n';		else if (c == 't')	/* match a tab */			c = '\t';		else if (c == 'r')	/* match a return */			c = '\r';		goto defchar;	    case '\0':		/* ignore nuls */		continue;	    case '\n':		/* trailing pattern delimiter is missing */		return(cp = sp, BAD);	    case '.':		/* match any char except newline */		*ep++ = CDOT;		continue;	    case '*':		/* 0..n repeats of previous pattern */		if (lastep == NULL)	/* if * isn't first on line */			goto defchar;	/* match a literal * */		if (*lastep == CKET)	/* can't iterate a tag */			return(cp = sp, BAD);		*lastep |= STAR;/* flag previous pattern */		continue;	    case '$':		/* match only end-of-line */		if (*sp != redelim)	/* if we're not at end of RE */			goto defchar;	/* match a literal $ */		*ep++ = CDOL;	/* insert end-symbol mark */		continue;	    case '[':		/* begin character set pattern */		if (ep + 17 >= expbuf + RELIMIT) ABORT(REITL);		*ep++ = CCL;	/* insert class mark */		if (negclass = ((c = *sp++) == '^')) c = *sp++;		svclass = sp;	/* save ptr to class start */		do {			if (c == '\0') ABORT(CGMSG);			/* Handle character ranges */			if (c == '-' && sp > svclass && *sp != ']')				for (c = sp[-2]; c < *sp; c++)					ep[c >> 3] |= bits[c & 7];			/* Handle escape sequences in sets */			if (c == '\\')				if ((c = *sp++) == 'n')					c = '\n';				else if (c == 't')					c = '\t';				else if (c == 'r')					c = '\r';			/* Enter (possibly translated) char in set */			ep[c >> 3] |= bits[c & 7];		} while			((c = *sp++) != ']');		/* Invert the bitmask if all-but was specified */		if (negclass) for (classct = 0; classct < 16; classct++)				ep[classct] ^= 0xFF;		ep[0] &= 0xFE;	/* never match ASCII 0 */		ep += 16;	/* advance ep past set mask */		continue;  defchar:			/* match literal character */	    default:		/* which is what we'd do by default */		*ep++ = CCHR;	/* insert character mark */		*ep++ = c;	}  }}static int cmdline(cbuf)	/* uses eflag, eargc, cmdf */ /* Read next command from -e argument or command file */register char *cbuf;{  register int inc;		/* not char because must hold EOF */  *cbuf-- = 0;			/* so pre-increment points us at cbuf */  /* E command flag is on */  if (eflag) {	register char *p;	/* ptr to current -e argument */	static char *savep;	/* saves previous value of p */	if (eflag > 0) {	/* there are pending -e arguments */		eflag = -1;		if (eargc-- <= 0) quit(2);	/* if no arguments, barf */		/* Else transcribe next e argument into cbuf */		p = *++eargv;		while (*++cbuf = *p++)			if (*cbuf == '\\') {				if ((*++cbuf = *p++) == '\0')					return(savep = NULL, -1);				else					continue;			} else if (*cbuf == '\n') {	/* end of 1 cmd line */				*cbuf = '\0';				return(savep = p, 1);				/* We'll be back for the rest... */			}		/* Found end-of-string; can advance to next argument */		return(savep = NULL, 1);	}	if ((p = savep) == NULL) return(-1);	while (*++cbuf = *p++)		if (*cbuf == '\\') {			if ((*++cbuf = *p++) == '0')				return(savep = NULL, -1);			else				continue;		} else if (*cbuf == '\n') {			*cbuf = '\0';			return(savep = p, 1);		}	return(savep = NULL, 1);  }  /* If no -e flag read from command file descriptor */  while ((inc = getc(cmdf)) != EOF)	/* get next char */	if ((*++cbuf = inc) == '\\')	/* if it's escape */		*++cbuf = inc = getc(cmdf);	/* get next char */	else if (*cbuf == '\n')	/* end on newline */		return(*cbuf = '\0', 1);	/* cap the string */  return(*++cbuf = '\0', -1);	/* end-of-file, no more chars */}static char *address(expbuf)	/* uses cp, linenum */ /* Expand an address at *cp... into expbuf, return ptr at following char */register char *expbuf;{  static int numl = 0;		/* current ind in addr-number table */  register char *rcp;		/* temp compile ptr for forwd look */  long lno;			/* computed value of numeric address */  if (*cp == '$') {		/* end-of-source address */	*expbuf++ = CEND;	/* write symbolic end address */	*expbuf++ = CEOF;	/* and the end-of-address mark (!) */	cp++;			/* go to next source character */	return(expbuf);	/* we're done */  }  if (*cp == '/' || *cp == '\\') { /* start of regular-expression match */	if (*cp == '\\') cp++;	return(recomp(expbuf, *cp++));	/* compile the RE */  }  rcp = cp;  lno = 0;			/* now handle a numeric address */  while (*rcp >= '0' && *rcp <= '9')	/* collect digits */	lno = lno * 10 + *rcp++ - '0';	/* compute their value */  if (rcp > cp) {		/* if we caught a number... */	*expbuf++ = CLNUM;	/* put a numeric-address marker */	*expbuf++ = numl;	/* and the address table index */	linenum[numl++] = lno;	/* and set the table entry */	if (numl >= MAXLINES)	/* oh-oh, address table overflow */		ABORT(TMLNR);	/* abort with error message */	*expbuf++ = CEOF;	/* write the end-of-address marker */	cp = rcp;		/* point compile past the address */	return(expbuf);	/* we're done */  }  return(NULL);			/* no legal address was found */}static char *gettext(txp)	/* uses global cp */ /* Accept multiline input from *cp..., discarding leading whitespace */register char *txp;		/* where to put the text */{  register char *p = cp;	/* this is for speed */  SKIPWS(p);			/* discard whitespace */  do {	if ((*txp = *p++) == '\\')	/* handle escapes */		*txp = *p++;	if (*txp == '\0')	/* we're at end of input */		return(cp = --p, ++txp);	else if (*txp == '\n')	/* also SKIPWS after newline */		SKIPWS(p);  } while	(txp++);		/* keep going till we find that nul */  return(txp);}static label *search(ptr)	/* uses global lablst */ /* Find the label matching *ptr, return NULL if none */register label *ptr;{  register label *rp;  for (rp = lablst; rp < ptr; rp++)

⌨️ 快捷键说明

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