1ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/**************************************************************** 2ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCopyright (C) Lucent Technologies 1997 3ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerAll Rights Reserved 4ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 5ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerPermission to use, copy, modify, and distribute this software and 6ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerits documentation for any purpose and without fee is hereby 7ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnergranted, provided that the above copyright notice appear in all 8ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnercopies and that both that the copyright notice and this 9ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerpermission notice and warranty disclaimer appear in supporting 10ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerdocumentation, and that the name Lucent Technologies or any of 11ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerits entities not be used in advertising or publicity pertaining 12ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerto distribution of the software without specific, written prior 13ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerpermission. 14ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 15ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerTHIS SOFTWARE. 23ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner****************************************************************/ 24ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 25ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#define DEBUG 26ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <stdio.h> 27ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <ctype.h> 28ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <setjmp.h> 29ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <limits.h> 30ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <math.h> 31ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <string.h> 32ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <stdlib.h> 33ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include <time.h> 34ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include "awk.h" 35ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#include "ytab.h" 36ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 37ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#define tempfree(x) if (istemp(x)) tfree(x); else 38ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 39ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* 40ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#undef tempfree 41ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 42ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid tempfree(Cell *p) { 43ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (p->ctype == OCELL && (p->csub < CUNK || p->csub > CFREE)) { 44ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING("bad csub %d in Cell %d %s", 45ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner p->csub, p->ctype, p->sval); 46ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 47ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istemp(p)) 48ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tfree(p); 49ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 50ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner*/ 51ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 52ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* do we really need these? */ 53ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #ifdef _NFILE */ 54ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #ifndef FOPEN_MAX */ 55ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #define FOPEN_MAX _NFILE */ 56ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #endif */ 57ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #endif */ 58ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* */ 59ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #ifndef FOPEN_MAX */ 60ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #define FOPEN_MAX 40 */ /* max number of open files */ 61ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #endif */ 62ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* */ 63ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #ifndef RAND_MAX */ 64ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #define RAND_MAX 32767 */ /* all that ansi guarantees */ 65ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* #endif */ 66ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 67ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerjmp_buf env; 68ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerextern int pairstack[]; 69ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 70ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerNode *winner = NULL; /* root of parse tree */ 71ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *tmps; /* free temporary cells for execution */ 72ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 73ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; 74ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *True = &truecell; 75ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; 76ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *False = &falsecell; 77ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; 78ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jbreak = &breakcell; 79ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; 80ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jcont = &contcell; 81ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM }; 82ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jnext = &nextcell; 83ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell nextfilecell ={ OJUMP, JNEXTFILE, 0, 0, 0.0, NUM }; 84ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jnextfile = &nextfilecell; 85ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM }; 86ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jexit = &exitcell; 87ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM }; 88ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jret = &retcell; 89ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstatic Cell tempcell ={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE }; 90ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 91ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerNode *curnode = NULL; /* the node being executed, for debugging */ 92ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 93ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* buffer memory management */ 94ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerint adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, 95ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner const char *whatrtn) 96ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner/* pbuf: address of pointer to buffer being managed 97ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * psiz: address of buffer size variable 98ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * minlen: minimum length of buffer needed 99ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * quantum: buffer size quantum 100ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * pbptr: address of movable pointer into buffer, or 0 if none 101ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * whatrtn: name of the calling routine if failure should cause fatal error 102ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * 103ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner * return 0 for realloc failure, !=0 for success 104ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner */ 105ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 106ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (minlen > *psiz) { 107ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *tbuf; 108ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int rminlen = quantum ? minlen % quantum : 0; 109ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int boff = pbptr ? *pbptr - *pbuf : 0; 110ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* round up to next multiple of quantum */ 111ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (rminlen) 112ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner minlen += quantum - rminlen; 113ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tbuf = (char *) realloc(*pbuf, minlen); 114ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) ); 115ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (tbuf == NULL) { 116ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (whatrtn) 117ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in %s", whatrtn); 118ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 0; 119ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 120ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pbuf = tbuf; 121ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *psiz = minlen; 122ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pbptr) 123ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pbptr = tbuf + boff; 124ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 125ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 1; 126ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 127ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 128ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid run(Node *a) /* execution of parse tree starts here */ 129ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 130ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner extern void stdinit(void); 131ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 132ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stdinit(); 133ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner execute(a); 134ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner closeall(); 135ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 136ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 137ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *execute(Node *u) /* execute a node of the parse tree */ 138ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 139ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *(*proc)(Node **, int); 140ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 141ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *a; 142ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 143ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (u == NULL) 144ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 145ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (a = u; ; a = a->nnext) { 146ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner curnode = a; 147ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isvalue(a)) { 148ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = (Cell *) (a->narg[0]); 149ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isfld(x) && !donefld) 150ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fldbld(); 151ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (isrec(x) && !donerec) 152ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner recbld(); 153ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 154ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 155ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */ 156ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal statement"); 157ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner proc = proctab[a->nobj-FIRSTTOKEN]; 158ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = (*proc)(a->narg, a->nobj); 159ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isfld(x) && !donefld) 160ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fldbld(); 161ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (isrec(x) && !donerec) 162ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner recbld(); 163ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isexpr(a)) 164ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 165ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isjump(x)) 166ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 167ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a->nnext == NULL) 168ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 169ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 170ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 171ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 172ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 173ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 174ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *program(Node **a, int n) /* execute an awk program */ 175ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ /* a[0] = BEGIN, a[1] = body, a[2] = END */ 176ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 177ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 178ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (setjmp(env) != 0) 179ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner goto ex; 180ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0]) { /* BEGIN */ 181ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 182ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isexit(x)) 183ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 184ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isjump(x)) 185ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal break, continue, next or nextfile from BEGIN"); 186ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 187ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 188ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] || a[2]) 189ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (getrec(&record, &recsize, 1) > 0) { 190ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 191ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isexit(x)) 192ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 193ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 194ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 195ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ex: 196ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (setjmp(env) != 0) /* handles exit within END */ 197ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner goto ex1; 198ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2]) { /* END */ 199ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 200ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isbreak(x) || isnext(x) || iscont(x)) 201ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal break, continue, next or nextfile from END"); 202ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 203ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 204ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ex1: 205ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 206ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 207ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 208ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstruct Frame { /* stack frame for awk function calls */ 209ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int nargs; /* number of arguments in this call */ 210ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *fcncell; /* pointer to Cell for function */ 211ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell **args; /* pointer to array of arguments after execute */ 212ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *retval; /* return value */ 213ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner}; 214ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 215ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#define NARGS 50 /* max args in a call */ 216ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 217ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstruct Frame *frame = NULL; /* base of stack frames; dynamically allocated */ 218ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerint nframe = 0; /* number of frames allocated */ 219ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstruct Frame *fp = NULL; /* frame pointer. bottom level unused */ 220ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 221ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *call(Node **a, int n) /* function call. very kludgy and fragile */ 222ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 223ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE }; 224ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i, ncall, ndef; 225ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */ 226ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *x; 227ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *args[NARGS], *oargs[NARGS]; /* BUG: fixed size arrays */ 228ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *y, *z, *fcn; 229ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 230ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 231ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fcn = execute(a[0]); /* the function itself */ 232ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = fcn->nval; 233ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!isfcn(fcn)) 234ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("calling undefined function %s", s); 235ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (frame == NULL) { 236ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); 237ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (frame == NULL) 238ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of space for stack frames calling %s", s); 239ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 240ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ 241ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ncall++; 242ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ndef = (int) fcn->fval; /* args in defn */ 243ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) ); 244ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ncall > ndef) 245ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING("function %s called with %d args, uses only %d", 246ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s, ncall, ndef); 247ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ncall + ndef > NARGS) 248ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS); 249ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ 250ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) ); 251ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(x); 252ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner oargs[i] = y; 253ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("args[%d]: %s %f <%s>, t=%o\n", 254ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) ); 255ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isfcn(y)) 256ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("can't use function %s as argument in %s", y->nval, s); 257ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isarr(y)) 258ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner args[i] = y; /* arrays by ref */ 259ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 260ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner args[i] = copycell(y); 261ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 262ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 263ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for ( ; i < ndef; i++) { /* add null args for ones not provided */ 264ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner args[i] = gettemp(); 265ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *args[i] = newcopycell; 266ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 267ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp++; /* now ok to up frame */ 268ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fp >= frame + nframe) { 269ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int dfp = fp - frame; /* old index */ 270ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner frame = (struct Frame *) 271ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner realloc((char *) frame, (nframe += 100) * sizeof(struct Frame)); 272ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (frame == NULL) 273ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of space for stack frames in %s", s); 274ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = frame + dfp; 275ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 276ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->fcncell = fcn; 277ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->args = args; 278ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->nargs = ndef; /* number defined with (excess are locals) */ 279ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->retval = gettemp(); 280ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 281ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) ); 282ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute((Node *)(fcn->sval)); /* execute body */ 283ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) ); 284ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 285ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < ndef; i++) { 286ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *t = fp->args[i]; 287ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isarr(t)) { 288ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (t->csub == CCOPY) { 289ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i >= ncall) { 290ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner freesymtab(t); 291ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t->csub = CTEMP; 292ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(t); 293ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 294ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner oargs[i]->tval = t->tval; 295ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner oargs[i]->tval &= ~(STR|NUM|DONTFREE); 296ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner oargs[i]->sval = t->sval; 297ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(t); 298ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 299ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 300ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (t != y) { /* kludge to prevent freeing twice */ 301ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t->csub = CTEMP; 302ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(t); 303ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (t == y && t->csub == CCOPY) { 304ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t->csub = CTEMP; 305ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(t); 306ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner freed = 1; 307ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 308ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 309ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(fcn); 310ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isexit(y) || isnext(y)) 311ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return y; 312ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (freed == 0) { 313ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); /* don't free twice! */ 314ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 315ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = fp->retval; /* return value */ 316ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) ); 317ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp--; 318ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 319ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 320ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 321ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *copycell(Cell *x) /* make a copy of a cell in a temp */ 322ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 323ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *y; 324ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 325ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = gettemp(); 326ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y->csub = CCOPY; /* prevents freeing until call is over */ 327ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y->nval = x->nval; /* BUG? */ 328ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isstr(x)) 329ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y->sval = tostring(x->sval); 330ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y->fval = x->fval; 331ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */ 332ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* is DONTFREE right? */ 333ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return y; 334ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 335ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 336ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *arg(Node **a, int n) /* nth argument of a function */ 337ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 338ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 339ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = ptoi(a[0]); /* argument number, counting from 0 */ 340ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) ); 341ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n+1 > fp->nargs) 342ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("argument #%d of function %s was not supplied", 343ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n+1, fp->fcncell->nval); 344ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return fp->args[n]; 345ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 346ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 347ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *jump(Node **a, int n) /* break, continue, next, nextfile, return */ 348ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 349ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *y; 350ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 351ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (n) { 352ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case EXIT: 353ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] != NULL) { 354ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[0]); 355ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner errorflag = (int) getfval(y); 356ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 357ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 358ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner longjmp(env, 1); 359ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case RETURN: 360ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] != NULL) { 361ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[0]); 362ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((y->tval & (STR|NUM)) == (STR|NUM)) { 363ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(fp->retval, getsval(y)); 364ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->retval->fval = getfval(y); 365ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp->retval->tval |= NUM; 366ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 367ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (y->tval & STR) 368ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(fp->retval, getsval(y)); 369ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (y->tval & NUM) 370ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(fp->retval, getfval(y)); 371ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else /* can't happen */ 372ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("bad type variable %d", y->tval); 373ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 374ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 375ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(jret); 376ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case NEXT: 377ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(jnext); 378ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case NEXTFILE: 379ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner nextfile(); 380ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(jnextfile); 381ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case BREAK: 382ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(jbreak); 383ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case CONTINUE: 384ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(jcont); 385ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: /* can't happen */ 386ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal jump type %d", n); 387ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 388ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 0; /* not reached */ 389ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 390ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 391ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *getline(Node **a, int n) /* get next line from specific input */ 392ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ /* a[0] is variable, a[1] is operator, a[2] is filename */ 393ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *r, *x; 394ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner extern Cell **fldtab; 395ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 396ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 397ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsize = recsize; 398ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int mode; 399ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 400ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsize)) == NULL) 401ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in getline"); 402ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 403ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(stdout); /* in case someone is waiting for a prompt */ 404ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner r = gettemp(); 405ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] != NULL) { /* getline < file */ 406ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); /* filename */ 407ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mode = ptoi(a[1]); 408ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (mode == '|') /* input pipe */ 409ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mode = LE; /* arbitrary flag */ 410ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = openfile(mode, getsval(x)); 411ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 412ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fp == NULL) 413ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = -1; 414ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 415ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = readrec(&buf, &bufsize, fp); 416ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n <= 0) { 417ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ; 418ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a[0] != NULL) { /* getline var <file */ 419ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 420ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, buf); 421ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 422ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { /* getline <file */ 423ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(fldtab[0], buf); 424ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (is_number(fldtab[0]->sval)) { 425ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fldtab[0]->fval = atof(fldtab[0]->sval); 426ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fldtab[0]->tval |= NUM; 427ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 428ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 429ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { /* bare getline; use current input */ 430ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] == NULL) /* getline */ 431ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = getrec(&record, &recsize, 1); 432ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { /* getline var */ 433ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = getrec(&buf, &bufsize, 0); 434ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 435ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, buf); 436ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 437ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 438ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 439ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(r, (Awkfloat) n); 440ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 441ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return r; 442ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 443ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 444ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *getnf(Node **a, int n) /* get NF */ 445ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 446ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (donefld == 0) 447ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fldbld(); 448ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return (Cell *) a[0]; 449ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 450ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 451ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ 452ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 453ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *z; 454ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 455ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *np; 456ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 457ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz = recsize; 458ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int nsub = strlen(*SUBSEP); 459ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 460ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 461ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in array"); 462ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 463ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); /* Cell* for symbol table */ 464ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf[0] = 0; 465ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (np = a[1]; np; np = np->nnext) { 466ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(np); /* subscript */ 467ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(y); 468ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array")) 469ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory for %s[%s...]", x->nval, buf); 470ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, s); 471ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (np->nnext) 472ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, *SUBSEP); 473ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 474ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 475ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!isarr(x)) { 476ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("making %s into an array\n", NN(x->nval)) ); 477ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (freeable(x)) 478ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xfree(x->sval); 479ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval &= ~(STR|NUM|DONTFREE); 480ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval |= ARR; 481ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->sval = (char *) makesymtab(NSYMTAB); 482ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 483ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval); 484ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z->ctype = OCELL; 485ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z->csub = CVAR; 486ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 487ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 488ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 489ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 490ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 491ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ 492ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 493ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 494ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *np; 495ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 496ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int nsub = strlen(*SUBSEP); 497ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 498ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); /* Cell* for symbol table */ 499ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!isarr(x)) 500ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 501ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] == 0) { /* delete the elements, not the table */ 502ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner freesymtab(x); 503ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval &= ~STR; 504ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval |= ARR; 505ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->sval = (char *) makesymtab(NSYMTAB); 506ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 507ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz = recsize; 508ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 509ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 510ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in adelete"); 511ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf[0] = 0; 512ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (np = a[1]; np; np = np->nnext) { 513ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(np); /* subscript */ 514ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(y); 515ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete")) 516ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory deleting %s[%s...]", x->nval, buf); 517ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, s); 518ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (np->nnext) 519ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, *SUBSEP); 520ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 521ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 522ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner freeelem(x, buf); 523ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 524ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 525ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 526ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 527ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 528ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 529ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ 530ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 531ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *ap, *k; 532ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *p; 533ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 534ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 535ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz = recsize; 536ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int nsub = strlen(*SUBSEP); 537ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 538ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap = execute(a[1]); /* array name */ 539ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!isarr(ap)) { 540ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("making %s into an array\n", ap->nval) ); 541ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (freeable(ap)) 542ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xfree(ap->sval); 543ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->tval &= ~(STR|NUM|DONTFREE); 544ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->tval |= ARR; 545ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->sval = (char *) makesymtab(NSYMTAB); 546ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 547ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) { 548ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in intest"); 549ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 550ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf[0] = 0; 551ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (p = a[0]; p; p = p->nnext) { 552ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(p); /* expr */ 553ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(x); 554ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest")) 555ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory deleting %s[%s...]", x->nval, buf); 556ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, s); 557ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 558ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (p->nnext) 559ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcat(buf, *SUBSEP); 560ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 561ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner k = lookup(buf, (Array *) ap->sval); 562ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(ap); 563ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 564ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (k == NULL) 565ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(False); 566ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 567ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 568ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 569ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 570ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 571ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *matchop(Node **a, int n) /* ~ and match() */ 572ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 573ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 574ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s, *t; 575ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 576ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fa *pfa; 577ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int (*mf)(fa *, const char *) = match, mode = 0; 578ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 579ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n == MATCHFCN) { 580ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mf = pmatch; 581ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mode = 1; 582ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 583ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); /* a[1] = target text */ 584ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(x); 585ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] == 0) /* a[1] == 0: already-compiled reg expr */ 586ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = (*mf)((fa *) a[2], s); 587ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { 588ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[2]); /* a[2] = regular expr */ 589ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = getsval(y); 590ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = makedfa(t, mode); 591ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = (*mf)(pfa, s); 592ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 593ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 594ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 595ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n == MATCHFCN) { 596ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int start = patbeg - s + 1; 597ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (patlen < 0) 598ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner start = 0; 599ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(rstartloc, (Awkfloat) start); 600ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(rlengthloc, (Awkfloat) patlen); 601ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 602ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval = NUM; 603ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->fval = start; 604ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return x; 605ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) 606ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 607ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 608ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(False); 609ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 610ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 611ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 612ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *boolop(Node **a, int n) /* a[0] || a[1], a[0] && a[1], !a[0] */ 613ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 614ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 615ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 616ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 617ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 618ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = istrue(x); 619ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 620ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (n) { 621ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case BOR: 622ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i) return(True); 623ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 624ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = istrue(y); 625ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 626ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i) return(True); 627ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 628ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case AND: 629ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ( !i ) return(False); 630ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 631ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = istrue(y); 632ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 633ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i) return(True); 634ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 635ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case NOT: 636ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i) return(False); 637ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(True); 638ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: /* can't happen */ 639ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("unknown boolean operator %d", n); 640ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 641ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 0; /*NOTREACHED*/ 642ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 643ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 644ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *relop(Node **a, int n) /* a[0 < a[1], etc. */ 645ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 646ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 647ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 648ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat j; 649ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 650ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 651ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 652ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (x->tval&NUM && y->tval&NUM) { 653ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner j = x->fval - y->fval; 654ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = j<0? -1: (j>0? 1: 0); 655ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 656ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = strcmp(getsval(x), getsval(y)); 657ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 658ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 659ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 660ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (n) { 661ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case LT: if (i<0) return(True); 662ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 663ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case LE: if (i<=0) return(True); 664ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 665ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case NE: if (i!=0) return(True); 666ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 667ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case EQ: if (i == 0) return(True); 668ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 669ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case GE: if (i>=0) return(True); 670ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 671ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case GT: if (i>0) return(True); 672ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else return(False); 673ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: /* can't happen */ 674ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("unknown relational operator %d", n); 675ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 676ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 0; /*NOTREACHED*/ 677ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 678ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 679ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid tfree(Cell *a) /* free a tempcell */ 680ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 681ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (freeable(a)) { 682ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) ); 683ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xfree(a->sval); 684ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 685ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == tmps) 686ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("tempcell list is curdled"); 687ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner a->cnext = tmps; 688ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tmps = a; 689ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 690ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 691ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *gettemp(void) /* get a tempcell */ 692ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ int i; 693ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 694ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 695ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!tmps) { 696ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tmps = (Cell *) calloc(100, sizeof(Cell)); 697ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!tmps) 698ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of space for temporaries"); 699ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for(i = 1; i < 100; i++) 700ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tmps[i-1].cnext = &tmps[i]; 701ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tmps[i-1].cnext = 0; 702ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 703ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = tmps; 704ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tmps = x->cnext; 705ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *x = tempcell; 706ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 707ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 708ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 709ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *indirect(Node **a, int n) /* $( a[0] ) */ 710ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 711ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat val; 712ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 713ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int m; 714ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 715ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 716ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 717ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner val = getfval(x); /* freebsd: defend against super large field numbers */ 718ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((Awkfloat)INT_MAX < val) 719ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("trying to access out of range field %s", x->nval); 720ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = (int) val; 721ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (m == 0 && !is_number(s = getsval(x))) /* suspicion! */ 722ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal field $(%s), name \"%s\"", s, x->nval); 723ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* BUG: can x->nval ever be null??? */ 724ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 725ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = fieldadr(m); 726ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->ctype = OCELL; /* BUG? why are these needed? */ 727ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->csub = CFLD; 728ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 729ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 730ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 731ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *substr(Node **a, int nnn) /* substr(a[0], a[1], a[2]) */ 732ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 733ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int k, m, n; 734ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 735ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int temp; 736ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *z = 0; 737ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 738ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 739ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 740ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2] != 0) 741ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = execute(a[2]); 742ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(x); 743ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner k = strlen(s) + 1; 744ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (k <= 1) { 745ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 746ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 747ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2] != 0) { 748ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(z); 749ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 750ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 751ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, ""); 752ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 753ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 754ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = (int) getfval(y); 755ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (m <= 0) 756ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = 1; 757ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (m > k) 758ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = k; 759ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 760ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2] != 0) { 761ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = (int) getfval(z); 762ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(z); 763ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else 764ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = k - 1; 765ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n < 0) 766ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = 0; 767ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (n > k - m) 768ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = k - m; 769ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) ); 770ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = gettemp(); 771ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner temp = s[n+m-1]; /* with thanks to John Linderman */ 772ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s[n+m-1] = '\0'; 773ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(y, s + m - 1); 774ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s[n+m-1] = temp; 775ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 776ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(y); 777ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 778ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 779ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */ 780ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 781ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *z; 782ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s1, *s2, *p1, *p2, *q; 783ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat v = 0.0; 784ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 785ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 786ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s1 = getsval(x); 787ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 788ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s2 = getsval(y); 789ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 790ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = gettemp(); 791ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (p1 = s1; *p1 != '\0'; p1++) { 792ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) 793ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ; 794ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*p2 == '\0') { 795ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner v = (Awkfloat) (p1 - s1 + 1); /* origin 1 */ 796ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 797ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 798ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 799ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 800ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 801ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(z, v); 802ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 803ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 804ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 805ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner#define MAXNUMSIZE 50 806ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 807ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerint format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */ 808ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 809ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *fmt; 810ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *p, *t; 811ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner const char *os; 812ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 813ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int flag = 0, n; 814ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int fmtwd; /* format width */ 815ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int fmtsz = recsize; 816ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf = *pbuf; 817ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsize = *pbufsize; 818ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 819ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner os = s; 820ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner p = buf; 821ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((fmt = (char *) malloc(fmtsz)) == NULL) 822ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in format()"); 823ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*s) { 824ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1"); 825ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s != '%') { 826ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p++ = *s++; 827ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner continue; 828ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 829ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*(s+1) == '%') { 830ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p++ = '%'; 831ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s += 2; 832ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner continue; 833ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 834ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* have to be real careful in case this is a huge number, eg, %100000d */ 835ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fmtwd = atoi(s+1); 836ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd < 0) 837ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fmtwd = -fmtwd; 838ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format2"); 839ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (t = fmt; (*t++ = *s) != '\0'; s++) { 840ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, "format3")) 841ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("format item %.30s... ran format() out of memory", os); 842ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isalpha((uschar)*s) && *s != 'l' && *s != 'h' && *s != 'L') 843ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; /* the ansi panoply */ 844ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s == '*') { 845ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a); 846ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner a = a->nnext; 847ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(t-1, "%d", fmtwd=(int) getfval(x)); 848ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd < 0) 849ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fmtwd = -fmtwd; 850ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); 851ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = fmt + strlen(fmt); 852ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 853ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 854ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 855ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *t = '\0'; 856ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd < 0) 857ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fmtwd = -fmtwd; 858ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format4"); 859ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 860ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (*s) { 861ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'f': case 'e': case 'g': case 'E': case 'G': 862ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = 'f'; 863ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 864ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'd': case 'i': 865ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = 'd'; 866ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if(*(s-1) == 'l') break; 867ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *(t-1) = 'l'; 868ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *t = 'd'; 869ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *++t = '\0'; 870ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 871ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'o': case 'x': case 'X': case 'u': 872ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = *(s-1) == 'l' ? 'd' : 'u'; 873ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 874ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 's': 875ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = 's'; 876ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 877ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'c': 878ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = 'c'; 879ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 880ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: 881ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING("weird printf conversion %s", fmt); 882ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flag = '?'; 883ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 884ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 885ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == NULL) 886ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("not enough args in printf(%s)", os); 887ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a); 888ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner a = a->nnext; 889ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = MAXNUMSIZE; 890ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd > n) 891ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = fmtwd; 892ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); 893ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (flag) { 894ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */ 895ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = getsval(x); 896ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = strlen(t); 897ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd > n) 898ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = fmtwd; 899ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); 900ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner p += strlen(p); 901ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(p, "%s", t); 902ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 903ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'f': sprintf(p, fmt, getfval(x)); break; 904ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'd': sprintf(p, fmt, (long) getfval(x)); break; 905ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'u': sprintf(p, fmt, (int) getfval(x)); break; 906ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 's': 907ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = getsval(x); 908ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = strlen(t); 909ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fmtwd > n) 910ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = fmtwd; 911ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) 912ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); 913ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(p, fmt, t); 914ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 915ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case 'c': 916ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isnum(x)) { 917ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (getfval(x)) 918ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(p, fmt, (int) getfval(x)); 919ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { 920ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p++ = '\0'; /* explicit null byte */ 921ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p = '\0'; /* next output will start here */ 922ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 923ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else 924ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(p, fmt, getsval(x)[0]); 925ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 926ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: 927ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("can't happen: bad conversion %c in format()", flag); 928ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 929ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 930ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner p += strlen(p); 931ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s++; 932ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 933ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p = '\0'; 934ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(fmt); 935ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for ( ; a; a = a->nnext) /* evaluate any remaining args */ 936ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner execute(a); 937ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pbuf = buf; 938ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pbufsize = bufsize; 939ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return p - buf; 940ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 941ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 942ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *awksprintf(Node **a, int n) /* sprintf(a[0]) */ 943ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 944ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 945ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *y; 946ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 947ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz=3*recsize; 948ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 949ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 950ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in awksprintf"); 951ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = a[0]->nnext; 952ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 953ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (format(&buf, &bufsz, getsval(x), y) == -1) 954ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("sprintf string %.30s... too long. can't happen.", buf); 955ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 956ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 957ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->sval = buf; 958ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval = STR; 959ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 960ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 961ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 962ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *awkprintf(Node **a, int n) /* printf */ 963ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ /* a[0] is list of args, starting with format string */ 964ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* a[1] is redirection operator, a[2] is redirection file */ 965ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 966ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 967ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *y; 968ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 969ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int len; 970ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz=3*recsize; 971ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 972ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 973ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in awkprintf"); 974ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = a[0]->nnext; 975ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 976ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((len = format(&buf, &bufsz, getsval(x), y)) == -1) 977ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("printf string %.30s... too long. can't happen.", buf); 978ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 979ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] == NULL) { 980ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* fputs(buf, stdout); */ 981ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fwrite(buf, len, 1, stdout); 982ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ferror(stdout)) 983ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("write error on stdout"); 984ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 985ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = redirect(ptoi(a[1]), a[2]); 986ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* fputs(buf, fp); */ 987ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fwrite(buf, len, 1, fp); 988ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(fp); 989ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ferror(fp)) 990ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("write error on %s", filename(fp)); 991ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 992ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 993ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 994ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 995ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 996ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ 997ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 998ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat i, j = 0; 999ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner double v; 1000ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *z; 1001ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1002ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1003ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = getfval(x); 1004ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1005ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n != UMINUS) { 1006ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 1007ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner j = getfval(y); 1008ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1009ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1010ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = gettemp(); 1011ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (n) { 1012ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case ADD: 1013ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i += j; 1014ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1015ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case MINUS: 1016ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i -= j; 1017ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1018ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case MULT: 1019ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i *= j; 1020ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1021ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case DIVIDE: 1022ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (j == 0) 1023ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("division by zero"); 1024ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i /= j; 1025ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1026ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case MOD: 1027ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (j == 0) 1028ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("division by zero in mod"); 1029ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner modf(i/j, &v); 1030ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = i - j * v; 1031ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1032ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case UMINUS: 1033ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = -i; 1034ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1035ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case POWER: 1036ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ 1037ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = ipow(i, (int) j); 1038ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1039ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner i = errcheck(pow(i, j), "pow"); 1040ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1041ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: /* can't happen */ 1042ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal arithmetic operator %d", n); 1043ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1044ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(z, i); 1045ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 1046ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1047ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1048ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerdouble ipow(double x, int n) /* x**n. ought to be done by pow, but isn't always */ 1049ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1050ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner double v; 1051ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1052ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n <= 0) 1053ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 1; 1054ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner v = ipow(x, n/2); 1055ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n % 2 == 0) 1056ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return v * v; 1057ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1058ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return x * v * v; 1059ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1060ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1061ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *incrdecr(Node **a, int n) /* a[0]++, etc. */ 1062ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1063ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *z; 1064ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int k; 1065ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat xf; 1066ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1067ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1068ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf = getfval(x); 1069ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner k = (n == PREINCR || n == POSTINCR) ? 1 : -1; 1070ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n == PREINCR || n == PREDECR) { 1071ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, xf + k); 1072ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1073ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1074ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = gettemp(); 1075ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(z, xf); 1076ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, xf + k); 1077ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1078ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 1079ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1080ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1081ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ 1082ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ /* this is subtle; don't muck with it. */ 1083ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 1084ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat xf, yf; 1085ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner double v; 1086ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1087ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 1088ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1089ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (n == ASSIGN) { /* ordinary assignment */ 1090ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */ 1091ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ; /* leave alone unless it's a field */ 1092ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if ((y->tval & (STR|NUM)) == (STR|NUM)) { 1093ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, getsval(y)); 1094ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->fval = getfval(y); 1095ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval |= NUM; 1096ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1097ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (isstr(y)) 1098ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, getsval(y)); 1099ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (isnum(y)) 1100ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, getfval(y)); 1101ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1102ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner funnyvar(y, "read value of"); 1103ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1104ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1105ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1106ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf = getfval(x); 1107ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner yf = getfval(y); 1108ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (n) { 1109ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case ADDEQ: 1110ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf += yf; 1111ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1112ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case SUBEQ: 1113ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf -= yf; 1114ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1115ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case MULTEQ: 1116ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf *= yf; 1117ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1118ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case DIVEQ: 1119ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (yf == 0) 1120ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("division by zero in /="); 1121ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf /= yf; 1122ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1123ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case MODEQ: 1124ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (yf == 0) 1125ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("division by zero in %%="); 1126ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner modf(xf/yf, &v); 1127ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf = xf - yf * v; 1128ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1129ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case POWEQ: 1130ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ 1131ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf = ipow(xf, (int) yf); 1132ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1133ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xf = errcheck(pow(xf, yf), "pow"); 1134ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1135ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: 1136ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal assignment operator %d", n); 1137ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1138ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1139ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1140ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, xf); 1141ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1142ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1143ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1144ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *cat(Node **a, int q) /* a[0] cat a[1] */ 1145ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1146ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *z; 1147ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int n1, n2; 1148ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 1149ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1150ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1151ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 1152ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner getsval(x); 1153ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner getsval(y); 1154ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n1 = strlen(x->sval); 1155ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n2 = strlen(y->sval); 1156ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = (char *) malloc(n1 + n2 + 1); 1157ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (s == NULL) 1158ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of space concatenating %.15s... and %.15s...", 1159ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->sval, y->sval); 1160ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcpy(s, x->sval); 1161ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner strcpy(s+n1, y->sval); 1162ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1163ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z = gettemp(); 1164ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z->sval = s; 1165ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner z->tval = STR; 1166ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1167ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(z); 1168ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1169ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1170ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *pastat(Node **a, int n) /* a[0] { a[1] } */ 1171ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1172ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1173ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1174ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] == 0) 1175ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1176ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { 1177ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1178ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istrue(x)) { 1179ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1180ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1181ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1182ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1183ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return x; 1184ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1185ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1186ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *dopa2(Node **a, int n) /* a[0], a[1] { a[2] } */ 1187ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1188ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1189ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int pair; 1190ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1191ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pair = ptoi(a[3]); 1192ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pairstack[pair] == 0) { 1193ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1194ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istrue(x)) 1195ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pairstack[pair] = 1; 1196ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1197ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1198ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pairstack[pair] == 1) { 1199ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1200ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istrue(x)) 1201ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pairstack[pair] = 0; 1202ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1203ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1204ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1205ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1206ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(False); 1207ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1208ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1209ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ 1210ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1211ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x = 0, *y, *ap; 1212ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *s; 1213ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int sep; 1214ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *t, temp, num[50], *fs = 0; 1215ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int n, tempstat, arg3type; 1216ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1217ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[0]); /* source string */ 1218ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = getsval(y); 1219ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner arg3type = ptoi(a[3]); 1220ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2] == 0) /* fs string */ 1221ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fs = *FS; 1222ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else if (arg3type == STRING) { /* split(str,arr,"string") */ 1223ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1224ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fs = getsval(x); 1225ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (arg3type == REGEXPR) 1226ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ 1227ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1228ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal type of split"); 1229ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sep = *fs; 1230ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap = execute(a[1]); /* array name */ 1231ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner freesymtab(ap); 1232ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); 1233ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->tval &= ~STR; 1234ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->tval |= ARR; 1235ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ap->sval = (char *) makesymtab(NSYMTAB); 1236ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1237ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = 0; 1238ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */ 1239ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fa *pfa; 1240ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (arg3type == REGEXPR) { /* it's ready already */ 1241ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = (fa *) a[2]; 1242ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 1243ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = makedfa(fs, 1); 1244ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1245ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (nematch(pfa,s)) { 1246ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempstat = pfa->initstat; 1247ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa->initstat = 2; 1248ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner do { 1249ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1250ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1251ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner temp = *patbeg; 1252ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *patbeg = '\0'; 1253ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (is_number(s)) 1254ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1255ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1256ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1257ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *patbeg = temp; 1258ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s = patbeg + patlen; 1259ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*(patbeg+patlen-1) == 0 || *s == 0) { 1260ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1261ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1262ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, "", 0.0, STR, (Array *) ap->sval); 1263ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa->initstat = tempstat; 1264ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner goto spdone; 1265ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1266ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } while (nematch(pfa,s)); 1267ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa->initstat = tempstat; /* bwk: has to be here to reset */ 1268ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* cf gsub and refldbld */ 1269ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1270ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1271ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1272ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (is_number(s)) 1273ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); 1274ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1275ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, s, 0.0, STR, (Array *) ap->sval); 1276ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner spdone: 1277ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = NULL; 1278ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (sep == ' ') { 1279ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (n = 0; ; ) { 1280ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*s == ' ' || *s == '\t' || *s == '\n') 1281ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s++; 1282ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s == 0) 1283ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1284ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1285ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = s; 1286ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner do 1287ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s++; 1288ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); 1289ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner temp = *s; 1290ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *s = '\0'; 1291ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1292ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (is_number(t)) 1293ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1294ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1295ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1296ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *s = temp; 1297ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s != 0) 1298ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s++; 1299ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1300ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (sep == 0) { /* new: split(s, a, "") => 1 char/elem */ 1301ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (n = 0; *s != 0; s++) { 1302ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char buf[2]; 1303ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1304ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1305ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf[0] = *s; 1306ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf[1] = 0; 1307ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isdigit((uschar)buf[0])) 1308ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, buf, atof(buf), STR|NUM, (Array *) ap->sval); 1309ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1310ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, buf, 0.0, STR, (Array *) ap->sval); 1311ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1312ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (*s != 0) { 1313ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (;;) { 1314ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n++; 1315ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = s; 1316ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*s != sep && *s != '\n' && *s != '\0') 1317ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner s++; 1318ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner temp = *s; 1319ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *s = '\0'; 1320ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sprintf(num, "%d", n); 1321ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (is_number(t)) 1322ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); 1323ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1324ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsymtab(num, t, 0.0, STR, (Array *) ap->sval); 1325ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *s = temp; 1326ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s++ == 0) 1327ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1328ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1329ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1330ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(ap); 1331ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1332ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[2] != 0 && arg3type == STRING) { 1333ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1334ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1335ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 1336ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval = NUM; 1337ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->fval = n; 1338ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1339ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1340ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1341ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *condexpr(Node **a, int n) /* a[0] ? a[1] : a[2] */ 1342ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1343ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1344ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1345ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1346ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istrue(x)) { 1347ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1348ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1349ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 1350ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1351ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1352ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1353ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1354ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1355ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1356ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *ifstat(Node **a, int n) /* if (a[0]) a[1]; else a[2] */ 1357ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1358ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1359ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1360ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1361ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (istrue(x)) { 1362ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1363ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1364ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a[2] != 0) { 1365ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1366ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1367ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1368ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1369ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1370ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1371ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *whilestat(Node **a, int n) /* while (a[0]) a[1] */ 1372ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1373ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1374ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1375ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (;;) { 1376ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1377ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!istrue(x)) 1378ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1379ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1380ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1381ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isbreak(x)) { 1382ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = True; 1383ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1384ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1385ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isnext(x) || isexit(x) || isret(x)) 1386ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1387ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1388ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1389ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1390ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1391ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *dostat(Node **a, int n) /* do a[0]; while(a[1]) */ 1392ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1393ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1394ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1395ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (;;) { 1396ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1397ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isbreak(x)) 1398ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 1399ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isnext(x) || isexit(x) || isret(x)) 1400ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1401ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1402ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1403ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!istrue(x)) 1404ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1405ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1406ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1407ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1408ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1409ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *forstat(Node **a, int n) /* for (a[0]; a[1]; a[2]) a[3] */ 1410ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1411ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1412ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1413ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1414ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1415ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (;;) { 1416ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1]!=0) { 1417ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1418ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!istrue(x)) return(x); 1419ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else tempfree(x); 1420ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1421ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[3]); 1422ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isbreak(x)) /* turn off break */ 1423ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 1424ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isnext(x) || isexit(x) || isret(x)) 1425ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1426ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1427ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1428ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1429ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1430ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1431ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1432ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *instat(Node **a, int n) /* for (a[0] in a[1]) a[2] */ 1433ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1434ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *vp, *arrayp, *cp, *ncp; 1435ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Array *tp; 1436ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 1437ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1438ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner vp = execute(a[0]); 1439ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner arrayp = execute(a[1]); 1440ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (!isarr(arrayp)) { 1441ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 1442ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1443ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tp = (Array *) arrayp->sval; 1444ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(arrayp); 1445ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < tp->size; i++) { /* this routine knows too much */ 1446ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (cp = tp->tab[i]; cp != NULL; cp = ncp) { 1447ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(vp, cp->nval); 1448ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ncp = cp->cnext; 1449ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[2]); 1450ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isbreak(x)) { 1451ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(vp); 1452ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 1453ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1454ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isnext(x) || isexit(x) || isret(x)) { 1455ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(vp); 1456ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1457ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1458ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1459ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1460ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1461ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return True; 1462ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1463ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1464ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ 1465ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1466ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 1467ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Awkfloat u; 1468ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int t; 1469ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *p, *buf; 1470ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *nextarg; 1471ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 1472ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner void flush_all(void); 1473ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1474ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = ptoi(a[0]); 1475ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[1]); 1476ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner nextarg = a[1]->nnext; 1477ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner switch (t) { 1478ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FLENGTH: 1479ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isarr(x)) 1480ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ 1481ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1482ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = strlen(getsval(x)); 1483ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1484ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FLOG: 1485ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = errcheck(log(getfval(x)), "log"); break; 1486ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FINT: 1487ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner modf(getfval(x), &u); break; 1488ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FEXP: 1489ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = errcheck(exp(getfval(x)), "exp"); break; 1490ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FSQRT: 1491ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = errcheck(sqrt(getfval(x)), "sqrt"); break; 1492ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FSIN: 1493ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = sin(getfval(x)); break; 1494ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FCOS: 1495ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = cos(getfval(x)); break; 1496ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FATAN: 1497ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (nextarg == 0) { 1498ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING("atan2 requires two arguments; returning 1.0"); 1499ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = 1.0; 1500ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 1501ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]->nnext); 1502ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = atan2(getfval(x), getfval(y)); 1503ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1504ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner nextarg = nextarg->nnext; 1505ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1506ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1507ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FSYSTEM: 1508ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(stdout); /* in case something is buffered already */ 1509ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = (Awkfloat) system(getsval(x)) / 256; /* 256 is unix-dep */ 1510ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1511ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FRAND: 1512ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner /* in principle, rand() returns something in 0..RAND_MAX */ 1513ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX; 1514ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1515ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FSRAND: 1516ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isrec(x)) /* no argument provided */ 1517ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = time((time_t *)0); 1518ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1519ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = getfval(x); 1520ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner srand((unsigned int) u); 1521ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1522ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FTOUPPER: 1523ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FTOLOWER: 1524ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner buf = tostring(getsval(x)); 1525ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (t == FTOUPPER) { 1526ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (p = buf; *p; p++) 1527ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (islower((uschar) *p)) 1528ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p = toupper((uschar)*p); 1529ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { 1530ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (p = buf; *p; p++) 1531ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isupper((uschar) *p)) 1532ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *p = tolower((uschar)*p); 1533ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1534ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1535ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 1536ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, buf); 1537ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 1538ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return x; 1539ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner case FFLUSH: 1540ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (isrec(x) || strlen(getsval(x)) == 0) { 1541ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner flush_all(); /* fflush() or fflush("") -> all */ 1542ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = 0; 1543ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) 1544ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = EOF; 1545ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1546ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner u = fflush(fp); 1547ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1548ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner default: /* can't happen */ 1549ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal function type %d", t); 1550ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1551ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1552ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1553ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 1554ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, u); 1555ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (nextarg != 0) { 1556ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING("warning: function has too many arguments"); 1557ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for ( ; nextarg; nextarg = nextarg->nnext) 1558ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner execute(nextarg); 1559ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1560ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1561ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1562ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1563ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *printstat(Node **a, int n) /* print a[0] */ 1564ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1565ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Node *x; 1566ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *y; 1567ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 1568ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1569ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] == 0) /* a[1] is redirection operator, a[2] is file */ 1570ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = stdout; 1571ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1572ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = redirect(ptoi(a[1]), a[2]); 1573ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (x = a[0]; x != NULL; x = x->nnext) { 1574ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(x); 1575ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fputs(getpssval(y), fp); 1576ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1577ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (x->nnext == NULL) 1578ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fputs(*ORS, fp); 1579ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1580ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fputs(*OFS, fp); 1581ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1582ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[1] != 0) 1583ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(fp); 1584ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ferror(fp)) 1585ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("write error on %s", filename(fp)); 1586ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(True); 1587ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1588ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1589ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *nullproc(Node **a, int n) 1590ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1591ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = n; 1592ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner a = a; 1593ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return 0; 1594ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1595ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1596ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1597ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerFILE *redirect(int a, Node *b) /* set up all i/o redirections */ 1598ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1599ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 1600ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1601ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *fname; 1602ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1603ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(b); 1604ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fname = getsval(x); 1605ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = openfile(a, fname); 1606ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fp == NULL) 1607ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("can't open file %s", fname); 1608ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1609ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return fp; 1610ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1611ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1612ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerstruct files { 1613ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp; 1614ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner const char *fname; 1615ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int mode; /* '|', 'a', 'w' => LE/LT, GT */ 1616ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} files[FOPEN_MAX] ={ 1617ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner { NULL, "/dev/stdin", LT }, /* watch out: don't free this! */ 1618ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner { NULL, "/dev/stdout", GT }, 1619ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner { NULL, "/dev/stderr", GT } 1620ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner}; 1621ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1622ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid stdinit(void) /* in case stdin, etc., are not constants */ 1623ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1624ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[0].fp = stdin; 1625ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[1].fp = stdout; 1626ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[2].fp = stderr; 1627ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1628ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1629ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerFILE *openfile(int a, const char *us) 1630ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1631ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner const char *s = us; 1632ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i, m; 1633ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FILE *fp = 0; 1634ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1635ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*s == '\0') 1636ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("null file name in print or getline"); 1637ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i=0; i < FOPEN_MAX; i++) 1638ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].fname && strcmp(s, files[i].fname) == 0) { 1639ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == files[i].mode || (a==APPEND && files[i].mode==GT)) 1640ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return files[i].fp; 1641ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == FFLUSH) 1642ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return files[i].fp; 1643ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1644ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == FFLUSH) /* didn't find it, so don't create it! */ 1645ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return NULL; 1646ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1647ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i=0; i < FOPEN_MAX; i++) 1648ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].fp == 0) 1649ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner break; 1650ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i >= FOPEN_MAX) 1651ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("%s makes too many open files", s); 1652ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(stdout); /* force a semblance of order */ 1653ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = a; 1654ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a == GT) { 1655ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = fopen(s, "w"); 1656ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a == APPEND) { 1657ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = fopen(s, "a"); 1658ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner m = GT; /* so can mix > and >> */ 1659ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a == '|') { /* output pipe */ 1660ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = popen(s, "w"); 1661ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a == LE) { /* input pipe */ 1662ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = popen(s, "r"); 1663ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (a == LT) { /* getline <file */ 1664ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fp = strcmp(s, "-") == 0 ? stdin : fopen(s, "r"); /* "-" is stdin */ 1665ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else /* can't happen */ 1666ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("illegal redirection %d", a); 1667ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fp != NULL) { 1668ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[i].fname = tostring(s); 1669ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[i].fp = fp; 1670ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[i].mode = m; 1671ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1672ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return fp; 1673ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1674ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1675ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnerconst char *filename(FILE *fp) 1676ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1677ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 1678ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1679ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < FOPEN_MAX; i++) 1680ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (fp == files[i].fp) 1681ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return files[i].fname; 1682ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return "???"; 1683ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1684ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1685ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *closefile(Node **a, int n) 1686ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1687ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x; 1688ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i, stat; 1689ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1690ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner n = n; 1691ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[0]); 1692ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner getsval(x); 1693ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stat = -1; 1694ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < FOPEN_MAX; i++) { 1695ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { 1696ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ferror(files[i].fp)) 1697ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING( "i/o error occurred on %s", files[i].fname ); 1698ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].mode == '|' || files[i].mode == LE) 1699ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stat = pclose(files[i].fp); 1700ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1701ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stat = fclose(files[i].fp); 1702ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (stat == EOF) 1703ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING( "i/o error occurred closing %s", files[i].fname ); 1704ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (i > 2) /* don't do /dev/std... */ 1705ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner xfree(files[i].fname); 1706ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[i].fname = NULL; /* watch out for ref thru this */ 1707ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner files[i].fp = NULL; 1708ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1709ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1710ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1711ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 1712ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setfval(x, (Awkfloat) stat); 1713ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1714ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1715ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1716ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid closeall(void) 1717ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1718ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i, stat; 1719ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1720ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < FOPEN_MAX; i++) { 1721ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].fp) { 1722ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (ferror(files[i].fp)) 1723ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING( "i/o error occurred on %s", files[i].fname ); 1724ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].mode == '|' || files[i].mode == LE) 1725ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stat = pclose(files[i].fp); 1726ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else 1727ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner stat = fclose(files[i].fp); 1728ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (stat == EOF) 1729ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner WARNING( "i/o error occurred while closing %s", files[i].fname ); 1730ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1731ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1732ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1733ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1734ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid flush_all(void) 1735ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1736ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int i; 1737ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1738ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (i = 0; i < FOPEN_MAX; i++) 1739ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (files[i].fp) 1740ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fflush(files[i].fp); 1741ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1742ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1743ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid backsub(char **pb_ptr, char **sptr_ptr); 1744ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1745ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *sub(Node **a, int nnn) /* substitute command */ 1746ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1747ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *sptr, *pb, *q; 1748ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y, *result; 1749ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *t, *buf; 1750ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fa *pfa; 1751ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz = recsize; 1752ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1753ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 1754ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in sub"); 1755ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[3]); /* target string */ 1756ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = getsval(x); 1757ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ 1758ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = (fa *) a[1]; /* regular expression */ 1759ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { 1760ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 1761ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = makedfa(getsval(y), 1); 1762ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1763ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1764ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[2]); /* replacement string */ 1765ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner result = False; 1766ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pmatch(pfa, t)) { 1767ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = t; 1768ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); 1769ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pb = buf; 1770ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (sptr < patbeg) 1771ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1772ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = getsval(y); 1773ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*sptr != 0) { 1774ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); 1775ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*sptr == '\\') { 1776ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner backsub(&pb, &sptr); 1777ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (*sptr == '&') { 1778ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr++; 1779ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); 1780ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (q = patbeg; q < patbeg+patlen; ) 1781ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *q++; 1782ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else 1783ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1784ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1785ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb = '\0'; 1786ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pb > buf + bufsz) 1787ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("sub result1 %.30s too big; can't happen", buf); 1788ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = patbeg + patlen; 1789ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { 1790ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); 1791ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while ((*pb++ = *sptr++) != 0) 1792ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ; 1793ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1794ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pb > buf + bufsz) 1795ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("sub result2 %.30s too big; can't happen", buf); 1796ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, buf); /* BUG: should be able to avoid copy */ 1797ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner result = True;; 1798ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1799ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1800ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1801ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 1802ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return result; 1803ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1804ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1805ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David TurnerCell *gsub(Node **a, int nnn) /* global substitute */ 1806ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ 1807ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner Cell *x, *y; 1808ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *rptr, *sptr, *t, *pb, *q; 1809ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *buf; 1810ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner fa *pfa; 1811ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int mflag, tempstat, num; 1812ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner int bufsz = recsize; 1813ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1814ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if ((buf = (char *) malloc(bufsz)) == NULL) 1815ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("out of memory in gsub"); 1816ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mflag = 0; /* if mflag == 0, can replace empty string */ 1817ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner num = 0; 1818ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = execute(a[3]); /* target string */ 1819ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = getsval(x); 1820ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ 1821ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = (fa *) a[1]; /* regular expression */ 1822ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { 1823ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[1]); 1824ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa = makedfa(getsval(y), 1); 1825ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1826ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1827ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner y = execute(a[2]); /* replacement string */ 1828ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pmatch(pfa, t)) { 1829ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempstat = pfa->initstat; 1830ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa->initstat = 2; 1831ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pb = buf; 1832ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner rptr = getsval(y); 1833ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner do { 1834ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (patlen == 0 && *patbeg != 0) { /* matched empty string */ 1835ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (mflag == 0) { /* can replace empty */ 1836ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner num++; 1837ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = rptr; 1838ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*sptr != 0) { 1839ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1840ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*sptr == '\\') { 1841ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner backsub(&pb, &sptr); 1842ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (*sptr == '&') { 1843ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr++; 1844ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1845ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (q = patbeg; q < patbeg+patlen; ) 1846ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *q++; 1847ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else 1848ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1849ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1850ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1851ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*t == 0) /* at end */ 1852ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner goto done; 1853ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); 1854ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *t++; 1855ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pb > buf + bufsz) /* BUG: not sure of this test */ 1856ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("gsub result0 %.30s too big; can't happen", buf); 1857ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mflag = 0; 1858ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1859ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner else { /* matched nonempty string */ 1860ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner num++; 1861ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = t; 1862ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); 1863ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (sptr < patbeg) 1864ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1865ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = rptr; 1866ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while (*sptr != 0) { 1867ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); 1868ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (*sptr == '\\') { 1869ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner backsub(&pb, &sptr); 1870ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (*sptr == '&') { 1871ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr++; 1872ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); 1873ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner for (q = patbeg; q < patbeg+patlen; ) 1874ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *q++; 1875ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else 1876ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1877ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1878ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner t = patbeg + patlen; 1879ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (patlen == 0 || *t == 0 || *(t-1) == 0) 1880ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner goto done; 1881ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (pb > buf + bufsz) 1882ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("gsub result1 %.30s too big; can't happen", buf); 1883ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner mflag = 1; 1884ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1885ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } while (pmatch(pfa,t)); 1886ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr = t; 1887ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); 1888ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner while ((*pb++ = *sptr++) != 0) 1889ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner ; 1890ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner done: if (pb > buf + bufsz) 1891ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner FATAL("gsub result2 %.30s too big; can't happen", buf); 1892ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb = '\0'; 1893ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner setsval(x, buf); /* BUG: should be able to avoid copy + free */ 1894ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner pfa->initstat = tempstat; 1895ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1896ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(x); 1897ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner tempfree(y); 1898ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x = gettemp(); 1899ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->tval = NUM; 1900ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner x->fval = num; 1901ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner free(buf); 1902ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner return(x); 1903ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1904ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1905ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turnervoid backsub(char **pb_ptr, char **sptr_ptr) /* handle \\& variations */ 1906ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner{ /* sptr[0] == '\\' */ 1907ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner char *pb = *pb_ptr, *sptr = *sptr_ptr; 1908ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1909ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (sptr[1] == '\\') { 1910ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ 1911ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = '\\'; 1912ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = '&'; 1913ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr += 4; 1914ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (sptr[2] == '&') { /* \\& -> \ + matched */ 1915ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = '\\'; 1916ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr += 2; 1917ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else { /* \\x -> \\x */ 1918ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1919ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1920ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } 1921ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else if (sptr[1] == '&') { /* literal & */ 1922ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner sptr++; 1923ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1924ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner } else /* literal \ */ 1925ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb++ = *sptr++; 1926ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner 1927ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *pb_ptr = pb; 1928ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner *sptr_ptr = sptr; 1929ce5707c0255040b895f1c90ac9a435d8a4b8f2d6David Turner} 1930