14b588458SPeter Avalos /**************************************************************** 24b588458SPeter Avalos Copyright (C) Lucent Technologies 1997 34b588458SPeter Avalos All Rights Reserved 44b588458SPeter Avalos 54b588458SPeter Avalos Permission to use, copy, modify, and distribute this software and 64b588458SPeter Avalos its documentation for any purpose and without fee is hereby 74b588458SPeter Avalos granted, provided that the above copyright notice appear in all 84b588458SPeter Avalos copies and that both that the copyright notice and this 94b588458SPeter Avalos permission notice and warranty disclaimer appear in supporting 104b588458SPeter Avalos documentation, and that the name Lucent Technologies or any of 114b588458SPeter Avalos its entities not be used in advertising or publicity pertaining 124b588458SPeter Avalos to distribution of the software without specific, written prior 134b588458SPeter Avalos permission. 144b588458SPeter Avalos 154b588458SPeter Avalos LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 164b588458SPeter Avalos INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 174b588458SPeter Avalos IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 184b588458SPeter Avalos SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 194b588458SPeter Avalos WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 204b588458SPeter Avalos IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 214b588458SPeter Avalos ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 224b588458SPeter Avalos THIS SOFTWARE. 234b588458SPeter Avalos ****************************************************************/ 244b588458SPeter Avalos 254b588458SPeter Avalos #include <assert.h> 261d48fce0SDaniel Fojt #include <stdint.h> 271d48fce0SDaniel Fojt #include <stdbool.h> 281d48fce0SDaniel Fojt #if __STDC_VERSION__ <= 199901L 291d48fce0SDaniel Fojt #define noreturn 301d48fce0SDaniel Fojt #else 311d48fce0SDaniel Fojt #include <stdnoreturn.h> 321d48fce0SDaniel Fojt #endif 334b588458SPeter Avalos 344b588458SPeter Avalos typedef double Awkfloat; 354b588458SPeter Avalos 364b588458SPeter Avalos /* unsigned char is more trouble than it's worth */ 374b588458SPeter Avalos 384b588458SPeter Avalos typedef unsigned char uschar; 394b588458SPeter Avalos 4048f09a05SAntonio Huete Jimenez #define xfree(a) { free((void *)(intptr_t)(a)); (a) = NULL; } 411d48fce0SDaniel Fojt /* 421d48fce0SDaniel Fojt * We sometimes cheat writing read-only pointers to NUL-terminate them 431d48fce0SDaniel Fojt * and then put back the original value 441d48fce0SDaniel Fojt */ 451d48fce0SDaniel Fojt #define setptr(ptr, a) (*(char *)(intptr_t)(ptr)) = (a) 464b588458SPeter Avalos 47e5e686a0SDaniel Fojt #define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for DPRINTF 484b588458SPeter Avalos */ 494b588458SPeter Avalos #define DEBUG 504b588458SPeter Avalos #ifdef DEBUG 51e5e686a0SDaniel Fojt # define DPRINTF(...) if (dbg) printf(__VA_ARGS__) 524b588458SPeter Avalos #else 53e5e686a0SDaniel Fojt # define DPRINTF(...) 544b588458SPeter Avalos #endif 554b588458SPeter Avalos 561d48fce0SDaniel Fojt extern enum compile_states { 571d48fce0SDaniel Fojt RUNNING, 581d48fce0SDaniel Fojt COMPILING, 591d48fce0SDaniel Fojt ERROR_PRINTING 601d48fce0SDaniel Fojt } compile_time; 611d48fce0SDaniel Fojt 621d48fce0SDaniel Fojt extern bool safe; /* false => unsafe, true => safe */ 634b588458SPeter Avalos 644b588458SPeter Avalos #define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ 654b588458SPeter Avalos extern int recsize; /* size of current record, orig RECSIZE */ 664b588458SPeter Avalos 67*ed569bc2SAaron LI extern size_t awk_mb_cur_max; /* max size of a multi-byte character */ 68*ed569bc2SAaron LI 691d48fce0SDaniel Fojt extern char EMPTY[]; /* this avoid -Wwritable-strings issues */ 704b588458SPeter Avalos extern char **FS; 714b588458SPeter Avalos extern char **RS; 724b588458SPeter Avalos extern char **ORS; 734b588458SPeter Avalos extern char **OFS; 744b588458SPeter Avalos extern char **OFMT; 754b588458SPeter Avalos extern Awkfloat *NR; 764b588458SPeter Avalos extern Awkfloat *FNR; 774b588458SPeter Avalos extern Awkfloat *NF; 784b588458SPeter Avalos extern char **FILENAME; 794b588458SPeter Avalos extern char **SUBSEP; 804b588458SPeter Avalos extern Awkfloat *RSTART; 814b588458SPeter Avalos extern Awkfloat *RLENGTH; 824b588458SPeter Avalos 83*ed569bc2SAaron LI extern bool CSV; /* true for csv input */ 84*ed569bc2SAaron LI 854b588458SPeter Avalos extern char *record; /* points to $0 */ 864b588458SPeter Avalos extern int lineno; /* line number in awk program */ 874b588458SPeter Avalos extern int errorflag; /* 1 if error has occurred */ 881d48fce0SDaniel Fojt extern bool donefld; /* true if record broken into fields */ 891d48fce0SDaniel Fojt extern bool donerec; /* true if record is valid (no fld has changed */ 904b588458SPeter Avalos extern int dbg; 914b588458SPeter Avalos 921d48fce0SDaniel Fojt extern const char *patbeg; /* beginning of pattern matched */ 934b588458SPeter Avalos extern int patlen; /* length of pattern matched. set in b.c */ 944b588458SPeter Avalos 954b588458SPeter Avalos /* Cell: all information about a variable or constant */ 964b588458SPeter Avalos 974b588458SPeter Avalos typedef struct Cell { 984b588458SPeter Avalos uschar ctype; /* OCELL, OBOOL, OJUMP, etc. */ 994b588458SPeter Avalos uschar csub; /* CCON, CTEMP, CFLD, etc. */ 1004b588458SPeter Avalos char *nval; /* name, for variables only */ 1014b588458SPeter Avalos char *sval; /* string value */ 1024b588458SPeter Avalos Awkfloat fval; /* value as number */ 1031d48fce0SDaniel Fojt int tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE|CONVC|CONVO */ 1041d48fce0SDaniel Fojt char *fmt; /* CONVFMT/OFMT value used to convert from number */ 1054b588458SPeter Avalos struct Cell *cnext; /* ptr to next if chained */ 1064b588458SPeter Avalos } Cell; 1074b588458SPeter Avalos 1084b588458SPeter Avalos typedef struct Array { /* symbol table array */ 1094b588458SPeter Avalos int nelem; /* elements in table right now */ 1104b588458SPeter Avalos int size; /* size of tab */ 1114b588458SPeter Avalos Cell **tab; /* hash table pointers */ 1124b588458SPeter Avalos } Array; 1134b588458SPeter Avalos 1144b588458SPeter Avalos #define NSYMTAB 50 /* initial size of a symbol table */ 1154b588458SPeter Avalos extern Array *symtab; 1164b588458SPeter Avalos 1174b588458SPeter Avalos extern Cell *nrloc; /* NR */ 1184b588458SPeter Avalos extern Cell *fnrloc; /* FNR */ 1191d48fce0SDaniel Fojt extern Cell *fsloc; /* FS */ 1204b588458SPeter Avalos extern Cell *nfloc; /* NF */ 1211d48fce0SDaniel Fojt extern Cell *ofsloc; /* OFS */ 1221d48fce0SDaniel Fojt extern Cell *orsloc; /* ORS */ 1231d48fce0SDaniel Fojt extern Cell *rsloc; /* RS */ 1244b588458SPeter Avalos extern Cell *rstartloc; /* RSTART */ 1254b588458SPeter Avalos extern Cell *rlengthloc; /* RLENGTH */ 1261d48fce0SDaniel Fojt extern Cell *subseploc; /* SUBSEP */ 1271d48fce0SDaniel Fojt extern Cell *symtabloc; /* SYMTAB */ 1284b588458SPeter Avalos 1294b588458SPeter Avalos /* Cell.tval values: */ 1304b588458SPeter Avalos #define NUM 01 /* number value is valid */ 1314b588458SPeter Avalos #define STR 02 /* string value is valid */ 1324b588458SPeter Avalos #define DONTFREE 04 /* string space is not freeable */ 1334b588458SPeter Avalos #define CON 010 /* this is a constant */ 1344b588458SPeter Avalos #define ARR 020 /* this is an array */ 1354b588458SPeter Avalos #define FCN 040 /* this is a function name */ 1364b588458SPeter Avalos #define FLD 0100 /* this is a field $1, $2, ... */ 1374b588458SPeter Avalos #define REC 0200 /* this is $0 */ 1381d48fce0SDaniel Fojt #define CONVC 0400 /* string was converted from number via CONVFMT */ 1391d48fce0SDaniel Fojt #define CONVO 01000 /* string was converted from number via OFMT */ 1404b588458SPeter Avalos 1414b588458SPeter Avalos 1424b588458SPeter Avalos /* function types */ 1434b588458SPeter Avalos #define FLENGTH 1 1444b588458SPeter Avalos #define FSQRT 2 1454b588458SPeter Avalos #define FEXP 3 1464b588458SPeter Avalos #define FLOG 4 1474b588458SPeter Avalos #define FINT 5 1484b588458SPeter Avalos #define FSYSTEM 6 1494b588458SPeter Avalos #define FRAND 7 1504b588458SPeter Avalos #define FSRAND 8 1514b588458SPeter Avalos #define FSIN 9 1524b588458SPeter Avalos #define FCOS 10 1534b588458SPeter Avalos #define FATAN 11 1544b588458SPeter Avalos #define FTOUPPER 12 1554b588458SPeter Avalos #define FTOLOWER 13 1564b588458SPeter Avalos #define FFLUSH 14 1574b588458SPeter Avalos 1584b588458SPeter Avalos /* Node: parse tree is made of nodes, with Cell's at bottom */ 1594b588458SPeter Avalos 1604b588458SPeter Avalos typedef struct Node { 1614b588458SPeter Avalos int ntype; 1624b588458SPeter Avalos struct Node *nnext; 1634b588458SPeter Avalos int lineno; 1644b588458SPeter Avalos int nobj; 1654b588458SPeter Avalos struct Node *narg[1]; /* variable: actual size set by calling malloc */ 1664b588458SPeter Avalos } Node; 1674b588458SPeter Avalos 1684b588458SPeter Avalos #define NIL ((Node *) 0) 1694b588458SPeter Avalos 1704b588458SPeter Avalos extern Node *winner; 1714b588458SPeter Avalos extern Node *nullstat; 1724b588458SPeter Avalos extern Node *nullnode; 1734b588458SPeter Avalos 1744b588458SPeter Avalos /* ctypes */ 1754b588458SPeter Avalos #define OCELL 1 1764b588458SPeter Avalos #define OBOOL 2 1774b588458SPeter Avalos #define OJUMP 3 1784b588458SPeter Avalos 1794b588458SPeter Avalos /* Cell subtypes: csub */ 1804b588458SPeter Avalos #define CFREE 7 1814b588458SPeter Avalos #define CCOPY 6 1824b588458SPeter Avalos #define CCON 5 1834b588458SPeter Avalos #define CTEMP 4 1844b588458SPeter Avalos #define CNAME 3 1854b588458SPeter Avalos #define CVAR 2 1864b588458SPeter Avalos #define CFLD 1 1874b588458SPeter Avalos #define CUNK 0 1884b588458SPeter Avalos 1894b588458SPeter Avalos /* bool subtypes */ 1904b588458SPeter Avalos #define BTRUE 11 1914b588458SPeter Avalos #define BFALSE 12 1924b588458SPeter Avalos 1934b588458SPeter Avalos /* jump subtypes */ 1944b588458SPeter Avalos #define JEXIT 21 1954b588458SPeter Avalos #define JNEXT 22 1964b588458SPeter Avalos #define JBREAK 23 1974b588458SPeter Avalos #define JCONT 24 1984b588458SPeter Avalos #define JRET 25 1994b588458SPeter Avalos #define JNEXTFILE 26 2004b588458SPeter Avalos 2014b588458SPeter Avalos /* node types */ 2024b588458SPeter Avalos #define NVALUE 1 2034b588458SPeter Avalos #define NSTAT 2 2044b588458SPeter Avalos #define NEXPR 3 2054b588458SPeter Avalos 2064b588458SPeter Avalos 2074b588458SPeter Avalos extern int pairstack[], paircnt; 2084b588458SPeter Avalos 2094b588458SPeter Avalos #define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) 2104b588458SPeter Avalos #define isvalue(n) ((n)->ntype == NVALUE) 2114b588458SPeter Avalos #define isexpr(n) ((n)->ntype == NEXPR) 2124b588458SPeter Avalos #define isjump(n) ((n)->ctype == OJUMP) 2134b588458SPeter Avalos #define isexit(n) ((n)->csub == JEXIT) 2144b588458SPeter Avalos #define isbreak(n) ((n)->csub == JBREAK) 2154b588458SPeter Avalos #define iscont(n) ((n)->csub == JCONT) 2164b588458SPeter Avalos #define isnext(n) ((n)->csub == JNEXT || (n)->csub == JNEXTFILE) 2174b588458SPeter Avalos #define isret(n) ((n)->csub == JRET) 2184b588458SPeter Avalos #define isrec(n) ((n)->tval & REC) 2194b588458SPeter Avalos #define isfld(n) ((n)->tval & FLD) 2204b588458SPeter Avalos #define isstr(n) ((n)->tval & STR) 2214b588458SPeter Avalos #define isnum(n) ((n)->tval & NUM) 2224b588458SPeter Avalos #define isarr(n) ((n)->tval & ARR) 2234b588458SPeter Avalos #define isfcn(n) ((n)->tval & FCN) 2244b588458SPeter Avalos #define istrue(n) ((n)->csub == BTRUE) 2254b588458SPeter Avalos #define istemp(n) ((n)->csub == CTEMP) 2264b588458SPeter Avalos #define isargument(n) ((n)->nobj == ARG) 2274b588458SPeter Avalos /* #define freeable(p) (!((p)->tval & DONTFREE)) */ 2284b588458SPeter Avalos #define freeable(p) ( ((p)->tval & (STR|DONTFREE)) == STR ) 2294b588458SPeter Avalos 2304b588458SPeter Avalos /* structures used by regular expression matching machinery, mostly b.c: */ 2314b588458SPeter Avalos 232*ed569bc2SAaron LI #define NCHARS (1256+3) /* 256 handles 8-bit chars; 128 does 7-bit */ 233*ed569bc2SAaron LI /* BUG: some overflows (caught) if we use 256 */ 2344b588458SPeter Avalos /* watch out in match(), etc. */ 2351d48fce0SDaniel Fojt #define HAT (NCHARS+2) /* matches ^ in regular expr */ 2364b588458SPeter Avalos #define NSTATES 32 2374b588458SPeter Avalos 2384b588458SPeter Avalos typedef struct rrow { 2394b588458SPeter Avalos long ltype; /* long avoids pointer warnings on 64-bit */ 2404b588458SPeter Avalos union { 2414b588458SPeter Avalos int i; 2424b588458SPeter Avalos Node *np; 2434b588458SPeter Avalos uschar *up; 244*ed569bc2SAaron LI int *rp; /* rune representation of char class */ 2454b588458SPeter Avalos } lval; /* because Al stores a pointer in it! */ 2464b588458SPeter Avalos int *lfollow; 2474b588458SPeter Avalos } rrow; 2484b588458SPeter Avalos 249*ed569bc2SAaron LI typedef struct gtte { /* gototab entry */ 250*ed569bc2SAaron LI unsigned int ch; 251*ed569bc2SAaron LI unsigned int state; 252*ed569bc2SAaron LI } gtte; 253*ed569bc2SAaron LI 254*ed569bc2SAaron LI typedef struct gtt { /* gototab */ 255*ed569bc2SAaron LI size_t allocated; 256*ed569bc2SAaron LI size_t inuse; 257*ed569bc2SAaron LI gtte *entries; 258*ed569bc2SAaron LI } gtt; 259*ed569bc2SAaron LI 2604b588458SPeter Avalos typedef struct fa { 261*ed569bc2SAaron LI gtt *gototab; 2621d48fce0SDaniel Fojt uschar *out; 2634b588458SPeter Avalos uschar *restr; 2641d48fce0SDaniel Fojt int **posns; 2651d48fce0SDaniel Fojt int state_count; 2661d48fce0SDaniel Fojt bool anchor; 2674b588458SPeter Avalos int use; 2684b588458SPeter Avalos int initstat; 2694b588458SPeter Avalos int curstat; 2704b588458SPeter Avalos int accept; 2714b588458SPeter Avalos struct rrow re[1]; /* variable: actual size set by calling malloc */ 2724b588458SPeter Avalos } fa; 2734b588458SPeter Avalos 2744b588458SPeter Avalos 2754b588458SPeter Avalos #include "proto.h" 276