Cell *awkgetline(Node **a, int n) /* get next line from specific input */ { /* a[0] is variable, a[1] is operator, a[2] is filename */ Cell *r, *x; extern Cell **fldtab; FILE *fp; char *buf; int bufsize = recsize; int mode; if ((buf = (char *) malloc(bufsize)) == NULL) FATAL("out of memory in getline"); fflush(stdout); /* in case someone is waiting for a prompt */ r = gettemp(); if (a[1] != NULL) { /* getline < file */ x = execute(a[2]); /* filename */ mode = ptoi(a[1]); if (mode == '|') /* input pipe */ mode = LE; /* arbitrary flag */ fp = openfile(mode, getsval(x)); tempfree(x); if (fp == NULL) n = -1; else n = readrec(&buf, &bufsize, fp); if (n <= 0) { ; } else if (a[0] != NULL) { /* getline var <file */ x = execute(a[0]); setsval(x, buf); tempfree(x); } else { /* getline <file */ setsval(fldtab[0], buf); if (is_number(fldtab[0]->sval)) { fldtab[0]->fval = atof(fldtab[0]->sval); fldtab[0]->tval |= NUM; } } } else { /* bare getline; use current input */ if (a[0] == NULL) /* getline */ n = getrec(&record, &recsize, 1); else { /* getline var */ n = getrec(&buf, &bufsize, 0); x = execute(a[0]); setsval(x, buf); tempfree(x); } } setfval(r, (Awkfloat) n); free(buf); return r; }
Cell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */ { Cell *x, *vp, *arrayp, *cp, *ncp; Array *tp; int i; vp = execute(a[0]); arrayp = execute(a[1]); if (!isarr(arrayp)) { return true; } tp = (Array *) arrayp->sval; tempfree(arrayp); for (i = 0; i < tp->size; i++) { /* this routine knows too much */ for (cp = tp->tab[i]; cp != NULL; cp = ncp) { setsval(vp, cp->nval); ncp = cp->cnext; x = execute(a[2]); if (isbreak(x)) { tempfree(vp); return true; } if (isnext(x) || isexit(x) || isret(x)) { tempfree(vp); return(x); } tempfree(x); } } return true; }
Cell *substr(Node **a, int nnn) /* substr(a[0], a[1], a[2]) */ { int k, m, n; char *s; int temp; Cell *x, *y, *z = 0; x = execute(a[0]); y = execute(a[1]); if (a[2] != 0) z = execute(a[2]); s = getsval(x); k = strlen(s) + 1; if (k <= 1) { tempfree(x); tempfree(y); if (a[2] != 0) { tempfree(z); } x = gettemp(); setsval(x, ""); return(x); } m = (int) getfval(y); if (m <= 0) m = 1; else if (m > k) m = k; tempfree(y); if (a[2] != 0) { n = (int) getfval(z); tempfree(z); } 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) ); y = gettemp(); temp = s[n+m-1]; /* with thanks to John Linderman */ s[n+m-1] = '\0'; setsval(y, s + m - 1); s[n+m-1] = temp; tempfree(x); return(y); }
Cell *sub(Node **a, int nnn) /* substitute command */ { char *sptr, *pb, *q; Cell *x, *y, *result; char *t, *buf; fa *pfa; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in sub"); x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ result = False; if (pmatch(pfa, t)) { sptr = t; adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); pb = buf; while (sptr < patbeg) *pb++ = *sptr++; sptr = getsval(y); while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } *pb = '\0'; if (pb > buf + bufsz) FATAL("sub result1 %.30s too big; can't happen", buf); sptr = patbeg + patlen; if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); while ((*pb++ = *sptr++) != 0) ; } if (pb > buf + bufsz) FATAL("sub result2 %.30s too big; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy */ result = True;; } tempfree(x); tempfree(y); free(buf); return result; }
void proj2D(struct data *d) { char seqcon[6]; /* For 2D projections we fake the data is 2D and recon accordingly */ /* Get the seqcon */ strcpy(seqcon,*sval("seqcon",&d->p)); /* ROxPE projection has profile='ny' */ if (spar(d,"profile","ny")) { /* Adjust seqcon for 2D */ seqcon[3]='n'; setsval(&d->p,"seqcon",seqcon); setseqmode(d); default2D(d); } /* ROxPE2 projection has profile='yn' */ if (spar(d,"profile","yn")) { /* Adjust seqcon for 2D */ seqcon[2]=seqcon[3]; seqcon[3]='n'; setsval(&d->p,"seqcon",seqcon); setval(&d->p,"nv",d->nv2); setval(&d->p,"nseg",d->nv2); setval(&d->p,"etl",1); setval(&d->p,"pelist",0); setval(&d->p,"nv2",1); setsval(&d->p,"apptype","im2D"); setdatapars(d); setseqmode(d); /* The following is required to be able to graphically plan on the output images: thk = lpe lpe = lpe2 ppe of each slice in turn = pss of each slice in turn psi, phi, theta need to be corrected (90 degree rotation about readout axis) */ /* For now just adjust FOV and offset for centre of slice(s) */ setval(&d->p,"thk",*val("lpe",&d->p)); setval(&d->p,"lpe",*val("lpe2",&d->p)); setval(&d->p,"ppe",*val("pss0",&d->p)); default2D(d); } }
Cell *getline(Node **a, int n) /* get next line from specific input */ { /* a[0] is variable, a[1] is operator, a[2] is filename */ Cell *r, *x; char buf[RECSIZE]; FILE *fp; fflush(stdout); /* in case someone is waiting for a prompt */ r = gettemp(); if (a[1] != NULL) { /* getline < file */ x = execute(a[2]); /* filename */ if ((int) a[1] == '|') /* input pipe */ a[1] = (Node *) LE; /* arbitrary flag */ fp = openfile((int) a[1], getsval(x)); tempfree(x); if (fp == NULL) n = -1; else n = readrec(buf, sizeof(buf), fp); if (n <= 0) { ; } else if (a[0] != NULL) { /* getline var <file */ setsval(execute(a[0]), buf); } else { /* getline <file */ if (!(recloc->tval & DONTFREE)) xfree(recloc->sval); strcpy(record, buf); recloc->sval = record; recloc->tval = REC | STR | DONTFREE; if (isnumber(recloc->sval)) { recloc->fval = atof(recloc->sval); recloc->tval |= NUM; } donerec = 1; donefld = 0; } } else { /* bare getline; use current input */ if (a[0] == NULL) /* getline */ n = getrec(record); else { /* getline var */ n = getrec(buf); setsval(execute(a[0]), buf); } } setfval(r, (Awkfloat) n); return r; }
Cell *jump(Node **a, int n) /* break, continue, next, nextfile, return */ { Cell *y; switch (n) { case EXIT: if (a[0] != NULL) { y = execute(a[0]); errorflag = getfval(y); tempfree(y); } longjmp(env, 1); case RETURN: if (a[0] != NULL) { y = execute(a[0]); if ((y->tval & (STR|NUM)) == (STR|NUM)) { setsval(fp->retval, getsval(y)); fp->retval->fval = getfval(y); fp->retval->tval |= NUM; } else if (y->tval & STR) setsval(fp->retval, getsval(y)); else if (y->tval & NUM) setfval(fp->retval, getfval(y)); else /* can't happen */ ERROR "bad type variable %d", y->tval FATAL; tempfree(y); } return(jret); case NEXT: return(jnext); case NEXTFILE: nextfile(); return(jnextfile); case BREAK: return(jbreak); case CONTINUE: return(jcont); default: /* can't happen */ ERROR "illegal jump type %d", n FATAL; } return 0; /* not reached */ }
void setclvar(char *s) /* set var=value from s */ { char *p; cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; q = setsymtab(s, tostring(p), 0.0, STR, symtab); setsval(q, p); dprintf("command line set %s to |%s|\n", s, p); }
Cell *sub(Node **a, int nnn) /* substitute command */ { register uchar *sptr, *pb, *q; register Cell *x, *y, *result; uchar buf[SUBSIZE], *t; fa *pfa; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ result = false; if (pmatch(pfa, t)) { pb = buf; sptr = t; while (sptr < patbeg) *pb++ = *sptr++; sptr = getsval(y); while (*sptr != 0 && pb < buf + SUBSIZE - 1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; /* skip \, */ *pb++ = *sptr++; /* add & */ } else if (*sptr == '&') { sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; *pb = '\0'; if (pb >= buf + SUBSIZE) ERROR "sub() result %30s too big", buf FATAL; sptr = patbeg + patlen; if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) while (*pb++ = *sptr++) ; if (pb >= buf + SUBSIZE) ERROR "sub() result %.30s too big", buf FATAL; setsval(x, buf); result = true;; } tempfree(x); tempfree(y); return result; }
void setclvar(unsigned char *s) /* set var=value from s */ { unsigned char *p; Cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; p = qstring(p, '\0'); q = setsymtab(s, p, 0.0, STR, symtab); setsval(q, p); (void)is2number(0, q); dprintf( ("command line set %s to |%s|\n", s, p) ); }
void initgetrec(void) { int i; char *p; for (i = 1; i < *ARGC; i++) { if (!isclvar(p = getargv(i))) { /* find 1st real filename */ setsval(lookup("FILENAME", symtab), getargv(i)); return; } setclvar(p); /* a commandline assignment before filename */ argno++; } infile = stdin; /* no filenames, so use stdin */ }
void setclvar(char *s) /* set var=value from s */ { char *p; Cell *q; for (p=s; *p != '='; p++) ; *p++ = 0; p = qstring(p, '\0'); q = setsymtab(s, p, 0.0, STR, symtab); setsval(q, p); if (is_number(q->sval)) { q->fval = atof(q->sval); q->tval |= NUM; } dprintf( ("command line set %s to |%s|\n", s, p) ); }
void initgetrec(void) { int i; char *p; for (i = 1; i < *ARGC; i++) { p = getargv(i); /* find 1st real filename */ if (p == NULL || *p == '\0') { /* deleted or zapped */ argno++; continue; } if (!isclvar(p)) { setsval(lookup("FILENAME", symtab), p); return; } setclvar(p); /* a commandline assignment before filename */ argno++; } infile = stdin; /* no filenames, so use stdin */ }
void arginit(int ac, uchar *av[]) { Cell *cp; int i; uchar temp[5]; for (i = 1; i < ac; i++) /* first make FILENAME first real argument */ if (!isclvar(av[i])) { setsval(lookup("FILENAME", symtab), av[i]); break; } ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval; cp = setsymtab("ARGV", "", 0.0, ARR, symtab); ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */ cp->sval = (uchar *) ARGVtab; for (i = 0; i < ac; i++) { sprintf((char *)temp, "%d", i); if (isnumber(*av)) setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab); else setsymtab(temp, *av, 0.0, STR, ARGVtab); av++; } }
Cell *gsub(Node **a, int nnn) /* global substitute */ { register Cell *x, *y; register uchar *rptr, *sptr, *t, *pb; uchar buf[SUBSIZE]; register fa *pfa; int mflag, tempstat, num; mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; pb = buf; rptr = getsval(y); do { /* uchar *p; int i; printf("target string: %s, *patbeg = %o, patlen = %d\n", t, *patbeg, patlen); printf(" match found: "); p=patbeg; for (i=0; i<patlen; i++) printf("%c", *p++); printf("\n"); */ if (patlen == 0 && *patbeg != 0) { /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; while (*sptr != 0 && pb < buf + SUBSIZE-1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; *pb++ = *sptr++; } else if (*sptr == '&') { uchar *q; sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } if (*t == 0) /* at end */ goto done; *pb++ = *t++; if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; mflag = 0; } else { /* matched nonempty string */ num++; sptr = t; while (sptr < patbeg && pb < buf + SUBSIZE-1) *pb++ = *sptr++; sptr = rptr; while (*sptr != 0 && pb < buf + SUBSIZE-1) if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; *pb++ = *sptr++; } else if (*sptr == '&') { uchar *q; sptr++; for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; t = patbeg + patlen; if ((*(t-1) == 0) || (*t == 0)) goto done; if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; mflag = 1; } } while (pmatch(pfa,t)); sptr = t; while (*pb++ = *sptr++) ; done: if (pb >= buf + SUBSIZE-1) ERROR "gsub() result %.30s too big", buf FATAL; *pb = '\0'; setsval(x, buf); pfa->initstat = tempstat; } tempfree(x); tempfree(y); x = gettemp(); x->tval = NUM; x->fval = num; return(x); }
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ { Cell *x, *y; Awkfloat u; int t; Awkfloat tmp; char *p, *buf; Node *nextarg; FILE *fp; void flush_all(void); t = ptoi(a[0]); x = execute(a[1]); nextarg = a[1]->nnext; switch (t) { case FLENGTH: if (isarr(x)) u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ else u = strlen(getsval(x)); break; case FLOG: u = errcheck(log(getfval(x)), "log"); break; case FINT: modf(getfval(x), &u); break; case FEXP: u = errcheck(exp(getfval(x)), "exp"); break; case FSQRT: u = errcheck(sqrt(getfval(x)), "sqrt"); break; case FSIN: u = sin(getfval(x)); break; case FCOS: u = cos(getfval(x)); break; case FATAN: if (nextarg == 0) { WARNING("atan2 requires two arguments; returning 1.0"); u = 1.0; } else { y = execute(a[1]->nnext); u = atan2(getfval(x), getfval(y)); tempfree(y); nextarg = nextarg->nnext; } break; case FSYSTEM: fflush(stdout); /* in case something is buffered already */ u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ break; case FRAND: /* in principle, rand() returns something in 0..RAND_MAX */ u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; break; case FSRAND: if (isrec(x)) /* no argument provided */ u = time((time_t *)0); else u = getfval(x); tmp = u; srand((unsigned int) u); u = srand_seed; srand_seed = tmp; break; case FTOUPPER: case FTOLOWER: buf = tostring(getsval(x)); if (t == FTOUPPER) { for (p = buf; *p; p++) if (islower((uschar) *p)) *p = toupper((uschar)*p); } else { for (p = buf; *p; p++) if (isupper((uschar) *p)) *p = tolower((uschar)*p); } tempfree(x); x = gettemp(); setsval(x, buf); free(buf); return x; case FFLUSH: if (isrec(x) || strlen(getsval(x)) == 0) { flush_all(); /* fflush() or fflush("") -> all */ u = 0; } else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) u = EOF; else u = fflush(fp); break; default: /* can't happen */ FATAL("illegal function type %d", t); break; } tempfree(x); x = gettemp(); setfval(x, u); if (nextarg != 0) { WARNING("warning: function has too many arguments"); for ( ; nextarg; nextarg = nextarg->nnext) execute(nextarg); } return(x); }
Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ { /* this is subtle; don't muck with it. */ Cell *x, *y; Awkfloat xf, yf; double v; y = execute(a[1]); x = execute(a[0]); if (n == ASSIGN) { /* ordinary assignment */ if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */ ; /* leave alone unless it's a field */ else if ((y->tval & (STR|NUM)) == (STR|NUM)) { setsval(x, getsval(y)); x->fval = getfval(y); x->tval |= NUM; } else if (y->tval & STR) setsval(x, getsval(y)); else if (y->tval & NUM) setfval(x, getfval(y)); else funnyvar(y, "read value of"); tempfree(y); return(x); } xf = getfval(x); yf = getfval(y); switch (n) { case ADDEQ: xf += yf; break; case SUBEQ: xf -= yf; break; case MULTEQ: xf *= yf; break; case DIVEQ: if (yf == 0) ERROR "division by zero in /=" FATAL; xf /= yf; break; case MODEQ: if (yf == 0) ERROR "division by zero in %%=" FATAL; modf(xf/yf, &v); xf = xf - yf * v; break; case POWEQ: if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ xf = ipow(xf, (int) yf); else xf = errcheck(pow(xf, yf), "pow"); break; default: ERROR "illegal assignment operator %d", n FATAL; break; } tempfree(y); setfval(x, xf); return(x); }
Cell *gsub(Node **a, int nnn) /* global substitute */ { Cell *x, *y; char *rptr, *sptr, *t, *pb, *q; char *buf; fa *pfa; int mflag, tempstat, num; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in gsub"); mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; pb = buf; rptr = getsval(y); do { if (patlen == 0 && *patbeg != 0) { /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } } if (*t == 0) /* at end */ goto done; adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); *pb++ = *t++; if (pb > buf + bufsz) /* BUG: not sure of this test */ FATAL("gsub result0 %.30s too big; can't happen", buf); mflag = 0; } else { /* matched nonempty string */ num++; sptr = t; adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); while (sptr < patbeg) *pb++ = *sptr++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } t = patbeg + patlen; if (patlen == 0 || *t == 0 || *(t-1) == 0) goto done; if (pb > buf + bufsz) FATAL("gsub result1 %.30s too big; can't happen", buf); mflag = 1; } } while (pmatch(pfa,t)); sptr = t; adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); while ((*pb++ = *sptr++) != 0) ; done: if (pb < buf + bufsz) *pb = '\0'; else if (*(pb-1) != '\0') FATAL("gsub result2 %.30s truncated; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy + free */ pfa->initstat = tempstat; } tempfree(x); tempfree(y); x = gettemp(); x->tval = NUM; x->fval = num; free(buf); return(x); }
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ { register Cell *x, *y; Awkfloat u; register int t; uchar *p, buf[RECSIZE]; Node *nextarg; FILE *fp; t = (int) a[0]; x = execute(a[1]); nextarg = a[1]->nnext; switch (t) { case FLENGTH: u = strlen(getsval(x)); break; case FLOG: u = errcheck(log(getfval(x)), "log"); break; case FINT: modf(getfval(x), &u); break; case FEXP: u = errcheck(exp(getfval(x)), "exp"); break; case FSQRT: u = errcheck(sqrt(getfval(x)), "sqrt"); break; case FSIN: u = sin(getfval(x)); break; case FCOS: u = cos(getfval(x)); break; case FATAN: if (nextarg == 0) { ERROR "atan2 requires two arguments; returning 1.0" WARNING; u = 1.0; } else { y = execute(a[1]->nnext); u = atan2(getfval(x), getfval(y)); tempfree(y); nextarg = nextarg->nnext; } break; case FSYSTEM: fflush(stdout); /* in case something is buffered already */ u = (Awkfloat) system((char *)getsval(x)) / 256; /* 256 is unix-dep */ break; case FRAND: /* in principle, rand() returns something in 0..RAND_MAX */ u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; break; case FSRAND: if (x->tval & REC) /* no argument provided */ u = time((long *)0); else u = getfval(x); srand((int) u); u = (int) u; break; case FTOUPPER: case FTOLOWER: strcpy(buf, getsval(x)); if (t == FTOUPPER) { for (p = buf; *p; p++) if (islower(*p)) *p = toupper(*p); } else { for (p = buf; *p; p++) if (isupper(*p)) *p = tolower(*p); } tempfree(x); x = gettemp(); setsval(x, buf); return x; case FFLUSH: if ((fp = openfile(GT, getsval(x))) == NULL) u = EOF; else u = fflush(fp); break; default: /* can't happen */ ERROR "illegal function type %d", t FATAL; break; } tempfree(x); x = gettemp(); setfval(x, u); if (nextarg != 0) { ERROR "warning: function has too many arguments" WARNING; for ( ; nextarg; nextarg = nextarg->nnext) execute(nextarg); } return(x); }