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

📄 lib.c

📁 著名Awk语言的编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
	setfval(nfloc, (Awkfloat) lastfld);	if (dbg) {		for (j = 0; j <= lastfld; j++) {			p = fldtab[j];			printf("field %d (%s): |%s|\n", j, p->nval, p->sval);		}	}}void cleanfld(int n1, int n2)	/* clean out fields n1 .. n2 inclusive */{				/* nvals remain intact */	Cell *p;	int i;	for (i = n1; i <= n2; i++) {		p = fldtab[i];		if (freeable(p))			xfree(p->sval);		p->sval = "";		p->tval = FLD | STR | DONTFREE;	}}void newfld(int n)	/* add field n after end of existing lastfld */{	if (n > nfields)		growfldtab(n);	cleanfld(lastfld+1, n);	lastfld = n;	setfval(nfloc, (Awkfloat) n);}Cell *fieldadr(int n)	/* get nth field */{	if (n < 0)		FATAL("trying to access field %d", n);	if (n > nfields)	/* fields after NF are empty */		growfldtab(n);	/* but does not increase NF */	return(fldtab[n]);}void growfldtab(int n)	/* make new fields up to at least $n */{	int nf = 2 * nfields;	if (n > nf)		nf = n;	fldtab = (Cell **) realloc(fldtab, (nf+1) * (sizeof (struct Cell *)));	if (fldtab == NULL)		FATAL("out of space creating %d fields", nf);	makefields(nfields+1, nf);	nfields = nf;}int refldbld(const char *rec, const char *fs)	/* build fields from reg expr in FS */{	/* this relies on having fields[] the same length as $0 */	/* the fields are all stored in this one array with \0's */	char *fr;	int i, tempstat, n;	fa *pfa;	n = strlen(rec);	if (n > fieldssize) {		xfree(fields);		if ((fields = (char *) malloc(n+1)) == NULL)			FATAL("out of space for fields in refldbld %d", n);		fieldssize = n;	}	fr = fields;	*fr = '\0';	if (*rec == '\0')		return 0;	pfa = makedfa(fs, 1);	   dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) );	tempstat = pfa->initstat;	for (i = 1; ; i++) {		if (i > nfields)			growfldtab(i);		if (freeable(fldtab[i]))			xfree(fldtab[i]->sval);		fldtab[i]->tval = FLD | STR | DONTFREE;		fldtab[i]->sval = fr;		   dprintf( ("refldbld: i=%d\n", i) );		if (nematch(pfa, rec)) {			pfa->initstat = 2;	/* horrible coupling to b.c */			   dprintf( ("match %s (%d chars)\n", patbeg, patlen) );			strncpy(fr, rec, patbeg-rec);			fr += patbeg - rec + 1;			*(fr-1) = '\0';			rec = patbeg + patlen;		} else {			   dprintf( ("no match %s\n", rec) );			strcpy(fr, rec);			pfa->initstat = tempstat;			break;		}	}	return i;		}void recbld(void)	/* create $0 from $1..$NF if necessary */{	int i;	char *r, *p;	if (donerec == 1)		return;	r = record;	for (i = 1; i <= *NF; i++) {		p = getsval(fldtab[i]);		if (!adjbuf(&record, &recsize, 1+strlen(p)+r-record, recsize, &r, "recbld 1"))			FATAL("created $0 `%.30s...' too long", record);		while ((*r = *p++) != 0)			r++;		if (i < *NF) {			if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2"))				FATAL("created $0 `%.30s...' too long", record);			for (p = *OFS; (*r = *p++) != 0; )				r++;		}	}	if (!adjbuf(&record, &recsize, 2+r-record, recsize, &r, "recbld 3"))		FATAL("built giant record `%.30s...'", record);	*r = '\0';	   dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );	if (freeable(fldtab[0]))		xfree(fldtab[0]->sval);	fldtab[0]->tval = REC | STR | DONTFREE;	fldtab[0]->sval = record;	   dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );	   dprintf( ("recbld = |%s|\n", record) );	donerec = 1;}int	errorflag	= 0;void yyerror(const char *s){	SYNTAX(s);}void SYNTAX(const char *fmt, ...){	extern char *cmdname, *curfname;	static int been_here = 0;	va_list varg;	if (been_here++ > 2)		return;	fprintf(stderr, "%s: ", cmdname);	va_start(varg, fmt);	vfprintf(stderr, fmt, varg);	va_end(varg);	fprintf(stderr, " at source line %d", lineno);	if (curfname != NULL)		fprintf(stderr, " in function %s", curfname);	if (compile_time == 1 && cursource() != NULL)		fprintf(stderr, " source file %s", cursource());	fprintf(stderr, "\n");	errorflag = 2;	eprint();}void fpecatch(int n){	FATAL("floating point exception %d", n);}extern int bracecnt, brackcnt, parencnt;void bracecheck(void){	int c;	static int beenhere = 0;	if (beenhere++)		return;	while ((c = input()) != EOF && c != '\0')		bclass(c);	bcheck2(bracecnt, '{', '}');	bcheck2(brackcnt, '[', ']');	bcheck2(parencnt, '(', ')');}void bcheck2(int n, int c1, int c2){	if (n == 1)		fprintf(stderr, "\tmissing %c\n", c2);	else if (n > 1)		fprintf(stderr, "\t%d missing %c's\n", n, c2);	else if (n == -1)		fprintf(stderr, "\textra %c\n", c2);	else if (n < -1)		fprintf(stderr, "\t%d extra %c's\n", -n, c2);}void FATAL(const char *fmt, ...){	extern char *cmdname;	va_list varg;	fflush(stdout);	fprintf(stderr, "%s: ", cmdname);	va_start(varg, fmt);	vfprintf(stderr, fmt, varg);	va_end(varg);	error();	if (dbg > 1)		/* core dump if serious debugging on */		abort();	exit(2);}void WARNING(const char *fmt, ...){	extern char *cmdname;	va_list varg;	fflush(stdout);	fprintf(stderr, "%s: ", cmdname);	va_start(varg, fmt);	vfprintf(stderr, fmt, varg);	va_end(varg);	error();}void error(){	extern Node *curnode;	fprintf(stderr, "\n");	if (compile_time != 2 && NR && *NR > 0) {		fprintf(stderr, " input record number %d", (int) (*FNR));		if (strcmp(*FILENAME, "-") != 0)			fprintf(stderr, ", file %s", *FILENAME);		fprintf(stderr, "\n");	}	if (compile_time != 2 && curnode)		fprintf(stderr, " source line number %d", curnode->lineno);	else if (compile_time != 2 && lineno)		fprintf(stderr, " source line number %d", lineno);	if (compile_time == 1 && cursource() != NULL)		fprintf(stderr, " source file %s", cursource());	fprintf(stderr, "\n");	eprint();}void eprint(void)	/* try to print context around error */{	char *p, *q;	int c;	static int been_here = 0;	extern char ebuf[], *ep;	if (compile_time == 2 || compile_time == 0 || been_here++ > 0)		return;	p = ep - 1;	if (p > ebuf && *p == '\n')		p--;	for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--)		;	while (*p == '\n')		p++;	fprintf(stderr, " context is\n\t");	for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)		;	for ( ; p < q; p++)		if (*p)			putc(*p, stderr);	fprintf(stderr, " >>> ");	for ( ; p < ep; p++)		if (*p)			putc(*p, stderr);	fprintf(stderr, " <<< ");	if (*ep)		while ((c = input()) != '\n' && c != '\0' && c != EOF) {			putc(c, stderr);			bclass(c);		}	putc('\n', stderr);	ep = ebuf;}void bclass(int c){	switch (c) {	case '{': bracecnt++; break;	case '}': bracecnt--; break;	case '[': brackcnt++; break;	case ']': brackcnt--; break;	case '(': parencnt++; break;	case ')': parencnt--; break;	}}double errcheck(double x, const char *s){	if (errno == EDOM) {		errno = 0;		WARNING("%s argument out of domain", s);		x = 1;	} else if (errno == ERANGE) {		errno = 0;		WARNING("%s result out of range", s);		x = 1;	}	return x;}int isclvar(const char *s)	/* is s of form var=something ? */{	const char *os = s;	if (!isalpha((uschar) *s) && *s != '_')		return 0;	for ( ; *s; s++)		if (!(isalnum((uschar) *s) || *s == '_'))			break;	return *s == '=' && s > os && *(s+1) != '=';}/* strtod is supposed to be a proper test of what's a valid number *//* appears to be broken in gcc on linux: thinks 0x123 is a valid FP number *//* wrong: violates 4.10.1.4 of ansi C standard */#include <math.h>int is_number(const char *s){	double r;	char *ep;	errno = 0;	r = strtod(s, &ep);	if (ep == s || r == HUGE_VAL || errno == ERANGE)		return 0;	while (*ep == ' ' || *ep == '\t' || *ep == '\n')		ep++;	if (*ep == '\0')		return 1;	else		return 0;}

⌨️ 快捷键说明

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