aboutsummaryrefslogtreecommitdiffstats
path: root/awk.h
diff options
context:
space:
mode:
Diffstat (limited to 'awk.h')
-rw-r--r--awk.h649
1 files changed, 464 insertions, 185 deletions
diff --git a/awk.h b/awk.h
index be792e07..fce57f65 100644
--- a/awk.h
+++ b/awk.h
@@ -1,163 +1,351 @@
/*
- * awk.h -- Definitions for gawk.
+ * awk.h -- Definitions for gawk.
*
- * Copyright (C) 1986 Free Software Foundation
- * Written by Paul Rubin, August 1986
+ * Copyright (C) 1986 Free Software Foundation Written by Paul Rubin, August
+ * 1986
+ *
+ * $Log: awk.h,v $
+ * Revision 1.29 88/12/15 12:52:10 david
+ * casetable made static elsewhere
+ *
+ * Revision 1.28 88/12/14 10:50:21 david
+ * change FREE_TEMP macro to free_temp
+ *
+ * Revision 1.27 88/12/13 22:20:09 david
+ * macro-front-end tree_eval, force_string and force_number
+ *
+ * Revision 1.25 88/12/08 15:57:11 david
+ * added some #ifdef'd out debugging code
+ *
+ * Revision 1.24 88/12/07 19:58:37 david
+ * changes for printing current source file in error messages
+ *
+ * Revision 1.23 88/12/01 15:07:10 david
+ * changes to accomodate source line numbers in error messages
+ *
+ * Revision 1.22 88/11/30 15:14:59 david
+ * FREE_ONE_REFERENCE macro merged inot do_deref()
+ *
+ * Revision 1.21 88/11/29 15:17:01 david
+ * minor movement
+ *
+ * Revision 1.20 88/11/23 21:36:00 david
+ * Arnold: portability addition
+ *
+ * Revision 1.19 88/11/22 15:51:23 david
+ * changed order of elements in NODE decl. for better packing on sparc and
+ * similar machines
+ *
+ * Revision 1.18 88/11/22 13:45:15 david
+ * Arnold: changes for case-insensitive matching
+ *
+ * Revision 1.17 88/11/15 10:15:28 david
+ * Arnold: move a bunch of #include's here
+ *
+ * Revision 1.16 88/11/14 21:50:26 david
+ * Arnold: get sprintf() declaration right; correct STREQ macro
+ *
+ * Revision 1.15 88/11/14 21:24:50 david
+ * added extern decl. for field_num
+ *
+ * Revision 1.14 88/11/03 15:21:03 david
+ * extended flags defines; made force_number safe; added TEMP_FREE define
+ *
+ * Revision 1.13 88/11/01 12:52:18 david
+ * allowed for vprintf code in awk5.c
+ *
+ * Revision 1.12 88/11/01 12:07:27 david
+ * cleanup; additions of external declarations; added variable name to node;
+ * moved flags from sub.val to node proper
+ *
+ * Revision 1.11 88/10/19 21:54:29 david
+ * safe_malloc to be used by obstack_alloc
+ * Node_val to replace other value types (to be done)
+ * emalloc and erealloc macros
+ *
+ * Revision 1.10 88/10/17 19:52:50 david
+ * Arnold: fix cant_happen(); improve VPRINTF; purge FAST
+ *
+ * Revision 1.9 88/10/13 22:02:47 david
+ * added some external declarations to make life easier
+ * #define VPRINTF for portable variable arg list handling
+ *
+ * Revision 1.8 88/10/11 22:19:05 david
+ * added external decl.
+ *
+ * Revision 1.7 88/06/05 22:15:40 david
+ * deleted level member from hashnode structure
+ *
+ * Revision 1.6 88/06/05 22:05:25 david
+ * added cnt member to NODE structure (doesn't add to size, since val member
+ * dominates)
+ *
+ * Revision 1.5 88/05/31 09:29:14 david
+ * expunge Node_local_var
+ *
+ * Revision 1.4 88/05/27 11:04:07 david
+ * changed AWKNUM to double to correspond to nawk
+ *
+ * Revision 1.3 88/05/13 22:07:56 david
+ * moved some defines here from elsewhere
+ *
+ * Revision 1.2 88/05/04 12:17:04 david
+ * make_for_loop() now returns a NODE *
+ *
+ * Revision 1.1 88/04/08 15:15:25 david
+ * Initial revision
+ * Revision 1.6 88/04/08 14:48:25 david changes from Arnold
+ * Robbins
+ *
+ * Revision 1.5 88/03/23 22:17:23 david mostly delinting -- a couple of bug
+ * fixes
+ *
+ * Revision 1.4 88/03/18 21:00:05 david Baseline -- hoefully all the
+ * functionality of the new awk added. Just debugging and tuning to do.
+ *
+ * Revision 1.3 87/11/19 14:34:12 david added a bunch of new Node types added
+ * a new union entry to the expnode structure to accomodate function
+ * parameter names added a level variable to the symbol structure to keep
+ * track of function nesting level
+ *
+ * Revision 1.2 87/10/29 21:48:32 david added Node_in_array NODETYPE
+ *
+ * Revision 1.1 87/10/27 15:23:07 david Initial revision
*
*/
/*
-GAWK is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GAWK General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GAWK,
-but only under the conditions described in the GAWK General Public
-License. A copy of this license is supposed to have been given to you
-along with GAWK so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GAWK, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
+ * GAWK is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY. No author or distributor accepts responsibility to anyone for
+ * the consequences of using it or for whether it serves any particular
+ * purpose or works at all, unless he says so in writing. Refer to the GAWK
+ * General Public License for full details.
+ *
+ * Everyone is granted permission to copy, modify and redistribute GAWK, but
+ * only under the conditions described in the GAWK General Public License. A
+ * copy of this license is supposed to have been given to you along with GAWK
+ * so you can know your rights and responsibilities. It should be in a file
+ * named COPYING. Among other things, the copyright notice and this notice
+ * must be preserved on all copies.
+ *
+ * In other words, go ahead and share GAWK, but don't try to stop anyone else
+ * from sharing it farther. Help stamp out software hoarding!
+ */
-#define AWKNUM float
+#define AWKNUM double
+#include <stdio.h>
#include <ctype.h>
+#include <setjmp.h>
+#include <varargs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "regex.h"
#define is_identchar(c) (isalnum(c) || (c) == '_')
+#ifdef notdef
+#define free do_free /* for debugging */
+#define malloc do_malloc /* for debugging */
+#endif
+
#include "obstack.h"
-#define obstack_chunk_alloc malloc
+#define obstack_chunk_alloc safe_malloc
#define obstack_chunk_free free
-char *malloc(),*realloc();
+char *malloc(), *realloc();
+char *safe_malloc();
void free();
typedef enum {
- /* illegal entry == 0 */
- Node_illegal, /* 0 */
-
- /* binary operators lnode and rnode are the expressions to work on */
- Node_times, /* 1 */
- Node_quotient, /* 2 */
- Node_mod, /* 3 */
- Node_plus, /* 4 */
- Node_minus, /* 5 */
- Node_cond_pair, /* 6: conditional pair (see Node_line_range) jfw */
- Node_subscript, /* 7 */
- Node_concat, /* 8 */
-
- /* unary operators subnode is the expression to work on */
- Node_preincrement, /* 9 */
- Node_predecrement, /* 10 */
- Node_postincrement, /* 11 */
- Node_postdecrement, /* 12 */
- Node_unary_minus, /* 13 */
- Node_field_spec, /* 14 */
-
- /* assignments lnode is the var to assign to, rnode is the exp */
- Node_assign, /* 15 */
- Node_assign_times, /* 16 */
- Node_assign_quotient, /* 17 */
- Node_assign_mod, /* 18 */
- Node_assign_plus, /* 19 */
- Node_assign_minus, /* 20 */
-
- /* boolean binaries lnode and rnode are expressions */
- Node_and, /* 21 */
- Node_or, /* 22 */
-
- /* binary relationals compares lnode and rnode */
- Node_equal, /* 23 */
- Node_notequal, /* 24 */
- Node_less, /* 25 */
- Node_greater, /* 26 */
- Node_leq, /* 27 */
- Node_geq, /* 28 */
-
- /* unary relationals works on subnode */
- Node_not, /* 29 */
-
- /* match ops (binary) work on lnode and rnode ??? */
- Node_match, /* 30 */
- Node_nomatch, /* 31 */
-
- /* data items */
- Node_string, /* 32 has stlen, stptr, and stref */
- Node_temp_string, /* 33 has stlen, stptr, and stref */
- Node_number, /* 34 has numbr */
-
- /* program structures */
- Node_rule_list, /* 35 lnode is a rule, rnode is rest of list */
- Node_rule_node, /* 36 lnode is an conditional, rnode is statement */
- Node_statement_list, /* 37 lnode is a statement, rnode is more list */
- Node_if_branches, /* 38 lnode is to run on true, rnode on false */
- Node_expression_list, /* 39 lnode is an exp, rnode is more list */
-
- /* keywords */
- Node_K_BEGIN, /* 40 no stuff */
- Node_K_END, /* 41 ditto */
- Node_K_if, /* 42 lnode is conditonal, rnode is if_branches */
- Node_K_while, /* 43 lnode is condtional, rnode is stuff to run */
- Node_K_for, /* 44 lnode is for_struct, rnode is stuff to run */
- Node_K_arrayfor, /* 45 lnode is for_struct, rnode is stuff to run */
- Node_K_break, /* 46 no subs */
- Node_K_continue, /* 47 no stuff */
- Node_K_print, /* 48 lnode is exp_list, rnode is redirect */
- Node_K_printf, /* 49 lnode is exp_list, rnode is redirect */
- Node_K_next, /* 59 no subs */
- Node_K_exit, /* 51 subnode is return value, or NULL */
-
- /* I/O redirection for print statements */
- Node_redirect_output, /* 52 subnode is where to redirect */
- Node_redirect_append, /* 53 subnode is where to redirect */
- Node_redirect_pipe, /* 54 subnode is where to redirect */
-
- /* Variables */
- Node_var, /* 55 rnode is value, lnode is array stuff */
- Node_var_array, /* 56 array is ptr to elements, asize num of eles */
-
- /* Builtins subnode is explist to work on, proc is func to call */
- Node_builtin, /* 57 */
-
- /* pattern: conditional ',' conditional ; lnode of Node_line_range is
- * the two conditionals (Node_cond_pair), other word (rnode place) is
- * a flag indicating whether or not this range has been entered.
- * (jfw@eddie.mit.edu)
- */
- Node_line_range, /* 58 */
+ /* illegal entry == 0 */
+ Node_illegal, /* 0 */
+
+ /* binary operators lnode and rnode are the expressions to work on */
+ Node_times, /* 1 */
+ Node_quotient, /* 2 */
+ Node_mod, /* 3 */
+ Node_plus, /* 4 */
+ Node_minus, /* 5 */
+ Node_cond_pair, /* 6: conditional pair (see Node_line_range)
+ * jfw */
+ Node_subscript, /* 7 */
+ Node_concat, /* 8 */
+
+ /* unary operators subnode is the expression to work on */
+ Node_preincrement, /* 9 */
+ Node_predecrement, /* 10 */
+ Node_postincrement, /* 11 */
+ Node_postdecrement, /* 12 */
+ Node_unary_minus, /* 13 */
+ Node_field_spec, /* 14 */
+
+ /* assignments lnode is the var to assign to, rnode is the exp */
+ Node_assign, /* 15 */
+ Node_assign_times, /* 16 */
+ Node_assign_quotient, /* 17 */
+ Node_assign_mod, /* 18 */
+ Node_assign_plus, /* 19 */
+ Node_assign_minus, /* 20 */
+
+ /* boolean binaries lnode and rnode are expressions */
+ Node_and, /* 21 */
+ Node_or, /* 22 */
+
+ /* binary relationals compares lnode and rnode */
+ Node_equal, /* 23 */
+ Node_notequal, /* 24 */
+ Node_less, /* 25 */
+ Node_greater, /* 26 */
+ Node_leq, /* 27 */
+ Node_geq, /* 28 */
+
+ /* unary relationals works on subnode */
+ Node_not, /* 29 */
+
+ /* match ops (binary) work on lnode and rnode ??? */
+ Node_match, /* 30 */
+ Node_nomatch, /* 31 */
+
+ /* data items */
+ Node_string, /* deprecated: 32 has stlen, stptr, and stref */
+ Node_temp_string, /* deprecated: 33 has stlen, stptr, and stref */
+ Node_number, /* deprecated: 34 has numbr */
+
+ /* program structures */
+ Node_rule_list, /* 35 lnode is a rule, rnode is rest of list */
+ Node_rule_node, /* 36 lnode is an conditional, rnode is
+ * statement */
+ Node_statement_list, /* 37 lnode is a statement, rnode is more
+ * list */
+ Node_if_branches, /* 38 lnode is to run on true, rnode on false */
+ Node_expression_list, /* 39 lnode is an exp, rnode is more list */
+ Node_param_list, /* 40 lnode is a variable, rnode is more list */
+
+ /* keywords */
+ Node_K_BEGIN, /* 41 no stuff */
+ Node_K_END, /* 42 ditto */
+ Node_K_if, /* 43 lnode is conditonal, rnode is
+ * if_branches */
+ Node_K_while, /* 44 lnode is condtional, rnode is stuff to
+ * run */
+ Node_K_for, /* 45 lnode is for_struct, rnode is stuff to
+ * run */
+ Node_K_arrayfor, /* 46 lnode is for_struct, rnode is stuff to
+ * run */
+ Node_K_break, /* 47 no subs */
+ Node_K_continue, /* 48 no stuff */
+ Node_K_print, /* 49 lnode is exp_list, rnode is redirect */
+ Node_K_printf, /* 50 lnode is exp_list, rnode is redirect */
+ Node_K_next, /* 51 no subs */
+ Node_K_exit, /* 52 subnode is return value, or NULL */
+ Node_K_do, /* 53 lnode is conditional, rnode is stuff to
+ * run */
+ Node_K_return, /* 54 */
+ Node_K_delete, /* 55 */
+
+ /* I/O redirection for print statements */
+ Node_redirect_output, /* 56 subnode is where to redirect */
+ Node_redirect_append, /* 57 subnode is where to redirect */
+ Node_redirect_pipe, /* 58 subnode is where to redirect */
+ Node_redirect_pipein, /* 59 subnode is where to redirect */
+ Node_redirect_input, /* 60 subnode is where to redirect */
+
+ /* Variables */
+ Node_var, /* 61 rnode is value, lnode is array stuff */
+ Node_var_array, /* 62 array is ptr to elements, asize num of
+ * eles */
+
+ /* Builtins subnode is explist to work on, proc is func to call */
+ Node_builtin, /* 63 */
+
+ /*
+ * pattern: conditional ',' conditional ; lnode of Node_line_range
+ * is the two conditionals (Node_cond_pair), other word (rnode place)
+ * is a flag indicating whether or not this range has been entered.
+ * (jfw@eddie.mit.edu)
+ */
+ Node_line_range, /* 64 */
+
+ /*
+ * boolean test of membership in array lnode is string-valued
+ * expression rnode is array name
+ */
+ Node_in_array, /* 65 */
+ Node_K_function, /* 66 lnode is statement list, rnode is
+ * func_params */
+ Node_func, /* 67 lnode is param. list, rnode is
+ * statement list */
+ Node_func_call, /* 68 lnode is name, rnode is expression list */
+ Node_K_getline, /* 69 */
+ Node_sub, /* 70 */
+ Node_gsub, /* 71 */
+ Node_K_match, /* 72 */
+ Node_cond_exp, /* 73 lnode is conditonal, rnode is
+ * if_branches */
+ Node_exp, /* 74 */
+ Node_assign_exp, /* 75 */
+ Node_regex, /* 76 */
+ Node_str_num, /* deprecated: 77 both string and numeric
+ * values are valid
+ */
+ Node_val, /* 78 node is a value - type given by bits in
+ * status - to replace Node_string, Node_num,
+ * Node_temp_str and Node_str_num
+ */
+ Node_case_match, /* 79 case independant regexp match */
+ Node_case_nomatch, /* 80 case independant regexp no match */
} NODETYPE;
typedef struct exp_node {
- NODETYPE type;
- union {
- struct {
- struct exp_node *lptr;
- union {
- struct exp_node *rptr;
- struct exp_node *(* pptr)();
- struct re_pattern_buffer *preg;
- struct for_loop_header *hd;
- struct ahash **av;
- int r_ent; /* range entered (jfw) */
- } r;
- } nodep;
- struct {
- struct exp_node **ap;
- int as;
- } ar;
- struct {
- char *sp;
- short slen,sref;
- } str;
- AWKNUM fltnum;
- } sub;
+ NODETYPE type;
+ union {
+ struct {
+ union {
+ struct exp_node *lptr;
+ char *param_name;
+ } l;
+ union {
+ struct exp_node *rptr;
+ struct exp_node *(*pptr) ();
+ struct re_pattern_buffer *preg;
+ struct for_loop_header *hd;
+ struct ahash **av;
+ int r_ent; /* range entered (jfw) */
+ } r;
+ int number;
+ char *name;
+ } nodep;
+ struct {
+ struct exp_node **ap;
+ int as;
+ } ar;
+ struct {
+ char *sp;
+ AWKNUM fltnum; /* this is here for optimal packing of
+ * the structure on many machines
+ */
+ short slen;
+ unsigned char sref;
+ } val;
+ } sub;
+ unsigned char flags;
+# define MEM 0x7
+# define MALLOC 1 /* can be free'd */
+# define TEMP 2 /* should be free'd */
+# define PERM 4 /* can't be free'd */
+# define VAL 0x18
+# define NUM 8
+# define STR 16
} NODE;
-#define lnode sub.nodep.lptr
+#define lnode sub.nodep.l.lptr
#define rnode sub.nodep.r.rptr
+#define varname sub.nodep.name
+#define source_file sub.nodep.name
+#define source_line sub.nodep.number
+#define param_cnt sub.nodep.number
+#define param sub.nodep.l.param_name
#define subnode lnode
#define proc sub.nodep.r.pptr
@@ -166,16 +354,17 @@ typedef struct exp_node {
#define rereg sub.nodep.r.preg
#define forsub lnode
-#define forloop sub.nodep.r.hd
+#define forloop rnode->sub.nodep.r.hd
#define array sub.ar.ap
#define arrsiz sub.ar.as
-#define stptr sub.str.sp
-#define stlen sub.str.slen
-#define stref sub.str.sref
+#define stptr sub.val.sp
+#define stlen sub.val.slen
+#define stref sub.val.sref
+#define valstat flags
-#define numbr sub.fltnum
+#define numbr sub.val.fltnum
#define var_value lnode
#define var_array sub.nodep.r.av
@@ -184,33 +373,43 @@ typedef struct exp_node {
#define triggered sub.nodep.r.r_ent
NODE *newnode(), *dupnode();
-NODE *node(), *snode(), *make_number(), *make_string();
-NODE *mkrangenode(); /* to remove the temptation to use sub.nodep.r.rptr
- * as a boolean flag, or to call node() with a 0 and
- * hope that it will store correctly as an int. (jfw)
- */
-NODE *tmp_string(),*tmp_number();
+NODE *node(), *snode(), *make_number(), *make_string(), *make_name();
+NODE *make_param();
+NODE *mkrangenode(); /* to remove the temptation to use
+ * sub.nodep.r.rptr as a boolean flag, or to
+ * call node() with a 0 and hope that it will
+ * store correctly as an int. (jfw) */
+NODE *tmp_string(), *tmp_number();
NODE *variable(), *append_right();
-NODE *tree_eval();
+NODE *r_tree_eval();
+NODE **get_lhs();
struct re_pattern_buffer *make_regexp();
+extern NODE **stack_ptr;
extern NODE *Nnull_string;
-
-#ifdef FAST
-double atof();
-NODE *strforce();
-#define force_number(x) ((x)->type==Node_number ? (x)->numbr : atof((x)->stptr))
-#define force_string(x) ((x)->type==Node_number ? (strforce(x)) : (x))
-#define tmp_node(ty) (global_tmp=(NODE *)obstack_alloc(&temp_strings,sizeof(NODE)),global_tmp->type=ty)
-#define tmp_number(n) (tmp_node(Node_number),global_tmp->numbr=(n),global_tmp)
-/* #define tmp_string(s,len) (tmp_node(Node_temp_string),global_tmp->stref=1,global_tmp->stlen=len,global_tmp->stptr=(char *)obstack_alloc(&temp_strings,len+1),bcopy(s,global_tmp->stptr,len),global_tmp->stptr[len]='\0',global_tmp) */
-NODE *global_tmp;
+extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
+extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
+extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
+
+extern struct obstack other_stack;
+extern NODE *deref;
+extern NODE **fields_arr;
+extern int sourceline;
+extern char *source;
+
+#ifdef USG
+int sprintf();
#else
-AWKNUM force_number();
-NODE *force_string();
+char *sprintf();
#endif
+char *strcpy(), *strcat();
+
+double atof();
+AWKNUM r_force_number();
+NODE *r_force_string();
+
NODE *expression_value;
@@ -218,38 +417,118 @@ NODE *expression_value;
typedef struct hashnode HASHNODE;
struct hashnode {
- HASHNODE *next;
- char *name;
- int length;
- NODE *value;
+ HASHNODE *next;
+ char *name;
+ int length;
+ NODE *value;
} *variables[HASHSIZE];
typedef struct ahash AHASH;
struct ahash {
AHASH *next;
- NODE *name,
- *symbol,
- *value;
+ NODE *name, *symbol, *value;
};
typedef struct for_loop_header {
- NODE *init;
- NODE *cond;
- NODE *incr;
+ NODE *init;
+ NODE *cond;
+ NODE *incr;
} FOR_LOOP_HEADER;
-FOR_LOOP_HEADER *make_for_loop();
-
-#define ADD_ONE_REFERENCE(s) ++(s)->stref
-#define FREE_ONE_REFERENCE(s) {\
- if(s==Nnull_string) {\
- fprintf(stderr,"Free_Nnull_string %d",(s)->stref);\
- }\
- if (--(s)->stref == 0) {\
- free((char *)((s)->stptr));\
- free((char *)s);\
- }\
-}
-/* #define FREE_ONE_REFERENCE(s) {if (--(s)->stref == 0) {printf("FREE %x\n",s);free((s)->stptr);free(s);}} */
+NODE *make_for_loop();
+
+/* for "for(iggy in foo) {" */
+struct search {
+ int numleft;
+ AHASH **arr_ptr;
+ AHASH *bucket;
+ NODE *symbol;
+ NODE *retval;
+};
+
+struct search *assoc_scan(), *assoc_next();
+
+extern NODE *_t; /* used as temporary in following macro */
+extern NODE *_result;
+#define tree_eval(t) (_result = (_t = (t),(_t) == NULL ? Nnull_string : \
+ ((_t)->type == Node_val ? (_t) : r_tree_eval((_t)))))
+
+#define free_temp(n) if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
+#define free_result() if (_result) free_temp(_result); else
+
+#ifdef USG
+#define index strchr
+#define rindex strrchr
+#define bcmp memcmp
+/* nasty nasty berkelixm */
+#define _setjmp setjmp
+#define _longjmp longjmp
+#endif
+
+char *index();
+
+/* longjmp return codes, must be nonzero */
+/* Continue means either for loop/while continue, or next input record */
+#define TAG_CONTINUE 1
+/* Break means either for/while break, or stop reading input */
+#define TAG_BREAK 2
+/* Return means return from a function call; leave value in ret_node */
+#define TAG_RETURN 3
+
+/*
+ * the loop_tag_valid variable allows continue/break-out-of-context to be
+ * caught and diagnosed (jfw)
+ */
+#define PUSH_BINDING(stack, x, val) (bcopy ((char *)(x), (char *)(stack), sizeof (jmp_buf)), val++)
+#define RESTORE_BINDING(stack, x, val) (bcopy ((char *)(stack), (char *)(x), sizeof (jmp_buf)), val--)
+
+/* nasty nasty SunOS-ism */
+#ifdef sparc
+#include <alloca.h>
+#endif
+
+extern char *myname;
+void msg();
+void warning();
+void illegal_type();
+void fatal();
+
+#define cant_happen() fatal("line %d, file: %s; bailing out", \
+ __LINE__, __FILE__);
+
+/*
+ * if you don't have vprintf, but you are BSD, the version defined in
+ * awk5.c should do the trick. Otherwise, use this and cross your fingers.
+ */
+#if !defined(VPRINTF) && !defined(BSD)
+#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
+#endif
+
+extern int errno;
+extern char *sys_errlist[];
+
+#define emalloc(var,ty,x,str) if ((var = (ty) malloc((unsigned)(x))) == NULL)\
+ fatal("%s: %s: can't allocate memory (%s)",\
+ (str), "var", sys_errlist[errno]); else
+#define erealloc(var,ty,x,str) if((var=(ty)realloc(var,(unsigned)(x)))==NULL)\
+ fatal("%s: %s: can't allocate memory (%s)",\
+ (str), "var", sys_errlist[errno]); else
+#ifdef DEBUG
+#define force_number r_force_number
+#define force_string r_force_string
+#else
+#define force_number(n) (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
+#define force_string(s) (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
+#endif
+
+#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+#define HUGE 0x7fffffff
+
+extern int node0_valid;
+extern int field_num;
+extern NODE **get_field();
+#define WHOLELINE (node0_valid ? fields_arr[0] : *get_field(0))
+
+extern int strict;