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

📄 sed.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}}static int substitute(ipc)/* Perform s command */sedcmd *ipc;			/* ptr to s command struct */{  int nullmatch;  if (match(ipc->u.lhs, 0)) {	/* if no match */	nullmatch = (loc1 == loc2);	dosub(ipc->rhs);	/* perform it once */  } else	return(FALSE);		/* command fails */  if (ipc->flags.global)	/* if global flag enabled */	while (*loc2) {		/* cycle through possibles */		if (nullmatch) loc2++;		if (match(ipc->u.lhs, 1)) {	/* found another */			nullmatch = (loc1 == loc2);			dosub(ipc->rhs);	/* so substitute */		} else		/* otherwise, */			break;	/* we're done */	}  return(TRUE);			/* we succeeded */}static void dosub(rhsbuf)	/* uses linebuf, genbuf, spend */ /* Generate substituted right-hand side (of s command) */char *rhsbuf;			/* where to put the result */{  register char *lp, *sp, *rp;  int c;  /* Copy linebuf to genbuf up to location  1 */  lp = linebuf;  sp = genbuf;  while (lp < loc1) *sp++ = *lp++;  for (rp = rhsbuf; c = *rp++;) {	if (c == '&') {		sp = place(sp, loc1, loc2);		continue;	} else if (c & 0200 && (c &= 0177) >= '1' && c < MAXTAGS + '1') {		sp = place(sp, brastart[c - '1'], bracend[c - '1']);		continue;	}	*sp++ = c & 0177;	if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG);  }  lp = loc2;  loc2 = sp - genbuf + linebuf;  while (*sp++ = *lp++)	if (sp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG);  lp = linebuf;  sp = genbuf;  while (*lp++ = *sp++);  spend = lp - 1;}static char *place(asp, al1, al2)	/* uses genbuf */ /* Place chars at *al1...*(al1 - 1) at asp... in genbuf[] */register char *asp, *al1, *al2;{  while (al1 < al2) {	*asp++ = *al1++;	if (asp >= genbuf + MAXBUF) fprintf(stderr, LTLMSG);  }  return(asp);}static void listto(p1, fp)/* Write a hex dump expansion of *p1... to fp */register char *p1;		/* the source */FILE *fp;			/* output stream to write to */{  p1--;  while (*p1++)	if (isprint(*p1))		putc(*p1, fp);	/* pass it through */	else {		putc('\\', fp);	/* emit a backslash */		switch (*p1) {		    case '\b':			putc('b', fp);			break;	/* BS */		    case '\t':			putc('t', fp);			break;	/* TAB */		    case '\n':			putc('n', fp);			break;	/* NL */		    case '\r':			putc('r', fp);			break;	/* CR */		    case '\33':			putc('e', fp);			break;	/* ESC */		    default:			fprintf(fp, "%02x", *p1 & 0xFF);		}	}  putc('\n', fp);}static void truncated(h)int h;{  static long last = 0L;  if (lnum == last) return;  last = lnum;  fprintf(stderr, "sed: ");  fprintf(stderr, h ? "hold space" : "line %ld", lnum);  fprintf(stderr, " truncated to %d characters\n", MAXBUF);}static void command(ipc)/* Execute compiled command pointed at by ipc */sedcmd *ipc;{  static char holdsp[MAXHOLD + 1];	/* the hold space */  static char *hspend = holdsp;	/* hold space end pointer */  register char *p1, *p2;  char *execp;  int didsub;			/* true if last s succeeded */  switch (ipc->command) {      case ACMD:		/* append */	*aptr++ = ipc;	if (aptr >= appends + MAXAPPENDS) fprintf(stderr,			"sed: too many appends after line %ld\n",			lnum);	*aptr = 0;	break;      case CCMD:		/* change pattern space */	delete = TRUE;	if (!ipc->flags.inrange || lastline) printf("%s\n", ipc->u.lhs);	break;      case DCMD:		/* delete pattern space */	delete++;	break;      case CDCMD:		/* delete a line in hold space */	p1 = p2 = linebuf;	while (*p1 != '\n')		if (delete = (*p1++ == 0)) return;	p1++;	while (*p2++ = *p1++) continue;	spend = p2 - 1;	jump++;	break;      case EQCMD:		/* show current line number */	fprintf(stdout, "%ld\n", lnum);	break;      case GCMD:		/* copy hold space to pattern space */	p1 = linebuf;	p2 = holdsp;	while (*p1++ = *p2++);	spend = p1 - 1;	break;      case CGCMD:		/* append hold space to pattern space */	*spend++ = '\n';	p1 = spend;	p2 = holdsp;	do		if (p1 > linebuf + MAXBUF) {			truncated(0);			p1[-1] = 0;			break;		}	while (*p1++ = *p2++);	spend = p1 - 1;	break;      case HCMD:		/* copy pattern space to hold space */	p1 = holdsp;	p2 = linebuf;	while (*p1++ = *p2++);	hspend = p1 - 1;	break;      case CHCMD:		/* append pattern space to hold space */	*hspend++ = '\n';	p1 = hspend;	p2 = linebuf;	do		if (p1 > holdsp + MAXBUF) {			truncated(1);			p1[-1] = 0;			break;		}	while (*p1++ = *p2++);	hspend = p1 - 1;	break;      case ICMD:		/* insert text */	printf("%s\n", ipc->u.lhs);	break;      case BCMD:		/* branch to label */	jump = TRUE;	break;      case LCMD:		/* list text */	listto(linebuf, (ipc->fout != NULL) ? ipc->fout : stdout);	break;      case NCMD:		/* read next line into pattern space */	if (!nflag) puts(linebuf);	/* flush out the current line */	if (aptr > appends) readout();	/* do pending a, r commands */	if ((execp = getline(linebuf)) == BAD) {		delete = TRUE;		break;	}	spend = execp;	anysub = FALSE;	break;      case CNCMD:		/* append next line to pattern space */	if (aptr > appends) readout();	*spend++ = '\n';	if ((execp = getline(spend)) == BAD) {		*--spend = 0;		break;	}	spend = execp;	anysub = FALSE;	break;      case PCMD:		/* print pattern space */	puts(linebuf);	break;      case CPCMD:		/* print one line from pattern space */cpcom:				/* so s command can jump here */	for (p1 = linebuf; *p1 != '\n' && *p1 != '\0';) putc(*p1++, stdout);	putc('\n', stdout);	break;      case QCMD:		/* quit the stream editor */	if (!nflag) puts(linebuf);	/* flush out the current line */	if (aptr > appends)		readout();	/* do any pending a and r commands */	quit(0);      case RCMD:		/* read a file into the stream */	*aptr++ = ipc;	if (aptr >= appends + MAXAPPENDS) fprintf(stderr,			"sed: too many reads after line %ld\n",			lnum);	*aptr = 0;	break;      case SCMD:		/* substitute RE */	didsub = substitute(ipc);	if (didsub) anysub = TRUE;	if (ipc->flags.print && didsub)		if (ipc->flags.print == TRUE)			puts(linebuf);		else			goto cpcom;	if (didsub && ipc->fout) fprintf(ipc->fout, "%s\n", linebuf);	break;      case TCMD:		/* branch on any s successful */      case CTCMD:		/* branch on any s failed */	if (anysub == (ipc->command == CTCMD))		break;		/* no branch if any s failed, else */	anysub = FALSE;	jump = TRUE;		/* set up to jump to assoc'd label */	break;      case CWCMD:		/* write one line from pattern space */	for (p1 = linebuf; *p1 != '\n' && *p1 != '\0';)		putc(*p1++, ipc->fout);	putc('\n', ipc->fout);	break;      case WCMD:		/* write pattern space to file */	fprintf(ipc->fout, "%s\n", linebuf);	break;      case XCMD:		/* exchange pattern and hold spaces */	p1 = linebuf;	p2 = genbuf;	while (*p2++ = *p1++) continue;	p1 = holdsp;	p2 = linebuf;	while (*p2++ = *p1++) continue;	spend = p2 - 1;	p1 = genbuf;	p2 = holdsp;	while (*p2++ = *p1++) continue;	hspend = p2 - 1;	break;      case YCMD:	p1 = linebuf;	p2 = ipc->u.lhs;	while (*p1 = p2[*p1]) p1++;	break;  }}static void openfile(file)char *file;/* Replace stdin by given file */{  if (freopen(file, "r", stdin) == NULL) {	fprintf(stderr, "sed: can't open %s\n", file);	quit(1);  }}static int c;			/* Will be the next char to read, a kind of			 * lookahead */static void get()/* Read next character into c treating all argument files as run through cat */{  while ((c = getchar()) == EOF && --eargc >= 0) openfile(*eargv++);}static void initget()/* Initialise character input */{  if (--eargc >= 0) openfile(*eargv++);	/* else input == stdin */  get();}static char *getline(buf)/* Get next line of text to be edited, return pointer to end */register char *buf;		/* where to send the input */{  if (c == EOF) return BAD;  lnum++;			/* we can read a new line */  do {	if (c == '\n') {		get();		break;	}	if (buf <= linebuf + MAXBUF) *buf++ = c;	get();  } while (c != EOF);  if (c == EOF) lastline = TRUE;  if (buf > linebuf + MAXBUF) {	truncated(0);	--buf;  }  *buf = 0;  return buf;}static int Memcmp(a, b, count)/* Return TRUE if *a... == *b... for count chars, FALSE otherwise */register char *a, *b;int count;{  while (count--)		/* look at count characters */	if (*a++ != *b++)	/* if any are nonequal	 */		return(FALSE);	/* return FALSE for false */  return(TRUE);			/* compare succeeded */}static void readout()/* Write file indicated by r command to output */{  register int t;		/* hold input char or EOF */  FILE *fi;			/* ptr to file to be read */  aptr = appends - 1;		/* arrange for pre-increment to work right */  while (*++aptr)	if ((*aptr)->command == ACMD)	/* process "a" cmd */		printf("%s\n", (*aptr)->u.lhs);	else {			/* process "r" cmd */		if ((fi = fopen((*aptr)->u.lhs, "r")) == NULL) {			fprintf(stderr, "sed: can't open %s\n",				(*aptr)->u.lhs);			continue;		}		while ((t = getc(fi)) != EOF) putc((char) t, stdout);		fclose(fi);	}  aptr = appends;		/* reset the append ptr */  *aptr = 0;}/* Sedexec.c ends here */

⌨️ 快捷键说明

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