#ifndef COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_ #define COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_ #include "libc/assert.h" #include "libc/limits.h" #include "libc/literal.h" #include "libc/stdio/stdio.h" COSMOPOLITAN_C_START_ typedef double Awkfloat; /* unsigned char is more trouble than it's worth */ typedef unsigned char uschar; #define xfree(a) { if ((a) != NULL) { free((void *)(intptr_t)(a)); (a) = NULL; } } /* * We sometimes cheat writing read-only pointers to NUL-terminate them * and then put back the original value */ #define setptr(ptr, a) (*(char *)(intptr_t)(ptr)) = (a) #define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for DPRINTF */ #define DEBUG #ifdef DEBUG # define DPRINTF(...) if (dbg) printf(__VA_ARGS__) #else # define DPRINTF(...) #endif extern enum compile_states { RUNNING, COMPILING, ERROR_PRINTING } compile_time; extern bool safe; /* false => unsafe, true => safe */ #define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ extern int recsize; /* size of current record, orig RECSIZE */ extern char EMPTY[]; /* this avoid -Wwritable-strings issues */ extern char **FS; extern char **RS; extern char **ORS; extern char **OFS; extern char **OFMT; extern Awkfloat *NR; extern Awkfloat *FNR; extern Awkfloat *NF; extern char **FILENAME; extern char **SUBSEP; extern Awkfloat *RSTART; extern Awkfloat *RLENGTH; extern char *record; /* points to $0 */ extern int lineno; /* line number in awk program */ extern int errorflag; /* 1 if error has occurred */ extern bool donefld; /* true if record broken into fields */ extern bool donerec; /* true if record is valid (no fld has changed */ extern int dbg; extern const char *patbeg; /* beginning of pattern matched */ extern int patlen; /* length of pattern matched. set in b.c */ /* Cell: all information about a variable or constant */ typedef struct Cell { uschar ctype; /* OCELL, OBOOL, OJUMP, etc. */ uschar csub; /* CCON, CTEMP, CFLD, etc. */ char *nval; /* name, for variables only */ char *sval; /* string value */ Awkfloat fval; /* value as number */ int tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE|CONVC|CONVO */ char *fmt; /* CONVFMT/OFMT value used to convert from number */ struct Cell *cnext; /* ptr to next if chained */ } Cell; typedef struct Array { /* symbol table array */ int nelem; /* elements in table right now */ int size; /* size of tab */ Cell **tab; /* hash table pointers */ } Array; #define NSYMTAB 50 /* initial size of a symbol table */ extern Array *symtab; extern Cell *nrloc; /* NR */ extern Cell *fnrloc; /* FNR */ extern Cell *fsloc; /* FS */ extern Cell *nfloc; /* NF */ extern Cell *ofsloc; /* OFS */ extern Cell *orsloc; /* ORS */ extern Cell *rsloc; /* RS */ extern Cell *rstartloc; /* RSTART */ extern Cell *rlengthloc; /* RLENGTH */ extern Cell *subseploc; /* SUBSEP */ extern Cell *symtabloc; /* SYMTAB */ /* Cell.tval values: */ #define NUM 01 /* number value is valid */ #define STR 02 /* string value is valid */ #define DONTFREE 04 /* string space is not freeable */ #define CON 010 /* this is a constant */ #define ARR 020 /* this is an array */ #define FCN 040 /* this is a function name */ #define FLD 0100 /* this is a field $1, $2, ... */ #define REC 0200 /* this is $0 */ #define CONVC 0400 /* string was converted from number via CONVFMT */ #define CONVO 01000 /* string was converted from number via OFMT */ /* function types */ #define FLENGTH 1 #define FSQRT 2 #define FEXP 3 #define FLOG 4 #define FINT 5 #define FSYSTEM 6 #define FRAND 7 #define FSRAND 8 #define FSIN 9 #define FCOS 10 #define FATAN 11 #define FTOUPPER 12 #define FTOLOWER 13 #define FFLUSH 14 /* Node: parse tree is made of nodes, with Cell's at bottom */ typedef struct Node { int ntype; struct Node *nnext; int lineno; int nobj; struct Node *narg[1]; /* variable: actual size set by calling malloc */ } Node; #define NIL ((Node *) 0) extern Node *winner; extern Node *nullstat; extern Node *nullnode; /* ctypes */ #define OCELL 1 #define OBOOL 2 #define OJUMP 3 /* Cell subtypes: csub */ #define CFREE 7 #define CCOPY 6 #define CCON 5 #define CTEMP 4 #define CNAME 3 #define CVAR 2 #define CFLD 1 #define CUNK 0 /* bool subtypes */ #define BTRUE 11 #define BFALSE 12 /* jump subtypes */ #define JEXIT 21 #define JNEXT 22 #define JBREAK 23 #define JCONT 24 #define JRET 25 #define JNEXTFILE 26 /* node types */ #define NVALUE 1 #define NSTAT 2 #define NEXPR 3 extern int pairstack[], paircnt; #define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) #define isvalue(n) ((n)->ntype == NVALUE) #define isexpr(n) ((n)->ntype == NEXPR) #define isjump(n) ((n)->ctype == OJUMP) #define isexit(n) ((n)->csub == JEXIT) #define isbreak(n) ((n)->csub == JBREAK) #define iscont(n) ((n)->csub == JCONT) #define isnext(n) ((n)->csub == JNEXT || (n)->csub == JNEXTFILE) #define isret(n) ((n)->csub == JRET) #define isrec(n) ((n)->tval & REC) #define isfld(n) ((n)->tval & FLD) #define isstr(n) ((n)->tval & STR) #define isnum(n) ((n)->tval & NUM) #define isarr(n) ((n)->tval & ARR) #define isfcn(n) ((n)->tval & FCN) #define istrue(n) ((n)->csub == BTRUE) #define istemp(n) ((n)->csub == CTEMP) #define isargument(n) ((n)->nobj == ARG) /* #define freeable(p) (!((p)->tval & DONTFREE)) */ #define freeable(p) ( ((p)->tval & (STR|DONTFREE)) == STR ) /* structures used by regular expression matching machinery, mostly b.c: */ #define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */ /* watch out in match(), etc. */ #define HAT (NCHARS+2) /* matches ^ in regular expr */ #define NSTATES 32 typedef struct rrow { long ltype; /* long avoids pointer warnings on 64-bit */ union { int i; Node *np; uschar *up; } lval; /* because Al stores a pointer in it! */ int *lfollow; } rrow; typedef struct fa { unsigned int **gototab; uschar *out; uschar *restr; int **posns; int state_count; bool anchor; int use; int initstat; int curstat; int accept; struct rrow re[1]; /* variable: actual size set by calling malloc */ } fa; extern int yywrap(void); extern void setfname(Cell *); extern int constnode(Node *); extern char *strnode(Node *); extern Node *notnull(Node *); extern int yyparse(void); extern int yylex(void); extern void startreg(void); extern int input(void); extern void unput(int); extern void unputstr(const char *); extern int yylook(void); extern int yyback(int *, int); extern int yyinput(void); extern fa *makedfa(const char *, bool); extern fa *mkdfa(const char *, bool); extern int makeinit(fa *, bool); extern void penter(Node *); extern void freetr(Node *); extern int hexstr(const uschar **); extern int quoted(const uschar **); extern char *cclenter(const char *); extern wontreturn void overflo(const char *); extern void cfoll(fa *, Node *); extern int first(Node *); extern void follow(Node *); extern int member(int, const char *); extern int match(fa *, const char *); extern int pmatch(fa *, const char *); extern int nematch(fa *, const char *); extern bool fnematch(fa *, FILE *, char **, int *, int); extern Node *reparse(const char *); extern Node *regexp(void); extern Node *primary(void); extern Node *concat(Node *); extern Node *alt(Node *); extern Node *unary(Node *); extern int relex(void); extern int cgoto(fa *, int, int); extern void freefa(fa *); extern int pgetc(void); extern char *cursource(void); extern Node *nodealloc(int); extern Node *exptostat(Node *); extern Node *node1(int, Node *); extern Node *node2(int, Node *, Node *); extern Node *node3(int, Node *, Node *, Node *); extern Node *node4(int, Node *, Node *, Node *, Node *); extern Node *stat3(int, Node *, Node *, Node *); extern Node *op2(int, Node *, Node *); extern Node *op1(int, Node *); extern Node *stat1(int, Node *); extern Node *op3(int, Node *, Node *, Node *); extern Node *op4(int, Node *, Node *, Node *, Node *); extern Node *stat2(int, Node *, Node *); extern Node *stat4(int, Node *, Node *, Node *, Node *); extern Node *celltonode(Cell *, int); extern Node *rectonode(void); extern Node *makearr(Node *); extern Node *pa2stat(Node *, Node *, Node *); extern Node *linkum(Node *, Node *); extern void defn(Cell *, Node *, Node *); extern int isarg(const char *); extern const char *tokname(int); extern Cell *(*proctab[])(Node **, int); extern int ptoi(void *); extern Node *itonp(int); extern void syminit(void); extern void arginit(int, char **); extern void envinit(char **); extern Array *makesymtab(int); extern void freesymtab(Cell *); extern void freeelem(Cell *, const char *); extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *); extern int hash(const char *, int); extern void rehash(Array *); extern Cell *lookup(const char *, Array *); extern double setfval(Cell *, double); extern void funnyvar(Cell *, const char *); extern char *setsval(Cell *, const char *); extern double getfval(Cell *); extern char *getsval(Cell *); extern char *getpssval(Cell *); /* for print */ extern char *tostring(const char *); extern char *tostringN(const char *, size_t); extern char *qstring(const char *, int); extern Cell *catstr(Cell *, Cell *); extern void recinit(unsigned int); extern void initgetrec(void); extern void makefields(int, int); extern void growfldtab(int n); extern void savefs(void); extern int getrec(char **, int *, bool); extern void nextfile(void); extern int readrec(char **buf, int *bufsize, FILE *inf, bool isnew); extern char *getargv(int); extern void setclvar(char *); extern void fldbld(void); extern void cleanfld(int, int); extern void newfld(int); extern void setlastfld(int); extern int refldbld(const char *, const char *); extern void recbld(void); extern Cell *fieldadr(int); extern void yyerror(const char *); extern void bracecheck(void); extern void bcheck2(int, int, int); extern void SYNTAX(const char *, ...) __attribute__((__format__(__printf__, 1, 2))); extern wontreturn void FATAL(const char *, ...) __attribute__((__format__(__printf__, 1, 2))); extern void WARNING(const char *, ...) __attribute__((__format__(__printf__, 1, 2))); extern void error(void); extern void eprint(void); extern void bclass(int); extern double errcheck(double, const char *); extern int isclvar(const char *); extern bool is_valid_number(const char *s, bool trailing_stuff_ok, bool *no_trailing, double *result); #define is_number(s, val) is_valid_number(s, false, NULL, val) extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what); extern void run(Node *); extern Cell *execute(Node *); extern Cell *program(Node **, int); extern Cell *call(Node **, int); extern Cell *copycell(Cell *); extern Cell *arg(Node **, int); extern Cell *jump(Node **, int); extern Cell *awkgetline(Node **, int); extern Cell *getnf(Node **, int); extern Cell *array(Node **, int); extern Cell *awkdelete(Node **, int); extern Cell *intest(Node **, int); extern Cell *matchop(Node **, int); extern Cell *boolop(Node **, int); extern Cell *relop(Node **, int); extern void tfree(Cell *); extern Cell *gettemp(void); extern Cell *field(Node **, int); extern Cell *indirect(Node **, int); extern Cell *substr(Node **, int); extern Cell *sindex(Node **, int); extern int format(char **, int *, const char *, Node *); extern Cell *awksprintf(Node **, int); extern Cell *awkprintf(Node **, int); extern Cell *arith(Node **, int); extern double ipow(double, int); extern Cell *incrdecr(Node **, int); extern Cell *assign(Node **, int); extern Cell *cat(Node **, int); extern Cell *pastat(Node **, int); extern Cell *dopa2(Node **, int); extern Cell *split(Node **, int); extern Cell *condexpr(Node **, int); extern Cell *ifstat(Node **, int); extern Cell *whilestat(Node **, int); extern Cell *dostat(Node **, int); extern Cell *forstat(Node **, int); extern Cell *instat(Node **, int); extern Cell *bltin(Node **, int); extern Cell *printstat(Node **, int); extern Cell *nullproc(Node **, int); extern FILE *redirect(int, Node *); extern FILE *openfile(int, const char *, bool *); extern const char *filename(FILE *); extern Cell *closefile(Node **, int); extern void closeall(void); extern Cell *sub(Node **, int); extern Cell *gsub(Node **, int); extern const char *flags2str(int flags); COSMOPOLITAN_C_END_ #endif /* COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_ */