sed0.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 995 行 · 第 1/2 页

C
995
字号
#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include "sed.h"struct label	*labtab = ltab;char	CGMES[]	= "sed: Command garbled: %s\n";char	TMMES[]	= "sed: Too much text: %s\n";char	LTL[]	= "sed: Label too long: %s\n";char	AD0MES[]	= "sed: No addresses allowed: %s\n";char	AD1MES[]	= "sed: Only one address allowed: %s\n";uchar	bittab[]  = {		1,		2,		4,		8,		16,		32,		64,		128	};main(int argc, char **argv){	eargc = argc;	eargv = (uchar**)argv;	badp = &bad;	aptr = abuf;	hspend = holdsp;	lab = labtab + 1;	/* 0 reserved for end-pointer */	rep = ptrspace;	rep->r1.ad1 = respace;	lbend = &linebuf[LBSIZE];	hend = &holdsp[LBSIZE];	lcomend = &genbuf[64];	ptrend = &ptrspace[PTRSIZE];	reend = &respace[RESIZE];	labend = &labtab[LABSIZE];	lnum = 0;	pending = 0;	depth = 0;	spend = linebuf;	hspend = holdsp;	fcode[0] = stdout;	nfiles = 1;	lastre = NULL;	if(eargc == 1)		exit(0);	while (--eargc > 0 && (++eargv)[0][0] == '-')		switch (eargv[0][1]) {		case 'n':			nflag++;			continue;		case 'f':			if(eargc-- <= 0)	exit(2);			if((fin = fopen((char*)(*++eargv), "r")) == NULL) {				fprintf(stderr, "sed: Cannot open pattern-file: %s\n", *eargv);				exit(2);			}			fcomp();			fclose(fin);			continue;		case 'e':			eflag++;			fcomp();			eflag = 0;			continue;		case 'g':			gflag++;			continue;		default:			fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]);			continue;		}	if(compfl == 0) {		eargv--;		eargc++;		eflag++;		fcomp();		eargv++;		eargc--;		eflag = 0;	}	if(depth) {		fprintf(stderr, "sed: Too many {'s\n");		exit(2);	}	labtab->address = rep;	dechain();/*	abort();	/*DEBUG*/	if(eargc <= 0)		execute((uchar *)NULL);	else while(--eargc >= 0) {		execute(*eargv++);	}	fclose(stdout);	exit(0);}voidfcomp(void){	uchar	*p, *op, *tp;    uchar *address(uchar*);	union reptr	*pt, *pt1;	int	i;	struct label	*lpt;	compfl = 1;	op = lastre;	if(rline(linebuf) < 0) {		lastre = op;		return;	}	if(*linebuf == '#') {		if(linebuf[1] == 'n')			nflag = 1;	}	else {		cp = linebuf;		goto comploop;	}	for(;;) {		if(rline(linebuf) < 0)	break;		cp = linebuf;comploop:/*	fprintf(stdout, "cp: %s\n", cp);	/*DEBUG*/		while(*cp == ' ' || *cp == '\t')	cp++;		if(*cp == '\0' || *cp == '#')		continue;		if(*cp == ';') {			cp++;			goto comploop;		}		p = address(rep->r1.ad1);		if(p == badp) {			fprintf(stderr, CGMES, linebuf);			exit(2);		}		if(p == 0) {			p = rep->r1.ad1;			rep->r1.ad1 = 0;		} else {			if(p == rep->r1.ad1) {				if(op)					rep->r1.ad1 = op;				else {					fprintf(stderr, "sed: First RE may not be null\n");					exit(2);				}			}			if(*rep->r1.ad1 != CLNUM && *rep->r1.ad1 != CEND)				op = rep->r1.ad1;			if(*cp == ',' || *cp == ';') {				cp++;				if((rep->r1.ad2 = p) > reend) {					fprintf(stderr, TMMES, linebuf);					exit(2);				}				p = address(rep->r1.ad2);				if(p == badp || p == 0) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				if(p == rep->r1.ad2)					rep->r1.ad2 = op;				else{				if(*rep->r1.ad2 != CLNUM && *rep->r1.ad2 != CEND)					op = rep->r1.ad2;				}			} else				rep->r1.ad2 = 0;		}		if(p > reend) {			fprintf(stderr, "sed: Too much text: %s\n", linebuf);			exit(2);		}		while(*cp == ' ' || *cp == '\t')	cp++;swit:		switch(*cp++) {			default:/*fprintf(stderr, "cp = %d; *cp = %o\n", cp - linebuf, *cp);*/				fprintf(stderr, "sed: Unrecognized command: %s\n", linebuf);				exit(2);			case '!':				rep->r1.negfl = 1;				goto swit;			case '{':				rep->r1.command = BCOM;				rep->r1.negfl = !(rep->r1.negfl);				cmpend[depth++] = &rep->r2.lb1;				if(++rep >= ptrend) {					fprintf(stderr, "sed: Too many commands: %s\n", linebuf);					exit(2);				}				rep->r1.ad1 = p;				if(*cp == '\0')	continue;				goto comploop;			case '}':				if(rep->r1.ad1) {					fprintf(stderr, AD0MES, linebuf);					exit(2);				}				if(--depth < 0) {					fprintf(stderr, "sed: Too many }'s\n");					exit(2);				}				*cmpend[depth] = rep;				rep->r1.ad1 = p;				if(*cp == 0)	continue;				goto comploop;			case '=':				rep->r1.command = EQCOM;				if(rep->r1.ad2) {					fprintf(stderr, AD1MES, linebuf);					exit(2);				}				break;			case ':':				if(rep->r1.ad1) {					fprintf(stderr, AD0MES, linebuf);					exit(2);				}				while(*cp++ == ' ');				cp--;				tp = lab->asc;				while((*tp = *cp++) && *tp != ';')					if(++tp >= &(lab->asc[8])) {						fprintf(stderr, LTL, linebuf);						exit(2);					}				*tp = '\0';				if(*lab->asc == 0) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				if(lpt = search(lab)) {					if(lpt->address) {						fprintf(stderr, "sed: Duplicate labels: %s\n", linebuf);						exit(2);					}				} else {					lab->chain = 0;					lpt = lab;					if(++lab >= labend) {						fprintf(stderr, "sed: Too many labels: %s\n", linebuf);						exit(2);					}				}				lpt->address = rep;				rep->r1.ad1 = p;				continue;			case 'a':				rep->r1.command = ACOM;				if(rep->r1.ad2) {					fprintf(stderr, AD1MES, linebuf);					exit(2);				}				if(*cp == '\\')	cp++;				if(*cp++ != '\n') {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				rep->r1.re1 = p;				p = text(rep->r1.re1);				break;			case 'c':				rep->r1.command = CCOM;				if(*cp == '\\')	cp++;				if(*cp++ != ('\n')) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				rep->r1.re1 = p;				p = text(rep->r1.re1);				break;			case 'i':				rep->r1.command = ICOM;				if(rep->r1.ad2) {					fprintf(stderr, AD1MES, linebuf);					exit(2);				}				if(*cp == '\\')	cp++;				if(*cp++ != ('\n')) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				rep->r1.re1 = p;				p = text(rep->r1.re1);				break;			case 'g':				rep->r1.command = GCOM;				break;			case 'G':				rep->r1.command = CGCOM;				break;			case 'h':				rep->r1.command = HCOM;				break;			case 'H':				rep->r1.command = CHCOM;				break;			case 't':				rep->r1.command = TCOM;				goto jtcommon;			case 'b':				rep->r1.command = BCOM;jtcommon:				while(*cp++ == ' ');				cp--;				if(*cp == '\0') {					if(pt = labtab->chain) {						while(pt1 = pt->r2.lb1)							pt = pt1;						pt->r2.lb1 = rep;					} else						labtab->chain = rep;					break;				}				tp = lab->asc;				while((*tp = *cp++) && *tp != ';')					if(++tp >= &(lab->asc[8])) {						fprintf(stderr, LTL, linebuf);						exit(2);					}				cp--;				*tp = '\0';				if(*lab->asc == 0) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				if(lpt = search(lab)) {					if(lpt->address) {						rep->r2.lb1 = lpt->address;					} else {						pt = lpt->chain;						while(pt1 = pt->r2.lb1)							pt = pt1;						pt->r2.lb1 = rep;					}				} else {					lab->chain = rep;					lab->address = 0;					if(++lab >= labend) {						fprintf(stderr, "sed: Too many labels: %s\n", linebuf);						exit(2);					}				}				break;			case 'n':				rep->r1.command = NCOM;				break;			case 'N':				rep->r1.command = CNCOM;				break;			case 'p':				rep->r1.command = PCOM;				break;			case 'P':				rep->r1.command = CPCOM;				break;			case 'r':				rep->r1.command = RCOM;				if(rep->r1.ad2) {					fprintf(stderr, AD1MES, linebuf);					exit(2);				}				if(*cp++ != ' ') {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				rep->r1.re1 = p;				p = text(rep->r1.re1);				break;			case 'd':				rep->r1.command = DCOM;				break;			case 'D':				rep->r1.command = CDCOM;				rep->r2.lb1 = ptrspace;				break;			case 'q':				rep->r1.command = QCOM;				if(rep->r1.ad2) {					fprintf(stderr, AD1MES, linebuf);					exit(2);				}				break;			case 'l':				rep->r1.command = LCOM;				break;			case 's':				rep->r1.command = SCOM;				seof = *cp++;				rep->r1.re1 = p;				p = compile(rep->r1.re1);				if(p == badp) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				if(p == rep->r1.re1) {					if(op == NULL) {						fprintf(stderr, "sed: First RE may not be null.\n");						exit(2);					}					rep->r1.re1 = op;				} else {					op = rep->r1.re1;				}				if((rep->r1.rhs = p) > reend) {					fprintf(stderr, TMMES, linebuf);					exit(2);				}				if((p = compsub(rep->r1.rhs)) == badp) {					fprintf(stderr, CGMES, linebuf);					exit(2);				}				if(*cp == 'g') {					cp++;					rep->r1.gfl++;				} else if(gflag)					rep->r1.gfl++;				if(*cp == 'p') {					cp++;					rep->r1.pfl = 1;				}				if(*cp == 'P') {					cp++;					rep->r1.pfl = 2;				}				if(*cp == 'w') {					cp++;

⌨️ 快捷键说明

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