|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* awk.h -- Definitions for gawk.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* Copyright (C) 1986, 1988, 1989, 1991-2018 the Free Software Foundation, Inc.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* This file is part of GAWK, the GNU implementation of the
|
|
Packit |
575503 |
* AWK Programming Language.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* GAWK is free software; you can redistribute it and/or modify
|
|
Packit |
575503 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
575503 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
575503 |
* (at your option) any later version.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* GAWK is distributed in the hope that it will be useful,
|
|
Packit |
575503 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
575503 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
575503 |
* GNU General Public License for more details.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
575503 |
* along with this program; if not, write to the Free Software
|
|
Packit |
575503 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------------------------ Includes ------------------------------ */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* config.h absolutely, positively, *M*U*S*T* be included before
|
|
Packit |
575503 |
* any system headers. Otherwise, extreme death, destruction
|
|
Packit |
575503 |
* and loss of life results.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
#if defined(_TANDEM_SOURCE)
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* config.h forces this even on non-tandem systems but it
|
|
Packit |
575503 |
* causes problems elsewhere if used in the check below.
|
|
Packit |
575503 |
* so workaround it. bleah.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
#define tandem_for_real 1
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
575503 |
#include <config.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef _GNU_SOURCE
|
|
Packit |
575503 |
#define _GNU_SOURCE 1 /* enable GNU extensions */
|
|
Packit |
575503 |
#endif /* _GNU_SOURCE */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if defined(tandem_for_real) && ! defined(_SCO_DS)
|
|
Packit |
575503 |
#define _XOPEN_SOURCE_EXTENDED 1
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include <stdio.h>
|
|
Packit |
575503 |
#include <assert.h>
|
|
Packit |
575503 |
#ifdef HAVE_LIMITS_H
|
|
Packit |
575503 |
#include <limits.h>
|
|
Packit |
575503 |
#endif /* HAVE_LIMITS_H */
|
|
Packit |
575503 |
#include <ctype.h>
|
|
Packit |
575503 |
#include <setjmp.h>
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include "gettext.h"
|
|
Packit |
575503 |
#define _(msgid) gettext(msgid)
|
|
Packit |
575503 |
#define N_(msgid) msgid
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0)
|
|
Packit |
575503 |
#ifndef LOCALEDIR
|
|
Packit |
575503 |
#define LOCALEDIR NULL
|
|
Packit |
575503 |
#endif /* LOCALEDIR */
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if !defined(__STDC__) || __STDC__ < 1
|
|
Packit |
575503 |
#error "gawk no longer supports non-C89 environments (no __STDC__ or __STDC__ < 1)"
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if defined(HAVE_STDARG_H)
|
|
Packit |
575503 |
#include <stdarg.h>
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#error "gawk no longer supports <varargs.h>. Please update your compiler and runtime"
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#include <signal.h>
|
|
Packit |
575503 |
#include <time.h>
|
|
Packit |
575503 |
#include <errno.h>
|
|
Packit |
575503 |
#if ! defined(errno)
|
|
Packit |
575503 |
extern int errno;
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef STDC_HEADERS
|
|
Packit |
575503 |
#include <stdlib.h>
|
|
Packit |
575503 |
#endif /* not STDC_HEADERS */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_STDBOOL_H
|
|
Packit |
575503 |
#include <stdbool.h>
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#include "missing_d/gawkbool.h"
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* We can handle multibyte strings. */
|
|
Packit |
575503 |
#include <wchar.h>
|
|
Packit |
575503 |
#include <wctype.h>
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include "mbsupport.h" /* defines stuff for DJGPP to fake MBS */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef STDC_HEADERS
|
|
Packit |
575503 |
#include <float.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#undef CHARBITS
|
|
Packit |
575503 |
#undef INTBITS
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if HAVE_INTTYPES_H
|
|
Packit |
575503 |
# include <inttypes.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#if HAVE_STDINT_H
|
|
Packit |
575503 |
# include <stdint.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ----------------- System dependencies (with more includes) -----------*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* This section is the messiest one in the file, not a lot that can be done */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef VMS
|
|
Packit |
575503 |
#ifdef HAVE_FCNTL_H
|
|
Packit |
575503 |
#include <fcntl.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#include <sys/types.h>
|
|
Packit |
575503 |
#include <sys/stat.h>
|
|
Packit |
575503 |
#else /* VMS */
|
|
Packit |
575503 |
#include <stddef.h>
|
|
Packit |
575503 |
#include <stat.h>
|
|
Packit |
575503 |
#include <file.h> /* avoid <fcntl.h> in io.c */
|
|
Packit |
575503 |
/* debug.c needs this; when _DECC_V4_SOURCE is defined (as it is
|
|
Packit |
575503 |
in our config.h [vms/vms-conf.h]), off_t won't get declared */
|
|
Packit |
575503 |
# if !defined(__OFF_T) && !defined(_OFF_T)
|
|
Packit |
575503 |
# if defined(____OFF_T) || defined(___OFF_T)
|
|
Packit |
575503 |
typedef __off_t off_t; /* __off_t is either int or __int64 */
|
|
Packit |
575503 |
# else
|
|
Packit |
575503 |
typedef int off_t;
|
|
Packit |
575503 |
# endif
|
|
Packit |
575503 |
# endif
|
|
Packit |
575503 |
#endif /* VMS */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include "protos.h"
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_STRING_H
|
|
Packit |
575503 |
#include <string.h>
|
|
Packit |
575503 |
#ifdef NEED_MEMORY_H
|
|
Packit |
575503 |
#include <memory.h>
|
|
Packit |
575503 |
#endif /* NEED_MEMORY_H */
|
|
Packit |
575503 |
#endif /* HAVE_STRING_H */
|
|
Packit |
575503 |
#ifdef HAVE_STRINGS_H
|
|
Packit |
575503 |
#include <strings.h>
|
|
Packit |
575503 |
#endif /* HAVE_STRINGS_H */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if HAVE_UNISTD_H
|
|
Packit |
575503 |
#include <unistd.h>
|
|
Packit |
575503 |
#endif /* HAVE_UNISTD_H */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef VMS
|
|
Packit |
575503 |
#include <unixlib.h>
|
|
Packit |
575503 |
#include "vms/redirect.h"
|
|
Packit |
575503 |
#endif /*VMS*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef O_BINARY
|
|
Packit |
575503 |
#define O_BINARY 0
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef HAVE_SETLOCALE
|
|
Packit |
575503 |
#define setlocale(locale, val) /* nothing */
|
|
Packit |
575503 |
#endif /* HAVE_SETLOCALE */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if HAVE_MEMCPY_ULONG
|
|
Packit |
575503 |
extern char *memcpy_ulong(char *dest, const char *src, unsigned long l);
|
|
Packit |
575503 |
#define memcpy memcpy_ulong
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#if HAVE_MEMSET_ULONG
|
|
Packit |
575503 |
extern void *memset_ulong(void *dest, int val, unsigned long l);
|
|
Packit |
575503 |
#define memset memset_ulong
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_FWRITE_UNLOCKED
|
|
Packit |
575503 |
#define fwrite fwrite_unlocked
|
|
Packit |
575503 |
#endif /* HAVE_FWRITE_UNLOCKED */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if defined(__DJGPP__) || defined(__EMX__) || defined(__MINGW32__)
|
|
Packit |
575503 |
#include "nonposix.h"
|
|
Packit |
575503 |
#endif /* defined(__DJGPP__) || defined(__EMX__) || defined(__MINGW32__) */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* use this as lintwarn("...")
|
|
Packit |
575503 |
this is a hack but it gives us the right semantics */
|
|
Packit |
575503 |
#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
|
|
Packit |
575503 |
/* same thing for warning */
|
|
Packit |
575503 |
#define warning (*(set_loc(__FILE__, __LINE__),r_warning))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
#include <gmp.h>
|
|
Packit |
575503 |
#include <mpfr.h>
|
|
Packit |
575503 |
#ifndef MPFR_RNDN
|
|
Packit |
575503 |
/* for compatibility with MPFR 2.X */
|
|
Packit |
575503 |
#define MPFR_RNDN GMP_RNDN
|
|
Packit |
575503 |
#define MPFR_RNDZ GMP_RNDZ
|
|
Packit |
575503 |
#define MPFR_RNDU GMP_RNDU
|
|
Packit |
575503 |
#define MPFR_RNDD GMP_RNDD
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include "regex.h"
|
|
Packit |
575503 |
#include "dfa.h"
|
|
Packit |
575503 |
typedef struct Regexp {
|
|
Packit |
575503 |
struct re_pattern_buffer pat;
|
|
Packit |
575503 |
struct re_registers regs;
|
|
Packit |
575503 |
struct dfa *dfareg;
|
|
Packit |
575503 |
bool has_meta; /* re has meta chars so (probably) isn't simple string */
|
|
Packit |
575503 |
bool maybe_long; /* re has meta chars that can match long text */
|
|
Packit |
575503 |
} Regexp;
|
|
Packit |
575503 |
#define RESTART(rp,s) (rp)->regs.start[0]
|
|
Packit |
575503 |
#define REEND(rp,s) (rp)->regs.end[0]
|
|
Packit |
575503 |
#define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
|
|
Packit |
575503 |
#define SUBPATEND(rp,s,n) (rp)->regs.end[n]
|
|
Packit |
575503 |
#define NUMSUBPATS(rp,s) (rp)->regs.num_regs
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* regexp matching flags: */
|
|
Packit |
575503 |
#define RE_NO_FLAGS 0 /* empty flags */
|
|
Packit |
575503 |
#define RE_NEED_START 1 /* need to know start/end of match */
|
|
Packit |
575503 |
#define RE_NO_BOL 2 /* not allowed to match ^ in regexp */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include "gawkapi.h"
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Stuff for losing systems. */
|
|
Packit |
575503 |
#if !defined(HAVE_STRTOD)
|
|
Packit |
575503 |
extern double gawk_strtod();
|
|
Packit |
575503 |
#define strtod gawk_strtod
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
|
Packit |
575503 |
# define __attribute__(x)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef ATTRIBUTE_UNUSED
|
|
Packit |
575503 |
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
|
Packit |
575503 |
#endif /* ATTRIBUTE_UNUSED */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef ATTRIBUTE_NORETURN
|
|
Packit |
575503 |
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
|
Packit |
575503 |
#endif /* ATTRIBUTE_NORETURN */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef ATTRIBUTE_PRINTF
|
|
Packit |
575503 |
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
|
Packit |
575503 |
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
|
Packit |
575503 |
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
|
Packit |
575503 |
#endif /* ATTRIBUTE_PRINTF */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------------ Constants, Structures, Typedefs ------------------ */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define AWKNUM double
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum defrule { BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
|
|
Packit |
575503 |
MAXRULE /* sentinel, not legal */ };
|
|
Packit |
575503 |
extern const char *const ruletab[];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef enum nodevals {
|
|
Packit |
575503 |
/* illegal entry == 0 */
|
|
Packit |
575503 |
Node_illegal,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Node_val, /* node is a value - type in flags */
|
|
Packit |
575503 |
Node_regex, /* a regexp, text, compiled, flags, etc */
|
|
Packit |
575503 |
Node_dynregex, /* a dynamic regexp */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* symbol table values */
|
|
Packit |
575503 |
Node_var, /* scalar variable, lnode is value */
|
|
Packit |
575503 |
Node_var_array, /* array is ptr to elements, table_size num of eles */
|
|
Packit |
575503 |
Node_var_new, /* newly created variable, may become an array */
|
|
Packit |
575503 |
Node_param_list, /* lnode is a variable, rnode is more list */
|
|
Packit |
575503 |
Node_func, /* lnode is param. list, rnode is body */
|
|
Packit |
575503 |
Node_ext_func, /* extension function, code_ptr is builtin code */
|
|
Packit |
575503 |
Node_builtin_func, /* built-in function, main use is for FUNCTAB */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Node_array_ref, /* array passed by ref as parameter */
|
|
Packit |
575503 |
Node_array_tree, /* Hashed array tree (HAT) */
|
|
Packit |
575503 |
Node_array_leaf, /* Linear 1-D array */
|
|
Packit |
575503 |
Node_dump_array, /* array info */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* program execution -- stack item types */
|
|
Packit |
575503 |
Node_arrayfor,
|
|
Packit |
575503 |
Node_frame,
|
|
Packit |
575503 |
Node_instruction,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Node_final /* sentry value, not legal */
|
|
Packit |
575503 |
} NODETYPE;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct exp_node;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef union bucket_item {
|
|
Packit |
575503 |
struct {
|
|
Packit |
575503 |
union bucket_item *next;
|
|
Packit |
575503 |
char *str;
|
|
Packit |
575503 |
size_t len;
|
|
Packit |
575503 |
size_t code;
|
|
Packit |
575503 |
struct exp_node *name;
|
|
Packit |
575503 |
struct exp_node *val;
|
|
Packit |
575503 |
} hs;
|
|
Packit |
575503 |
struct {
|
|
Packit |
575503 |
union bucket_item *next;
|
|
Packit |
575503 |
long li[2];
|
|
Packit |
575503 |
struct exp_node *val[2];
|
|
Packit |
575503 |
size_t cnt;
|
|
Packit |
575503 |
} hi;
|
|
Packit |
575503 |
} BUCKET;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* string hash table */
|
|
Packit |
575503 |
#define ahnext hs.next
|
|
Packit |
575503 |
#define ahname hs.name /* a string index node */
|
|
Packit |
575503 |
#define ahname_str hs.str /* shallow copy; = ahname->stptr */
|
|
Packit |
575503 |
#define ahname_len hs.len /* = ahname->stlen */
|
|
Packit |
575503 |
#define ahvalue hs.val
|
|
Packit |
575503 |
#define ahcode hs.code
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* integer hash table */
|
|
Packit |
575503 |
#define ainext hi.next
|
|
Packit |
575503 |
#define ainum hi.li /* integer indices */
|
|
Packit |
575503 |
#define aivalue hi.val
|
|
Packit |
575503 |
#define aicount hi.cnt
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct exp_instruction;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef int (*Func_print)(FILE *, const char *, ...);
|
|
Packit |
575503 |
typedef struct exp_node **(*afunc_t)(struct exp_node *, struct exp_node *);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* NOTE - this struct is a rather kludgey -- it is packed to minimize
|
|
Packit |
575503 |
* space usage, at the expense of cleanliness. Alter at own risk.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
typedef struct exp_node {
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
struct {
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
struct exp_node *lptr;
|
|
Packit |
575503 |
struct exp_instruction *li;
|
|
Packit |
575503 |
long ll;
|
|
Packit |
575503 |
afunc_t *lp;
|
|
Packit |
575503 |
} l;
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
struct exp_node *rptr;
|
|
Packit |
575503 |
Regexp *preg[2];
|
|
Packit |
575503 |
struct exp_node **av;
|
|
Packit |
575503 |
BUCKET **bv;
|
|
Packit |
575503 |
void (*uptr)(void);
|
|
Packit |
575503 |
struct exp_instruction *iptr;
|
|
Packit |
575503 |
} r;
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
struct exp_node *extra;
|
|
Packit |
575503 |
void (*aptr)(void);
|
|
Packit |
575503 |
long xl;
|
|
Packit |
575503 |
} x;
|
|
Packit |
575503 |
char *name;
|
|
Packit |
575503 |
size_t reserved;
|
|
Packit |
575503 |
struct exp_node *rn;
|
|
Packit |
575503 |
unsigned long cnt;
|
|
Packit |
575503 |
unsigned long reflags;
|
|
Packit |
575503 |
# define CONSTANT 1
|
|
Packit |
575503 |
# define FS_DFLT 2
|
|
Packit |
575503 |
} nodep;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct {
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
AWKNUM fltnum;
|
|
Packit |
575503 |
mpfr_t mpnum;
|
|
Packit |
575503 |
mpz_t mpi;
|
|
Packit |
575503 |
} nm;
|
|
Packit |
575503 |
int rndmode;
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
AWKNUM fltnum;
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
char *sp;
|
|
Packit |
575503 |
size_t slen;
|
|
Packit |
575503 |
long sref;
|
|
Packit |
575503 |
int idx;
|
|
Packit |
575503 |
wchar_t *wsp;
|
|
Packit |
575503 |
size_t wslen;
|
|
Packit |
575503 |
struct exp_node *typre;
|
|
Packit |
575503 |
} val;
|
|
Packit |
575503 |
} sub;
|
|
Packit |
575503 |
NODETYPE type;
|
|
Packit |
575503 |
unsigned int flags;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* type = Node_val */
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* STRING and NUMBER are mutually exclusive, except for the special
|
|
Packit |
575503 |
* case of an uninitialized value, represented internally by
|
|
Packit |
575503 |
* Nnull_string. They represent the type of a value as assigned.
|
|
Packit |
575503 |
* Nnull_string has both STRING and NUMBER attributes, but all other
|
|
Packit |
575503 |
* scalar values should have precisely one of these bits set.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* STRCUR and NUMCUR are not mutually exclusive. They represent that
|
|
Packit |
575503 |
* the particular type of value is up to date. For example,
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* a = 5 # NUMBER | NUMCUR
|
|
Packit |
575503 |
* b = a "" # Adds STRCUR to a, since a string value
|
|
Packit |
575503 |
* # is now available. But the type hasn't changed!
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* a = "42" # STRING | STRCUR
|
|
Packit |
575503 |
* b = a + 0 # Adds NUMCUR to a, since numeric value
|
|
Packit |
575503 |
* # is now available. But the type hasn't changed!
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* USER_INPUT is the joker. When STRING|USER_INPUT is set, it means
|
|
Packit |
575503 |
* "this is string data, but the user may have really wanted it to be a
|
|
Packit |
575503 |
* number. If we have to guess, like in a comparison, turn it into a
|
|
Packit |
575503 |
* number if the string is indeed numeric."
|
|
Packit |
575503 |
* For example, gawk -v a=42 ....
|
|
Packit |
575503 |
* Here, `a' gets STRING|STRCUR|USER_INPUT and then when used where
|
|
Packit |
575503 |
* a number is needed, it gets turned into a NUMBER and STRING
|
|
Packit |
575503 |
* is cleared. In that case, we leave the USER_INPUT in place, so
|
|
Packit |
575503 |
* the combination NUMBER|USER_INPUT means it is a strnum a.k.a. a
|
|
Packit |
575503 |
* "numeric string".
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* WSTRCUR is for efficiency. If in a multibyte locale, and we
|
|
Packit |
575503 |
* need to do something character based (substr, length, etc.)
|
|
Packit |
575503 |
* we create the corresponding wide character string and store it,
|
|
Packit |
575503 |
* and add WSTRCUR to the flags so that we don't have to do the
|
|
Packit |
575503 |
* conversion more than once.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* The NUMINT flag may be used with a value of any type -- NUMBER,
|
|
Packit |
575503 |
* STRING, or STRNUM. It indicates that the string representation
|
|
Packit |
575503 |
* equals the result of sprintf("%ld", <numeric value>). So, for
|
|
Packit |
575503 |
* example, NUMINT should NOT be set if it's a strnum or string value
|
|
Packit |
575503 |
* where the string is " 1" or "01" or "+1" or "1.0" or "0.1E1". This
|
|
Packit |
575503 |
* is a hint to indicate that an integer array optimization may be
|
|
Packit |
575503 |
* used when this value appears as a subscript.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* We hope that the rest of the flags are self-explanatory. :-)
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
# define MALLOC 0x0001 /* stptr can be free'd, i.e. not a field node pointing into a shared buffer */
|
|
Packit |
575503 |
# define STRING 0x0002 /* assigned as string */
|
|
Packit |
575503 |
# define STRCUR 0x0004 /* string value is current */
|
|
Packit |
575503 |
# define NUMCUR 0x0008 /* numeric value is current */
|
|
Packit |
575503 |
# define NUMBER 0x0010 /* assigned as number */
|
|
Packit |
575503 |
# define USER_INPUT 0x0020 /* user input: if NUMERIC then
|
|
Packit |
575503 |
* a NUMBER */
|
|
Packit |
575503 |
# define INTLSTR 0x0040 /* use localized version */
|
|
Packit |
575503 |
# define NUMINT 0x0080 /* numeric value is an integer */
|
|
Packit |
575503 |
# define INTIND 0x0100 /* integral value is array index;
|
|
Packit |
575503 |
* lazy conversion to string.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
# define WSTRCUR 0x0200 /* wide str value is current */
|
|
Packit |
575503 |
# define MPFN 0x0400 /* arbitrary-precision floating-point number */
|
|
Packit |
575503 |
# define MPZN 0x0800 /* arbitrary-precision integer */
|
|
Packit |
575503 |
# define NO_EXT_SET 0x1000 /* extension cannot set a value for this variable */
|
|
Packit |
575503 |
# define NULL_FIELD 0x2000 /* this is the null field */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* type = Node_var_array */
|
|
Packit |
575503 |
# define ARRAYMAXED 0x4000 /* array is at max size */
|
|
Packit |
575503 |
# define HALFHAT 0x8000 /* half-capacity Hashed Array Tree;
|
|
Packit |
575503 |
* See cint_array.c */
|
|
Packit |
575503 |
# define XARRAY 0x10000
|
|
Packit |
575503 |
# define NUMCONSTSTR 0x20000 /* have string value for numeric constant */
|
|
Packit |
575503 |
# define REGEX 0x40000 /* this is a typed regex */
|
|
Packit |
575503 |
} NODE;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define vname sub.nodep.name
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define lnode sub.nodep.l.lptr
|
|
Packit |
575503 |
#define rnode sub.nodep.r.rptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_param_list */
|
|
Packit |
575503 |
#define param vname
|
|
Packit |
575503 |
#define dup_ent sub.nodep.r.rptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_param_list, Node_func */
|
|
Packit |
575503 |
#define param_cnt sub.nodep.l.ll
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_func */
|
|
Packit |
575503 |
#define fparms sub.nodep.rn
|
|
Packit |
575503 |
#define code_ptr sub.nodep.r.iptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_regex, Node_dynregex */
|
|
Packit |
575503 |
#define re_reg sub.nodep.r.preg
|
|
Packit |
575503 |
#define re_flags sub.nodep.reflags
|
|
Packit |
575503 |
#define re_text lnode
|
|
Packit |
575503 |
#define re_exp sub.nodep.x.extra
|
|
Packit |
575503 |
#define re_cnt flags
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_val */
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* Note that the string in stptr may not be NUL-terminated, but it is
|
|
Packit |
575503 |
* guaranteed to have at least one extra byte that may be temporarily set
|
|
Packit |
575503 |
* to '\0'. This is helpful when calling functions such as strtod that require
|
|
Packit |
575503 |
* a NUL-terminated argument. In particular, field values $n for n > 0 and
|
|
Packit |
575503 |
* n < NF will not have a NUL terminator, since they point into the $0 buffer.
|
|
Packit |
575503 |
* All other strings are NUL-terminated.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
#define stptr sub.val.sp
|
|
Packit |
575503 |
#define stlen sub.val.slen
|
|
Packit |
575503 |
#define valref sub.val.sref
|
|
Packit |
575503 |
#define stfmt sub.val.idx
|
|
Packit |
575503 |
#define strndmode sub.val.rndmode
|
|
Packit |
575503 |
#define wstptr sub.val.wsp
|
|
Packit |
575503 |
#define wstlen sub.val.wslen
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
#define mpg_numbr sub.val.nm.mpnum
|
|
Packit |
575503 |
#define mpg_i sub.val.nm.mpi
|
|
Packit |
575503 |
#define numbr sub.val.nm.fltnum
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#define numbr sub.val.fltnum
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#define typed_re sub.val.typre
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* If stfmt is set to STFMT_UNUSED, it means that the string representation
|
|
Packit |
575503 |
* stored in stptr is not a function of the value of CONVFMT or OFMT. That
|
|
Packit |
575503 |
* indicates that either the string value was explicitly assigned, or it
|
|
Packit |
575503 |
* was converted from a NUMBER that has an integer value. When stfmt is not
|
|
Packit |
575503 |
* set to STFMT_UNUSED, it is an offset into the fmt_list array of distinct
|
|
Packit |
575503 |
* CONVFMT and OFMT node pointers.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
#define STFMT_UNUSED -1
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_arrayfor */
|
|
Packit |
575503 |
#define for_list sub.nodep.r.av
|
|
Packit |
575503 |
#define for_list_size sub.nodep.reflags
|
|
Packit |
575503 |
#define cur_idx sub.nodep.l.ll
|
|
Packit |
575503 |
#define for_array sub.nodep.rn
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_frame: */
|
|
Packit |
575503 |
#define stack sub.nodep.r.av
|
|
Packit |
575503 |
#define func_node sub.nodep.x.extra
|
|
Packit |
575503 |
#define prev_frame_size sub.nodep.reflags
|
|
Packit |
575503 |
#define reti sub.nodep.l.li
|
|
Packit |
575503 |
#define num_tail_calls sub.nodep.cnt
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_var: */
|
|
Packit |
575503 |
#define var_value lnode
|
|
Packit |
575503 |
#define var_update sub.nodep.r.uptr
|
|
Packit |
575503 |
#define var_assign sub.nodep.x.aptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_var_array: */
|
|
Packit |
575503 |
#define buckets sub.nodep.r.bv
|
|
Packit |
575503 |
#define nodes sub.nodep.r.av
|
|
Packit |
575503 |
#define array_funcs sub.nodep.l.lp
|
|
Packit |
575503 |
#define array_base sub.nodep.l.ll
|
|
Packit |
575503 |
#define table_size sub.nodep.reflags
|
|
Packit |
575503 |
#define array_size sub.nodep.cnt
|
|
Packit |
575503 |
#define array_capacity sub.nodep.reserved
|
|
Packit |
575503 |
#define xarray sub.nodep.rn
|
|
Packit |
575503 |
#define parent_array sub.nodep.x.extra
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define ainit array_funcs[0]
|
|
Packit |
575503 |
#define ainit_ind 0
|
|
Packit |
575503 |
#define atypeof array_funcs[1]
|
|
Packit |
575503 |
#define atypeof_ind 1
|
|
Packit |
575503 |
#define alength array_funcs[2]
|
|
Packit |
575503 |
#define alength_ind 2
|
|
Packit |
575503 |
#define alookup array_funcs[3]
|
|
Packit |
575503 |
#define alookup_ind 3
|
|
Packit |
575503 |
#define aexists array_funcs[4]
|
|
Packit |
575503 |
#define aexists_ind 4
|
|
Packit |
575503 |
#define aclear array_funcs[5]
|
|
Packit |
575503 |
#define aclear_ind 5
|
|
Packit |
575503 |
#define aremove array_funcs[6]
|
|
Packit |
575503 |
#define aremove_ind 6
|
|
Packit |
575503 |
#define alist array_funcs[7]
|
|
Packit |
575503 |
#define alist_ind 7
|
|
Packit |
575503 |
#define acopy array_funcs[8]
|
|
Packit |
575503 |
#define acopy_ind 8
|
|
Packit |
575503 |
#define adump array_funcs[9]
|
|
Packit |
575503 |
#define adump_ind 9
|
|
Packit |
575503 |
#define astore array_funcs[10]
|
|
Packit |
575503 |
#define astore_ind 10
|
|
Packit |
575503 |
#define NUM_AFUNCS 11 /* # of entries in array_funcs */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_array_ref: */
|
|
Packit |
575503 |
#define orig_array lnode
|
|
Packit |
575503 |
#define prev_array rnode
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Node_array_print */
|
|
Packit |
575503 |
#define adepth sub.nodep.l.ll
|
|
Packit |
575503 |
#define alevel sub.nodep.x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_comment */
|
|
Packit |
575503 |
#define comment_type sub.val.idx
|
|
Packit |
575503 |
#define EOL_COMMENT 1
|
|
Packit |
575503 |
#define FULL_COMMENT 2
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* --------------------------------lint warning types----------------------------*/
|
|
Packit |
575503 |
typedef enum lintvals {
|
|
Packit |
575503 |
LINT_illegal,
|
|
Packit |
575503 |
LINT_assign_in_cond,
|
|
Packit |
575503 |
LINT_no_effect
|
|
Packit |
575503 |
} LINTTYPE;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* --------------------------------Instruction ---------------------------------- */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef enum opcodeval {
|
|
Packit |
575503 |
Op_illegal = 0, /* illegal entry */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* binary operators */
|
|
Packit |
575503 |
Op_times,
|
|
Packit |
575503 |
Op_times_i,
|
|
Packit |
575503 |
Op_quotient,
|
|
Packit |
575503 |
Op_quotient_i,
|
|
Packit |
575503 |
Op_mod,
|
|
Packit |
575503 |
Op_mod_i,
|
|
Packit |
575503 |
Op_plus,
|
|
Packit |
575503 |
Op_plus_i,
|
|
Packit |
575503 |
Op_minus,
|
|
Packit |
575503 |
Op_minus_i,
|
|
Packit |
575503 |
Op_exp,
|
|
Packit |
575503 |
Op_exp_i,
|
|
Packit |
575503 |
Op_concat,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* line range instruction pair */
|
|
Packit |
575503 |
Op_line_range, /* flags for Op_cond_pair */
|
|
Packit |
575503 |
Op_cond_pair, /* conditional pair */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_subscript,
|
|
Packit |
575503 |
Op_sub_array,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* unary operators */
|
|
Packit |
575503 |
Op_preincrement,
|
|
Packit |
575503 |
Op_predecrement,
|
|
Packit |
575503 |
Op_postincrement,
|
|
Packit |
575503 |
Op_postdecrement,
|
|
Packit |
575503 |
Op_unary_minus,
|
|
Packit |
575503 |
Op_unary_plus,
|
|
Packit |
575503 |
Op_field_spec,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* unary relationals */
|
|
Packit |
575503 |
Op_not,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* assignments */
|
|
Packit |
575503 |
Op_assign,
|
|
Packit |
575503 |
Op_store_var, /* simple variable assignment optimization */
|
|
Packit |
575503 |
Op_store_sub, /* array[subscript] assignment optimization */
|
|
Packit |
575503 |
Op_store_field, /* $n assignment optimization */
|
|
Packit |
575503 |
Op_assign_times,
|
|
Packit |
575503 |
Op_assign_quotient,
|
|
Packit |
575503 |
Op_assign_mod,
|
|
Packit |
575503 |
Op_assign_plus,
|
|
Packit |
575503 |
Op_assign_minus,
|
|
Packit |
575503 |
Op_assign_exp,
|
|
Packit |
575503 |
Op_assign_concat,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* boolean binaries */
|
|
Packit |
575503 |
Op_and, /* a left subexpression in && */
|
|
Packit |
575503 |
Op_and_final, /* right subexpression of && */
|
|
Packit |
575503 |
Op_or,
|
|
Packit |
575503 |
Op_or_final,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* binary relationals */
|
|
Packit |
575503 |
Op_equal,
|
|
Packit |
575503 |
Op_notequal,
|
|
Packit |
575503 |
Op_less,
|
|
Packit |
575503 |
Op_greater,
|
|
Packit |
575503 |
Op_leq,
|
|
Packit |
575503 |
Op_geq,
|
|
Packit |
575503 |
Op_match,
|
|
Packit |
575503 |
Op_match_rec, /* match $0 */
|
|
Packit |
575503 |
Op_nomatch,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_rule,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* keywords */
|
|
Packit |
575503 |
Op_K_case,
|
|
Packit |
575503 |
Op_K_default,
|
|
Packit |
575503 |
Op_K_break,
|
|
Packit |
575503 |
Op_K_continue,
|
|
Packit |
575503 |
Op_K_print,
|
|
Packit |
575503 |
Op_K_print_rec,
|
|
Packit |
575503 |
Op_K_printf,
|
|
Packit |
575503 |
Op_K_next,
|
|
Packit |
575503 |
Op_K_exit,
|
|
Packit |
575503 |
Op_K_return,
|
|
Packit |
575503 |
Op_K_delete,
|
|
Packit |
575503 |
Op_K_delete_loop,
|
|
Packit |
575503 |
Op_K_getline_redir,
|
|
Packit |
575503 |
Op_K_getline,
|
|
Packit |
575503 |
Op_K_nextfile,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_builtin,
|
|
Packit |
575503 |
Op_sub_builtin, /* sub, gsub and gensub */
|
|
Packit |
575503 |
Op_ext_builtin,
|
|
Packit |
575503 |
Op_in_array, /* boolean test of membership in array */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* function call instruction */
|
|
Packit |
575503 |
Op_func_call,
|
|
Packit |
575503 |
Op_indirect_func_call,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_push, /* scalar variable */
|
|
Packit |
575503 |
Op_push_arg, /* variable type (scalar or array) argument to built-in */
|
|
Packit |
575503 |
Op_push_arg_untyped, /* like Op_push_arg, but for typeof */
|
|
Packit |
575503 |
Op_push_i, /* number, string */
|
|
Packit |
575503 |
Op_push_re, /* regex */
|
|
Packit |
575503 |
Op_push_array,
|
|
Packit |
575503 |
Op_push_param,
|
|
Packit |
575503 |
Op_push_lhs,
|
|
Packit |
575503 |
Op_subscript_lhs,
|
|
Packit |
575503 |
Op_field_spec_lhs,
|
|
Packit |
575503 |
Op_no_op, /* jump target */
|
|
Packit |
575503 |
Op_pop, /* pop an item from the runtime stack */
|
|
Packit |
575503 |
Op_jmp,
|
|
Packit |
575503 |
Op_jmp_true,
|
|
Packit |
575503 |
Op_jmp_false,
|
|
Packit |
575503 |
Op_get_record,
|
|
Packit |
575503 |
Op_newfile,
|
|
Packit |
575503 |
Op_arrayfor_init,
|
|
Packit |
575503 |
Op_arrayfor_incr,
|
|
Packit |
575503 |
Op_arrayfor_final,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_var_update, /* update value of NR, NF or FNR */
|
|
Packit |
575503 |
Op_var_assign,
|
|
Packit |
575503 |
Op_field_assign,
|
|
Packit |
575503 |
Op_subscript_assign,
|
|
Packit |
575503 |
Op_after_beginfile,
|
|
Packit |
575503 |
Op_after_endfile,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_func,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
Op_comment, /* for pretty printing */
|
|
Packit |
575503 |
Op_exec_count,
|
|
Packit |
575503 |
Op_breakpoint,
|
|
Packit |
575503 |
Op_lint,
|
|
Packit |
575503 |
Op_atexit,
|
|
Packit |
575503 |
Op_stop,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* parsing (yylex and yyparse), should never appear in valid compiled code */
|
|
Packit |
575503 |
Op_token,
|
|
Packit |
575503 |
Op_symbol,
|
|
Packit |
575503 |
Op_list,
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* program structures -- for use in the profiler/pretty printer */
|
|
Packit |
575503 |
Op_K_do,
|
|
Packit |
575503 |
Op_K_for,
|
|
Packit |
575503 |
Op_K_arrayfor,
|
|
Packit |
575503 |
Op_K_while,
|
|
Packit |
575503 |
Op_K_switch,
|
|
Packit |
575503 |
Op_K_if,
|
|
Packit |
575503 |
Op_K_else,
|
|
Packit |
575503 |
Op_K_function,
|
|
Packit |
575503 |
Op_cond_exp,
|
|
Packit |
575503 |
Op_parens,
|
|
Packit |
575503 |
Op_final /* sentry value, not legal */
|
|
Packit |
575503 |
} OPCODE;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum redirval {
|
|
Packit |
575503 |
/* I/O redirections */
|
|
Packit |
575503 |
redirect_none = 0,
|
|
Packit |
575503 |
redirect_output,
|
|
Packit |
575503 |
redirect_append,
|
|
Packit |
575503 |
redirect_pipe,
|
|
Packit |
575503 |
redirect_pipein,
|
|
Packit |
575503 |
redirect_input,
|
|
Packit |
575503 |
redirect_twoway
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct break_point;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef struct exp_instruction {
|
|
Packit |
575503 |
struct exp_instruction *nexti;
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
NODE *dn;
|
|
Packit |
575503 |
struct exp_instruction *di;
|
|
Packit |
575503 |
NODE *(*fptr)(int);
|
|
Packit |
575503 |
awk_value_t *(*efptr)(int num_actual_args,
|
|
Packit |
575503 |
awk_value_t *result,
|
|
Packit |
575503 |
struct awk_ext_func *finfo);
|
|
Packit |
575503 |
long dl;
|
|
Packit |
575503 |
char *name;
|
|
Packit |
575503 |
} d;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
union {
|
|
Packit |
575503 |
long xl;
|
|
Packit |
575503 |
NODE *xn;
|
|
Packit |
575503 |
void (*aptr)(void);
|
|
Packit |
575503 |
struct exp_instruction *xi;
|
|
Packit |
575503 |
struct break_point *bpt;
|
|
Packit |
575503 |
awk_ext_func_t *exf;
|
|
Packit |
575503 |
} x;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
short source_line;
|
|
Packit |
575503 |
short pool_size; // memory management in symbol.c
|
|
Packit |
575503 |
OPCODE opcode;
|
|
Packit |
575503 |
} INSTRUCTION;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define func_name d.name
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define memory d.dn
|
|
Packit |
575503 |
#define builtin d.fptr
|
|
Packit |
575503 |
#define extfunc d.efptr
|
|
Packit |
575503 |
#define builtin_idx d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define expr_count x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define c_function x.exf
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define target_continue d.di
|
|
Packit |
575503 |
#define target_jmp d.di
|
|
Packit |
575503 |
#define target_break x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_sub_builtin */
|
|
Packit |
575503 |
#define sub_flags d.dl
|
|
Packit |
575503 |
#define GSUB 0x01 /* builtin is gsub */
|
|
Packit |
575503 |
#define GENSUB 0x02 /* builtin is gensub */
|
|
Packit |
575503 |
#define LITERAL 0x04 /* target is a literal string */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_exit */
|
|
Packit |
575503 |
#define target_end d.di
|
|
Packit |
575503 |
#define target_atexit x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_newfile, Op_K_getline, Op_nextfile */
|
|
Packit |
575503 |
#define target_endfile x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_newfile */
|
|
Packit |
575503 |
#define target_get_record x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_get_record, Op_K_nextfile */
|
|
Packit |
575503 |
#define target_newfile d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_getline */
|
|
Packit |
575503 |
#define target_beginfile d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_get_record */
|
|
Packit |
575503 |
#define has_endfile x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_token */
|
|
Packit |
575503 |
#define lextok d.name
|
|
Packit |
575503 |
#define param_count x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_rule */
|
|
Packit |
575503 |
#define in_rule x.xl
|
|
Packit |
575503 |
#define source_file d.name
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_case, Op_K_default */
|
|
Packit |
575503 |
#define case_stmt x.xi
|
|
Packit |
575503 |
#define case_exp d.di
|
|
Packit |
575503 |
#define stmt_start case_exp
|
|
Packit |
575503 |
#define stmt_end case_stmt
|
|
Packit |
575503 |
#define match_exp x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define target_stmt x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_switch */
|
|
Packit |
575503 |
#define switch_end x.xi
|
|
Packit |
575503 |
#define switch_start d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_getline, Op_K_getline_redir */
|
|
Packit |
575503 |
#define into_var x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_getline_redir, Op_K_print, Op_K_print_rec, Op_K_printf */
|
|
Packit |
575503 |
#define redir_type d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_arrayfor_incr */
|
|
Packit |
575503 |
#define array_var x.xn
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_line_range */
|
|
Packit |
575503 |
#define triggered x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_cond_pair */
|
|
Packit |
575503 |
#define line_range x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_func_call, Op_func */
|
|
Packit |
575503 |
#define func_body x.xn
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_func_call */
|
|
Packit |
575503 |
#define tail_call d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_subscript */
|
|
Packit |
575503 |
#define sub_count d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_push_lhs, Op_subscript_lhs, Op_field_spec_lhs */
|
|
Packit |
575503 |
#define do_reference x.xl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_list, Op_rule, Op_func */
|
|
Packit |
575503 |
#define lasti d.di
|
|
Packit |
575503 |
#define firsti x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_rule, Op_func */
|
|
Packit |
575503 |
#define last_line x.xl
|
|
Packit |
575503 |
#define first_line source_line
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_lint */
|
|
Packit |
575503 |
#define lint_type d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_field_spec_lhs */
|
|
Packit |
575503 |
#define target_assign d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_var_assign */
|
|
Packit |
575503 |
#define assign_var x.aptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_var_update */
|
|
Packit |
575503 |
#define update_var x.aptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_field_assign */
|
|
Packit |
575503 |
#define field_assign x.aptr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_field_assign, Op_var_assign */
|
|
Packit |
575503 |
#define assign_ctxt d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_concat */
|
|
Packit |
575503 |
#define concat_flag d.dl
|
|
Packit |
575503 |
#define CSUBSEP 1
|
|
Packit |
575503 |
#define CSVAR 2
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_breakpoint */
|
|
Packit |
575503 |
#define break_pt x.bpt
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*------------------ pretty printing/profiling --------*/
|
|
Packit |
575503 |
/* Op_exec_count */
|
|
Packit |
575503 |
#define exec_count d.dl
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_while */
|
|
Packit |
575503 |
#define while_body d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_do */
|
|
Packit |
575503 |
#define doloop_cond d.di
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_for */
|
|
Packit |
575503 |
#define forloop_cond d.di
|
|
Packit |
575503 |
#define forloop_body x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_if */
|
|
Packit |
575503 |
#define branch_if d.di
|
|
Packit |
575503 |
#define branch_else x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_K_else */
|
|
Packit |
575503 |
#define branch_end x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_line_range */
|
|
Packit |
575503 |
#define condpair_left d.di
|
|
Packit |
575503 |
#define condpair_right x.xi
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Op_store_var */
|
|
Packit |
575503 |
#define initval x.xn
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef struct iobuf {
|
|
Packit |
575503 |
awk_input_buf_t public; /* exposed to extensions */
|
|
Packit |
575503 |
char *buf; /* start data buffer */
|
|
Packit |
575503 |
char *off; /* start of current record in buffer */
|
|
Packit |
575503 |
char *dataend; /* first byte in buffer to hold new data,
|
|
Packit |
575503 |
NULL if not read yet */
|
|
Packit |
575503 |
char *end; /* end of buffer */
|
|
Packit |
575503 |
size_t readsize; /* set from fstat call */
|
|
Packit |
575503 |
size_t size; /* buffer size */
|
|
Packit |
575503 |
ssize_t count; /* amount read last time */
|
|
Packit |
575503 |
size_t scanoff; /* where we were in the buffer when we had
|
|
Packit |
575503 |
to regrow/refill */
|
|
Packit |
575503 |
bool valid;
|
|
Packit |
575503 |
int errcode;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int flag;
|
|
Packit |
575503 |
# define IOP_IS_TTY 1
|
|
Packit |
575503 |
# define IOP_AT_EOF 2
|
|
Packit |
575503 |
# define IOP_CLOSED 4
|
|
Packit |
575503 |
# define IOP_AT_START 8
|
|
Packit |
575503 |
} IOBUF;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef void (*Func_ptr)(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* structure used to dynamically maintain a linked-list of open files/pipes */
|
|
Packit |
575503 |
struct redirect {
|
|
Packit |
575503 |
unsigned int flag;
|
|
Packit |
575503 |
# define RED_FILE 1
|
|
Packit |
575503 |
# define RED_PIPE 2
|
|
Packit |
575503 |
# define RED_READ 4
|
|
Packit |
575503 |
# define RED_WRITE 8
|
|
Packit |
575503 |
# define RED_APPEND 16
|
|
Packit |
575503 |
# define RED_NOBUF 32
|
|
Packit |
575503 |
# define RED_USED 64 /* closed temporarily to reuse fd */
|
|
Packit |
575503 |
# define RED_EOF 128
|
|
Packit |
575503 |
# define RED_TWOWAY 256
|
|
Packit |
575503 |
# define RED_PTY 512
|
|
Packit |
575503 |
# define RED_SOCKET 1024
|
|
Packit |
575503 |
# define RED_TCP 2048
|
|
Packit |
575503 |
char *value;
|
|
Packit |
575503 |
FILE *ifp; /* input fp, needed for PIPES_SIMULATED */
|
|
Packit |
575503 |
IOBUF *iop;
|
|
Packit |
575503 |
int pid;
|
|
Packit |
575503 |
int status;
|
|
Packit |
575503 |
struct redirect *prev;
|
|
Packit |
575503 |
struct redirect *next;
|
|
Packit |
575503 |
const char *mode;
|
|
Packit |
575503 |
awk_output_buf_t output;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* values for BINMODE, used as bit flags */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum binmode_values {
|
|
Packit |
575503 |
TEXT_TRANSLATE = 0, /* usual \r\n ---> \n translation */
|
|
Packit |
575503 |
BINMODE_INPUT = 1, /* no translation for input files */
|
|
Packit |
575503 |
BINMODE_OUTPUT = 2, /* no translation for output files */
|
|
Packit |
575503 |
BINMODE_BOTH = 3 /* no translation for either */
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* structure for our source, either a command line string or a source file.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef struct srcfile {
|
|
Packit |
575503 |
struct srcfile *next;
|
|
Packit |
575503 |
struct srcfile *prev;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum srctype {
|
|
Packit |
575503 |
SRC_CMDLINE = 1,
|
|
Packit |
575503 |
SRC_STDIN,
|
|
Packit |
575503 |
SRC_FILE,
|
|
Packit |
575503 |
SRC_INC,
|
|
Packit |
575503 |
SRC_EXTLIB
|
|
Packit |
575503 |
} stype;
|
|
Packit |
575503 |
char *src; /* name on command line or include statement */
|
|
Packit |
575503 |
char *fullpath; /* full path after AWKPATH search */
|
|
Packit |
575503 |
time_t mtime;
|
|
Packit |
575503 |
struct stat sbuf;
|
|
Packit |
575503 |
int srclines; /* no of lines in source */
|
|
Packit |
575503 |
size_t bufsize;
|
|
Packit |
575503 |
char *buf;
|
|
Packit |
575503 |
int *line_offset; /* offset to the beginning of each line */
|
|
Packit |
575503 |
int fd;
|
|
Packit |
575503 |
int maxlen; /* size of the longest line */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
void (*fini_func)(); /* dynamic extension of type SRC_EXTLIB */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
char *lexptr;
|
|
Packit |
575503 |
char *lexend;
|
|
Packit |
575503 |
char *lexeme;
|
|
Packit |
575503 |
char *lexptr_begin;
|
|
Packit |
575503 |
int lasttok;
|
|
Packit |
575503 |
} SRCFILE;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
// structure for INSTRUCTION pool, needed mainly for debugger
|
|
Packit |
575503 |
typedef struct instruction_pool {
|
|
Packit |
575503 |
#define MAX_INSTRUCTION_ALLOC 3 // we don't call bcalloc with more than this
|
|
Packit |
575503 |
struct instruction_mem_pool {
|
|
Packit |
575503 |
struct instruction_block *block_list;
|
|
Packit |
575503 |
INSTRUCTION *free_space; // free location in active block
|
|
Packit |
575503 |
INSTRUCTION *free_list;
|
|
Packit |
575503 |
} pool[MAX_INSTRUCTION_ALLOC];
|
|
Packit |
575503 |
} INSTRUCTION_POOL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* structure for execution context */
|
|
Packit |
575503 |
typedef struct context {
|
|
Packit |
575503 |
INSTRUCTION_POOL pools;
|
|
Packit |
575503 |
NODE symbols;
|
|
Packit |
575503 |
INSTRUCTION rule_list;
|
|
Packit |
575503 |
SRCFILE srcfiles;
|
|
Packit |
575503 |
int sourceline;
|
|
Packit |
575503 |
char *source;
|
|
Packit |
575503 |
void (*install_func)(NODE *);
|
|
Packit |
575503 |
struct context *prev;
|
|
Packit |
575503 |
} AWK_CONTEXT;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* for debugging purposes */
|
|
Packit |
575503 |
struct flagtab {
|
|
Packit |
575503 |
int val;
|
|
Packit |
575503 |
const char *name;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct block_item {
|
|
Packit |
575503 |
struct block_item *freep;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct block_header {
|
|
Packit |
575503 |
struct block_item *freep;
|
|
Packit |
575503 |
size_t size;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum block_id {
|
|
Packit |
575503 |
BLOCK_NODE = 0,
|
|
Packit |
575503 |
BLOCK_BUCKET,
|
|
Packit |
575503 |
BLOCK_MPFR,
|
|
Packit |
575503 |
BLOCK_MPZ,
|
|
Packit |
575503 |
BLOCK_MAX /* count */
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef int (*Func_pre_exec)(INSTRUCTION **);
|
|
Packit |
575503 |
typedef void (*Func_post_exec)(INSTRUCTION *);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifndef LONG_MAX
|
|
Packit |
575503 |
#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#ifndef ULONG_MAX
|
|
Packit |
575503 |
#define ULONG_MAX (~(unsigned long)0)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#ifndef LONG_MIN
|
|
Packit |
575503 |
#define LONG_MIN ((long)(-LONG_MAX - 1L))
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#define UNLIMITED LONG_MAX
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* -------------------------- External variables -------------------------- */
|
|
Packit |
575503 |
/* gawk builtin variables */
|
|
Packit |
575503 |
extern long NF;
|
|
Packit |
575503 |
extern long NR;
|
|
Packit |
575503 |
extern long FNR;
|
|
Packit |
575503 |
extern int BINMODE;
|
|
Packit |
575503 |
extern bool IGNORECASE;
|
|
Packit |
575503 |
extern bool RS_is_null;
|
|
Packit |
575503 |
extern char *OFS;
|
|
Packit |
575503 |
extern int OFSlen;
|
|
Packit |
575503 |
extern char *ORS;
|
|
Packit |
575503 |
extern int ORSlen;
|
|
Packit |
575503 |
extern char *OFMT;
|
|
Packit |
575503 |
extern char *CONVFMT;
|
|
Packit |
575503 |
extern int CONVFMTidx;
|
|
Packit |
575503 |
extern int OFMTidx;
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
extern int MPFR_round_mode;
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
extern char *TEXTDOMAIN;
|
|
Packit |
575503 |
extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
|
|
Packit |
575503 |
extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
|
|
Packit |
575503 |
extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
|
|
Packit |
575503 |
extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
|
|
Packit |
575503 |
extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node, *FPAT_node;
|
|
Packit |
575503 |
extern NODE *PREC_node, *ROUNDMODE_node;
|
|
Packit |
575503 |
extern NODE *Nnull_string;
|
|
Packit |
575503 |
extern NODE *Null_field;
|
|
Packit |
575503 |
extern NODE **fields_arr;
|
|
Packit |
575503 |
extern int sourceline;
|
|
Packit |
575503 |
extern char *source;
|
|
Packit |
575503 |
extern int (*interpret)(INSTRUCTION *); /* interpreter routine */
|
|
Packit |
575503 |
extern NODE *(*make_number)(double); /* double instead of AWKNUM on purpose */
|
|
Packit |
575503 |
extern NODE *(*str2number)(NODE *);
|
|
Packit |
575503 |
extern NODE *(*format_val)(const char *, int, NODE *);
|
|
Packit |
575503 |
extern int (*cmp_numbers)(const NODE *, const NODE *);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* built-in array types */
|
|
Packit |
575503 |
extern afunc_t str_array_func[];
|
|
Packit |
575503 |
extern afunc_t cint_array_func[];
|
|
Packit |
575503 |
extern afunc_t int_array_func[];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* special node used to indicate success in array routines (not NULL) */
|
|
Packit |
575503 |
extern NODE *success_node;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern struct block_header nextfree[];
|
|
Packit |
575503 |
extern bool field0_valid;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern int do_flags;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern SRCFILE *srcfiles; /* source files */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
enum do_flag_values {
|
|
Packit |
575503 |
DO_LINT_INVALID = 0x0001, /* only warn about invalid */
|
|
Packit |
575503 |
DO_LINT_ALL = 0x0002, /* warn about all things */
|
|
Packit |
575503 |
DO_LINT_OLD = 0x0004, /* warn about stuff not in V7 awk */
|
|
Packit |
575503 |
DO_TRADITIONAL = 0x0008, /* no gnu extensions, add traditional weirdnesses */
|
|
Packit |
575503 |
DO_POSIX = 0x0010, /* turn off gnu and unix extensions */
|
|
Packit |
575503 |
DO_INTL = 0x0020, /* dump locale-izable strings to stdout */
|
|
Packit |
575503 |
DO_NON_DEC_DATA = 0x0040, /* allow octal/hex C style DATA. Use with caution! */
|
|
Packit |
575503 |
DO_INTERVALS = 0x0080, /* allow {...,...} in regexps, see resetup() */
|
|
Packit |
575503 |
DO_PRETTY_PRINT = 0x0100, /* pretty print the program */
|
|
Packit |
575503 |
DO_DUMP_VARS = 0x0200, /* dump all global variables at end */
|
|
Packit |
575503 |
DO_TIDY_MEM = 0x0400, /* release vars when done */
|
|
Packit |
575503 |
DO_SANDBOX = 0x0800, /* sandbox mode - disable 'system' function & redirections */
|
|
Packit |
575503 |
DO_PROFILE = 0x1000, /* profile the program */
|
|
Packit |
575503 |
DO_DEBUG = 0x2000, /* debug the program */
|
|
Packit |
575503 |
DO_MPFR = 0x4000 /* arbitrary-precision floating-point math */
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define do_traditional (do_flags & DO_TRADITIONAL)
|
|
Packit |
575503 |
#define do_posix (do_flags & DO_POSIX)
|
|
Packit |
575503 |
#define do_intl (do_flags & DO_INTL)
|
|
Packit |
575503 |
#define do_non_decimal_data (do_flags & DO_NON_DEC_DATA)
|
|
Packit |
575503 |
#define do_intervals (do_flags & DO_INTERVALS)
|
|
Packit |
575503 |
#define do_pretty_print (do_flags & DO_PRETTY_PRINT)
|
|
Packit |
575503 |
#define do_profile (do_flags & DO_PROFILE)
|
|
Packit |
575503 |
#define do_dump_vars (do_flags & DO_DUMP_VARS)
|
|
Packit |
575503 |
#define do_tidy_mem (do_flags & DO_TIDY_MEM)
|
|
Packit |
575503 |
#define do_sandbox (do_flags & DO_SANDBOX)
|
|
Packit |
575503 |
#define do_debug (do_flags & DO_DEBUG)
|
|
Packit |
575503 |
#define do_mpfr (do_flags & DO_MPFR)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern bool do_optimize;
|
|
Packit |
575503 |
extern int use_lc_numeric;
|
|
Packit |
575503 |
extern int exit_val;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef NO_LINT
|
|
Packit |
575503 |
#define do_lint 0
|
|
Packit |
575503 |
#define do_lint_old 0
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#define do_lint (do_flags & (DO_LINT_INVALID|DO_LINT_ALL))
|
|
Packit |
575503 |
#define do_lint_old (do_flags & DO_LINT_OLD)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
extern int gawk_mb_cur_max;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
|
Packit |
575503 |
extern GETGROUPS_T *groupset;
|
|
Packit |
575503 |
extern int ngroups;
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_LOCALE_H
|
|
Packit |
575503 |
extern struct lconv loc;
|
|
Packit |
575503 |
#endif /* HAVE_LOCALE_H */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
extern mpfr_prec_t PRECISION;
|
|
Packit |
575503 |
extern mpfr_rnd_t ROUND_MODE;
|
|
Packit |
575503 |
extern mpz_t MNR;
|
|
Packit |
575503 |
extern mpz_t MFNR;
|
|
Packit |
575503 |
extern mpz_t mpzval;
|
|
Packit |
575503 |
extern bool do_ieee_fmt; /* emulate IEEE 754 floating-point format */
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern const char *myname;
|
|
Packit |
575503 |
extern const char def_strftime_format[];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern char quote;
|
|
Packit |
575503 |
extern char *defpath;
|
|
Packit |
575503 |
extern char *deflibpath;
|
|
Packit |
575503 |
extern char envsep;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern char casetable[]; /* for case-independent regexp matching */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------------------- Runtime stack -------------------------------- */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef union stack_item {
|
|
Packit |
575503 |
NODE *rptr; /* variable etc. */
|
|
Packit |
575503 |
NODE **lptr; /* address of a variable etc. */
|
|
Packit |
575503 |
} STACK_ITEM;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern STACK_ITEM *stack_ptr;
|
|
Packit |
575503 |
extern NODE *frame_ptr;
|
|
Packit |
575503 |
extern STACK_ITEM *stack_bottom;
|
|
Packit |
575503 |
extern STACK_ITEM *stack_top;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define decr_sp() (stack_ptr--)
|
|
Packit |
575503 |
#define incr_sp() ((stack_ptr < stack_top) ? ++stack_ptr : grow_stack())
|
|
Packit |
575503 |
#define stack_adj(n) (stack_ptr += (n))
|
|
Packit |
575503 |
#define stack_empty() (stack_ptr < stack_bottom)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define POP() (decr_sp()->rptr)
|
|
Packit |
575503 |
#define POP_ADDRESS() (decr_sp()->lptr)
|
|
Packit |
575503 |
#define PEEK(n) ((stack_ptr - (n))->rptr)
|
|
Packit |
575503 |
#define TOP() (stack_ptr->rptr) /* same as PEEK(0) */
|
|
Packit |
575503 |
#define TOP_ADDRESS() (stack_ptr->lptr)
|
|
Packit |
575503 |
#define PUSH(r) (void) (incr_sp()->rptr = (r))
|
|
Packit |
575503 |
#define PUSH_ADDRESS(l) (void) (incr_sp()->lptr = (l))
|
|
Packit |
575503 |
#define REPLACE(r) (void) (stack_ptr->rptr = (r))
|
|
Packit |
575503 |
#define REPLACE_ADDRESS(l) (void) (stack_ptr->lptr = (l))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* function param */
|
|
Packit |
575503 |
#define GET_PARAM(n) frame_ptr->stack[n]
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* UPREF --- simplified versions of dupnode, does not handle FIELD node.
|
|
Packit |
575503 |
* Most appropriate use is for elements on the runtime stack.
|
|
Packit |
575503 |
* When in doubt, use dupnode.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define UPREF(r) (void) ((r)->valref++)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern void r_unref(NODE *tmp);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void
|
|
Packit |
575503 |
DEREF(NODE *r)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
assert(r->valref > 0);
|
|
Packit |
575503 |
if (--r->valref == 0)
|
|
Packit |
575503 |
r_unref(r);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define POP_NUMBER() force_number(POP_SCALAR())
|
|
Packit |
575503 |
#define TOP_NUMBER() force_number(TOP_SCALAR())
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------------------- Pseudo-functions ------------------------- */
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if 0
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* In principle, there is no need to have both the MPFN and MPZN flags,
|
|
Packit |
575503 |
* since we are using 2 bits to encode 1 bit of information. But
|
|
Packit |
575503 |
* there may be some minor performance advantages from testing only the
|
|
Packit |
575503 |
* node flag bits without needing also to access the global do_mpfr flag bit.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
#define numtype_choose(n, mpfrval, mpzval, dblval) \
|
|
Packit |
575503 |
(!do_mpfr ? (dblval) : (((n)->flags & MPFN) ? (mpfrval) : (mpzval)))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* N.B. This implementation seems to give the fastest results. */
|
|
Packit |
575503 |
#define numtype_choose(n, mpfrval, mpzval, dblval) \
|
|
Packit |
575503 |
(!((n)->flags & (MPFN|MPZN)) ? (dblval) : (((n)->flags & MPFN) ? (mpfrval) : (mpzval)))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* conversion to C types */
|
|
Packit |
575503 |
#define get_number_ui(n) numtype_choose((n), mpfr_get_ui((n)->mpg_numbr, ROUND_MODE), mpz_get_ui((n)->mpg_i), (unsigned long) (n)->numbr)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define get_number_si(n) numtype_choose((n), mpfr_get_si((n)->mpg_numbr, ROUND_MODE), mpz_get_si((n)->mpg_i), (long) (n)->numbr)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define get_number_d(n) numtype_choose((n), mpfr_get_d((n)->mpg_numbr, ROUND_MODE), mpz_get_d((n)->mpg_i), (double) (n)->numbr)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define get_number_uj(n) numtype_choose((n), mpfr_get_uj((n)->mpg_numbr, ROUND_MODE), (uintmax_t) mpz_get_d((n)->mpg_i), (uintmax_t) (n)->numbr)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define iszero(n) numtype_choose((n), mpfr_zero_p((n)->mpg_numbr), (mpz_sgn((n)->mpg_i) == 0), ((n)->numbr == 0.0))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define IEEE_FMT(r, t) (void) (do_ieee_fmt && format_ieee(r, t))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define mpg_float() mpg_node(MPFN)
|
|
Packit |
575503 |
#define mpg_integer() mpg_node(MPZN)
|
|
Packit |
575503 |
#define is_mpg_float(n) (((n)->flags & MPFN) != 0)
|
|
Packit |
575503 |
#define is_mpg_integer(n) (((n)->flags & MPZN) != 0)
|
|
Packit |
575503 |
#define is_mpg_number(n) (((n)->flags & (MPZN|MPFN)) != 0)
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#define get_number_ui(n) (unsigned long) (n)->numbr
|
|
Packit |
575503 |
#define get_number_si(n) (long) (n)->numbr
|
|
Packit |
575503 |
#define get_number_d(n) (double) (n)->numbr
|
|
Packit |
575503 |
#define get_number_uj(n) (uintmax_t) (n)->numbr
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define is_mpg_number(n) 0
|
|
Packit |
575503 |
#define is_mpg_float(n) 0
|
|
Packit |
575503 |
#define is_mpg_integer(n) 0
|
|
Packit |
575503 |
#define iszero(n) ((n)->numbr == 0.0)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define var_uninitialized(n) ((n)->var_value == Nnull_string)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
|
|
Packit |
575503 |
&((n)->var_value) : r_get_lhs((n), (r))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define getblock(p, id, ty) (void) ((p = (ty) nextfree[id].freep) ? \
|
|
Packit |
575503 |
(ty) (nextfree[id].freep = ((struct block_item *) p)->freep) \
|
|
Packit |
575503 |
: (p = (ty) more_blocks(id)))
|
|
Packit |
575503 |
#define freeblock(p, id) (void) (((struct block_item *) p)->freep = nextfree[id].freep, \
|
|
Packit |
575503 |
nextfree[id].freep = (struct block_item *) p)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define getnode(n) getblock(n, BLOCK_NODE, NODE *)
|
|
Packit |
575503 |
#define freenode(n) freeblock(n, BLOCK_NODE)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define getbucket(b) getblock(b, BLOCK_BUCKET, BUCKET *)
|
|
Packit |
575503 |
#define freebucket(b) freeblock(b, BLOCK_BUCKET)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define make_string(s, l) make_str_node((s), (l), 0)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define SCAN 1
|
|
Packit |
575503 |
#define ALREADY_MALLOCED 2
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define cant_happen() r_fatal("internal error line %d, file: %s", \
|
|
Packit |
575503 |
__LINE__, __FILE__)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define emalloc(var,ty,x,str) (void) (var = (ty) emalloc_real((size_t)(x), str, #var, __FILE__, __LINE__))
|
|
Packit |
575503 |
#define ezalloc(var,ty,x,str) (void) (var = (ty) ezalloc_real((size_t)(x), str, #var, __FILE__, __LINE__))
|
|
Packit |
575503 |
#define erealloc(var,ty,x,str) (void) (var = (ty) erealloc_real((void *) var, (size_t)(x), str, #var, __FILE__, __LINE__))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define efree(p) free(p)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define fatal (*(set_loc(__FILE__, __LINE__), r_fatal))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern jmp_buf fatal_tag;
|
|
Packit |
575503 |
extern int fatal_tag_valid;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define PUSH_BINDING(stack, tag, val) \
|
|
Packit |
575503 |
if (val++) \
|
|
Packit |
575503 |
memcpy((char *) (stack), (const char *) tag, sizeof(jmp_buf))
|
|
Packit |
575503 |
#define POP_BINDING(stack, tag, val) \
|
|
Packit |
575503 |
if (--val) \
|
|
Packit |
575503 |
memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define assoc_length(a) ((*((a)->alength(a, NULL)))->table_size)
|
|
Packit |
575503 |
#define assoc_empty(a) (assoc_length(a) == 0)
|
|
Packit |
575503 |
#define assoc_lookup(a, s) ((a)->alookup(a, s))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* assoc_clear --- flush all the values in symbol[] */
|
|
Packit |
575503 |
#define assoc_clear(a) (void) ((a)->aclear(a, NULL))
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* assoc_remove --- remove an index from symbol[] */
|
|
Packit |
575503 |
#define assoc_remove(a, s) ((a)->aremove(a, s) != NULL)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------- Function prototypes or defs (as appropriate) ------------- */
|
|
Packit |
575503 |
/* array.c */
|
|
Packit |
575503 |
typedef enum { SORTED_IN = 1, ASORT, ASORTI } sort_context_t;
|
|
Packit |
575503 |
typedef enum {
|
|
Packit |
575503 |
ANONE = 0x00, /* "unused" value */
|
|
Packit |
575503 |
AINDEX = 0x001, /* list of indices */
|
|
Packit |
575503 |
AVALUE = 0x002, /* list of values */
|
|
Packit |
575503 |
AINUM = 0x004, /* numeric index */
|
|
Packit |
575503 |
AISTR = 0x008, /* string index */
|
|
Packit |
575503 |
AVNUM = 0x010, /* numeric scalar value */
|
|
Packit |
575503 |
AVSTR = 0x020, /* string scalar value */
|
|
Packit |
575503 |
AASC = 0x040, /* ascending order */
|
|
Packit |
575503 |
ADESC = 0x080, /* descending order */
|
|
Packit |
575503 |
ADELETE = 0x100 /* need a single index; for use in do_delete_loop */
|
|
Packit |
575503 |
} assoc_kind_t;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern NODE *make_array(void);
|
|
Packit |
575503 |
extern void null_array(NODE *symbol);
|
|
Packit |
575503 |
extern NODE *force_array(NODE *symbol, bool canfatal);
|
|
Packit |
575503 |
extern const char *make_aname(const NODE *symbol);
|
|
Packit |
575503 |
extern const char *array_vname(const NODE *symbol);
|
|
Packit |
575503 |
extern void array_init(void);
|
|
Packit |
575503 |
extern int register_array_func(afunc_t *afunc);
|
|
Packit |
575503 |
extern NODE **null_length(NODE *symbol, NODE *subs);
|
|
Packit |
575503 |
extern NODE **null_afunc(NODE *symbol, NODE *subs);
|
|
Packit |
575503 |
extern void set_SUBSEP(void);
|
|
Packit |
575503 |
extern NODE *concat_exp(int nargs, bool do_subsep);
|
|
Packit |
575503 |
extern NODE *assoc_copy(NODE *symbol, NODE *newsymb);
|
|
Packit |
575503 |
extern void assoc_dump(NODE *symbol, NODE *p);
|
|
Packit |
575503 |
extern NODE **assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt);
|
|
Packit |
575503 |
extern void assoc_info(NODE *subs, NODE *val, NODE *p, const char *aname);
|
|
Packit |
575503 |
extern void do_delete(NODE *symbol, int nsubs);
|
|
Packit |
575503 |
extern void do_delete_loop(NODE *symbol, NODE **lhs);
|
|
Packit |
575503 |
extern NODE *do_adump(int nargs);
|
|
Packit |
575503 |
extern NODE *do_aoption(int nargs);
|
|
Packit |
575503 |
extern NODE *do_asort(int nargs);
|
|
Packit |
575503 |
extern NODE *do_asorti(int nargs);
|
|
Packit |
575503 |
extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
|
|
Packit |
575503 |
extern void init_env_array(NODE *env_node);
|
|
Packit |
575503 |
/* awkgram.c */
|
|
Packit |
575503 |
extern NODE *variable(int location, char *name, NODETYPE type);
|
|
Packit |
575503 |
extern int parse_program(INSTRUCTION **pcode);
|
|
Packit |
575503 |
extern void track_ext_func(const char *name);
|
|
Packit |
575503 |
extern void dump_funcs(void);
|
|
Packit |
575503 |
extern void dump_vars(const char *fname);
|
|
Packit |
575503 |
extern const char *getfname(NODE *(*)(int));
|
|
Packit |
575503 |
extern NODE *stopme(int nargs);
|
|
Packit |
575503 |
extern void shadow_funcs(void);
|
|
Packit |
575503 |
extern int check_special(const char *name);
|
|
Packit |
575503 |
extern SRCFILE *add_srcfile(enum srctype stype, char *src, SRCFILE *curr, bool *already_included, int *errcode);
|
|
Packit |
575503 |
extern void free_srcfile(SRCFILE *thisfile);
|
|
Packit |
575503 |
extern int files_are_same(char *path, SRCFILE *src);
|
|
Packit |
575503 |
extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
|
|
Packit |
575503 |
extern void negate_num(NODE *n);
|
|
Packit |
575503 |
typedef NODE *(*builtin_func_t)(int); /* function that implements a built-in */
|
|
Packit |
575503 |
extern builtin_func_t lookup_builtin(const char *name);
|
|
Packit |
575503 |
extern void install_builtins(void);
|
|
Packit |
575503 |
extern bool is_alpha(int c);
|
|
Packit |
575503 |
extern bool is_alnum(int c);
|
|
Packit |
575503 |
extern bool is_letter(int c);
|
|
Packit |
575503 |
extern bool is_identchar(int c);
|
|
Packit |
575503 |
extern NODE *make_regnode(int type, NODE *exp);
|
|
Packit |
575503 |
/* builtin.c */
|
|
Packit |
575503 |
extern double double_to_int(double d);
|
|
Packit |
575503 |
extern NODE *do_exp(int nargs);
|
|
Packit |
575503 |
extern NODE *do_fflush(int nargs);
|
|
Packit |
575503 |
extern NODE *do_index(int nargs);
|
|
Packit |
575503 |
extern NODE *do_int(int nargs);
|
|
Packit |
575503 |
extern NODE *do_isarray(int nargs);
|
|
Packit |
575503 |
extern NODE *do_length(int nargs);
|
|
Packit |
575503 |
extern NODE *do_log(int nargs);
|
|
Packit |
575503 |
extern NODE *do_mktime(int nargs);
|
|
Packit |
575503 |
extern NODE *do_sprintf(int nargs);
|
|
Packit |
575503 |
extern void do_printf(int nargs, int redirtype);
|
|
Packit |
575503 |
extern void print_simple(NODE *tree, FILE *fp);
|
|
Packit |
575503 |
extern NODE *do_sqrt(int nargs);
|
|
Packit |
575503 |
extern NODE *do_substr(int nargs);
|
|
Packit |
575503 |
extern NODE *do_strftime(int nargs);
|
|
Packit |
575503 |
extern NODE *do_systime(int nargs);
|
|
Packit |
575503 |
extern NODE *do_system(int nargs);
|
|
Packit |
575503 |
extern void do_print(int nargs, int redirtype);
|
|
Packit |
575503 |
extern void do_print_rec(int args, int redirtype);
|
|
Packit |
575503 |
extern NODE *do_tolower(int nargs);
|
|
Packit |
575503 |
extern NODE *do_toupper(int nargs);
|
|
Packit |
575503 |
extern NODE *do_atan2(int nargs);
|
|
Packit |
575503 |
extern NODE *do_sin(int nargs);
|
|
Packit |
575503 |
extern NODE *do_cos(int nargs);
|
|
Packit |
575503 |
extern NODE *do_rand(int nargs);
|
|
Packit |
575503 |
extern NODE *do_srand(int nargs);
|
|
Packit |
575503 |
extern NODE *do_match(int nargs);
|
|
Packit |
575503 |
extern NODE *do_sub(int nargs, unsigned int flags);
|
|
Packit |
575503 |
extern NODE *call_sub(const char *name, int nargs);
|
|
Packit |
575503 |
extern NODE *call_match(int nargs);
|
|
Packit |
575503 |
extern NODE *call_split_func(const char *name, int nargs);
|
|
Packit |
575503 |
extern NODE *format_tree(const char *, size_t, NODE **, long);
|
|
Packit |
575503 |
extern NODE *do_lshift(int nargs);
|
|
Packit |
575503 |
extern NODE *do_rshift(int nargs);
|
|
Packit |
575503 |
extern NODE *do_and(int nargs);
|
|
Packit |
575503 |
extern NODE *do_or(int nargs);
|
|
Packit |
575503 |
extern NODE *do_xor(int nargs);
|
|
Packit |
575503 |
extern NODE *do_compl(int nargs);
|
|
Packit |
575503 |
extern NODE *do_strtonum(int nargs);
|
|
Packit |
575503 |
extern AWKNUM nondec2awknum(char *str, size_t len, char **endptr);
|
|
Packit |
575503 |
extern NODE *do_dcgettext(int nargs);
|
|
Packit |
575503 |
extern NODE *do_dcngettext(int nargs);
|
|
Packit |
575503 |
extern NODE *do_bindtextdomain(int nargs);
|
|
Packit |
575503 |
extern NODE *do_intdiv(int nargs);
|
|
Packit |
575503 |
extern NODE *do_typeof(int nargs);
|
|
Packit |
575503 |
extern int strncasecmpmbs(const unsigned char *,
|
|
Packit |
575503 |
const unsigned char *, size_t);
|
|
Packit |
575503 |
extern int sanitize_exit_status(int status);
|
|
Packit |
575503 |
/* eval.c */
|
|
Packit |
575503 |
extern void PUSH_CODE(INSTRUCTION *cp);
|
|
Packit |
575503 |
extern INSTRUCTION *POP_CODE(void);
|
|
Packit |
575503 |
extern void init_interpret(void);
|
|
Packit |
575503 |
extern int cmp_nodes(NODE *t1, NODE *t2, bool use_strcmp);
|
|
Packit |
575503 |
extern int cmp_awknums(const NODE *t1, const NODE *t2);
|
|
Packit |
575503 |
extern void set_IGNORECASE(void);
|
|
Packit |
575503 |
extern void set_OFS(void);
|
|
Packit |
575503 |
extern void set_ORS(void);
|
|
Packit |
575503 |
extern void set_OFMT(void);
|
|
Packit |
575503 |
extern void set_CONVFMT(void);
|
|
Packit |
575503 |
extern void set_BINMODE(void);
|
|
Packit |
575503 |
extern void set_LINT(void);
|
|
Packit |
575503 |
extern void set_TEXTDOMAIN(void);
|
|
Packit |
575503 |
extern void update_ERRNO_int(int);
|
|
Packit |
575503 |
extern void update_ERRNO_string(const char *string);
|
|
Packit |
575503 |
extern void unset_ERRNO(void);
|
|
Packit |
575503 |
extern void update_NR(void);
|
|
Packit |
575503 |
extern void update_NF(void);
|
|
Packit |
575503 |
extern void update_FNR(void);
|
|
Packit |
575503 |
extern const char *redflags2str(int);
|
|
Packit |
575503 |
extern const char *flags2str(int);
|
|
Packit |
575503 |
extern const char *genflags2str(int flagval, const struct flagtab *tab);
|
|
Packit |
575503 |
extern const char *nodetype2str(NODETYPE type);
|
|
Packit |
575503 |
extern void load_casetable(void);
|
|
Packit |
575503 |
extern AWKNUM calc_exp(AWKNUM x1, AWKNUM x2);
|
|
Packit |
575503 |
extern const char *opcode2str(OPCODE type);
|
|
Packit |
575503 |
extern const char *op2str(OPCODE type);
|
|
Packit |
575503 |
extern NODE **r_get_lhs(NODE *n, bool reference);
|
|
Packit |
575503 |
extern STACK_ITEM *grow_stack(void);
|
|
Packit |
575503 |
extern void dump_fcall_stack(FILE *fp);
|
|
Packit |
575503 |
extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth);
|
|
Packit |
575503 |
extern NODE **r_get_field(NODE *n, Func_ptr *assign, bool reference);
|
|
Packit |
575503 |
/* ext.c */
|
|
Packit |
575503 |
extern NODE *do_ext(int nargs);
|
|
Packit |
575503 |
void load_ext(const char *lib_name); /* temporary */
|
|
Packit |
575503 |
extern void close_extensions(void);
|
|
Packit |
575503 |
#ifdef DYNAMIC
|
|
Packit |
575503 |
extern awk_bool_t make_builtin(const awk_ext_func_t *);
|
|
Packit |
575503 |
extern NODE *get_argument(int);
|
|
Packit |
575503 |
extern NODE *get_actual_argument(NODE *, int, bool);
|
|
Packit |
575503 |
#define get_scalar_argument(n, i) get_actual_argument((n), (i), false)
|
|
Packit |
575503 |
#define get_array_argument(n, i) get_actual_argument((n), (i), true)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
/* field.c */
|
|
Packit |
575503 |
extern void init_fields(void);
|
|
Packit |
575503 |
extern void set_record(const char *buf, int cnt, const awk_fieldwidth_info_t *);
|
|
Packit |
575503 |
extern void reset_record(void);
|
|
Packit |
575503 |
extern void rebuild_record(void);
|
|
Packit |
575503 |
extern void set_NF(void);
|
|
Packit |
575503 |
extern NODE **get_field(long num, Func_ptr *assign);
|
|
Packit |
575503 |
extern NODE *do_split(int nargs);
|
|
Packit |
575503 |
extern NODE *do_patsplit(int nargs);
|
|
Packit |
575503 |
extern void set_FS(void);
|
|
Packit |
575503 |
extern void set_RS(void);
|
|
Packit |
575503 |
extern void set_FIELDWIDTHS(void);
|
|
Packit |
575503 |
extern void set_FPAT(void);
|
|
Packit |
575503 |
extern void update_PROCINFO_str(const char *subscript, const char *str);
|
|
Packit |
575503 |
extern void update_PROCINFO_num(const char *subscript, AWKNUM val);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
typedef enum {
|
|
Packit |
575503 |
Using_FS,
|
|
Packit |
575503 |
Using_FIELDWIDTHS,
|
|
Packit |
575503 |
Using_FPAT,
|
|
Packit |
575503 |
Using_API
|
|
Packit |
575503 |
} field_sep_type;
|
|
Packit |
575503 |
extern field_sep_type current_field_sep(void);
|
|
Packit |
575503 |
extern const char *current_field_sep_str(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* gawkapi.c: */
|
|
Packit |
575503 |
extern gawk_api_t api_impl;
|
|
Packit |
575503 |
extern void init_ext_api(void);
|
|
Packit |
575503 |
extern void update_ext_api(void);
|
|
Packit |
575503 |
extern NODE *awk_value_to_node(const awk_value_t *);
|
|
Packit |
575503 |
extern void run_ext_exit_handlers(int exitval);
|
|
Packit |
575503 |
extern void print_ext_versions(void);
|
|
Packit |
575503 |
extern void free_api_string_copies(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* gawkmisc.c */
|
|
Packit |
575503 |
extern char *gawk_name(const char *filespec);
|
|
Packit |
575503 |
extern void os_arg_fixup(int *argcp, char ***argvp);
|
|
Packit |
575503 |
extern int os_devopen(const char *name, int flag);
|
|
Packit |
575503 |
extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir);
|
|
Packit |
575503 |
extern int os_isatty(int fd);
|
|
Packit |
575503 |
extern int os_isdir(int fd);
|
|
Packit |
575503 |
extern int os_isreadable(const awk_input_buf_t *iobuf, bool *isdir);
|
|
Packit |
575503 |
extern int os_is_setuid(void);
|
|
Packit |
575503 |
extern int os_setbinmode(int fd, int mode);
|
|
Packit |
575503 |
extern void os_restore_mode(int fd);
|
|
Packit |
575503 |
extern size_t optimal_bufsize(int fd, struct stat *sbuf);
|
|
Packit |
575503 |
extern int ispath(const char *file);
|
|
Packit |
575503 |
extern int isdirpunct(int c);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* io.c */
|
|
Packit |
575503 |
extern void init_sockets(void);
|
|
Packit |
575503 |
extern void init_io(void);
|
|
Packit |
575503 |
extern void register_input_parser(awk_input_parser_t *input_parser);
|
|
Packit |
575503 |
extern void register_output_wrapper(awk_output_wrapper_t *wrapper);
|
|
Packit |
575503 |
extern void register_two_way_processor(awk_two_way_processor_t *processor);
|
|
Packit |
575503 |
extern void set_FNR(void);
|
|
Packit |
575503 |
extern void set_NR(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal);
|
|
Packit |
575503 |
extern struct redirect *redirect_string(const char *redir_exp_str,
|
|
Packit |
575503 |
size_t redir_exp_len, bool not_string_flag, int redirtype,
|
|
Packit |
575503 |
int *errflg, int extfd, bool failure_fatal);
|
|
Packit |
575503 |
extern NODE *do_close(int nargs);
|
|
Packit |
575503 |
extern int flush_io(void);
|
|
Packit |
575503 |
extern int close_io(bool *stdio_problem);
|
|
Packit |
575503 |
typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
|
|
Packit |
575503 |
extern int close_rp(struct redirect *rp, two_way_close_type how);
|
|
Packit |
575503 |
extern int devopen_simple(const char *name, const char *mode, bool try_real_open);
|
|
Packit |
575503 |
extern int devopen(const char *name, const char *mode);
|
|
Packit |
575503 |
extern int srcopen(SRCFILE *s);
|
|
Packit |
575503 |
extern char *find_source(const char *src, struct stat *stb, int *errcode, int is_extlib);
|
|
Packit |
575503 |
extern NODE *do_getline_redir(int intovar, enum redirval redirtype);
|
|
Packit |
575503 |
extern NODE *do_getline(int intovar, IOBUF *iop);
|
|
Packit |
575503 |
extern struct redirect *getredirect(const char *str, int len);
|
|
Packit |
575503 |
extern bool inrec(IOBUF *iop, int *errcode);
|
|
Packit |
575503 |
extern int nextfile(IOBUF **curfile, bool skipping);
|
|
Packit |
575503 |
extern bool is_non_fatal_std(FILE *fp);
|
|
Packit |
575503 |
extern bool is_non_fatal_redirect(const char *str, size_t len);
|
|
Packit |
575503 |
extern void ignore_sigpipe(void);
|
|
Packit |
575503 |
extern void set_sigpipe_to_default(void);
|
|
Packit |
575503 |
extern bool non_fatal_flush_std_file(FILE *fp);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* main.c */
|
|
Packit |
575503 |
extern int arg_assign(char *arg, bool initing);
|
|
Packit |
575503 |
extern int is_std_var(const char *var);
|
|
Packit |
575503 |
extern int is_off_limits_var(const char *var);
|
|
Packit |
575503 |
extern char *estrdup(const char *str, size_t len);
|
|
Packit |
575503 |
extern void update_global_values();
|
|
Packit |
575503 |
extern long getenv_long(const char *name);
|
|
Packit |
575503 |
extern void after_beginfile(IOBUF **curfile);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* mpfr.c */
|
|
Packit |
575503 |
extern void set_PREC(void);
|
|
Packit |
575503 |
extern void set_ROUNDMODE(void);
|
|
Packit |
575503 |
extern void mpfr_unset(NODE *n);
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
extern int mpg_cmp(const NODE *, const NODE *);
|
|
Packit |
575503 |
extern int format_ieee(mpfr_ptr, int);
|
|
Packit |
575503 |
extern NODE *mpg_update_var(NODE *);
|
|
Packit |
575503 |
extern long mpg_set_var(NODE *);
|
|
Packit |
575503 |
extern NODE *do_mpfr_and(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_atan2(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_compl(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_cos(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_exp(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_int(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_intdiv(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_log(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_lshift(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_or(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_rand(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_rshift(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_sin(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_sqrt(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_srand(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_strtonum(int);
|
|
Packit |
575503 |
extern NODE *do_mpfr_xor(int);
|
|
Packit |
575503 |
extern void init_mpfr(mpfr_prec_t, const char *);
|
|
Packit |
575503 |
extern void cleanup_mpfr(void);
|
|
Packit |
575503 |
extern NODE *mpg_node(unsigned int);
|
|
Packit |
575503 |
extern const char *mpg_fmt(const char *, ...);
|
|
Packit |
575503 |
extern int mpg_strtoui(mpz_ptr, char *, size_t, char **, int);
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
/* msg.c */
|
|
Packit |
575503 |
extern void gawk_exit(int status);
|
|
Packit |
575503 |
extern void final_exit(int status) ATTRIBUTE_NORETURN;
|
|
Packit |
575503 |
extern void err(bool isfatal, const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(3, 0);
|
|
Packit |
575503 |
extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
|
Packit |
575503 |
extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
|
Packit |
575503 |
extern void r_warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
|
Packit |
575503 |
extern void set_loc (const char *file, int line);
|
|
Packit |
575503 |
extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
|
Packit |
575503 |
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
|
|
Packit |
575503 |
extern void (*lintfunc)(const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
extern void (*lintfunc)(const char *mesg, ...);
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
/* profile.c */
|
|
Packit |
575503 |
extern void init_profiling_signals(void);
|
|
Packit |
575503 |
extern void set_prof_file(const char *filename);
|
|
Packit |
575503 |
extern void dump_prog(INSTRUCTION *code);
|
|
Packit |
575503 |
extern char *pp_number(NODE *n);
|
|
Packit |
575503 |
extern char *pp_string(const char *in_str, size_t len, int delim);
|
|
Packit |
575503 |
extern char *pp_node(NODE *n);
|
|
Packit |
575503 |
extern int pp_func(INSTRUCTION *pc, void *);
|
|
Packit |
575503 |
extern void pp_string_fp(Func_print print_func, FILE *fp, const char *str,
|
|
Packit |
575503 |
size_t namelen, int delim, bool breaklines);
|
|
Packit |
575503 |
/* node.c */
|
|
Packit |
575503 |
extern NODE *r_force_number(NODE *n);
|
|
Packit |
575503 |
extern NODE *r_format_val(const char *format, int index, NODE *s);
|
|
Packit |
575503 |
extern NODE *r_dupnode(NODE *n);
|
|
Packit |
575503 |
extern NODE *make_str_node(const char *s, size_t len, int flags);
|
|
Packit |
575503 |
extern NODE *make_typed_regex(const char *re, size_t len);
|
|
Packit |
575503 |
extern void *more_blocks(int id);
|
|
Packit |
575503 |
extern int parse_escape(const char **string_ptr);
|
|
Packit |
575503 |
extern NODE *str2wstr(NODE *n, size_t **ptr);
|
|
Packit |
575503 |
extern NODE *wstr2str(NODE *n);
|
|
Packit |
575503 |
#define force_wstring(n) str2wstr(n, NULL)
|
|
Packit |
575503 |
extern const wchar_t *wstrstr(const wchar_t *haystack, size_t hs_len,
|
|
Packit |
575503 |
const wchar_t *needle, size_t needle_len);
|
|
Packit |
575503 |
extern const wchar_t *wcasestrstr(const wchar_t *haystack, size_t hs_len,
|
|
Packit |
575503 |
const wchar_t *needle, size_t needle_len);
|
|
Packit |
575503 |
extern void r_free_wstr(NODE *n);
|
|
Packit |
575503 |
#define free_wstr(n) do { if ((n)->flags & WSTRCUR) r_free_wstr(n); } while(0)
|
|
Packit |
575503 |
extern wint_t btowc_cache[];
|
|
Packit |
575503 |
#define btowc_cache(x) btowc_cache[(x)&0xFF]
|
|
Packit |
575503 |
extern void init_btowc_cache();
|
|
Packit |
575503 |
#define is_valid_character(b) (btowc_cache[(b)&0xFF] != WEOF)
|
|
Packit |
575503 |
/* re.c */
|
|
Packit |
575503 |
extern Regexp *make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal);
|
|
Packit |
575503 |
extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
|
|
Packit |
575503 |
extern void refree(Regexp *rp);
|
|
Packit |
575503 |
extern void reg_error(const char *s);
|
|
Packit |
575503 |
extern Regexp *re_update(NODE *t);
|
|
Packit |
575503 |
extern void resyntax(int syntax);
|
|
Packit |
575503 |
extern void resetup(void);
|
|
Packit |
575503 |
extern int reisstring(const char *text, size_t len, Regexp *re, const char *buf);
|
|
Packit |
575503 |
extern int get_numbase(const char *str, size_t len, bool use_locale);
|
|
Packit |
575503 |
extern bool using_utf8(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* symbol.c */
|
|
Packit |
575503 |
extern void load_symbols();
|
|
Packit |
575503 |
extern void init_symbol_table();
|
|
Packit |
575503 |
extern NODE *symbol_table;
|
|
Packit |
575503 |
extern NODE *func_table;
|
|
Packit |
575503 |
extern NODE *install_symbol(const char *name, NODETYPE type);
|
|
Packit |
575503 |
extern NODE *remove_symbol(NODE *r);
|
|
Packit |
575503 |
extern void destroy_symbol(NODE *r);
|
|
Packit |
575503 |
extern void release_symbols(NODE *symlist, int keep_globals);
|
|
Packit |
575503 |
extern void append_symbol(NODE *r);
|
|
Packit |
575503 |
extern NODE *lookup(const char *name);
|
|
Packit |
575503 |
extern NODE *make_params(char **pnames, int pcount);
|
|
Packit |
575503 |
extern void install_params(NODE *func);
|
|
Packit |
575503 |
extern void remove_params(NODE *func);
|
|
Packit |
575503 |
extern void release_all_vars(void);
|
|
Packit |
575503 |
extern int foreach_func(NODE **table, int (*)(INSTRUCTION *, void *), void *);
|
|
Packit |
575503 |
extern INSTRUCTION *bcalloc(OPCODE op, int size, int srcline);
|
|
Packit |
575503 |
extern void bcfree(INSTRUCTION *);
|
|
Packit |
575503 |
extern AWK_CONTEXT *new_context(void);
|
|
Packit |
575503 |
extern void push_context(AWK_CONTEXT *ctxt);
|
|
Packit |
575503 |
extern void pop_context();
|
|
Packit |
575503 |
extern int in_main_context();
|
|
Packit |
575503 |
extern void free_context(AWK_CONTEXT *ctxt, bool keep_globals);
|
|
Packit |
575503 |
extern NODE **variable_list();
|
|
Packit |
575503 |
extern NODE **function_list(bool sort);
|
|
Packit |
575503 |
extern void print_vars(NODE **table, Func_print print_func, FILE *fp);
|
|
Packit |
575503 |
extern bool check_param_names(void);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* floatcomp.c */
|
|
Packit |
575503 |
#ifdef HAVE_UINTMAX_T
|
|
Packit |
575503 |
extern uintmax_t adjust_uint(uintmax_t n);
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#define adjust_uint(n) (n)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef HAVE_SYS_WAIT_H
|
|
Packit |
575503 |
#include <sys/wait.h>
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#ifndef WEXITSTATUS
|
|
Packit |
575503 |
#if defined(VMS)
|
|
Packit |
575503 |
#define WEXITSTATUS(stat_val) (stat_val)
|
|
Packit |
575503 |
#else /* ! defined(VMS) */
|
|
Packit |
575503 |
#define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
|
|
Packit |
575503 |
#endif /* ! defined(VMS)) */
|
|
Packit |
575503 |
#endif /* WEXITSTATUS */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* For z/OS, from Dave Pitts. EXIT_FAILURE is normally 8, make it 1. */
|
|
Packit |
575503 |
#if defined(EXIT_FAILURE) && EXIT_FAILURE == 8
|
|
Packit |
575503 |
# undef EXIT_FAILURE
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* EXIT_SUCCESS and EXIT_FAILURE normally come from <stdlib.h> */
|
|
Packit |
575503 |
#ifndef EXIT_SUCCESS
|
|
Packit |
575503 |
# define EXIT_SUCCESS 0
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#ifndef EXIT_FAILURE
|
|
Packit |
575503 |
# define EXIT_FAILURE 1
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
/* EXIT_FATAL is specific to gawk, not part of Standard C */
|
|
Packit |
575503 |
#ifndef EXIT_FATAL
|
|
Packit |
575503 |
# define EXIT_FATAL 2
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ------------------ Inline Functions ------------------ */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* These must come last to get all the function declarations and
|
|
Packit |
575503 |
* macro definitions before their bodies.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* This is wasteful if the compiler doesn't support inline. We won't
|
|
Packit |
575503 |
* worry about it until someone complains.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* POP_ARRAY --- get the array at the top of the stack */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
POP_ARRAY()
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE *t = POP();
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return (t->type == Node_var_array) ? t : force_array(t, true);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* POP_PARAM --- get the top parameter, array or scalar */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
POP_PARAM()
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE *t = POP();
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return (t->type == Node_var_array) ? t : force_array(t, false);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* POP_SCALAR --- pop the scalar at the top of the stack */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
POP_SCALAR()
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE *t = POP();
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (t->type == Node_var_array)
|
|
Packit |
575503 |
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return t;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* TOP_SCALAR --- get the scalar at the top of the stack */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
TOP_SCALAR()
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE *t = TOP();
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (t->type == Node_var_array)
|
|
Packit |
575503 |
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return t;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* POP_STRING --- pop the string at the top of the stack */
|
|
Packit |
575503 |
#define POP_STRING() force_string(POP_SCALAR())
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* TOP_STRING --- get the string at the top of the stack */
|
|
Packit |
575503 |
#define TOP_STRING() force_string(TOP_SCALAR())
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* in_array --- return pointer to element in array if there */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
in_array(NODE *a, NODE *s)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE **ret;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
ret = a->aexists(a, s);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return ret ? *ret : NULL;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef GAWKDEBUG
|
|
Packit |
575503 |
#define dupnode r_dupnode
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
/* dupnode --- up the reference on a node */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
dupnode(NODE *n)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
if ((n->flags & MALLOC) != 0) {
|
|
Packit |
575503 |
n->valref++;
|
|
Packit |
575503 |
return n;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
return r_dupnode(n);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* force_string_fmt --- force a node to have a string value in a given format.
|
|
Packit |
575503 |
* The string representation of a number may change due to whether it was most
|
|
Packit |
575503 |
* recently rendered with CONVFMT or OFMT, or due to changes in the CONVFMT
|
|
Packit |
575503 |
* and OFMT values. But if the value entered gawk as a string or strnum, then
|
|
Packit |
575503 |
* stfmt should be set to STFMT_UNUSED, and the string representation should
|
|
Packit |
575503 |
* not change.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* Additional twist: If ROUNDMODE changed at some point we have to
|
|
Packit |
575503 |
* recompute also.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
force_string_fmt(NODE *s, const char *fmtstr, int fmtidx)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
if ((s->flags & STRCUR) != 0
|
|
Packit |
575503 |
&& (s->stfmt == STFMT_UNUSED || (s->stfmt == fmtidx
|
|
Packit |
575503 |
#ifdef HAVE_MPFR
|
|
Packit |
575503 |
&& s->strndmode == MPFR_round_mode
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
)))
|
|
Packit |
575503 |
return s;
|
|
Packit |
575503 |
return format_val(fmtstr, fmtidx, s);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* conceptually should be force_string_convfmt, but this is the typical case */
|
|
Packit |
575503 |
#define force_string(s) force_string_fmt((s), CONVFMT, CONVFMTidx)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define force_string_ofmt(s) force_string_fmt((s), OFMT, OFMTidx)
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef GAWKDEBUG
|
|
Packit |
575503 |
#define unref r_unref
|
|
Packit |
575503 |
#define force_number str2number
|
|
Packit |
575503 |
#else /* not GAWKDEBUG */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* unref --- decrease the reference count and/or free a node */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void
|
|
Packit |
575503 |
unref(NODE *r)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
if (r != NULL && --r->valref <= 0)
|
|
Packit |
575503 |
r_unref(r);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* force_number --- force a node to have a numeric value */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
force_number(NODE *n)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return (n->flags & NUMCUR) != 0 ? n : str2number(n);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#endif /* GAWKDEBUG */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* fixtype --- make a node decide if it's a number or a string */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* In certain contexts, the true type of a scalar value matters, and we
|
|
Packit |
575503 |
* must ascertain whether it is a NUMBER or a STRING. In such situations,
|
|
Packit |
575503 |
* please use this function to resolve the type.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* It is safe to assume that the return value will be the same NODE,
|
|
Packit |
575503 |
* since force_number on a USER_INPUT should always return the same NODE,
|
|
Packit |
575503 |
* and force_string on an INTIND should as well.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
fixtype(NODE *n)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
assert(n->type == Node_val);
|
|
Packit |
575503 |
if ((n->flags & (NUMCUR|USER_INPUT)) == USER_INPUT)
|
|
Packit |
575503 |
return force_number(n);
|
|
Packit |
575503 |
if ((n->flags & INTIND) != 0)
|
|
Packit |
575503 |
return force_string(n);
|
|
Packit |
575503 |
return n;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* boolval --- return true/false based on awk's criteria */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* In awk, a value is considered to be true if it is nonzero _or_
|
|
Packit |
575503 |
* non-null. Otherwise, the value is false.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline bool
|
|
Packit |
575503 |
boolval(NODE *t)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
(void) fixtype(t);
|
|
Packit |
575503 |
if ((t->flags & NUMBER) != 0)
|
|
Packit |
575503 |
return ! iszero(t);
|
|
Packit |
575503 |
return (t->stlen > 0);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* emalloc_real --- malloc with error checking */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void *
|
|
Packit |
575503 |
emalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
void *ret;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (count == 0)
|
|
Packit |
575503 |
fatal("%s:%d: emalloc called with zero bytes", file, line);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
ret = (void *) malloc(count);
|
|
Packit |
575503 |
if (ret == NULL)
|
|
Packit |
575503 |
fatal(_("%s:%d:%s: %s: can't allocate %ld bytes of memory (%s)"),
|
|
Packit |
575503 |
file, line, where, var, (long) count, strerror(errno));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return ret;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ezalloc_real --- malloc zero-filled bytes with error checking */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void *
|
|
Packit |
575503 |
ezalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
void *ret;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (count == 0)
|
|
Packit |
575503 |
fatal("%s:%d: ezalloc called with zero bytes", file, line);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
ret = (void *) calloc(1, count);
|
|
Packit |
575503 |
if (ret == NULL)
|
|
Packit |
575503 |
fatal(_("%s:%d:%s: %s: can't allocate %ld bytes of memory (%s)"),
|
|
Packit |
575503 |
file, line, where, var, (long) count, strerror(errno));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return ret;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* erealloc_real --- realloc with error checking */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void *
|
|
Packit |
575503 |
erealloc_real(void *ptr, size_t count, const char *where, const char *var, const char *file, int line)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
void *ret;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (count == 0)
|
|
Packit |
575503 |
fatal("%s:%d: erealloc called with zero bytes", file, line);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
ret = (void *) realloc(ptr, count);
|
|
Packit |
575503 |
if (ret == NULL)
|
|
Packit |
575503 |
fatal(_("%s:%d:%s: %s: can't reallocate %ld bytes of memory (%s)"),
|
|
Packit |
575503 |
file, line, where, var, (long) count, strerror(errno));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return ret;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* make_number_node --- make node with the given flags */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline NODE *
|
|
Packit |
575503 |
make_number_node(unsigned int flags)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
NODE *r;
|
|
Packit |
575503 |
getnode(r);
|
|
Packit |
575503 |
memset(r, 0, sizeof(*r));
|
|
Packit |
575503 |
r->type = Node_val;
|
|
Packit |
575503 |
r->valref = 1;
|
|
Packit |
575503 |
r->flags = (flags|MALLOC|NUMBER|NUMCUR);
|
|
Packit |
575503 |
return r;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* str_terminate_f, str_terminate, str_restore: function and macros to
|
|
Packit |
575503 |
* reduce chances of typos when terminating and restoring strings.
|
|
Packit |
575503 |
* This also helps to enforce that the NODE must be in scope when we restore.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
static inline void
|
|
Packit |
575503 |
str_terminate_f(NODE *n, char *savep)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
*savep = n->stptr[n->stlen];
|
|
Packit |
575503 |
n->stptr[n->stlen] = '\0';
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#define str_terminate(n, save) str_terminate_f((n), &save)
|
|
Packit |
575503 |
#define str_restore(n, save) (n)->stptr[(n)->stlen] = save
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#ifdef SIGPIPE
|
|
Packit |
575503 |
#define ignore_sigpipe() signal(SIGPIPE, SIG_IGN)
|
|
Packit |
575503 |
#define set_sigpipe_to_default() signal(SIGPIPE, SIG_DFL)
|
|
Packit |
575503 |
#define die_via_sigpipe() (signal(SIGPIPE, SIG_DFL), kill(getpid(), SIGPIPE))
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
#define ignore_sigpipe()
|
|
Packit |
575503 |
#define set_sigpipe_to_default()
|
|
Packit |
575503 |
#ifdef __MINGW32__
|
|
Packit |
575503 |
/* 0xC0000008 is EXCEPTION_INVALID_HANDLE, somewhat appropriate for EPIPE */
|
|
Packit |
575503 |
#define die_via_sigpipe() exit(0xC0000008)
|
|
Packit |
575503 |
#else /* !__MINGW32__ */
|
|
Packit |
575503 |
#define die_via_sigpipe() exit(EXIT_FATAL)
|
|
Packit |
575503 |
#endif /* !__MINGW32__ */
|
|
Packit |
575503 |
#endif
|