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

📄 compile.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	*repp = xmalloc(sizeof(regex_t));	if (p && (eval = regcomp(*repp, re, 0)) != 0)		err(COMPILE, "RE error: %s", strregerror(eval, *repp));	if (maxnsub < (*repp)->re_nsub)		maxnsub = (*repp)->re_nsub;	return (p);}/* * Compile the substitution string of a regular expression and set res to * point to a saved copy of it.  Nsub is the number of parenthesized regular * expressions. */static char *compile_subst(p, s)	char *p;	struct s_subst *s;{	static char lbuf[_POSIX2_LINE_MAX + 1];	int asize, ref, size;	char c, *text, *op, *sp;	c = *p++;			/* Terminator character */	if (c == '\0')		return (NULL);	s->maxbref = 0;	s->linenum = linenum;	asize = 2 * _POSIX2_LINE_MAX + 1;	text = xmalloc(asize);	size = 0;	do {		op = sp = text + size;		for (; *p; p++) {			if (*p == '\\') {				p++;				if (strchr("123456789", *p) != NULL) {					*sp++ = '\\';					ref = *p - '0';					if (s->re != NULL &&					    ref > s->re->re_nsub)						err(COMPILE,"\\%c not defined in the RE", *p);					if (s->maxbref < ref)						s->maxbref = ref;				} else if (*p == '&' || *p == '\\')					*sp++ = '\\';			} else if (*p == c) {				p++;				*sp++ = '\0';				size += sp - op;				s->new = xrealloc(text, size);				return (p);			} else if (*p == '\n') {				err(COMPILE,"unescaped newline inside substitute pattern");				/* NOTREACHED */			}			*sp++ = *p;		}		size += sp - op;		if (asize - size < _POSIX2_LINE_MAX + 1) {			asize *= 2;			text = xmalloc(asize);		}	} while (cu_fgets(p = lbuf, sizeof(lbuf)));	err(COMPILE, "unterminated substitute in regular expression");	/* NOTREACHED */}/* * Compile the flags of the s command */static char *compile_flags(p, s)	char *p;	struct s_subst *s;{	int gn;			/* True if we have seen g or n */	char wfile[_POSIX2_LINE_MAX + 1], *q;	s->n = 1;				/* Default */	s->p = 0;	s->wfile = NULL;	s->wfd = -1;	for (gn = 0;;) {		EATSPACE();			/* EXTENSION */		switch (*p) {		case 'g':			if (gn)				err(COMPILE,"more than one number or 'g' in substitute flags");			gn = 1;			s->n = 0;			break;		case '\0':		case '\n':		case ';':			return (p);		case 'p':			s->p = 1;			break;		case '1': case '2': case '3':		case '4': case '5': case '6':		case '7': case '8': case '9':			if (gn)				err(COMPILE,"more than one number or 'g' in substitute flags");			gn = 1;			/* XXX Check for overflow */			s->n = (int)strtol(p, &p, 10);			break;		case 'w':			p++;#ifdef HISTORIC_PRACTICE			if (*p != ' ') {				err(WARNING, "space missing before w wfile");				return (p);			}#endif			EATSPACE();			q = wfile;			while (*p) {				if (*p == '\n')					break;				*q++ = *p++;			}			*q = '\0';			if (q == wfile)				err(COMPILE, "no wfile specified");			s->wfile = strdup(wfile);			if (!aflag && (s->wfd = open(wfile,			    O_WRONLY|O_APPEND|O_CREAT|O_TRUNC,			    DEFFILEMODE)) == -1)				err(FATAL, "%s: %s\n", wfile, strerror(errno));			return (p);		default:			err(COMPILE,			    "bad flag in substitute command: '%c'", *p);			break;		}		p++;	}}/* * Compile a translation set of strings into a lookup table. */static char *compile_tr(p, transtab)	char *p;	char **transtab;{	int i;	char *lt, *op, *np;	char old[_POSIX2_LINE_MAX + 1];	char new[_POSIX2_LINE_MAX + 1];	if (*p == '\0' || *p == '\\')		err(COMPILE,"transform pattern can not be delimited by newline or backslash");	p = compile_delimited(p, old);	if (p == NULL) {		err(COMPILE, "unterminated transform source string");		return (NULL);	}	p = compile_delimited(--p, new);	if (p == NULL) {		err(COMPILE, "unterminated transform target string");		return (NULL);	}	EATSPACE();	if (strlen(new) != strlen(old)) {		err(COMPILE, "transform strings are not the same length");		return (NULL);	}	/* We assume characters are 8 bits */	lt = xmalloc(UCHAR_MAX);	for (i = 0; i <= UCHAR_MAX; i++)		lt[i] = (char)i;	for (op = old, np = new; *op; op++, np++)		lt[(u_char)*op] = *np;	*transtab = lt;	return (p);}/* * Compile the text following an a or i command. */static char *compile_text(){	int asize, size;	char *text, *p, *op, *s;	char lbuf[_POSIX2_LINE_MAX + 1];	asize = 2 * _POSIX2_LINE_MAX + 1;	text = xmalloc(asize);	size = 0;	while (cu_fgets(lbuf, sizeof(lbuf))) {		op = s = text + size;		p = lbuf;		EATSPACE();		for (; *p; p++) {			if (*p == '\\')				p++;			*s++ = *p;		}		size += s - op;		if (p[-2] != '\\') {			*s = '\0';			break;		}		if (asize - size < _POSIX2_LINE_MAX + 1) {			asize *= 2;			text = xmalloc(asize);		}	}	return (xrealloc(text, size + 1));}/* * Get an address and return a pointer to the first character after * it.  Fill the structure pointed to according to the address. */static char *compile_addr(p, a)	char *p;	struct s_addr *a;{	char *end;	switch (*p) {	case '\\':				/* Context address */		++p;		/* FALLTHROUGH */	case '/':				/* Context address */		p = compile_re(p, &a->u.r);		if (p == NULL)			err(COMPILE, "unterminated regular expression");		a->type = AT_RE;		return (p);	case '$':				/* Last line */		a->type = AT_LAST;		return (p + 1);						/* Line number */	case '0': case '1': case '2': case '3': case '4': 	case '5': case '6': case '7': case '8': case '9':		a->type = AT_LINE;		a->u.l = strtol(p, &end, 10);		return (end);	default:		err(COMPILE, "expected context address");		return (NULL);	}}/* * duptoeol -- *	Return a copy of all the characters up to \n or \0. */static char *duptoeol(s, ctype)	register char *s;	char *ctype;{	size_t len;	int ws;	char *start;	ws = 0;	for (start = s; *s != '\0' && *s != '\n'; ++s)		ws = isspace(*s);	*s = '\0';	if (ws)		err(WARNING, "whitespace after %s", ctype);	len = s - start + 1;	return (memmove(xmalloc(len), start, len));}/* * Convert goto label names to addresses, and count a and r commands, in * the given subset of the script.  Free the memory used by labels in b * and t commands (but not by :). * * TODO: Remove } nodes */static voidfixuplabel(cp, end)	struct s_command *cp, *end;{	for (; cp != end; cp = cp->next)		switch (cp->code) {		case 'a':		case 'r':			appendnum++;			break;		case 'b':		case 't':			/* Resolve branch target. */			if (cp->t == NULL) {				cp->u.c = NULL;				break;			}			if ((cp->u.c = findlabel(cp->t)) == NULL)				err(COMPILE2, "undefined label '%s'", cp->t);			free(cp->t);			break;		case '{':			/* Do interior commands. */			fixuplabel(cp->u.c, cp->next);			break;		}}/* * Associate the given command label for later lookup. */static voidenterlabel(cp)	struct s_command *cp;{	register struct labhash **lhp, *lh;	register u_char *p;	register u_int h, c;	for (h = 0, p = (u_char *)cp->t; (c = *p) != 0; p++)		h = (h << 5) + h + c;	lhp = &labels[h & LHMASK];	for (lh = *lhp; lh != NULL; lh = lh->lh_next)		if (lh->lh_hash == h && strcmp(cp->t, lh->lh_cmd->t) == 0)			err(COMPILE2, "duplicate label '%s'", cp->t);	lh = xmalloc(sizeof *lh);	lh->lh_next = *lhp;	lh->lh_hash = h;	lh->lh_cmd = cp;	lh->lh_ref = 0;	*lhp = lh;}/* * Find the label contained in the command l in the command linked * list cp.  L is excluded from the search.  Return NULL if not found. */static struct s_command *findlabel(name)	char *name;{	register struct labhash *lh;	register u_char *p;	register u_int h, c;	for (h = 0, p = (u_char *)name; (c = *p) != 0; p++)		h = (h << 5) + h + c;	for (lh = labels[h & LHMASK]; lh != NULL; lh = lh->lh_next) {		if (lh->lh_hash == h && strcmp(name, lh->lh_cmd->t) == 0) {			lh->lh_ref = 1;			return (lh->lh_cmd);		}	}	return (NULL);}/*  * Warn about any unused labels.  As a side effect, release the label hash * table space. */static voiduselabel(){	register struct labhash *lh, *next;	register int i;	for (i = 0; i < LHSZ; i++) {		for (lh = labels[i]; lh != NULL; lh = next) {			next = lh->lh_next;			if (!lh->lh_ref)				err(WARNING, "unused label '%s'",				    lh->lh_cmd->t);			free(lh);		}	}}

⌨️ 快捷键说明

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