diff options
Diffstat (limited to 'awk.h')
-rw-r--r-- | awk.h | 187 |
1 files changed, 157 insertions, 30 deletions
@@ -30,6 +30,15 @@ * any system headers. Otherwise, extreme death, destruction * and loss of life results. */ +#if defined(_TANDEM_SOURCE) +/* + * config.h forces this even on non-tandem systems but it + * causes problems elsewhere if used in the check below. + * so workaround it. bleah. + */ +#define tandem_for_real 1 +#endif + #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -38,7 +47,7 @@ #define _GNU_SOURCE 1 /* enable GNU extensions */ #endif /* _GNU_SOURCE */ -#if defined(_TANDEM_SOURCE) && ! defined(_SCO_DS) +#if defined(tandem_for_real) && ! defined(_SCO_DS) #define _XOPEN_SOURCE_EXTENDED 1 #endif @@ -80,6 +89,12 @@ extern int errno; #include <stdlib.h> #endif /* not STDC_HEADERS */ +#ifdef HAVE_STDBOOL_H +#include <stdbool.h> +#else +#include "missing_d/gawkbool.h" +#endif + #include "mbsupport.h" /* defines MBS_SUPPORT */ #if MBS_SUPPORT @@ -195,6 +210,18 @@ typedef void *stackoverflow_context_t; this is a hack but it gives us the right semantics */ #define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc)) +#ifdef HAVE_MPFR +#include <gmp.h> +#include <mpfr.h> +#ifndef MPFR_RNDN +/* for compatibility with MPFR 2.X */ +#define MPFR_RNDN GMP_RNDN +#define MPFR_RNDZ GMP_RNDZ +#define MPFR_RNDU GMP_RNDU +#define MPFR_RNDD GMP_RNDD +#endif +#endif + #include "regex.h" #include "dfa.h" typedef struct Regexp { @@ -204,6 +231,8 @@ typedef struct Regexp { short dfa; short has_anchor; /* speed up of avoid_dfa kludge, temporary */ short non_empty; /* for use in fpat_parse_field */ + short has_meta; /* re has meta chars so (probably) isn't simple string */ + short maybe_long; /* re has meta chars that can match long text */ } Regexp; #define RESTART(rp,s) (rp)->regs.start[0] #define REEND(rp,s) (rp)->regs.end[0] @@ -369,9 +398,17 @@ typedef struct exp_node { } nodep; struct { +#ifdef HAVE_MPFR + union { + AWKNUM fltnum; + mpfr_t mpnum; + mpz_t mpi; + } nm; +#else AWKNUM fltnum; /* this is here for optimal packing of * the structure on many machines */ +#endif char *sp; size_t slen; long sref; @@ -402,12 +439,14 @@ typedef struct exp_node { * lazy conversion to string. */ # define WSTRCUR 0x0400 /* wide str value is current */ +# define MPFN 0x0800 /* arbitrary-precision floating-point number */ +# define MPZN 0x1000 /* arbitrary-precision integer */ /* type = Node_var_array */ -# define ARRAYMAXED 0x0800 /* array is at max size */ -# define HALFHAT 0x1000 /* half-capacity Hashed Array Tree; +# define ARRAYMAXED 0x2000 /* array is at max size */ +# define HALFHAT 0x4000 /* half-capacity Hashed Array Tree; * See cint_array.c */ -# define XARRAY 0x2000 +# define XARRAY 0x8000 } NODE; #define vname sub.nodep.name @@ -446,7 +485,13 @@ typedef struct exp_node { #define stfmt sub.val.idx #define wstptr sub.val.wsp #define wstlen sub.val.wslen -#define numbr sub.val.fltnum +#ifdef HAVE_MPFR +#define mpg_numbr sub.val.nm.mpnum +#define mpg_i sub.val.nm.mpi +#define numbr sub.val.nm.fltnum +#else +#define numbr sub.val.fltnum +#endif /* Node_arrayfor */ #define for_list sub.nodep.r.av @@ -602,7 +647,7 @@ typedef enum opcodeval { Op_indirect_func_call, Op_push, /* scalar variable */ - Op_push_arg, /* variable type (scalar or array) argument to built-in */ + Op_push_arg, /* variable type (scalar or array) argument to built-in */ Op_push_i, /* number, string */ Op_push_re, /* regex */ Op_push_array, @@ -655,7 +700,8 @@ typedef enum opcodeval { enum redirval { /* I/O redirections */ - redirect_output = 1, + redirect_none = 0, + redirect_output, redirect_append, redirect_pipe, redirect_pipein, @@ -990,13 +1036,20 @@ 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; +extern NODE *PREC_node, *ROUNDMODE_node; extern NODE *Nnull_string; extern NODE *Null_field; extern NODE **fields_arr; extern int sourceline; extern char *source; extern int (*interpret)(INSTRUCTION *); /* interpreter routine */ +extern NODE *(*make_number)(double); /* double instead of AWKNUM on purpose */ +extern NODE *(*str2number)(NODE *); +extern NODE *(*format_val)(const char *, int, NODE *); +extern int (*cmp_numbers)(const NODE *, const NODE *); +typedef int (*Func_pre_exec)(INSTRUCTION **); +typedef void (*Func_post_exec)(INSTRUCTION *); #if __GNUC__ < 2 extern NODE *_t; /* used as temporary in macros */ @@ -1036,7 +1089,8 @@ extern int do_flags; #define DO_PROFILE 0x1000 /* debug the program */ #define DO_DEBUG 0x2000 - +/* arbitrary-precision floating-point math */ +#define DO_MPFR 0x4000 #define do_traditional (do_flags & DO_TRADITIONAL) #define do_posix (do_flags & DO_POSIX) @@ -1049,7 +1103,7 @@ extern int do_flags; #define do_tidy_mem (do_flags & DO_TIDY_MEM) #define do_sandbox (do_flags & DO_SANDBOX) #define do_debug (do_flags & DO_DEBUG) - +#define do_mpfr (do_flags & DO_MPFR) extern int do_optimize; extern int use_lc_numeric; @@ -1077,6 +1131,16 @@ extern int ngroups; extern struct lconv loc; #endif /* HAVE_LOCALE_H */ +#ifdef HAVE_MPFR +extern mpfr_prec_t PRECISION; +extern mpfr_rnd_t ROUND_MODE; +extern mpz_t MNR; +extern mpz_t MFNR; +extern mpz_t mpzval; +extern int do_ieee_fmt; /* emulate IEEE 754 floating-point format */ +#endif + + extern const char *myname; extern const char def_strftime_format[]; @@ -1135,9 +1199,6 @@ extern STACK_ITEM *stack_top; #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 \ @@ -1154,9 +1215,6 @@ extern STACK_ITEM *stack_top; #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 \ @@ -1167,7 +1225,48 @@ extern STACK_ITEM *stack_top; #endif /* __GNUC__ */ +#define POP_NUMBER() force_number(POP_SCALAR()) +#define TOP_NUMBER() force_number(TOP_SCALAR()) + /* ------------------------- Pseudo-functions ------------------------- */ +#ifdef HAVE_MPFR +/* conversion to C types */ +#define get_number_ui(n) (((n)->flags & MPFN) ? mpfr_get_ui((n)->mpg_numbr, ROUND_MODE) \ + : ((n)->flags & MPZN) ? mpz_get_ui((n)->mpg_i) \ + : (unsigned long) (n)->numbr) +#define get_number_si(n) (((n)->flags & MPFN) ? mpfr_get_si((n)->mpg_numbr, ROUND_MODE) \ + : ((n)->flags & MPZN) ? mpz_get_si((n)->mpg_i) \ + : (long) (n)->numbr) +#define get_number_d(n) (((n)->flags & MPFN) ? mpfr_get_d((n)->mpg_numbr, ROUND_MODE) \ + : ((n)->flags & MPZN) ? mpz_get_d((n)->mpg_i) \ + : (double) (n)->numbr) +#define get_number_uj(n) (((n)->flags & MPFN) ? mpfr_get_uj((n)->mpg_numbr, ROUND_MODE) \ + : ((n)->flags & MPZN) ? (uintmax_t) mpz_get_d((n)->mpg_i) \ + : (uintmax_t) (n)->numbr) + +#define iszero(n) (((n)->flags & MPFN) ? mpfr_zero_p((n)->mpg_numbr) \ + : ((n)->flags & MPZN) ? (mpz_sgn((n)->mpg_i) == 0) \ + : ((n)->numbr == 0.0)) + +#define IEEE_FMT(r, t) (void) (do_ieee_fmt && format_ieee(r, t)) + +#define mpg_float() mpg_node(MPFN) +#define mpg_integer() mpg_node(MPZN) +#define is_mpg_float(n) (((n)->flags & MPFN) != 0) +#define is_mpg_integer(n) (((n)->flags & MPZN) != 0) +#define is_mpg_number(n) (((n)->flags & (MPZN|MPFN)) != 0) +#else +#define get_number_ui(n) (unsigned long) (n)->numbr +#define get_number_si(n) (long) (n)->numbr +#define get_number_d(n) (double) (n)->numbr +#define get_number_uj(n) (uintmax_t) (n)->numbr + +#define is_mpg_number(n) 0 +#define is_mpg_float(n) 0 +#define is_mpg_integer(n) 0 +#define iszero(n) ((n)->numbr == 0.0) +#endif + #define is_identchar(c) (isalnum(c) || (c) == '_') #define var_uninitialized(n) ((n)->var_value == Nnull_string) @@ -1207,7 +1306,7 @@ extern STACK_ITEM *stack_top; #define efree(p) free(p) #ifdef GAWKDEBUG -#define force_number r_force_number +#define force_number str2number #define dupnode r_dupnode #define unref r_unref #define m_force_string r_force_string @@ -1225,8 +1324,8 @@ extern NODE *r_force_string(NODE *s); #define dupnode(n) __extension__ ({ NODE *_tn = (n); \ (_tn->flags & MALLOC) ? (_tn->valref++, _tn) : r_dupnode(_tn); }) -#define force_number(n) __extension__ ({ NODE *_tn = (n);\ - (_tn->flags & NUMCUR) ? _tn->numbr : r_force_number(_tn); }) +#define force_number(n) __extension__ ({ NODE *_tn = (n); \ + (_tn->flags & NUMCUR) ? _tn : str2number(_tn); }) #define force_string(s) __extension__ ({ NODE *_ts = (s); m_force_string(_ts); }) @@ -1234,7 +1333,7 @@ extern NODE *r_force_string(NODE *s); #define dupnode(n) (_t = (n), \ (_t->flags & MALLOC) ? (_t->valref++, _t) : r_dupnode(_t)) -#define force_number r_force_number +#define force_number str2number #define force_string(s) (_t = (s), m_force_string(_t)) #endif /* __GNUC__ */ #endif /* GAWKDEBUG */ @@ -1316,6 +1415,7 @@ extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, int *already_in extern void register_deferred_variable(const char *name, NODE *(*load_func)(void)); extern int files_are_same(char *path, SRCFILE *src); extern void valinfo(NODE *n, Func_print print_func, FILE *fp); +extern void negate_num(NODE *n); /* builtin.c */ extern double double_to_int(double d); extern NODE *do_exp(int nargs); @@ -1365,9 +1465,8 @@ extern int strncasecmpmbs(const unsigned char *, extern void PUSH_CODE(INSTRUCTION *cp); extern INSTRUCTION *POP_CODE(void); extern void init_interpret(void); -extern int r_interpret(INSTRUCTION *); -extern int debug_interpret(INSTRUCTION *); -extern int cmp_nodes(NODE *p1, NODE *p2); +extern int cmp_nodes(NODE *t1, NODE *t2); +extern int cmp_awknums(const NODE *t1, const NODE *t2); extern void set_IGNORECASE(void); extern void set_OFS(void); extern void set_ORS(void); @@ -1388,13 +1487,13 @@ 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); extern void dump_fcall_stack(FILE *fp); +extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth); /* ext.c */ NODE *do_ext(int nargs); NODE *load_ext(const char *lib_name, const char *init_func, NODE *obj); @@ -1454,7 +1553,7 @@ 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, int is_extlib); -extern NODE *do_getline_redir(int intovar, int redirtype); +extern NODE *do_getline_redir(int intovar, enum redirval redirtype); extern NODE *do_getline(int intovar, IOBUF *iop); extern struct redirect *getredirect(const char *str, int len); extern int inrec(IOBUF *iop, int *errcode); @@ -1465,6 +1564,36 @@ extern int is_std_var(const char *var); extern char *estrdup(const char *str, size_t len); extern void update_global_values(); extern long getenv_long(const char *name); + +/* mpfr.c */ +extern void set_PREC(void); +extern void set_ROUNDMODE(void); +#ifdef HAVE_MPFR +extern int mpg_cmp(const NODE *, const NODE *); +extern int format_ieee(mpfr_ptr, int); +extern NODE *mpg_update_var(NODE *); +extern long mpg_set_var(NODE *); +extern NODE *do_mpfr_and(int); +extern NODE *do_mpfr_atan2(int); +extern NODE *do_mpfr_compl(int); +extern NODE *do_mpfr_cos(int); +extern NODE *do_mpfr_exp(int); +extern NODE *do_mpfr_int(int); +extern NODE *do_mpfr_log(int); +extern NODE *do_mpfr_lshift(int); +extern NODE *do_mpfr_or(int); +extern NODE *do_mpfr_rand(int); +extern NODE *do_mpfr_rhift(int); +extern NODE *do_mpfr_sin(int); +extern NODE *do_mpfr_sqrt(int); +extern NODE *do_mpfr_srand(int); +extern NODE *do_mpfr_strtonum(int); +extern NODE *do_mpfr_xor(int); +extern void init_mpfr(mpfr_prec_t, const char *); +extern NODE *mpg_node(unsigned int); +extern const char *mpg_fmt(const char *, ...); +extern int mpg_strtoui(mpz_ptr, char *, size_t, char **, int); +#endif /* msg.c */ extern void gawk_exit(int status); extern void err(const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(2, 0); @@ -1483,17 +1612,16 @@ 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_number(NODE *n); 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(NODE *n); -extern NODE *format_val(const char *format, int index, NODE *s); +extern NODE *r_force_number(NODE *n); +extern NODE *r_format_val(const char *format, int index, NODE *s); extern NODE *r_dupnode(NODE *n); -extern NODE *make_number(AWKNUM x); extern NODE *r_make_str_node(const char *s, size_t len, int flags); extern void *more_blocks(int id); extern void r_unref(NODE *tmp); @@ -1524,8 +1652,7 @@ 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); +extern int get_numbase(const char *str, int use_locale); /* symbol.c */ extern NODE *install_symbol(char *name, NODETYPE type); |