aboutsummaryrefslogtreecommitdiffstats
path: root/awk.h
diff options
context:
space:
mode:
Diffstat (limited to 'awk.h')
-rw-r--r--awk.h1439
1 files changed, 779 insertions, 660 deletions
diff --git a/awk.h b/awk.h
index 857741f9..74cba872 100644
--- a/awk.h
+++ b/awk.h
@@ -29,9 +29,6 @@
* config.h absolutely, positively, *M*U*S*T* be included before
* any system headers. Otherwise, extreme death, destruction
* and loss of life results.
- *
- * Well, OK, gawk just won't work on systems using egcs and LFS. But
- * that's almost as bad.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -63,16 +60,19 @@
#endif /* LOCALEDIR */
#endif
-#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
-#define CAN_USE_STDARG_H 1
+#if !defined(__STDC__) || __STDC__ < 1
+#error "gawk no longer supports non-C89 environments (no __STDC__ or __STDC__ < 1)"
+#endif
+
+#if defined(HAVE_STDARG_H)
#include <stdarg.h>
#else
-#include <varargs.h>
+#error "gawk no loner supports <varargs.h>. Please update your compiler and runtime"
#endif
#include <signal.h>
#include <time.h>
#include <errno.h>
-#if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
+#if ! defined(errno) && ! defined(OS2)
extern int errno;
#endif
@@ -101,24 +101,12 @@ extern int errno;
# include <stdint.h>
#endif
#endif /* !ZOS_USS */
-
-#if defined(_MSC_VER)
-/* for read()/close() in use replace.c */
-#include <io.h>
-#endif
/* ----------------- System dependencies (with more includes) -----------*/
/* This section is the messiest one in the file, not a lot that can be done */
-#ifdef __STDC__
-#define P(s) s
#define MALLOC_ARG_T size_t
-#else /* not __STDC__ */
-#define P(s) ()
-#define MALLOC_ARG_T unsigned
-#define volatile
-#endif /* not __STDC__ */
#ifndef VMS
#include <sys/types.h>
@@ -127,6 +115,15 @@ extern int errno;
#include <stddef.h>
#include <stat.h>
#include <file.h> /* avoid <fcntl.h> in io.c */
+/* debug.c needs this; when _DECC_V4_SOURCE is defined (as it is
+ in our config.h [vms/vms-conf.h]), off_t won't get declared */
+# if !defined(__OFF_T) && !defined(_OFF_T)
+# if defined(____OFF_T) || defined(___OFF_T)
+typedef __off_t off_t; /* __off_t is either int or __int64 */
+# else
+typedef int off_t;
+# endif
+# endif
#endif /* VMS */
#if ! defined(S_ISREG) && defined(S_IFREG)
@@ -150,69 +147,50 @@ extern int errno;
#endif /* HAVE_STRINGS_H */
#endif /* not HAVE_STRING_H */
-#ifdef NeXT
-#if __GNUC__ < 2 || __GNUC_MINOR__ < 7
-#include <libc.h>
-#endif
-#undef atof
-#define getopt GNU_getopt
-#define GFMT_WORKAROUND
-#endif /* NeXT */
-
-#if defined(atarist) || defined(VMS)
-#include <unixlib.h>
-#endif /* atarist || VMS */
-
-#if ! defined(MSDOS) && ! defined(OS2) && ! defined(WIN32) && ! defined(__EMX__) && ! defined(__CYGWIN__) && ! defined(O_BINARY) /*duh*/
+#if ! defined(O_BINARY)
#define O_BINARY 0
#endif
-#if defined(TANDEM)
-#define variable variabl
-#define open(name, how, mode) open(name, how) /* !!! ANSI C !!! */
-#endif
-
#if HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef VMS
+#include <unixlib.h>
#include "vms/redirect.h"
#endif /*VMS*/
-#ifdef atarist
-#include "unsupported/atari/redirect.h"
-#endif
-
#ifndef HAVE_VPRINTF
-/* if you don't have vprintf, try this and cross your fingers. */
-#ifdef HAVE_DOPRNT
-#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
-#else /* not HAVE_DOPRNT */
-you
-lose
-#endif /* not HAVE_DOPRNT */
+#error "you lose: you need a system with vfprintf"
#endif /* HAVE_VPRINTF */
#ifndef HAVE_SNPRINTF
-#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
/* will use replacement version */
-extern int snprintf P((char *restrict buf, size_t len, const char *restrict fmt, ...));
-#else
-extern int snprintf ();
-#endif
+extern int snprintf(char *restrict buf, size_t len, const char *restrict fmt, ...);
#endif
#ifndef HAVE_SETLOCALE
#define setlocale(locale, val) /* nothing */
#endif /* HAVE_SETLOCALE */
+#if HAVE_MEMCPY_ULONG
+extern char *memcpy_ulong(char *dest, const char *src, unsigned long l);
+#define memcpy memcpy_ulong
+#endif
+#if HAVE_MEMSET_ULONG
+extern void *memset_ulong(void *dest, int val, unsigned long l);
+#define memset memset_ulong
+#endif
+
+#ifndef HAVE_STRNCASECMP
+extern int strcasecmp(const char *s1, const char *s2);
+extern int strncasecmp(const char *s1, const char *s2, register size_t n);
+#endif
+
/* use this as lintwarn("...")
this is a hack but it gives us the right semantics */
#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
-#define GNU_REGEX
-#ifdef GNU_REGEX
#include "regex.h"
#include "dfa.h"
typedef struct Regexp {
@@ -227,7 +205,7 @@ typedef struct Regexp {
#define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
#define SUBPATEND(rp,s,n) (rp)->regs.end[n]
#define NUMSUBPATS(rp,s) (rp)->regs.num_regs
-#endif /* GNU_REGEX */
+
/* regexp matching flags: */
#define RE_NEED_START 1 /* need to know start/end of match */
#define RE_NO_BOL 2 /* not allowed to match ^ in regexp */
@@ -262,27 +240,8 @@ extern double gawk_strtod();
#define __extension__
#endif
-/* this is defined by Windows32 extension libraries. It must be added to
- * every variable which is exported (including function pointers) */
-#if defined(WIN32_EXTENSION) && !defined(ATTRIBUTE_EXPORTED)
-# define ATTRIBUTE_EXPORTED __declspec(dllimport)
-#else
-# define ATTRIBUTE_EXPORTED
-#endif
-
-
/* ------------------ Constants, Structures, Typedefs ------------------ */
-#if 0
-/* This isn't right. Figure it out the right way for the next release */
-#ifndef AWKNUM
-#ifdef LDBL_MANT_DIG
-#define AWKNUM long double
-#else
-#endif
-#endif
-#endif
-
#define AWKNUM double
#ifndef TRUE
@@ -294,164 +253,41 @@ extern double gawk_strtod();
#define LINT_INVALID 1 /* only warn about invalid */
#define LINT_ALL 2 /* warn about all things */
-/* Figure out what '\a' really is. */
-#ifdef __STDC__
-#define BELL '\a' /* sure makes life easy, don't it? */
-#else
-# if 'z' - 'a' == 25 /* ascii */
-# if 'a' != 97 /* machine is dumb enough to use mark parity */
-# define BELL '\207'
-# else
-# define BELL '\07'
-# endif
-# else
-# define BELL '\057'
-# endif
-#endif
+enum defrule {BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
+ MAXRULE /* sentinel, not legal */ };
+extern const char *const ruletab[];
+
typedef enum nodevals {
/* illegal entry == 0 */
Node_illegal,
- /* binary operators lnode and rnode are the expressions to work on */
- Node_times,
- Node_quotient,
- Node_mod,
- Node_plus,
- Node_minus,
- Node_cond_pair, /* conditional pair (see Node_line_range) */
- Node_subscript,
- Node_concat,
- Node_exp,
-
- /* unary operators subnode is the expression to work on */
- Node_preincrement,
- Node_predecrement,
- Node_postincrement,
- Node_postdecrement,
- Node_unary_minus,
- Node_field_spec,
-
- /* assignments lnode is the var to assign to, rnode is the exp */
- Node_assign,
- Node_assign_times,
- Node_assign_quotient,
- Node_assign_mod,
- Node_assign_plus,
- Node_assign_minus,
- Node_assign_exp,
- Node_assign_concat,
-
- /* boolean binaries lnode and rnode are expressions */
- Node_and,
- Node_or,
-
- /* binary relationals compares lnode and rnode */
- Node_equal,
- Node_notequal,
- Node_less,
- Node_greater,
- Node_leq,
- Node_geq,
- Node_match,
- Node_nomatch,
-
- /* unary relationals works on subnode */
- Node_not,
-
- /* program structures */
- Node_rule_list, /* lnode is a rule, rnode is rest of list */
- Node_rule_node, /* lnode is pattern, rnode is statement */
- Node_statement_list, /* lnode is statement, rnode is more list */
- Node_switch_body, /* lnode is the case list, rnode is default list */
- Node_case_list, /* lnode is the case, rnode is a statement list */
- Node_if_branches, /* lnode is to run on true, rnode on false */
- Node_expression_list, /* lnode is an exp, rnode is more list */
- Node_param_list, /* lnode is a variable, rnode is more list */
+ Node_val, /* node is a value - type in flags */
+ Node_regex, /* a regexp, text, compiled, flags, etc */
+ Node_dynregex, /* a dynamic regexp */
- /* keywords */
- Node_K_if, /* lnode is conditonal, rnode is if_branches */
- Node_K_switch, /* lnode is switch value, rnode is body of case statements */
- Node_K_case, /* lnode is case value, rnode is stuff to run */
- Node_K_default, /* lnode is empty, rnode is stuff to run */
- Node_K_while, /* lnode is condtional, rnode is stuff to run */
- Node_K_for, /* lnode is for_struct, rnode is stuff to run */
- Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
- Node_K_break, /* no subs */
- Node_K_continue, /* no subs */
- Node_K_print, /* lnode is exp_list, rnode is redirect */
- Node_K_print_rec, /* lnode is NULL, rnode is redirect */
- Node_K_printf, /* lnode is exp_list, rnode is redirect */
- Node_K_next, /* no subs */
- Node_K_exit, /* subnode is return value, or NULL */
- Node_K_do, /* lnode is conditional, rnode stuff to run */
- Node_K_return, /* lnode is return value */
- Node_K_delete, /* lnode is array, rnode is subscript */
- Node_K_delete_loop, /* lnode is array, rnode is subscript */
- Node_K_getline, /* lnode is opt var, rnode is redirection */
- Node_K_function, /* lnode is statement list, rnode is params */
- Node_K_nextfile, /* no subs */
-
- /* I/O redirection for print statements */
- Node_redirect_output, /* subnode is where to redirect */
- Node_redirect_append, /* subnode is where to redirect */
- Node_redirect_pipe, /* subnode is where to redirect */
- Node_redirect_pipein, /* subnode is where to redirect */
- Node_redirect_input, /* subnode is where to redirect */
- Node_redirect_twoway, /* subnode is where to redirect */
-
- /* Variables */
- Node_var_new, /* newly created variable, may become an array */
+ /* symbol table values */
Node_var, /* scalar variable, lnode is value */
Node_var_array, /* array is ptr to elements, table_size num of eles */
- Node_val, /* node is a value - type in flags */
-
- /* Builtins subnode is explist to work on, builtin is func to call */
- Node_builtin,
-
- /*
- * 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.
- */
- Node_line_range,
-
- /*
- * boolean test of membership in array
- * lnode is string-valued, expression rnode is array name
- */
- Node_in_array,
-
+ Node_var_new, /* newly created variable, may become an array */
+ Node_param_list, /* lnode is a variable, rnode is more list */
Node_func, /* lnode is param. list, rnode is body */
- Node_func_call, /* lnode is name, rnode is argument list */
- Node_indirect_func_call, /* lnode is name, rnode is argument list */
- Node_cond_exp, /* lnode is conditonal, rnode is if_branches */
- Node_regex, /* a regexp, text, compiled, flags, etc */
- Node_dynregex, /* a dynamic regexp */
Node_hashnode, /* an identifier in the symbol table */
Node_ahash, /* an array element */
Node_array_ref, /* array passed by ref as parameter */
- Node_BINMODE, /* variables recognized in the grammar */
- Node_CONVFMT,
- Node_FIELDWIDTHS,
- Node_FNR,
- Node_FPAT,
- Node_FS,
- Node_IGNORECASE,
- Node_LINT,
- Node_NF,
- Node_NR,
- Node_OFMT,
- Node_OFS,
- Node_ORS,
- Node_RS,
- Node_TEXTDOMAIN,
- Node_SUBSEP,
+ /* program execution -- stack item types */
+ Node_arrayfor,
+ Node_frame,
+ Node_instruction,
+
Node_final /* sentry value, not legal */
} NODETYPE;
+
+struct exp_instruction;
+
/*
* NOTE - this struct is a rather kludgey -- it is packed to minimize
* space usage, at the expense of cleanliness. Alter at own risk.
@@ -461,19 +297,18 @@ typedef struct exp_node {
struct {
union {
struct exp_node *lptr;
- char *param_name;
long ll;
} l;
union {
struct exp_node *rptr;
- struct exp_node *(*pptr) P((struct exp_node *));
Regexp *preg;
- struct for_loop_header *hd;
struct exp_node **av;
- int r_ent; /* range entered */
+ void (*uptr)(void);
+ struct exp_instruction *iptr;
} r;
union {
struct exp_node *extra;
+ void (*aptr)(void);
long xl;
char **param_list;
} x;
@@ -520,51 +355,43 @@ typedef struct exp_node {
NODETYPE type;
unsigned short flags;
# define MALLOC 1 /* can be free'd */
-# define TEMP 2 /* should be free'd */
-# define PERM 4 /* can't be free'd */
-# define STRING 8 /* assigned as string */
-# define STRCUR 16 /* string value is current */
-# define NUMCUR 32 /* numeric value is current */
-# define NUMBER 64 /* assigned as number */
-# define MAYBE_NUM 128 /* user input: if NUMERIC then
+# define PERM 2 /* can't be free'd */
+# define STRING 4 /* assigned as string */
+# define STRCUR 8 /* string value is current */
+# define NUMCUR 16 /* numeric value is current */
+# define NUMBER 32 /* assigned as number */
+# define MAYBE_NUM 64 /* user input: if NUMERIC then
* a NUMBER */
-# define ARRAYMAXED 256 /* array is at max size */
-# define FUNC 512 /* this parameter is really a
+# define ARRAYMAXED 128 /* array is at max size */
+# define FUNC 256 /* this parameter is really a
* function name; see awkgram.y */
-# define FIELD 1024 /* this is a field */
-# define INTLSTR 2048 /* use localized version */
-# define WSTRCUR 4096 /* wide str value is current */
-# define ASSIGNED 8192 /* value assigned, used for function pointer caching */
+# define FIELD 512 /* this is a field */
+# define INTLSTR 1024 /* use localized version */
+# define WSTRCUR 2048 /* wide str value is current */
} NODE;
+
#define vname sub.nodep.name
-#define exec_count sub.nodep.reflags
#define lnode sub.nodep.l.lptr
#define nextp sub.nodep.l.lptr
#define rnode sub.nodep.r.rptr
-#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 parmlist sub.nodep.x.param_list
-#define subnode lnode
-#define builtin sub.nodep.r.pptr
-#define callresult sub.nodep.x.extra
-#define funcbody sub.nodep.x.extra
+#define param_cnt sub.nodep.l.ll
+#define param vname
+
+#define parmlist sub.nodep.x.param_list
+#define code_ptr sub.nodep.r.iptr
#define re_reg sub.nodep.r.preg
#define re_flags sub.nodep.reflags
#define re_text lnode
#define re_exp sub.nodep.x.extra
-#define re_cnt sub.nodep.number
-
-#define forloop rnode->sub.nodep.r.hd
+#define re_cnt flags
#define stptr sub.val.sp
#define stlen sub.val.slen
-#define stref sub.val.sref
+#define valref sub.val.sref
#define stfmt sub.val.idx
#define wstptr sub.val.wsp
@@ -572,8 +399,16 @@ typedef struct exp_node {
#define numbr sub.val.fltnum
+/* Node_frame: */
+#define loop_count sub.nodep.l.ll
+#define stack sub.nodep.r.av
+#define func_node sub.nodep.x.extra
+#define reti sub.nodep.reflags
+
/* Node_var: */
#define var_value lnode
+#define var_update sub.nodep.r.uptr
+#define var_assign sub.nodep.x.aptr
/* Node_var_array: */
#define var_array sub.nodep.r.av
@@ -581,20 +416,306 @@ typedef struct exp_node {
#define table_size sub.nodep.x.xl
/* Node_array_ref: */
-#define orig_array sub.nodep.x.extra
+#define orig_array lnode
#define prev_array rnode
-#define printf_count sub.nodep.x.xl
+/* --------------------------------lint warning types----------------------------*/
+typedef enum lintvals {
+ LINT_illegal,
+ LINT_assign_in_cond,
+ LINT_no_effect
+} LINTTYPE;
+
+/* --------------------------------Instruction ---------------------------------- */
+
+typedef enum opcodeval {
+ /* illegal entry == 0 */
+ Op_illegal,
+
+ /* binary operators */
+ Op_times,
+ Op_times_i,
+ Op_quotient,
+ Op_quotient_i,
+ Op_mod,
+ Op_mod_i,
+ Op_plus,
+ Op_plus_i,
+ Op_minus,
+ Op_minus_i,
+ Op_exp,
+ Op_exp_i,
+ Op_concat,
+
+ /* line range instruction pair */
+ Op_line_range, /* flags for Op_cond_pair */
+ Op_cond_pair, /* conditional pair */
+
+ Op_subscript,
+ Op_sub_array,
+
+ /* unary operators */
+ Op_preincrement,
+ Op_predecrement,
+ Op_postincrement,
+ Op_postdecrement,
+ Op_unary_minus,
+ Op_field_spec,
+
+ /* unary relationals */
+ Op_not,
+
+ /* assignments */
+ Op_assign,
+ Op_store_var, /* simple variable assignment optimization */
+ Op_store_sub, /* array[subscript] assignment optimization */
+ Op_store_field, /* $n assignment optimization */
+ Op_assign_times,
+ Op_assign_quotient,
+ Op_assign_mod,
+ Op_assign_plus,
+ Op_assign_minus,
+ Op_assign_exp,
+ Op_assign_concat,
+
+ /* boolean binaries */
+ Op_and, /* a left subexpression in && */
+ Op_and_final, /* right subexpression of && */
+ Op_or,
+ Op_or_final,
+
+ /* binary relationals */
+ Op_equal,
+ Op_notequal,
+ Op_less,
+ Op_greater,
+ Op_leq,
+ Op_geq,
+ Op_match,
+ Op_match_rec, /* match $0 */
+ Op_nomatch,
+
+ Op_rule,
+
+ /* keywords */
+ Op_K_case,
+ Op_K_default,
+ Op_K_break,
+ Op_K_continue,
+ Op_K_print,
+ Op_K_print_rec,
+ Op_K_printf,
+ Op_K_next,
+ Op_K_exit,
+ Op_K_return,
+ Op_K_delete,
+ Op_K_delete_loop,
+ Op_K_getline_redir,
+ Op_K_getline,
+ Op_K_nextfile,
+
+ Op_builtin,
+ Op_in_array, /* boolean test of membership in array */
+
+ /* function call instruction */
+ Op_func_call,
+ Op_indirect_func_call,
+
+ Op_push, /* variable */
+ Op_push_i, /* number, string */
+ Op_push_re, /* regex */
+ Op_push_array,
+ Op_push_param,
+ Op_push_lhs,
+ Op_subscript_lhs,
+ Op_field_spec_lhs,
+ Op_no_op, /* jump target */
+ Op_pop, /* pop an item from the runtime stack */
+ Op_jmp,
+ Op_jmp_true,
+ Op_jmp_false,
+ Op_push_loop, /* break (continue) target for loop */
+ Op_pop_loop,
+ Op_get_record,
+ Op_newfile,
+ Op_arrayfor_init,
+ Op_arrayfor_incr,
+ Op_arrayfor_final,
+
+ Op_var_update, /* update value of NR, NF or FNR */
+ Op_var_assign,
+ Op_field_assign,
+ Op_after_beginfile,
+ Op_after_endfile,
+
+ Op_ext_func,
+ Op_func,
+
+ Op_exec_count,
+ Op_breakpoint,
+ Op_lint,
+ Op_atexit,
+ Op_stop,
+
+ /* parsing (yylex and yyparse), should never appear in valid compiled code */
+ Op_token,
+ Op_symbol,
+ Op_list,
+ Op_case_list,
+ /* program structures -- for use in the profiler/pretty printer */
+ Op_K_do,
+ Op_K_for,
+ Op_K_arrayfor,
+ Op_K_while,
+ Op_K_switch,
+ Op_K_if,
+ Op_K_else,
+ Op_K_function,
+ Op_cond_exp,
+ Op_final /* sentry value, not legal */
+} OPCODE;
+
+enum redirval {
+ /* I/O redirections */
+ redirect_output = 1,
+ redirect_append,
+ redirect_pipe,
+ redirect_pipein,
+ redirect_input,
+ redirect_twoway
+};
+
+struct break_point;
+
+typedef struct exp_instruction {
+ struct exp_instruction *nexti;
+ union {
+ NODE *dn;
+ struct exp_instruction *di;
+ NODE *(*fptr)(int);
+ long dl;
+ char *name;
+ } d;
+
+ union {
+ long xl;
+ NODE *xn;
+ void (*aptr)(void);
+ struct exp_instruction *xi;
+ struct break_point *bpt;
+ } x;
+
+ short source_line;
+ OPCODE opcode;
+} INSTRUCTION;
+
+#define func_name d.name
+
+#define memory d.dn
+#define builtin d.fptr
+#define builtin_idx d.dl
+
+#define expr_count x.xl
+
+#define target_continue d.di
+#define target_jmp d.di
+#define target_break x.xi
+
+/* Op_newfile, Op_K_getline */
+#define target_endfile x.xi
+
+/* Op_K_getline */
+#define target_beginfile d.di
+
+/* Op_token */
+#define lextok d.name
+
+/* Op_rule */
+#define in_rule x.xl
+#define source_file d.name
+
+/* Op_K_case, Op_K_default */
+#define target_stmt x.xi
+
+/* Op_case_list, Op_K_switch */
+#define case_val d.di
+#define case_stmt x.xi
+#define switch_dflt x.xi
+#define switch_body d.di /* pretty printing and profiling */
+
+/* Op_K_getline, Op_K_getline_redir */
+#define into_var x.xl
+
+/* Op_K_getline_redir, Op_K_print, Op_K_print_rec, Op_K_printf */
+#define redir_type d.dl
+
+/* Op_arrayfor_incr */
+#define array_var x.xn
+
+/* Op_line_range */
+#define triggered x.xl
+
+/* Op_cond_pair */
+#define line_range x.xi
+
+/* Op_func_call, Op_func */
+#define func_body x.xn
+
+/* Op_subscript */
+#define sub_count d.dl
+
+/* Op_push_lhs, Op_subscript_lhs, Op_field_spec_lhs */
+#define do_reference x.xl
+
+/* Op_list, Op_rule, Op_func */
+#define lasti d.di
+#define firsti x.xi
+
+/* Op_rule, Op_func */
+#define last_line x.xl
+#define first_line source_line
-#define condpair lnode
-#define triggered sub.nodep.r.r_ent
+/* Op_lint */
+#define lint_type d.dl
-/* a regular for loop */
-typedef struct for_loop_header {
- NODE *init;
- NODE *cond;
- NODE *incr;
-} FOR_LOOP_HEADER;
+/* Op_field_spec_lhs */
+#define target_assign d.di
+
+/* Op_field_assign */
+#define field_assign x.aptr
+
+/* Op_concat */
+#define concat_flag d.dl
+#define CSUBSEP 1
+#define CSVAR 2
+
+/* Op_breakpoint */
+#define break_pt x.bpt
+
+/*------------------ pretty printing/profiling --------*/
+/* Op_exec_count */
+#define exec_count d.dl
+
+/* Op_K_while */
+#define while_body d.di
+
+/* Op_K_do */
+#define doloop_cond d.di
+
+/* Op_K_for */
+#define forloop_cond d.di
+#define forloop_body x.xi
+
+/* Op_K_if */
+#define branch_if d.di
+#define branch_else x.xi
+
+/* Op_K_else */
+#define branch_end x.xi
+
+/* Op_line_range */
+#define condpair_left d.di
+#define condpair_right x.xi
typedef struct iobuf {
const char *name; /* filename */
@@ -611,19 +732,21 @@ typedef struct iobuf {
size_t scanoff; /* where we were in the buffer when we had
to regrow/refill */
- void *opaque; /* private data for open hooks */
- int (*get_record) P((char **out, struct iobuf *, int *errcode));
- void (*close_func) P((struct iobuf *)); /* open and close hooks */
+ void *opaque; /* private data for open hooks */
+ int (*get_record)(char **out, struct iobuf *, int *errcode);
+ void (*close_func)(struct iobuf *); /* open and close hooks */
+
+ int errcode;
- int flag;
+ int flag;
# define IOP_IS_TTY 1
# define IOP_NOFREE_OBJ 2
-# define IOP_AT_EOF 4
-# define IOP_CLOSED 8
-# define IOP_AT_START 16
+# define IOP_AT_EOF 4
+# define IOP_CLOSED 8
+# define IOP_AT_START 16
} IOBUF;
-typedef void (*Func_ptr) P((void));
+typedef void (*Func_ptr)(void);
/* structure used to dynamically maintain a linked-list of open files/pipes */
struct redirect {
@@ -653,13 +776,43 @@ struct redirect {
/*
* structure for our source, either a command line string or a source file.
- * the same structure is used to remember variable pre-assignments.
*/
-struct src {
- enum srctype { CMDLINE = 1, SOURCEFILE,
- PRE_ASSIGN, PRE_ASSIGN_FS } stype;
- char *val;
-};
+
+typedef struct srcfile {
+ struct srcfile *next;
+ struct srcfile *prev;
+
+ enum srctype { SRC_CMDLINE = 1, SRC_STDIN, SRC_FILE, SRC_INC } stype;
+ char *src; /* name on command line or inclde statement */
+ char *fullpath; /* full path after AWKPATH search */
+ time_t mtime;
+ struct stat sbuf;
+ int srclines; /* no of lines in source */
+ size_t bufsize;
+ char *buf;
+ int *line_offset; /* offset to the beginning of each line */
+ int fd;
+ int maxlen; /* size of the longest line */
+
+ char *lexptr;
+ char *lexend;
+ char *lexeme;
+ char *lexptr_begin;
+ int lasttok;
+} SRCFILE;
+
+
+typedef struct context {
+ INSTRUCTION pools;
+ NODE symbols;
+ INSTRUCTION rule_list;
+ SRCFILE srcfiles;
+ int sourceline;
+ char *source;
+ int level;
+ void (*install_func)(char *);
+ struct context *prev;
+} CONTEXT;
/* for debugging purposes */
struct flagtab {
@@ -667,14 +820,6 @@ struct flagtab {
const char *name;
};
-/* 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
-
#ifndef LONG_MAX
#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
#endif
@@ -700,7 +845,7 @@ extern char *ORS;
extern int ORSlen;
extern char *OFMT;
extern char *CONVFMT;
-ATTRIBUTE_EXPORTED extern int CONVFMTidx;
+extern int CONVFMTidx;
extern int OFMTidx;
extern char *TEXTDOMAIN;
extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
@@ -708,22 +853,16 @@ extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node, *FPAT_node;
-ATTRIBUTE_EXPORTED extern NODE **stack_ptr;
extern NODE *Nnull_string;
extern NODE *Null_field;
extern NODE **fields_arr;
extern int sourceline;
extern char *source;
-extern NODE *expression_value;
#if __GNUC__ < 2
-# if defined(WIN32_EXTENSION)
-static
-# else
-extern
-#endif
-NODE *_t; /* used as temporary in tree_eval */
+extern NODE *_t; /* used as temporary in tree_eval */
#endif
+extern NODE *_r; /* used as temporary in stack macros */
extern NODE *nextfree;
extern int field0_valid;
@@ -732,21 +871,20 @@ extern int do_posix;
extern int do_intervals;
extern int do_intl;
extern int do_non_decimal_data;
+extern int do_profiling;
extern int do_dump_vars;
extern int do_tidy_mem;
extern int do_sandbox;
extern int do_optimize;
extern int use_lc_numeric;
-extern int in_begin_rule;
-extern int in_end_rule;
-extern int in_beginfile_rule;
-extern int in_endfile_rule;
extern int whiny_users;
+extern int exit_val;
+
#ifdef NO_LINT
#define do_lint 0
#define do_lint_old 0
#else
-ATTRIBUTE_EXPORTED extern int do_lint;
+extern int do_lint;
extern int do_lint_old;
#endif
#ifdef MBS_SUPPORT
@@ -772,170 +910,166 @@ extern char envsep;
extern char casetable[]; /* for case-independent regexp matching */
+/*
+ * Provide a way for code to know which program is executing:
+ * gawk vs dgawk vs pgawk.
+ */
+enum exe_mode { exe_normal = 1, exe_debugging, exe_profiling };
+extern enum exe_mode which_gawk; /* (defined in eval.c) */
+
+/* ------------------------- Runtime stack -------------------------------- */
+
+typedef union stack_item {
+ NODE *rptr; /* variable etc. */
+ NODE **lptr; /* address of a variable etc. */
+} STACK_ITEM;
+
+extern STACK_ITEM *stack_ptr;
+extern NODE *frame_ptr;
+extern STACK_ITEM *stack_bottom;
+extern STACK_ITEM *stack_top;
+
+#define decr_sp() (stack_ptr--)
+#define incr_sp() ((stack_ptr < stack_top) ? ++stack_ptr : grow_stack())
+#define stack_adj(n) (stack_ptr += (n))
+#define stack_empty() (stack_ptr < stack_bottom)
+
+#define POP() decr_sp()->rptr
+#define POP_ADDRESS() decr_sp()->lptr
+#define PEEK(n) (stack_ptr - (n))->rptr
+#define TOP() stack_ptr->rptr /* same as PEEK(0) */
+#define TOP_ADDRESS() stack_ptr->lptr
+#define PUSH(r) (void) (incr_sp()->rptr = (r))
+#define PUSH_ADDRESS(l) (void) (incr_sp()->lptr = (l))
+#define REPLACE(r) (void) (stack_ptr->rptr = (r))
+#define REPLACE_ADDRESS(l) (void) (stack_ptr->lptr = (l))
+
+
+/* function param */
+#define GET_PARAM(n) frame_ptr->stack[n]
+
+/*
+ * UPREF and DEREF --- simplified versions of dupnode and unref
+ * UPREF does not handle FIELD node. Most appropriate use is
+ * for elements on the runtime stack. When in doubt, use dupnode.
+ */
+
+#define DEREF(r) ( _r = (r), (!(_r->flags & PERM) && (--_r->valref == 0)) ? unref(_r) : (void)0 )
+
+#if __GNUC__ >= 2
+#define UPREF(r) ({ NODE *_t = (r); !(_t->flags & PERM) && _t->valref++;})
+
+#define POP_ARRAY() ({ NODE *_t = POP(); \
+ _t->type == Node_var_array ? \
+ _t : get_array(_t, TRUE); })
+
+#define POP_PARAM() ({ NODE *_t = POP(); \
+ _t->type == Node_var_array ? \
+ _t : get_array(_t, FALSE); })
+
+#define POP_NUMBER(x) ({ NODE *_t = POP_SCALAR(); \
+ x = force_number(_t); DEREF(_t); })
+#define TOP_NUMBER(x) ({ NODE *_t = TOP_SCALAR(); \
+ x = force_number(_t); DEREF(_t); })
+
+#define POP_SCALAR() ({ NODE *_t = POP(); _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
+#define TOP_SCALAR() ({ NODE *_t = TOP(); _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
+
+#else /* not __GNUC__ */
+
+#define UPREF(r) (_t = (r), !(_t->flags & PERM) && _t->valref++)
+
+#define POP_ARRAY() (_t = POP(), \
+ _t->type == Node_var_array ? \
+ _t : get_array(_t, TRUE))
+
+#define POP_PARAM() (_t = POP(), \
+ _t->type == Node_var_array ? \
+ _t : get_array(_t, FALSE))
+
+#define POP_NUMBER(x) (_t = POP_SCALAR(), \
+ x = force_number(_t), DEREF(_t))
+#define TOP_NUMBER(x) (_t = TOP_SCALAR(), \
+ x = force_number(_t), DEREF(_t))
+
+#define POP_SCALAR() (_t = POP(), _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
+#define TOP_SCALAR() (_t = TOP(), _t->type != Node_var_array ? _t \
+ : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
+
+#endif /* __GNUC__ */
+
+
+#define POP_STRING() force_string(POP_SCALAR())
+#define TOP_STRING() force_string(TOP_SCALAR())
+
/* ------------------------- Pseudo-functions ------------------------- */
#define is_identchar(c) (isalnum(c) || (c) == '_')
#define var_uninitialized(n) ((n)->var_value == Nnull_string)
+#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
+ &((n)->var_value) : r_get_lhs((n), (r))
+
#ifdef MPROF
-#define getnode(n) (emalloc((n), NODE *, sizeof(NODE), "getnode"), (n)->flags = 0, (n)->exec_count = 0)
-#define freenode(n) free(n)
+#define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), \
+ (n)->flags = 0
+#define freenode(n) efree(n)
#else /* not MPROF */
-#define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
- else n = more_nodes()
-#ifndef NO_PROFILING
-#define freenode(n) ((n)->flags = 0,\
- (n)->exec_count = 0, (n)->nextp = nextfree, nextfree = (n))
-#else /* not PROFILING */
-#define freenode(n) ((n)->flags = 0,\
- (n)->nextp = nextfree, nextfree = (n))
-#endif /* not PROFILING */
+#define getnode(n) (void) (nextfree ? \
+ (n = nextfree, nextfree = nextfree->nextp) \
+ : (n = more_nodes()))
+#define freenode(n) ((n)->flags = 0, (n)->nextp = nextfree, nextfree = (n))
#endif /* not MPROF */
-#ifndef GAWKDEBUG
-#define DUPNODE_MACRO 1
-/*
- * Speed up the path leading to r_dupnode, as well as duplicating TEMP nodes,
- * on expense of slowing down the access to PERM nodes (by two instructions).
- * This is right since PERM nodes are realtively rare.
- *
- * The code also sets MALLOC flag for PERM nodes, which should not matter.
- */
-#define DUPNODE_COMMON (_t->flags & (TEMP|PERM)) != 0 ? \
- (_t->flags &= ~TEMP, _t->flags |= MALLOC, _t) : \
- r_dupnode(_t)
#if __GNUC__ >= 2
-#define dupnode(n) ({NODE * _t = (n); DUPNODE_COMMON;})
+#define ahash_dupnode(n) ({NODE * _t = (n); _t->ahname_ref++; _t;})
#else
-#define dupnode(n) (_t = (n), DUPNODE_COMMON)
+#define ahash_dupnode(n) (_t = (n), _t->ahname_ref++, _t)
#endif
-#else /* GAWKDEBUG */
-#define dupnode(n) r_dupnode(n)
-#endif /* GAWKDEBUG */
-#define get_array(t) get_actual(t, TRUE) /* allowed to die fatally */
-#define get_param(t) get_actual(t, FALSE) /* not allowed */
-#ifdef MEMDEBUG
-#undef freenode
-#define get_lhs(p, a, r) r_get_lhs((p), (a), (r))
-#define m_tree_eval(t, iscond) r_tree_eval(t, iscond)
-#else
-#define get_lhs(p, a, r) ((p)->type == Node_var && \
- ! var_uninitialized(p) ? \
- (&(p)->var_value) : \
- r_get_lhs((p), (a), (r)))
-#define TREE_EVAL_MACRO 1
-#if __GNUC__ >= 2
-#define m_tree_eval(t, iscond) __extension__ \
- ({NODE * _t = (t); \
- if (_t == (NODE*)NULL) \
- cant_happen(); \
- switch(_t->type) { \
- case Node_val: \
- if (_t->flags&INTLSTR) \
- _t = r_force_string(_t); \
- break; \
- case Node_var: \
- if (! var_uninitialized(_t)) { \
- _t = _t->var_value; \
- break; \
- } \
- /*FALLTHROUGH*/ \
- default: \
- _t = r_tree_eval(_t, iscond);\
- break; \
- } \
- _t;})
-#else
-#define m_tree_eval(t, iscond) (_t = (t), _t == (NODE*)NULL ? (cant_happen(), (NODE*)NULL) : \
- (_t->type == Node_param_list ? \
- r_tree_eval(_t, iscond) : \
- ((_t->type == Node_val && (_t->flags&INTLSTR)) ? \
- r_force_string(_t) : \
- (_t->type == Node_val ? _t : \
- (_t->type == Node_var && \
- ! var_uninitialized(_t) ? _t->var_value : \
- r_tree_eval(_t, iscond))))))
-#endif /* __GNUC__ */
-#endif /* not MEMDEBUG */
-#define tree_eval(t) m_tree_eval(t, FALSE)
+#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
-#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
-#define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUMCUR|NUMBER))
+#define make_string(s, l) r_make_str_node((s), (size_t) (l), 0)
+#define make_str_node(s, l, f) r_make_str_node((s), (size_t) (l), (f))
-#define free_temp(n) do { NODE *_n = (n); if (_n->flags&TEMP) unref(_n);} \
- while (FALSE)
-
-#define make_string(s, l) make_str_node((s), (size_t) (l), 0)
#define SCAN 1
#define ALREADY_MALLOCED 2
#define cant_happen() r_fatal("internal error line %d, file: %s", \
__LINE__, __FILE__)
-/*
- * For SunOS 4.1.x which is pre-Standard C, `realloc' doesn't
- * accept NULL. Sigh. The check must be done for both cases,
- * since could be using GCC but with stock C library. Sigh, again.
- */
-#ifdef HAVE_STRINGIZE
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
(fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
(str), #var, (long) (x), strerror(errno)),0))
-#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
- ? (ty)malloc((MALLOC_ARG_T)(x)) \
- : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
+#define erealloc(var,ty,x,str) (void)((var = (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) \
||\
(fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
(str), #var, (long) (x), strerror(errno)),0))
-#else /* HAVE_STRINGIZE */
-#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
- (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
- (str), "var", (long) (x), strerror(errno)),0))
-#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
- ? (ty)malloc((MALLOC_ARG_T)(x)) \
- : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
- ||\
- (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
- (str), "var", (long) (x), strerror(errno)),0))
-#endif /* HAVE_STRINGIZE */
+
+#define efree(p) free(p)
#ifdef GAWKDEBUG
#define force_number r_force_number
#define force_string r_force_string
#else /* not GAWKDEBUG */
-#ifdef lint
-extern AWKNUM force_number();
-#endif
#if __GNUC__ >= 2
#define force_number(n) __extension__ ({NODE *_tn = (n);\
- (_tn->flags & NUMCUR) ?_tn->numbr : r_force_number(_tn);})
+ (_tn->flags & NUMCUR) ? _tn->numbr : r_force_number(_tn);})
+
#define force_string(s) __extension__ ({NODE *_ts = (s);\
- ((_ts->flags & INTLSTR) ? \
- r_force_string(_ts) : \
- ((_ts->flags & STRCUR) && \
+ ((_ts->flags & STRCUR) && \
(_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
- _ts : r_force_string(_ts));})
-#else
-#ifdef MSDOS
-extern double _msc51bug;
-#define force_number(n) (_msc51bug=(_t = (n),\
- (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t)))
-#else /* not MSDOS */
-#define force_number(n) (_t = (n),\
- (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t))
-#endif /* not MSDOS */
-#define force_string(s) (_t = (s),(_t->flags & INTLSTR) ? \
- r_force_string(_t) :\
- ((_t->flags & STRCUR) && \
- (_t->stfmt == -1 || \
- _t->stfmt == CONVFMTidx))? \
- _t : r_force_string(_t))
-
-#endif /* not __GNUC__ */
-#endif /* not GAWKDEBUG */
+ _ts : format_val(CONVFMT, CONVFMTidx, _ts);})
+#else /* not __GNUC__ */
+#define force_number r_force_number
+#define force_string r_force_string
+#endif /* __GNUC__ */
+#endif /* GAWKDEBUG */
#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
#define STREQN(a,b,n) ((n) && *(a)== *(b) && \
@@ -943,260 +1077,267 @@ extern double _msc51bug;
#define fatal set_loc(__FILE__, __LINE__), r_fatal
+
+extern jmp_buf fatal_tag;
+extern int fatal_tag_valid;
+
+#define PUSH_BINDING(stack) \
+if (fatal_tag_valid++) \
+ memcpy((char *) (stack), (const char *) fatal_tag, sizeof(jmp_buf))
+#define POP_BINDING(stack) \
+if (--fatal_tag_valid) \
+ memcpy((char *) fatal_tag, (const char *) (stack), sizeof(jmp_buf))
+
/* ------------- Function prototypes or defs (as appropriate) ------------- */
+typedef int (*Func_print)(FILE *, const char *, ...);
/* array.c */
-extern NODE *get_actual P((NODE *symbol, int canfatal));
-extern char *array_vname P((const NODE *symbol));
-extern void array_init P((void));
-extern NODE *concat_exp P((NODE *tree));
-extern void assoc_clear P((NODE *symbol));
-extern NODE *in_array P((NODE *symbol, NODE *subs));
-extern NODE **assoc_lookup P((NODE *symbol, NODE *subs, int reference));
-extern void do_delete P((NODE *symbol, NODE *tree));
-extern void do_delete_loop P((NODE *symbol, NODE *tree));
-extern void set_SUBSEP P((void));
-extern NODE *assoc_dump P((NODE *symbol));
-extern NODE *do_adump P((NODE *tree));
-extern NODE *do_asort P((NODE *tree));
-extern NODE *do_asorti P((NODE *tree));
-extern unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize, size_t *code));
+extern NODE *get_array(NODE *symbol, int canfatal);
+extern char *array_vname(const NODE *symbol);
+extern char *make_aname(NODE *array, NODE *subs);
+extern void array_init(void);
+extern void set_SUBSEP(void);
+extern NODE *concat_exp(int nargs, int do_subsep);
+extern void ahash_unref(NODE *tmp);
+extern void assoc_clear(NODE *symbol);
+extern NODE *in_array(NODE *symbol, NODE *subs);
+extern NODE **assoc_lookup(NODE *symbol, NODE *subs, int reference);
+extern void do_delete(NODE *symbol, int nsubs);
+extern void do_delete_loop(NODE *symbol, NODE **lhs);
+extern NODE *assoc_dump(NODE *symbol, int indent_level);
+extern NODE *do_adump(int nargs);
+extern NODE *do_asort(int nargs);
+extern NODE *do_asorti(int nargs);
+extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
/* awkgram.c */
-extern char *tokexpand P((void));
-extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
-extern NODE *install P((char *name, NODE *value));
-extern NODE *lookup P((const char *name));
-extern NODE *variable P((char *name, int can_free, NODETYPE type));
-extern int yyparse P((void));
-extern void dump_funcs P((void));
-extern void dump_vars P((const char *fname));
-extern void release_all_vars P((void));
-extern const char *getfname P((NODE *(*)(NODE *)));
-extern NODE *stopme P((NODE *tree));
-extern void shadow_funcs P((void));
-extern int check_special P((const char *name));
-extern void register_deferred_variable P((const char *name,
- NODE *(*load_func)(void)));
+extern NODE *mk_symbol(NODETYPE type, NODE *value);
+extern NODE *install_symbol(char *name, NODE *value);
+extern NODE *remove_symbol(char *name);
+extern NODE *lookup(const char *name);
+extern NODE *variable(char *name, NODETYPE type);
+extern int parse_program(INSTRUCTION **pcode);
+extern void dump_funcs(void);
+extern void dump_vars(const char *fname);
+extern void release_all_vars(void);
+extern const char *getfname(NODE *(*)(int));
+extern NODE *stopme(int nargs);
+extern void shadow_funcs(void);
+extern int check_special(const char *name);
+extern int foreach_func(int (*)(INSTRUCTION *, void *), int, void *);
+extern INSTRUCTION *bcalloc(OPCODE op, int size, int srcline);
+extern void bcfree(INSTRUCTION *);
+extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, int *already_included, int *errcode);
+extern void register_deferred_variable(const char *name, NODE *(*load_func)(void));
+extern int files_are_same(struct stat *f1, struct stat *f2);
+extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
+extern void print_vars(Func_print print_func, FILE *fp);
+extern CONTEXT *new_context(void);
+extern CONTEXT *set_context(CONTEXT *ctxt);
+extern CONTEXT *get_context(void);
+extern void free_context(CONTEXT *ctxt, int );
+extern void append_symbol(char *name);
+
/* builtin.c */
-extern double double_to_int P((double d));
-extern NODE *do_exp P((NODE *tree));
-extern NODE *do_fflush P((NODE *tree));
-extern NODE *do_index P((NODE *tree));
-extern NODE *do_int P((NODE *tree));
-extern NODE *do_length P((NODE *tree));
-extern NODE *do_log P((NODE *tree));
-extern NODE *do_mktime P((NODE *tree));
-extern NODE *do_sprintf P((NODE *tree));
-extern void do_printf P((NODE *tree));
-extern void print_simple P((NODE *tree, FILE *fp));
-extern NODE *do_sqrt P((NODE *tree));
-extern NODE *do_substr P((NODE *tree));
-extern NODE *do_strftime P((NODE *tree));
-extern NODE *do_systime P((NODE *tree));
-extern NODE *do_system P((NODE *tree));
-extern void do_print P((NODE *tree));
-extern void do_print_rec P((NODE *tree));
-extern NODE *do_tolower P((NODE *tree));
-extern NODE *do_toupper P((NODE *tree));
-extern NODE *do_atan2 P((NODE *tree));
-extern NODE *do_sin P((NODE *tree));
-extern NODE *do_cos P((NODE *tree));
-extern NODE *do_rand P((NODE *tree));
-extern NODE *do_srand P((NODE *tree));
-extern NODE *do_match P((NODE *tree));
-extern NODE *do_gsub P((NODE *tree));
-extern NODE *do_sub P((NODE *tree));
-extern NODE *do_gensub P((NODE *tree));
-extern NODE *format_tree P((const char *, size_t, NODE *, long));
-extern NODE *do_lshift P((NODE *tree));
-extern NODE *do_rshift P((NODE *tree));
-extern NODE *do_and P((NODE *tree));
-extern NODE *do_or P((NODE *tree));
-extern NODE *do_xor P((NODE *tree));
-extern NODE *do_compl P((NODE *tree));
-extern NODE *do_strtonum P((NODE *tree));
-extern AWKNUM nondec2awknum P((char *str, size_t len));
-extern NODE *do_dcgettext P((NODE *tree));
-extern NODE *do_dcngettext P((NODE *tree));
-extern NODE *do_bindtextdomain P((NODE *tree));
+extern double double_to_int(double d);
+extern NODE *do_exp(int nargs);
+extern NODE *do_fflush(int nargs);
+extern NODE *do_index(int nargs);
+extern NODE *do_int(int nargs);
+extern NODE *do_length(int nargs);
+extern NODE *do_log(int nargs);
+extern NODE *do_mktime(int nargs);
+extern NODE *do_sprintf(int nargs);
+extern void do_printf(int nargs, int redirtype);
+extern void print_simple(NODE *tree, FILE *fp);
+extern NODE *do_sqrt(int nargs);
+extern NODE *do_substr(int nargs);
+extern NODE *do_strftime(int nargs);
+extern NODE *do_systime(int nargs);
+extern NODE *do_system(int nargs);
+extern void do_print(int nargs, int redirtype);
+extern void do_print_rec(int args, int redirtype);
+extern NODE *do_tolower(int nargs);
+extern NODE *do_toupper(int nargs);
+extern NODE *do_atan2(int nargs);
+extern NODE *do_sin(int nargs);
+extern NODE *do_cos(int nargs);
+extern NODE *do_rand(int nargs);
+extern NODE *do_srand(int nargs);
+extern NODE *do_match(int nargs);
+extern NODE *do_gsub(int nargs);
+extern NODE *do_sub(int nargs);
+extern NODE *do_gensub(int nargs);
+extern NODE *format_tree(const char *, size_t, NODE **, long);
+extern NODE *do_lshift(int nargs);
+extern NODE *do_rshift(int nargs);
+extern NODE *do_and(int nargs);
+extern NODE *do_or(int nargs);
+extern NODE *do_xor(int nargs);
+extern NODE *do_compl(int nargs);
+extern NODE *do_strtonum(int nargs);
+extern AWKNUM nondec2awknum(char *str, size_t len);
+extern NODE *do_dcgettext(int nargs);
+extern NODE *do_dcngettext(int nargs);
+extern NODE *do_bindtextdomain(int nargs);
#ifdef MBS_SUPPORT
-extern int strncasecmpmbs P((const char *, mbstate_t, const char *,
- mbstate_t, size_t));
+extern int strncasecmpmbs(const char *, const char *, size_t);
#endif
/* eval.c */
-extern int interpret P((NODE *volatile tree));
-extern NODE *r_tree_eval P((NODE *tree, int iscond));
-extern int cmp_nodes P((NODE *t1, NODE *t2));
-extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign, int reference));
-extern void set_IGNORECASE P((void));
-extern void set_OFS P((void));
-extern void set_ORS P((void));
-extern void set_OFMT P((void));
-extern void set_CONVFMT P((void));
-extern void set_BINMODE P((void));
-extern void set_LINT P((void));
-extern void set_TEXTDOMAIN P((void));
-extern void update_ERRNO P((void));
-extern void update_ERRNO_saved P((int));
-extern const char *redflags2str P((int));
-extern const char *flags2str P((int));
-extern const char *genflags2str P((int flagval, const struct flagtab *tab));
-extern const char *nodetype2str P((NODETYPE type));
-extern NODE *assign_val P((NODE **lhs_p, NODE *rhs));
-extern void load_casetable P((void));
-extern size_t get_curfunc_arg_count P((void));
-extern AWKNUM calc_exp P((AWKNUM x1, AWKNUM x2));
+extern void PUSH_CODE(INSTRUCTION *cp);
+extern INSTRUCTION *POP_CODE(void);
+extern int interpret(INSTRUCTION *);
+extern int cmp_nodes(NODE *, NODE *);
+extern void set_IGNORECASE(void);
+extern void set_OFS(void);
+extern void set_ORS(void);
+extern void set_OFMT(void);
+extern void set_CONVFMT(void);
+extern void set_BINMODE(void);
+extern void set_LINT(void);
+extern void set_TEXTDOMAIN(void);
+extern void update_ERRNO(void);
+extern void update_ERRNO_saved(int);
+extern void update_NR(void);
+extern void update_NF(void);
+extern void update_FNR(void);
+extern const char *redflags2str(int);
+extern const char *flags2str(int);
+extern const char *genflags2str(int flagval, const struct flagtab *tab);
+extern const char *nodetype2str(NODETYPE type);
+extern void load_casetable(void);
+
+extern AWKNUM calc_exp(AWKNUM x1, AWKNUM x2);
+extern const char *opcode2str(OPCODE type);
+extern const char *op2str(OPCODE type);
+extern NODE **r_get_lhs(NODE *n, int reference);
+extern STACK_ITEM *grow_stack(void);
#ifdef PROFILING
-extern void dump_fcall_stack P((FILE *fp));
+extern void dump_fcall_stack(FILE *fp);
#endif
/* ext.c */
-NODE *do_ext P((NODE *));
+NODE *do_ext(int nargs);
#ifdef DYNAMIC
-void make_builtin P((char *, NODE *(*)(NODE *), int));
-NODE *get_argument P((NODE *, int));
-NODE *get_actual_argument P((NODE *, unsigned int, int, int));
-#define get_scalar_argument(t, i, opt) get_actual_argument((t), (i), (opt), FALSE)
-#define get_array_argument(t, i, opt) get_actual_argument((t), (i), (opt), TRUE)
-void set_value P((NODE *));
+void make_builtin(char *, NODE *(*)(int), int);
+size_t get_curfunc_arg_count(void);
+NODE *get_argument(int);
+NODE *get_actual_argument(int, int, int);
+#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), FALSE)
+#define get_array_argument(i, opt) get_actual_argument((i), (opt), TRUE)
#endif
/* field.c */
-extern void init_fields P((void));
-extern void set_record P((const char *buf, int cnt));
-extern void reset_record P((void));
-extern void set_NF P((void));
-extern NODE **get_field P((long num, Func_ptr *assign));
-extern NODE *do_split P((NODE *tree));
-extern NODE *do_patsplit P((NODE *tree));
-extern void set_FS P((void));
-extern void set_RS P((void));
-extern void set_FIELDWIDTHS P((void));
-extern void set_FPAT P((void));
-extern void update_PROCINFO_str P((char *subscript, char *str));
-extern void update_PROCINFO_num P((char *subscript, AWKNUM val));
+extern void init_fields(void);
+extern void set_record(const char *buf, int cnt);
+extern void reset_record(void);
+extern void set_NF(void);
+extern NODE **get_field(long num, Func_ptr *assign);
+extern NODE *do_split(int nargs);
+extern NODE *do_patsplit(int nargs);
+extern void set_FS(void);
+extern void set_RS(void);
+extern void set_FIELDWIDTHS(void);
+extern void set_FPAT(void);
+extern void update_PROCINFO_str(char *subscript, char *str);
+extern void update_PROCINFO_num(char *subscript, AWKNUM val);
typedef enum {
Using_FS,
Using_FIELDWIDTHS,
- Using_FPAT,
+ Using_FPAT
} field_sep_type;
-extern field_sep_type current_field_sep P((void));
-/* gawkmisc.c */
-extern char *gawk_name P((const char *filespec));
-extern void os_arg_fixup P((int *argcp, char ***argvp));
-extern int os_devopen P((const char *name, int flag));
-extern void os_close_on_exec P((int fd, const char *name, const char *what,
- const char *dir));
-extern int os_isdir P((int fd));
-extern int os_is_setuid P((void));
-extern int os_setbinmode P((int fd, int mode));
-extern void os_restore_mode P((int fd));
-extern size_t optimal_bufsize P((int fd, struct stat *sbuf));
-extern int ispath P((const char *file));
-extern int isdirpunct P((int c));
+extern field_sep_type current_field_sep(void);
-#if HAVE_MEMCPY_ULONG
-extern char *memcpy_ulong P((char *dest, const char *src, unsigned long l));
-#define memcpy memcpy_ulong
-#endif
-#if HAVE_MEMSET_ULONG
-extern void *memset_ulong P((void *dest, int val, unsigned long l));
-#define memset memset_ulong
-#endif
+/* gawkmisc.c */
+extern char *gawk_name(const char *filespec);
+extern void os_arg_fixup(int *argcp, char ***argvp);
+extern int os_devopen(const char *name, int flag);
+extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir);
+extern int os_isdir(int fd);
+extern int os_is_setuid(void);
+extern int os_setbinmode(int fd, int mode);
+extern void os_restore_mode(int fd);
+extern size_t optimal_bufsize(int fd, struct stat *sbuf);
+extern int ispath(const char *file);
+extern int isdirpunct(int c);
/* io.c */
-extern void register_open_hook P((void *(*open_func)(IOBUF *)));
-extern void set_FNR P((void));
-extern void set_NR P((void));
-extern void do_input P((void));
-extern struct redirect *redirect P((NODE *tree, int *errflg));
-extern NODE *do_close P((NODE *tree));
-extern int flush_io P((void));
-extern int close_io P((int *stdio_problem));
-extern int devopen P((const char *name, const char *mode, int *isdir));
-extern int pathopen P((const char *file));
-extern NODE *do_getline P((NODE *tree));
-extern void do_nextfile P((void));
-extern struct redirect *getredirect P((const char *str, int len));
+extern void register_open_hook(void *(*open_func)(IOBUF *));
+extern void set_FNR(void);
+extern void set_NR(void);
+
+extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
+extern NODE *do_close(int nargs);
+extern int flush_io(void);
+extern int close_io(int *stdio_problem);
+extern int devopen(const char *name, const char *mode);
+extern int srcopen(SRCFILE *s);
+extern char *find_source(const char *src, struct stat *stb, int *errcode);
+extern NODE *do_getline_redir(int intovar, int redirtype);
+extern NODE *do_getline(int intovar, IOBUF *iop);
+extern struct redirect *getredirect(const char *str, int len);
+extern int inrec(IOBUF *iop);
+extern int nextfile(IOBUF **curfile, int skipping);
/* main.c */
-extern int main P((int argc, char **argv));
-extern int arg_assign P((char *arg, int initing));
-extern int is_std_var P((const char *var));
+extern int arg_assign(char *arg, int initing);
+extern int is_std_var(const char *var);
+extern char *estrdup(const char *str, size_t len);
+extern void update_global_values();
/* msg.c */
-extern void err P((const char *s, const char *emsg, va_list argp)) ATTRIBUTE_PRINTF(2, 0);
-#if _MSC_VER == 510
-extern void msg P((va_list va_alist, ...));
-extern void error P((va_list va_alist, ...));
-extern void warning P((va_list va_alist, ...));
-extern void set_loc P((const char *file, int line));
-extern void r_fatal P((va_list va_alist, ...));
-extern void (*lintfunc) P((va_list va_alist, ...));
-#else
-#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+extern void gawk_exit(int status);
+extern void err(const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(2, 0);
extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
extern void set_loc (const char *file, int line);
-extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-ATTRIBUTE_EXPORTED
+extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
#else
extern void (*lintfunc) (const char *mesg, ...);
#endif
-#else
-extern void msg ();
-extern void error ();
-extern void warning ();
-extern void set_loc ();
-extern void r_fatal ();
-extern void (*lintfunc) ();
-#endif
-#endif
/* profile.c */
-extern void init_profiling P((int *flag, const char *def_file));
-extern void init_profiling_signals P((void));
-extern void set_prof_file P((const char *filename));
-extern void dump_prog P((NODE *begin, NODE *beginfile, NODE *prog, NODE *endfile, NODE *end));
-extern void pp_func P((const char *name, size_t namelen, NODE *f));
-extern void pp_string_fp P((FILE *fp, const char *str, size_t namelen,
- int delim, int breaklines));
+extern void init_profiling(int *flag, const char *def_file);
+extern void init_profiling_signals(void);
+extern void set_prof_file(const char *filename);
+extern void dump_prog(INSTRUCTION *code);
+extern char *pp_number(AWKNUM d);
+extern char *pp_string(const char *in_str, size_t len, int delim);
+extern char *pp_node(NODE *n);
+extern int pp_func(INSTRUCTION *pc, void *);
+extern void pp_string_fp(Func_print print_func, FILE *fp, const char *str,
+ size_t namelen, int delim, int breaklines);
/* node.c */
-extern AWKNUM r_force_number P((NODE *n));
-extern NODE *format_val P((const char *format, int index, NODE *s));
-extern NODE *r_force_string P((NODE *s));
-extern NODE *r_dupnode P((NODE *n));
-extern NODE *copynode P((NODE *n));
-extern NODE *mk_number P((AWKNUM x, unsigned int flags));
-extern NODE *make_str_node P((char *s, unsigned long len, int scan ));
-extern NODE *tmp_string P((char *s, size_t len ));
-extern NODE *more_nodes P((void));
-#ifdef MEMDEBUG
-extern void freenode P((NODE *it));
-#endif
-extern void unref P((NODE *tmp));
-extern int parse_escape P((const char **string_ptr));
+extern AWKNUM r_force_number(NODE *n);
+extern NODE *format_val(const char *format, int index, NODE *s);
+extern NODE *r_force_string(NODE *s);
+extern NODE *dupnode(NODE *n);
+extern NODE *mk_number(AWKNUM x, unsigned int flags);
+extern NODE *r_make_str_node(char *s, unsigned long len, int scan);
+extern NODE *more_nodes(void);
+extern void unref(NODE *tmp);
+extern int parse_escape(const char **string_ptr);
#ifdef MBS_SUPPORT
-extern NODE *str2wstr P((NODE *n, size_t **ptr));
+extern NODE *str2wstr(NODE *n, size_t **ptr);
#define force_wstring(n) str2wstr(n, NULL)
-extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
-extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
-extern void free_wstr P((NODE *n));
+extern const wchar_t *wstrstr(const wchar_t *haystack, size_t hs_len,
+ const wchar_t *needle, size_t needle_len);
+extern const wchar_t *wcasestrstr(const wchar_t *haystack, size_t hs_len,
+ const wchar_t *needle, size_t needle_len);
+extern void free_wstr(NODE *n);
#else
#define free_wstr(NODE) /* empty */
#endif
/* re.c */
-extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa));
-extern int research P((Regexp *rp, char *str, int start,
- size_t len, int flags));
-extern void refree P((Regexp *rp));
-extern void reg_error P((const char *s));
-extern Regexp *re_update P((NODE *t));
-extern void resyntax P((int syntax));
-extern void resetup P((void));
-extern int avoid_dfa P((NODE *re, char *str, size_t len)); /* temporary */
-extern int reisstring P((const char *text, size_t len, Regexp *re, const char *buf));
-extern int remaybelong P((const char *text, size_t len));
-extern int isnondecimal P((const char *str, int use_locale));
+extern Regexp *make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal);
+extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
+extern void refree(Regexp *rp);
+extern void reg_error(const char *s);
+extern Regexp *re_update(NODE *t);
+extern void resyntax(int syntax);
+extern void resetup(void);
+extern int avoid_dfa(NODE *re, char *str, size_t len);
+extern int reisstring(const char *text, size_t len, Regexp *re, const char *buf);
+extern int remaybelong(const char *text, size_t len);
+extern int isnondecimal(const char *str, int use_locale);
/* floatcomp.c */
#ifdef VMS /* VMS linker weirdness? */
@@ -1204,49 +1345,27 @@ extern int isnondecimal P((const char *str, int use_locale));
#define Floor gawk_floor
#endif
-extern AWKNUM Floor P((AWKNUM n));
-extern AWKNUM Ceil P((AWKNUM n));
+extern AWKNUM Floor(AWKNUM n);
+extern AWKNUM Ceil(AWKNUM n);
#ifdef HAVE_UINTMAX_T
-extern uintmax_t adjust_uint P((uintmax_t n));
+extern uintmax_t adjust_uint(uintmax_t n);
#else
#define adjust_uint(n) (n)
#endif
-/* strncasecmp.c */
-#ifndef BROKEN_STRNCASECMP
-extern int strcasecmp P((const char *s1, const char *s2));
-extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
-#endif
-
-#if defined(atarist)
-#if defined(PIPES_SIMULATED)
-/* unsupported/atari/tmpnam.c */
-extern char *tmpnam P((char *buf));
-extern char *tempnam P((const char *path, const char *base));
-#else
-#include <wait.h>
-#endif
-#include <fcntl.h>
-#define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1)
-#else
#define INVALID_HANDLE (-1)
-#endif /* atarist */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
-#if defined(_MSC_VER) || defined(VMS)
+#if defined(VMS)
#define WEXITSTATUS(stat_val) (stat_val)
-#else /* ! (defined(_MSC_VER) || defined(VMS)) */
+#else /* ! defined(VMS) */
#define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
#endif /* ! (defined(_MSC_VER) || defined(VMS)) */
#endif /* WEXITSTATUS */
-#ifndef STATIC
-#define STATIC static
-#endif
-
/* EXIT_SUCCESS and EXIT_FAILURE normally come from <stdlib.h> */
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0