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 + -
显示快捷键?