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

📄 builtin.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			free_temp(arg);			chksize(fw + prec + 9);	/* 9==slop */			cp = cpbuf;			*cp++ = '%';			if (lj)				*cp++ = '-';			if (fill != sp)				*cp++ = '0';			if (cur != &fw) {				(void) strcpy(cp, "*.*e");				(void) sprintf(obuf + olen, cpbuf, (int) fw, (int) prec, (double) tmpval);			} else {				(void) strcpy(cp, "*e");				(void) sprintf(obuf + olen, cpbuf, (int) fw, (double) tmpval);			}			len = strlen(obuf + olen);			ofre -= len;			olen += len;			s0 = s1;			break;		default:	lose:			break;		}		if (toofew)			fatal("%s\n\t%s\n\t%*s%s",			"not enough arguments to satisfy format string",			sfmt->stptr, s1 - sfmt->stptr - 2, "",			"^ ran out for this one"			);	}	if (do_lint && carg != NULL)		warning("too many arguments supplied for format string");	bchunk(s0, s1 - s0);	free_temp(sfmt);	r = make_str_node(obuf, olen, ALREADY_MALLOCED);	r->flags |= TEMP;	return r;}voiddo_printf(tree)register NODE *tree;{	struct redirect *rp = NULL;	register FILE *fp;	if (tree->rnode) {		int errflg;	/* not used, sigh */		rp = redirect(tree->rnode, &errflg);		if (rp) {			fp = rp->fp;			if (!fp)				return;		} else			return;	} else		fp = stdout;	tree = do_sprintf(tree->lnode);	efwrite(tree->stptr, sizeof(char), tree->stlen, fp, "printf", rp , 1);	free_temp(tree);}NODE *do_sqrt(tree)NODE *tree;{	NODE *tmp;	double arg;	extern double sqrt P((double));	tmp = tree_eval(tree->lnode);	arg = (double) force_number(tmp);	free_temp(tmp);	if (arg < 0.0)		warning("sqrt called with negative argument %g", arg);	return tmp_number((AWKNUM) sqrt(arg));}NODE *do_substr(tree)NODE *tree;{	NODE *t1, *t2, *t3;	NODE *r;	register int indx;	size_t length;	t1 = tree_eval(tree->lnode);	t2 = tree_eval(tree->rnode->lnode);	if (tree->rnode->rnode == NULL)	/* third arg. missing */		length = t1->stlen;	else {		t3 = tree_eval(tree->rnode->rnode->lnode);		length = (size_t) force_number(t3);		free_temp(t3);	}	indx = (int) force_number(t2) - 1;	free_temp(t2);	t1 = force_string(t1);	if (indx < 0)		indx = 0;	if (indx >= t1->stlen || length <= 0) {		free_temp(t1);		return Nnull_string;	}	if (indx + length > t1->stlen || LONG_MAX - indx < length)		length = t1->stlen - indx;	r =  tmp_string(t1->stptr + indx, length);	free_temp(t1);	return r;}NODE *do_strftime(tree)NODE *tree;{	NODE *t1, *t2;	struct tm *tm;	time_t fclock;	char buf[100];	int ret;	t1 = force_string(tree_eval(tree->lnode));	if (tree->rnode == NULL)	/* second arg. missing, default */		(void) time(&fclock);	else {		t2 = tree_eval(tree->rnode->lnode);		fclock = (time_t) force_number(t2);		free_temp(t2);	}	tm = localtime(&fclock);	ret = strftime(buf, 100, t1->stptr, tm);	return tmp_string(buf, ret);}NODE *do_systime(tree)NODE *tree;{	time_t lclock;	(void) time(&lclock);	return tmp_number((AWKNUM) lclock);}NODE *do_system(tree)NODE *tree;{	NODE *tmp;	int ret = 0;	char *cmd;	(void) flush_io ();	/* so output is synchronous with gawk's */	tmp = tree_eval(tree->lnode);	cmd = force_string(tmp)->stptr;	if (cmd && *cmd) {		ret = system(cmd);		ret = (ret >> 8) & 0xff;	}	free_temp(tmp);	return tmp_number((AWKNUM) ret);}void do_print(tree)register NODE *tree;{	register NODE *t1;	struct redirect *rp = NULL;	register FILE *fp;	register char *s;	if (tree->rnode) {		int errflg;		/* not used, sigh */		rp = redirect(tree->rnode, &errflg);		if (rp) {			fp = rp->fp;			if (!fp)				return;		} else			return;	} else		fp = stdout;	tree = tree->lnode;	while (tree) {		t1 = tree_eval(tree->lnode);		if (t1->flags & NUMBER) {			if (OFMTidx == CONVFMTidx)				(void) force_string(t1);			else {				char buf[100];				sprintf(buf, OFMT, t1->numbr);				t1 = tmp_string(buf, strlen(buf));			}		}		efwrite(t1->stptr, sizeof(char), t1->stlen, fp, "print", rp, 0);		free_temp(t1);		tree = tree->rnode;		if (tree) {			s = OFS;			if (OFSlen)				efwrite(s, sizeof(char), OFSlen, fp, "print", rp, 0);		}	}	s = ORS;	if (ORSlen)		efwrite(s, sizeof(char), ORSlen, fp, "print", rp, 1);}NODE *do_tolower(tree)NODE *tree;{	NODE *t1, *t2;	register char *cp, *cp2;	t1 = tree_eval(tree->lnode);	t1 = force_string(t1);	t2 = tmp_string(t1->stptr, t1->stlen);	for (cp = t2->stptr, cp2 = t2->stptr + t2->stlen; cp < cp2; cp++)		if (isupper(*cp))			*cp = tolower(*cp);	free_temp(t1);	return t2;}NODE *do_toupper(tree)NODE *tree;{	NODE *t1, *t2;	register char *cp;	t1 = tree_eval(tree->lnode);	t1 = force_string(t1);	t2 = tmp_string(t1->stptr, t1->stlen);	for (cp = t2->stptr; cp < t2->stptr + t2->stlen; cp++)		if (islower(*cp))			*cp = toupper(*cp);	free_temp(t1);	return t2;}NODE *do_atan2(tree)NODE *tree;{	NODE *t1, *t2;	extern double atan2 P((double, double));	double d1, d2;	t1 = tree_eval(tree->lnode);	t2 = tree_eval(tree->rnode->lnode);	d1 = force_number(t1);	d2 = force_number(t2);	free_temp(t1);	free_temp(t2);	return tmp_number((AWKNUM) atan2(d1, d2));}NODE *do_sin(tree)NODE *tree;{	NODE *tmp;	extern double sin P((double));	double d;	tmp = tree_eval(tree->lnode);	d = sin((double)force_number(tmp));	free_temp(tmp);	return tmp_number((AWKNUM) d);}NODE *do_cos(tree)NODE *tree;{	NODE *tmp;	extern double cos P((double));	double d;	tmp = tree_eval(tree->lnode);	d = cos((double)force_number(tmp));	free_temp(tmp);	return tmp_number((AWKNUM) d);}static int firstrand = 1;static char state[256];/* ARGSUSED */NODE *do_rand(tree)NODE *tree;{	if (firstrand) {		(void) initstate((unsigned) 1, state, sizeof state);		srandom(1);		firstrand = 0;	}	return tmp_number((AWKNUM) random() / LONG_MAX);}NODE *do_srand(tree)NODE *tree;{	NODE *tmp;	static long save_seed = 0;	long ret = save_seed;	/* SVR4 awk srand returns previous seed */	if (firstrand)		(void) initstate((unsigned) 1, state, sizeof state);	else		(void) setstate(state);	if (!tree)		srandom((int) (save_seed = (long) time((time_t *) 0)));	else {		tmp = tree_eval(tree->lnode);		srandom((int) (save_seed = (long) force_number(tmp)));		free_temp(tmp);	}	firstrand = 0;	return tmp_number((AWKNUM) ret);}NODE *do_match(tree)NODE *tree;{	NODE *t1;	int rstart;	AWKNUM rlength;	Regexp *rp;	t1 = force_string(tree_eval(tree->lnode));	tree = tree->rnode->lnode;	rp = re_update(tree);	rstart = research(rp, t1->stptr, 0, t1->stlen, 1);	if (rstart >= 0) {	/* match succeded */		rstart++;	/* 1-based indexing */		rlength = REEND(rp, t1->stptr) - RESTART(rp, t1->stptr);	} else {		/* match failed */		rstart = 0;		rlength = -1.0;	}	free_temp(t1);	unref(RSTART_node->var_value);	RSTART_node->var_value = make_number((AWKNUM) rstart);	unref(RLENGTH_node->var_value);	RLENGTH_node->var_value = make_number(rlength);	return tmp_number((AWKNUM) rstart);}static NODE *sub_common(tree, global)NODE *tree;int global;{	register char *scan;	register char *bp, *cp;	char *buf;	int buflen;	register char *matchend;	register int len;	char *matchstart;	char *text;	int textlen;	char *repl;	char *replend;	int repllen;	int sofar;	int ampersands;	int matches = 0;	Regexp *rp;	NODE *s;		/* subst. pattern */	NODE *t;		/* string to make sub. in; $0 if none given */	NODE *tmp;	NODE **lhs = &tree;	/* value not used -- just different from NULL */	int priv = 0;	Func_ptr after_assign = NULL;	tmp = tree->lnode;	rp = re_update(tmp);	tree = tree->rnode;	s = tree->lnode;	tree = tree->rnode;	tmp = tree->lnode;	t = force_string(tree_eval(tmp));	/* do the search early to avoid work on non-match */	if (research(rp, t->stptr, 0, t->stlen, 1) == -1 ||	    (RESTART(rp, t->stptr) > t->stlen) && (matches = 1)) {		free_temp(t);		return tmp_number((AWKNUM) matches);	}	if (tmp->type == Node_val)		lhs = NULL;	else		lhs = get_lhs(tmp, &after_assign);	t->flags |= STRING;	/*	 * create a private copy of the string	 */	if (t->stref > 1 || (t->flags & PERM)) {		unsigned int saveflags;		saveflags = t->flags;		t->flags &= ~MALLOC;		tmp = dupnode(t);		t->flags = saveflags;		t = tmp;		priv = 1;	}	text = t->stptr;	textlen = t->stlen;	buflen = textlen + 2;	s = force_string(tree_eval(s));	repl = s->stptr;	replend = repl + s->stlen;	repllen = replend - repl;	emalloc(buf, char *, buflen, "do_sub");	ampersands = 0;	for (scan = repl; scan < replend; scan++) {		if (*scan == '&') {			repllen--;			ampersands++;		} else if (*scan == '\\' && (*(scan+1) == '&' || *(scan+1) == '\\')) {			repllen--;			scan++;		}	}	bp = buf;	for (;;) {		matches++;		matchstart = t->stptr + RESTART(rp, t->stptr);		matchend = t->stptr + REEND(rp, t->stptr);		/*		 * create the result, copying in parts of the original		 * string 		 */		len = matchstart - text + repllen		      + ampersands * (matchend - matchstart);		sofar = bp - buf;		while (buflen - sofar - len - 1 < 0) {			buflen *= 2;			erealloc(buf, char *, buflen, "do_sub");			bp = buf + sofar;		}		for (scan = text; scan < matchstart; scan++)			*bp++ = *scan;		for (scan = repl; scan < replend; scan++)			if (*scan == '&')				for (cp = matchstart; cp < matchend; cp++)					*bp++ = *cp;			else if (*scan == '\\' && (*(scan+1) == '&' || *(scan+1) == '\\')) {				scan++;				*bp++ = *scan;			} else				*bp++ = *scan;		if (global && matchstart == matchend && matchend < text + textlen) {			*bp++ = *matchend;			matchend++;		}		textlen = text + textlen - matchend;		text = matchend;		if (!global || textlen <= 0 ||		    research(rp, t->stptr, text-t->stptr, textlen, 1) == -1)			break;	}	sofar = bp - buf;	if (buflen - sofar - textlen - 1) {		buflen = sofar + textlen + 2;		erealloc(buf, char *, buflen, "do_sub");		bp = buf + sofar;	}	for (scan = matchend; scan < text + textlen; scan++)		*bp++ = *scan;	textlen = bp - buf;	free(t->stptr);	t->stptr = buf;	t->stlen = textlen;	free_temp(s);	if (matches > 0 && lhs) {		if (priv) {			unref(*lhs);			*lhs = t;		}		if (after_assign)			(*after_assign)();		t->flags &= ~(NUM|NUMBER);	}	return tmp_number((AWKNUM) matches);}NODE *do_gsub(tree)NODE *tree;{	return sub_common(tree, 1);}NODE *do_sub(tree)NODE *tree;{	return sub_common(tree, 0);}#ifdef GFMT_WORKAROUND	/*	 *	printf's %g format [can't rely on gcvt()]	 *		caveat: don't use as argument to *printf()!	 */char *gfmt(g, prec, buf)double g;	/* value to format */int prec;	/* indicates desired significant digits, not decimal places */char *buf;	/* return buffer; assumed big enough to hold result */{	if (g == 0.0) {		(void) strcpy(buf, "0");	/* easy special case */	} else {		register char *d, *e, *p;		/* start with 'e' format (it'll provide nice exponent) */		if (prec < 1) prec = 1;	    /* at least 1 significant digit */		(void) sprintf(buf, "%.*e", prec - 1, g);		if ((e = strchr(buf, 'e')) != 0) {	/* find exponent  */			int exp = atoi(e+1);		/* fetch exponent */			if (exp >= -4 && exp < prec) {	/* per K&R2, B1.2 */				/* switch to 'f' format and re-do */				prec -= (exp + 1);	/* decimal precision */				(void) sprintf(buf, "%.*f", prec, g);				e = buf + strlen(buf);			}			if ((d = strchr(buf, '.')) != 0) {				/* remove trailing zeroes and decimal point */				for (p = e; p > d && *--p == '0'; ) continue;				if (*p == '.') --p;				if (++p < e)	/* copy exponent and NUL */					while ((*p++ = *e++) != '\0') continue;			}		}	}	return buf;}#endif	/* GFMT_WORKAROUND */

⌨️ 快捷键说明

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