aboutsummaryrefslogtreecommitdiffstats
path: root/awk.h
diff options
context:
space:
mode:
Diffstat (limited to 'awk.h')
-rw-r--r--awk.h162
1 files changed, 136 insertions, 26 deletions
diff --git a/awk.h b/awk.h
index 72593902..a4b87617 100644
--- a/awk.h
+++ b/awk.h
@@ -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);