run.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,035 行 · 第 1/2 页

C
1,035
字号
#ifndef lintstatic	char	*sccsid = "@(#)run.c	4.1	(ULTRIX)	7/17/90";#endif/************************************************************************ *									* *			Copyright (c) 1983,1989 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	10/10/85  David Metsky* 001 - Rewrote the routine 'format' to be more robust.  It no longer*	crashes when given precision or fieldwidth variables and it*	now handles incorrect printf statements with more error*	messages.  Also fixed spr ica-933 about changing records in*	a line and then writing it out right away.**	12/16/86 David Metsky* 002 - Made sure that getsval is called every time in the forth section*	of printf during calls to Xsprintf.  This is to fix a problem *	printing the NR variable and probably all pre-defined variables.**	3/30/87 David Metsky* 003 - Added two if statements that were removed by accident in version*	1.3.***	5/31/89	Tim N* 004 - Added field_num field of cell record to definition of nullval.*	Also added fix from 4.3-5 to wait before exiting if busy.**************************************************************************/#include "awk.def"#include "math.h"#include "awk.h"#include "stdio.h"#include "fcntl.h"#define RECSIZE BUFSIZ#define FILENUM	10struct{	FILE *fp;	int type;	char *fname;} files[FILENUM];FILE *popen();extern obj execute(), nodetoobj(), fieldel(), dopa2(), gettemp();#define PA2NUM	29int pairstack[PA2NUM], paircnt;node *winner = (node *)NULL;#define MAXTMP 20cell tmps[MAXTMP];static cell nullval ={EMPTY,EMPTY,0.0,NUM,0,0};obj	true	={ OBOOL, BTRUE, 0 };obj	false	={ OBOOL, BFALSE, 0 };run(){	register int i;	execute(winner);	/* Wait for children to complete if output to a pipe. */	for (i=0; i<FILENUM; i++)		if (files[i].fp && files[i].type == '|')			pclose(files[i].fp);}obj execute(u) node *u;{	register obj (*proc)();	obj x;	node *a;	extern char *printname[];	if (u==(node *)NULL)		return(true);	for (a = u; ; a = a->nnext) {		if (cantexec(a))			return(nodetoobj(a));		if (a->ntype==NPA2)			proc=dopa2;		else {			if (notlegal(a->nobj))				error(FATAL, "illegal statement %o", a);			proc = proctab[a->nobj-FIRSTTOKEN];		}		x = (*proc)(a->narg,a->nobj);		if (isfld(x)) fldbld();		if (isexpr(a))			return(x);		/* a statement, goto next statement */		if (isjump(x))			return(x);		if (a->nnext == (node *)NULL)			return(x);		tempfree(x);	}}obj program(a, n) node **a;{	obj x;	if (a[0] != NULL) {		x = execute(a[0]);		if (isexit(x))			return(true);		if (isjump(x))			error(FATAL, "unexpected break, continue or next");		tempfree(x);	}	while (getrec()) {		x = execute(a[1]);		if (isexit(x)) break;		tempfree(x);	}	tempfree(x);	if (a[2] != NULL) {		x = execute(a[2]);		if (isbreak(x) || isnext(x) || iscont(x))			error(FATAL, "unexpected break, continue or next");		tempfree(x);	}	return(true);}obj getline(){	obj x;	x = gettemp();	setfval(x.optr, (awkfloat) getrec());	return(x);}obj array(a,n) node **a;{	obj x, y;	extern obj arrayel();	x = execute(a[1]);	y = arrayel(a[0], x);	tempfree(x);	return(y);}obj arrayel(a,b) node *a; obj b;{	char *s;	cell *x;	int i;	obj y;	s = getsval(b.optr);	x = (cell *) a;	if (!(x->tval&ARR)) {		strfree(x->sval);		x->tval &= ~STR;		x->tval |= ARR;		x->sval = (char *) makesymtab();	}	y.optr = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval);	y.otype = OCELL;	y.osub = CVAR;	return(y);}obj matchop(a,n) node **a;{	obj x;	char *s;	int i;	x = execute(a[0]);	if (isstr(x)) s = x.optr->sval;	else	s = getsval(x.optr);	tempfree(x);	i = match(a[1], s);	if (n==MATCH && i==1 || n==NOTMATCH && i==0)		return(true);	else		return(false);}obj boolop(a,n) node **a;{	obj x, y;	int i;	x = execute(a[0]);	i = istrue(x);	tempfree(x);	switch (n) {	default:		error(FATAL, "unknown boolean operator %d", n);	case BOR:		if (i) return(true);		y = execute(a[1]);		i = istrue(y);		tempfree(y);		if (i) return(true);		else return(false);	case AND:		if ( !i ) return(false);		y = execute(a[1]);		i = istrue(y);		tempfree(y);		if (i) return(true);		else return(false);	case NOT:		if (i) return(false);		else return(true);	}}obj relop(a,n) node **a;{	int i;	obj x, y;	awkfloat j;	x = execute(a[0]);	y = execute(a[1]);	if (x.optr->tval&NUM && y.optr->tval&NUM) {		j = x.optr->fval - y.optr->fval;		i = j<0? -1: (j>0? 1: 0);	} else {		i = strcmp(getsval(x.optr), getsval(y.optr));	}	tempfree(x);	tempfree(y);	switch (n) {	default:		error(FATAL, "unknown relational operator %d", n);	case LT:	if (i<0) return(true);			else return(false);	case LE:	if (i<=0) return(true);			else return(false);	case NE:	if (i!=0) return(true);			else return(false);	case EQ:	if (i==0) return(true);			else return(false);	case GE:	if (i>=0) return(true);			else return(false);	case GT:	if (i>0) return(true);			else return(false);	}}tempfree(a) obj a;{	if (!istemp(a)) return;	strfree(a.optr->sval);	a.optr->tval = 0;}obj gettemp(){	int i;	obj x;	for (i=0; i<MAXTMP; i++)		if (tmps[i].tval==0)			break;	if (i==MAXTMP)		error(FATAL, "out of temporaries in gettemp");	x.optr = &tmps[i];	tmps[i] = nullval;	x.otype = OCELL;	x.osub = CTEMP;	return(x);}obj indirect(a,n) node **a;{	obj x;	int m;	cell *fieldadr();	x = execute(a[0]);	m = getfval(x.optr);	tempfree(x);	x.optr = fieldadr(m);	x.otype = OCELL;	x.osub = CFLD;	return(x);}obj substr(a, nnn) node **a;{	char *s, temp;	obj x;	int k, m, n;	x = execute(a[0]);	s = getsval(x.optr);	k = strlen(s) + 1;	tempfree(x);	x = execute(a[1]);	m = getfval(x.optr);	if (m <= 0)		m = 1;	else if (m > k)		m = k;	tempfree(x);	if (a[2] != nullstat) {		x = execute(a[2]);		n = getfval(x.optr);		tempfree(x);	}	else		n = k - 1;	if (n < 0)		n = 0;	else if (n > k - m)		n = k - m;	dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s);	x = gettemp();	if (s) {		temp = s[n+m-1];	/* with thanks to John Linderman */		s[n+m-1] = '\0';	}	setsval(x.optr, s + m - 1);	if (s) 		s[n+m-1] = temp;	return(x);}obj sindex(a, nnn) node **a;{	obj x;	char *s1, *s2, *p1, *p2, *q;	x = execute(a[0]);	s1 = getsval(x.optr);	tempfree(x);	x = execute(a[1]);	s2 = getsval(x.optr);	tempfree(x);	x = gettemp();	for (p1 = s1; *p1 != '\0'; p1++) {		for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)			;		if (*p2 == '\0') {			setfval(x.optr, (awkfloat) (p1 - s1 + 1));	/* origin 1 */			return(x);		}	}	setfval(x.optr, 0.0);	return(x);}char *format(s,a) char *s; node *a;{#define TRUE 1#define FALSE 0	char *buf, *p, fmt[200], *t, *os;	obj x;	int flag = 0;	awkfloat xf;	int VarFieldWidth = FALSE;	/* TRUE if fieldwith seen */	int VarPrecision = FALSE;	/* TRUE if precision seen */	int FieldWidth, Precision;	/* hold variable values */	int endloop;			/* loop variable *//* macro for Precision and FieldWidth printf expansion */#define Xsprintf(str,fmt,var)\	if (!VarFieldWidth)\		if (!VarPrecision) sprintf(str,fmt,(var));\		else sprintf(str,fmt,Precision,(var));\	else\		if (!VarPrecision) sprintf(str,fmt,FieldWidth,(var));\		else sprintf(str,fmt,FieldWidth,Precision,(var));	os = s;	p = buf = (char *)malloc(RECSIZE); /* buf,p hold complete line */	while (*s) {			/* loop until d,f,o,x,g or e seen */		if (*s != '%') {	/* handle all chars before % */			*p++ = *s++;			continue;		}		if (*(s+1) == '%') {	/* handle a double % */			*p++ = '%';			s += 2;			continue;		}		/* to get to here, s must now point to % */		t = fmt;		/* start buffer for sprintf call */		*t++ = *s++;		/* store the '%' */		endloop = TRUE;		while (endloop)			switch(*s){				case ' ':					s++;	/* throw away spaces */					break;				case '-':	/* optional left adjustment */					*t++ = *s++;	/* store '-' */					break;				case '#':	/* optional alternate form */					*t++ = *s++;	/* store '#' */					break;				case 'l':	/* long */					*t++ = *s++;	/* store 'l' */					break;				case '*':	/* precision or field width */					*t++ = *s++;	/* store '*' */					if (!VarPrecision){					    if (VarFieldWidth)						error(FATAL,"More than one fieldwidth definition in printf(%s)",os);					    VarFieldWidth = TRUE;					    if (a == NULL)						error(FATAL,"Not enough arguments in printf(%s)",os);					    x = execute(a);					    FieldWidth = getfval(x.optr);					    a = a->nnext;					}					else{					    if (a == NULL)						error(FATAL,"Not enough arguments in printf(%s)",os);					    x = execute(a);					    Precision = getfval(x.optr);					    a = a->nnext;					}					break;						case '0': case '1': case '2':				case '3': case '4': case '5':				case '6': case '7':				case '8': case '9':					*t++ = *s++;					if (VarPrecision)						VarPrecision = FALSE;					break;				case '.':	/* precision */					if (VarPrecision)						error(FATAL,"More than one fieldwidth definition in printf(%s)",os);					*t++ = *s++;	 /* store '.' */					VarPrecision = TRUE;					break;				default:					*t = '\0';					if (t >= fmt + sizeof(fmt))						printf("format item %.20s... too long", os);					endloop = FALSE;					break;			}/* the next characters are either conversion types or literal chars */		switch (*s) {		case 'f': case 'e': case 'g':			flag = 1;			*t++ = *s++;			break;		case 'd': case 'o': case 'x':			flag = 2;			*t++ = *s++;			break;		case 'c':			flag = 3;			*t++ = *s++;			break;		case 's':			flag = 4;			*t++ = *s++;			break;		default:			flag = 0;			for(t=fmt;((*s) && (*s != '%'));*t++ = *s++);			break;		}

⌨️ 快捷键说明

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