diff options
Diffstat (limited to 'awk.h')
-rw-r--r-- | awk.h | 1439 |
1 files changed, 779 insertions, 660 deletions
@@ -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 |