diff options
Diffstat (limited to 'awk.h')
-rw-r--r-- | awk.h | 162 |
1 files changed, 136 insertions, 26 deletions
@@ -195,6 +195,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 { @@ -369,9 +381,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 +422,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 +468,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 +630,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, @@ -990,13 +1018,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 +1071,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 +1085,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 +1113,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[]; @@ -1134,9 +1180,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 \ @@ -1153,9 +1196,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 \ @@ -1166,7 +1206,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) @@ -1206,7 +1287,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 @@ -1224,8 +1305,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); }) @@ -1233,7 +1314,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 */ @@ -1315,6 +1396,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); @@ -1364,9 +1446,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); @@ -1385,13 +1466,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); @@ -1462,6 +1543,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); @@ -1480,17 +1591,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); @@ -1522,7 +1632,7 @@ 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); |