2
* awk.h -- Definitions for gawk.
2
* awk.h -- Definitions for gawk.
6
* Copyright (C) 1986, 1988, 1989, 1991-2024 the Free Software Foundation, Inc.
6
* Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
8
8
* This file is part of GAWK, the GNU implementation of the
9
9
* AWK Programming Language.
11
11
* GAWK is free software; you can redistribute it and/or modify
12
12
* it under the terms of the GNU General Public License as published by
13
13
* the Free Software Foundation; either version 3 of the License, or
14
14
* (at your option) any later version.
16
16
* GAWK is distributed in the hope that it will be useful,
17
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
19
* GNU General Public License for more details.
21
21
* You should have received a copy of the GNU General Public License
22
22
* along with this program; if not, write to the Free Software
23
23
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
158
184
#define setlocale(locale, val) /* nothing */
159
185
#endif /* HAVE_SETLOCALE */
161
#ifdef HAVE_FWRITE_UNLOCKED
162
#define fwrite fwrite_unlocked
163
#endif /* HAVE_FWRITE_UNLOCKED */
165
#if defined(__MINGW32__)
187
#if HAVE_MEMCPY_ULONG
188
extern char *memcpy_ulong(char *dest, const char *src, unsigned long l);
189
#define memcpy memcpy_ulong
191
#if HAVE_MEMSET_ULONG
192
extern void *memset_ulong(void *dest, int val, unsigned long l);
193
#define memset memset_ulong
196
#ifdef HAVE_LIBSIGSEGV
199
typedef void *stackoverflow_context_t;
200
#define sigsegv_install_handler(catchsegv) signal(SIGSEGV, catchsig)
201
/* define as 0 rather than empty so that (void) cast on it works */
202
#define stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE) 0
205
#if defined(__EMX__) || defined(__MINGW32__)
166
206
#include "nonposix.h"
167
#endif /* defined(__MINGW32__) */
207
#endif /* defined(__EMX__) || defined(__MINGW32__) */
169
209
/* use this as lintwarn("...")
170
210
this is a hack but it gives us the right semantics */
253
293
Node_var, /* scalar variable, lnode is value */
254
294
Node_var_array, /* array is ptr to elements, table_size num of eles */
255
295
Node_var_new, /* newly created variable, may become an array */
256
Node_elem_new, /* newly created array element, may become a subarray */
257
296
Node_param_list, /* lnode is a variable, rnode is more list */
258
297
Node_func, /* lnode is param. list, rnode is body */
259
298
Node_ext_func, /* extension function, code_ptr is builtin code */
260
Node_builtin_func, /* built-in function, main use is for FUNCTAB */
299
Node_old_ext_func, /* extension function, code_ptr is builtin code */
262
301
Node_array_ref, /* array passed by ref as parameter */
263
302
Node_array_tree, /* Hashed array tree (HAT) */
398
AWKNUM fltnum; /* this is here for optimal packing of
399
* the structure on many machines
392
struct exp_node *typre;
393
enum commenttype comtype;
398
/* type = Node_val */
400
* STRING and NUMBER are mutually exclusive, except for the special
401
* case of an uninitialized value, represented internally by
402
* Nnull_string. They represent the type of a value as assigned.
403
* Nnull_string has both STRING and NUMBER attributes, but all other
404
* scalar values should have precisely one of these bits set.
406
* STRCUR and NUMCUR are not mutually exclusive. They represent that
407
* the particular type of value is up to date. For example,
409
* a = 5 # NUMBER | NUMCUR
410
* b = a "" # Adds STRCUR to a, since a string value
411
* # is now available. But the type hasn't changed!
413
* a = "42" # STRING | STRCUR
414
* b = a + 0 # Adds NUMCUR to a, since numeric value
415
* # is now available. But the type hasn't changed!
417
* USER_INPUT is the joker. When STRING|USER_INPUT is set, it means
418
* "this is string data, but the user may have really wanted it to be a
419
* number. If we have to guess, like in a comparison, turn it into a
420
* number if the string is indeed numeric."
421
* For example, gawk -v a=42 ....
422
* Here, `a' gets STRING|STRCUR|USER_INPUT and then when used where
423
* a number is needed, it gets turned into a NUMBER and STRING
424
* is cleared. In that case, we leave the USER_INPUT in place, so
425
* the combination NUMBER|USER_INPUT means it is a strnum a.k.a. a
428
* WSTRCUR is for efficiency. If in a multibyte locale, and we
429
* need to do something character based (substr, length, etc.)
430
* we create the corresponding wide character string and store it,
431
* and add WSTRCUR to the flags so that we don't have to do the
432
* conversion more than once.
434
* The NUMINT flag may be used with a value of any type -- NUMBER,
435
* STRING, or STRNUM. It indicates that the string representation
436
* equals the result of sprintf("%ld", <numeric value>). So, for
437
* example, NUMINT should NOT be set if it's a strnum or string value
438
* where the string is " 1" or "01" or "+1" or "1.0" or "0.1E1". This
439
* is a hint to indicate that an integer array optimization may be
440
* used when this value appears as a subscript.
442
* The BOOL flag indicates that this number should be converted to True
443
* or False by extensions that interchange data with other languages,
444
* via JSON, XML or some other serialization mechanism.
446
* We hope that the rest of the flags are self-explanatory. :-)
448
MALLOC = 0x0001, /* stptr can be free'd, i.e. not a field node pointing into a shared buffer */
449
STRING = 0x0002, /* assigned as string */
450
STRCUR = 0x0004, /* string value is current */
451
NUMCUR = 0x0008, /* numeric value is current */
452
NUMBER = 0x0010, /* assigned as number */
453
USER_INPUT = 0x0020, /* user input: if NUMERIC then
455
BOOLVAL = 0x0040, /* this is a boolean value */
456
INTLSTR = 0x0080, /* use localized version */
457
NUMINT = 0x0100, /* numeric value is an integer */
458
INTIND = 0x0200, /* integral value is array index;
459
* lazy conversion to string.
461
WSTRCUR = 0x0400, /* wide str value is current */
462
MPFN = 0x0800, /* arbitrary-precision floating-point number */
463
MPZN = 0x01000, /* arbitrary-precision integer */
464
NO_EXT_SET = 0x02000, /* extension cannot set a value for this variable */
465
NULL_FIELD = 0x04000, /* this is the null field */
467
/* type = Node_var_array */
468
ARRAYMAXED = 0x08000, /* array is at max size */
469
HALFHAT = 0x010000, /* half-capacity Hashed Array Tree;
470
* See cint_array.c */
472
NUMCONSTSTR = 0x040000, /* have string value for numeric constant */
473
REGEX = 0x080000, /* this is a typed regex */
416
# define MALLOC 0x0001 /* can be free'd */
418
/* type = Node_val */
419
# define STRING 0x0002 /* assigned as string */
420
# define STRCUR 0x0004 /* string value is current */
421
# define NUMCUR 0x0008 /* numeric value is current */
422
# define NUMBER 0x0010 /* assigned as number */
423
# define MAYBE_NUM 0x0020 /* user input: if NUMERIC then
425
# define FIELD 0x0040 /* this is a field */
426
# define INTLSTR 0x0080 /* use localized version */
427
# define NUMINT 0x0100 /* numeric value is an integer */
428
# define INTIND 0x0200 /* integral value is array index;
429
* lazy conversion to string.
431
# define WSTRCUR 0x0400 /* wide str value is current */
432
# define MPFN 0x0800 /* arbitrary-precision floating-point number */
433
# define MPZN 0x1000 /* arbitrary-precision integer */
434
# define NO_EXT_SET 0x2000 /* extension cannot set a value for this variable */
435
# define NULL_FIELD 0x4000 /* this is the null field */
437
/* type = Node_var_array */
438
# define ARRAYMAXED 0x8000 /* array is at max size */
439
# define HALFHAT 0x10000 /* half-capacity Hashed Array Tree;
440
* See cint_array.c */
441
# define XARRAY 0x20000
478
444
#define vname sub.nodep.name
480
446
#define lnode sub.nodep.l.lptr
447
#define nextp sub.nodep.l.lptr
481
448
#define rnode sub.nodep.r.rptr
483
450
/* Node_param_list */
552
501
/* Node_var_array: */
553
502
#define buckets sub.nodep.r.bv
554
503
#define nodes sub.nodep.r.av
504
#define a_opaque sub.nodep.r.aq
555
505
#define array_funcs sub.nodep.l.lp
556
506
#define array_base sub.nodep.l.ll
557
507
#define table_size sub.nodep.reflags
558
508
#define array_size sub.nodep.cnt
559
509
#define array_capacity sub.nodep.reserved
560
510
#define xarray sub.nodep.rn
561
#define parent_array sub.nodep.x.extra
511
#define parent_array sub.nodep.x.extra
563
#define ainit array_funcs->init
564
#define atypeof array_funcs->type_of
565
#define alookup array_funcs->lookup
566
#define aexists array_funcs->exists
567
#define aclear array_funcs->clear
568
#define aremove array_funcs->remove
569
#define alist array_funcs->list
570
#define acopy array_funcs->copy
571
#define adump array_funcs->dump
572
#define astore array_funcs->store
513
#define ainit array_funcs[0]
515
#define atypeof array_funcs[1]
516
#define atypeof_ind 1
517
#define alength array_funcs[2]
518
#define alength_ind 2
519
#define alookup array_funcs[3]
520
#define alookup_ind 3
521
#define aexists array_funcs[4]
522
#define aexists_ind 4
523
#define aclear array_funcs[5]
525
#define aremove array_funcs[6]
526
#define aremove_ind 6
527
#define alist array_funcs[7]
529
#define acopy array_funcs[8]
531
#define adump array_funcs[9]
533
#define astore array_funcs[10]
534
#define astore_ind 10
535
#define NUM_AFUNCS 11 /* # of entries in array_funcs */
574
537
/* Node_array_ref: */
575
538
#define orig_array lnode
1151
1059
extern int (*cmp_numbers)(const NODE *, const NODE *);
1153
1061
/* built-in array types */
1154
extern const array_funcs_t str_array_func;
1155
extern const array_funcs_t cint_array_func;
1156
extern const array_funcs_t int_array_func;
1158
/* special node used to indicate success in array routines (not NULL) */
1159
extern NODE *success_node;
1161
extern struct block_header nextfree[BLOCK_MAX];
1062
extern afunc_t str_array_func[];
1063
extern afunc_t cint_array_func[];
1064
extern afunc_t int_array_func[];
1066
extern BLOCK nextfree[];
1162
1067
extern bool field0_valid;
1164
extern bool do_itrace; /* separate so can poke from a debugger */
1069
extern int do_flags;
1166
1071
extern SRCFILE *srcfiles; /* source files */
1168
extern enum do_flag_values {
1169
DO_FLAG_NONE = 0x00000,
1170
DO_LINT_INVALID = 0x00001, /* only warn about invalid */
1171
DO_LINT_EXTENSIONS = 0x00002, /* warn about gawk extensions */
1172
DO_LINT_ALL = 0x00004, /* warn about all things */
1173
DO_LINT_OLD = 0x00008, /* warn about stuff not in V7 awk */
1174
DO_TRADITIONAL = 0x00010, /* no gnu extensions, add traditional weirdnesses */
1175
DO_POSIX = 0x00020, /* turn off gnu and unix extensions */
1176
DO_INTL = 0x00040, /* dump locale-izable strings to stdout */
1177
DO_NON_DEC_DATA = 0x00080, /* allow octal/hex C style DATA. Use with caution! */
1178
DO_INTERVALS = 0x00100, /* allow {...,...} in regexps, see resetup() */
1179
DO_PRETTY_PRINT = 0x00200, /* pretty print the program */
1180
DO_DUMP_VARS = 0x00400, /* dump all global variables at end */
1181
DO_TIDY_MEM = 0x00800, /* release vars when done */
1182
DO_SANDBOX = 0x01000, /* sandbox mode - disable 'system' function & redirections */
1183
DO_PROFILE = 0x02000, /* profile the program */
1184
DO_DEBUG = 0x04000, /* debug the program */
1185
DO_MPFR = 0x08000, /* arbitrary-precision floating-point math */
1186
DO_CSV = 0x10000, /* process comma-separated-value files */
1073
enum do_flag_values {
1074
DO_LINT_INVALID = 0x0001, /* only warn about invalid */
1075
DO_LINT_ALL = 0x0002, /* warn about all things */
1076
DO_LINT_OLD = 0x0004, /* warn about stuff not in V7 awk */
1077
DO_TRADITIONAL = 0x0008, /* no gnu extensions, add traditional weirdnesses */
1078
DO_POSIX = 0x0010, /* turn off gnu and unix extensions */
1079
DO_INTL = 0x0020, /* dump locale-izable strings to stdout */
1080
DO_NON_DEC_DATA = 0x0040, /* allow octal/hex C style DATA. Use with caution! */
1081
DO_INTERVALS = 0x0080, /* allow {...,...} in regexps, see resetup() */
1082
DO_PRETTY_PRINT = 0x0100, /* pretty print the program */
1083
DO_DUMP_VARS = 0x0200, /* dump all global variables at end */
1084
DO_TIDY_MEM = 0x0400, /* release vars when done */
1085
DO_SANDBOX = 0x0800, /* sandbox mode - disable 'system' function & redirections */
1086
DO_PROFILE = 0x1000, /* profile the program */
1087
DO_DEBUG = 0x2000, /* debug the program */
1088
DO_MPFR = 0x4000 /* arbitrary-precision floating-point math */
1189
1091
#define do_traditional (do_flags & DO_TRADITIONAL)
1190
1092
#define do_posix (do_flags & DO_POSIX)
1306
1200
/* ------------------------- Pseudo-functions ------------------------- */
1307
1201
#ifdef HAVE_MPFR
1312
* In principle, there is no need to have both the MPFN and MPZN flags,
1313
* since we are using 2 bits to encode 1 bit of information. But
1314
* there may be some minor performance advantages from testing only the
1315
* node flag bits without needing also to access the global do_mpfr flag bit.
1317
#define numtype_choose(n, mpfrval, mpzval, dblval) \
1318
(!do_mpfr ? (dblval) : (((n)->flags & MPFN) ? (mpfrval) : (mpzval)))
1322
/* N.B. This implementation seems to give the fastest results. */
1323
#define numtype_choose(n, mpfrval, mpzval, dblval) \
1324
(!((n)->flags & (MPFN|MPZN)) ? (dblval) : (((n)->flags & MPFN) ? (mpfrval) : (mpzval)))
1326
1202
/* conversion to C types */
1327
#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)
1329
#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)
1331
#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)
1333
#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)
1335
#define is_zero(n) numtype_choose((n), mpfr_zero_p((n)->mpg_numbr), (mpz_sgn((n)->mpg_i) == 0), ((n)->numbr == 0.0))
1203
#define get_number_ui(n) (((n)->flags & MPFN) ? mpfr_get_ui((n)->mpg_numbr, ROUND_MODE) \
1204
: ((n)->flags & MPZN) ? mpz_get_ui((n)->mpg_i) \
1205
: (unsigned long) (n)->numbr)
1206
#define get_number_si(n) (((n)->flags & MPFN) ? mpfr_get_si((n)->mpg_numbr, ROUND_MODE) \
1207
: ((n)->flags & MPZN) ? mpz_get_si((n)->mpg_i) \
1208
: (long) (n)->numbr)
1209
#define get_number_d(n) (((n)->flags & MPFN) ? mpfr_get_d((n)->mpg_numbr, ROUND_MODE) \
1210
: ((n)->flags & MPZN) ? mpz_get_d((n)->mpg_i) \
1211
: (double) (n)->numbr)
1212
#define get_number_uj(n) (((n)->flags & MPFN) ? mpfr_get_uj((n)->mpg_numbr, ROUND_MODE) \
1213
: ((n)->flags & MPZN) ? (uintmax_t) mpz_get_d((n)->mpg_i) \
1214
: (uintmax_t) (n)->numbr)
1216
#define iszero(n) (((n)->flags & MPFN) ? mpfr_zero_p((n)->mpg_numbr) \
1217
: ((n)->flags & MPZN) ? (mpz_sgn((n)->mpg_i) == 0) \
1218
: ((n)->numbr == 0.0))
1337
1220
#define IEEE_FMT(r, t) (void) (do_ieee_fmt && format_ieee(r, t))
1358
1241
#define get_lhs(n, r) (n)->type == Node_var && ! var_uninitialized(n) ? \
1359
1242
&((n)->var_value) : r_get_lhs((n), (r))
1363
extern void *r_getblock(int id);
1364
extern void r_freeblock(void *, int id);
1365
#define getblock(p, id, ty) (void) (p = (ty) r_getblock(id))
1366
#define freeblock(p, id) (void) (r_freeblock(p, id))
1368
#else /* MEMDEBUG */
1370
1244
#define getblock(p, id, ty) (void) ((p = (ty) nextfree[id].freep) ? \
1371
(ty) (nextfree[id].freep = ((struct block_item *) p)->freep) \
1245
(ty) (nextfree[id].freep = ((BLOCK *) p)->freep) \
1372
1246
: (p = (ty) more_blocks(id)))
1373
#define freeblock(p, id) (void) (((struct block_item *) p)->freep = nextfree[id].freep, \
1374
nextfree[id].freep = (struct block_item *) p)
1376
#endif /* MEMDEBUG */
1247
#define freeblock(p, id) (void) (((BLOCK *) p)->freep = nextfree[id].freep, \
1248
nextfree[id].freep = (BLOCK *) p)
1378
1250
#define getnode(n) getblock(n, BLOCK_NODE, NODE *)
1379
1251
#define freenode(n) freeblock(n, BLOCK_NODE)
1384
1256
#define make_string(s, l) make_str_node((s), (l), 0)
1386
// Flags for making string nodes
1388
1259
#define ALREADY_MALLOCED 2
1390
#define cant_happen(format, ...) r_fatal("internal error: file %s, line %d: " format, \
1391
__FILE__, __LINE__, __VA_ARGS__)
1261
#define cant_happen() r_fatal("internal error line %d, file: %s", \
1393
#ifdef USE_REAL_MALLOC
1394
#define emalloc(var,ty,x,str) (void) (var = (ty) malloc((size_t)(x)))
1395
#define ezalloc(var,ty,x,str) (void) (var = (ty) calloc((size_t)(x), 1))
1396
#define erealloc(var,ty,x,str) (void) (var = (ty) realloc((void *) var, (size_t)(x)))
1398
#define emalloc(var,ty,x,str) (void) (var = (ty) emalloc_real((size_t)(x), str, #var, __FILE__, __LINE__))
1399
#define ezalloc(var,ty,x,str) (void) (var = (ty) ezalloc_real((size_t)(x), str, #var, __FILE__, __LINE__))
1400
#define erealloc(var,ty,x,str) (void) (var = (ty) erealloc_real((void *) var, (size_t)(x), str, #var, __FILE__, __LINE__))
1264
#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((size_t)(x))) ||\
1265
(fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
1266
(str), #var, (long) (x), strerror(errno)),0))
1267
#define erealloc(var,ty,x,str) (void)((var = (ty)realloc((char *)var, (size_t)(x))) \
1269
(fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
1270
(str), #var, (long) (x), strerror(errno)),0))
1403
1272
#define efree(p) free(p)
1405
#define fatal (*(set_loc(__FILE__, __LINE__), r_fatal))
1274
static inline NODE *
1275
force_string(NODE *s)
1277
if ((s->flags & STRCUR) != 0
1278
&& (s->stfmt == -1 || s->stfmt == CONVFMTidx)
1281
return format_val(CONVFMT, CONVFMTidx, s);
1285
#define unref r_unref
1286
#define force_number str2number
1287
#else /* not GAWKDEBUG */
1292
if (r != NULL && --r->valref <= 0)
1296
static inline NODE *
1297
force_number(NODE *n)
1299
return (n->flags & NUMCUR) ? n : str2number(n);
1302
#endif /* GAWKDEBUG */
1304
#define fatal set_loc(__FILE__, __LINE__), r_fatal
1407
1306
extern jmp_buf fatal_tag;
1408
extern int fatal_tag_valid;
1410
#define assoc_length(a) ((a)->table_size)
1307
extern bool fatal_tag_valid;
1309
#define PUSH_BINDING(stack, tag, val) \
1311
memcpy((char *) (stack), (const char *) tag, sizeof(jmp_buf))
1312
#define POP_BINDING(stack, tag, val) \
1314
memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
1316
#define assoc_length(a) ((*((a)->alength(a, NULL)))->table_size)
1411
1317
#define assoc_empty(a) (assoc_length(a) == 0)
1412
1318
#define assoc_lookup(a, s) ((a)->alookup(a, s))
1454
1360
extern NODE *do_asort(int nargs);
1455
1361
extern NODE *do_asorti(int nargs);
1456
1362
extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
1457
extern void init_env_array(NODE *env_node);
1458
extern void init_argv_array(NODE *argv_node, NODE *shadow_node);
1459
extern NODE *new_array_element(void);
1460
1363
/* awkgram.c */
1461
1364
extern NODE *variable(int location, char *name, NODETYPE type);
1462
extern int parse_program(INSTRUCTION **pcode, bool from_eval);
1365
extern int parse_program(INSTRUCTION **pcode);
1463
1366
extern void track_ext_func(const char *name);
1464
1367
extern void dump_funcs(void);
1465
1368
extern void dump_vars(const char *fname);
1466
extern const char *getfname(NODE *(*)(int), bool prepend_awk);
1369
extern const char *getfname(NODE *(*)(int));
1467
1370
extern NODE *stopme(int nargs);
1468
1371
extern void shadow_funcs(void);
1469
1372
extern int check_special(const char *name);
1470
extern SRCFILE *add_srcfile(enum srctype stype, char *src, SRCFILE *curr, bool *already_included, int *errcode);
1471
extern void free_srcfile(SRCFILE *thisfile);
1373
extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, bool *already_included, int *errcode);
1374
extern void register_deferred_variable(const char *name, NODE *(*load_func)(void));
1472
1375
extern int files_are_same(char *path, SRCFILE *src);
1473
1376
extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
1474
1377
extern void negate_num(NODE *n);
1475
typedef NODE *(*builtin_func_t)(int); /* function that implements a built-in */
1476
extern builtin_func_t lookup_builtin(const char *name);
1477
extern void install_builtins(void);
1478
extern bool is_alpha(int c);
1479
extern bool is_alnum(int c);
1480
extern bool is_letter(int c);
1481
extern bool is_identchar(int c);
1482
extern NODE *make_regnode(NODETYPE type, NODE *exp);
1483
extern bool validate_qualified_name(char *token);
1484
1378
/* builtin.c */
1485
extern void efflush(FILE *fp, const char *from, struct redirect *rp);
1486
extern void efwrite(const void *ptr, size_t size, size_t count, FILE *fp, const char *from,
1487
struct redirect *rp, bool flush);
1488
1379
extern double double_to_int(double d);
1489
1380
extern NODE *do_exp(int nargs);
1490
1381
extern NODE *do_fflush(int nargs);
1524
1412
extern NODE *do_xor(int nargs);
1525
1413
extern NODE *do_compl(int nargs);
1526
1414
extern NODE *do_strtonum(int nargs);
1527
extern AWKNUM nondec2awknum(char *str, size_t len, char **endptr);
1415
extern AWKNUM nondec2awknum(char *str, size_t len);
1528
1416
extern NODE *do_dcgettext(int nargs);
1529
1417
extern NODE *do_dcngettext(int nargs);
1530
1418
extern NODE *do_bindtextdomain(int nargs);
1531
extern NODE *do_intdiv(int nargs);
1532
extern NODE *do_typeof(int nargs);
1533
1420
extern int strncasecmpmbs(const unsigned char *,
1534
1421
const unsigned char *, size_t);
1535
extern int sanitize_exit_status(int status);
1536
extern void check_symtab_functab(NODE *dest, const char *fname, const char *msg);
1537
extern NODE *do_mkbool(int nargs);
1538
extern void check_exact_args(int nargs, const char *fname, int count);
1539
extern void check_args_min_max(int nargs, const char *fname, int min, int max);
1541
extern void init_debug(void);
1542
extern int debug_prog(INSTRUCTION *pc);
1544
1424
extern void PUSH_CODE(INSTRUCTION *cp);
1545
1425
extern INSTRUCTION *POP_CODE(void);
1546
1426
extern void init_interpret(void);
1547
extern int cmp_nodes(NODE *t1, NODE *t2, bool use_strcmp);
1427
extern int cmp_nodes(NODE *t1, NODE *t2);
1548
1428
extern int cmp_awknums(const NODE *t1, const NODE *t2);
1549
1429
extern void set_IGNORECASE(void);
1550
1430
extern void set_OFS(void);
1572
1452
extern STACK_ITEM *grow_stack(void);
1573
1453
extern void dump_fcall_stack(FILE *fp);
1574
1454
extern int register_exec_hook(Func_pre_exec preh, Func_post_exec posth);
1575
extern NODE **r_get_field(NODE *n, Func_ptr *assign, bool reference);
1576
extern NODE *elem_new_to_scalar(NODE *n);
1578
1456
extern NODE *do_ext(int nargs);
1579
1457
void load_ext(const char *lib_name); /* temporary */
1458
extern NODE *load_old_ext(SRCFILE *s, const char *init_func, const char *fini_func, NODE *obj);
1580
1459
extern void close_extensions(void);
1581
extern bool is_valid_identifier(const char *name);
1583
extern awk_bool_t make_builtin(const char *name_space, const awk_ext_func_t *);
1461
extern void make_old_builtin(const char *, NODE *(*)(int), int);
1462
extern awk_bool_t make_builtin(const awk_ext_func_t *);
1584
1463
extern NODE *get_argument(int);
1585
extern NODE *get_actual_argument(NODE *, int, bool);
1586
#define get_scalar_argument(n, i) get_actual_argument((n), (i), false)
1587
#define get_array_argument(n, i) get_actual_argument((n), (i), true)
1464
extern NODE *get_actual_argument(int, bool, bool);
1465
#define get_scalar_argument(i, opt) get_actual_argument((i), (opt), false)
1466
#define get_array_argument(i, opt) get_actual_argument((i), (opt), true)
1590
1469
extern void init_fields(void);
1591
extern void init_csv_fields(void);
1592
extern void set_record(const char *buf, size_t cnt, const awk_fieldwidth_info_t *);
1470
extern void set_record(const char *buf, int cnt);
1593
1471
extern void reset_record(void);
1594
extern void rebuild_record(void);
1595
1472
extern void set_NF(void);
1596
1473
extern NODE **get_field(long num, Func_ptr *assign);
1597
1474
extern NODE *do_split(int nargs);
1650
1514
extern void init_sockets(void);
1651
1515
extern void init_io(void);
1652
extern void init_csv_records(void);
1653
1516
extern void register_input_parser(awk_input_parser_t *input_parser);
1654
1517
extern void register_output_wrapper(awk_output_wrapper_t *wrapper);
1655
1518
extern void register_two_way_processor(awk_two_way_processor_t *processor);
1656
1519
extern void set_FNR(void);
1657
1520
extern void set_NR(void);
1659
extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg, bool failure_fatal);
1660
extern struct redirect *redirect_string(const char *redir_exp_str,
1661
size_t redir_exp_len, bool not_string_flag, int redirtype,
1662
int *errflg, int extfd, bool failure_fatal);
1522
extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
1663
1523
extern NODE *do_close(int nargs);
1664
1524
extern int flush_io(void);
1665
extern int close_io(bool *stdio_problem, bool *got_EPIPE);
1666
typedef enum { CLOSE_ALL, CLOSE_TO, CLOSE_FROM } two_way_close_type;
1667
extern int close_rp(struct redirect *rp, two_way_close_type how);
1668
extern int devopen_simple(const char *name, const char *mode, bool try_real_open);
1525
extern int close_io(bool *stdio_problem);
1669
1526
extern int devopen(const char *name, const char *mode);
1670
1527
extern int srcopen(SRCFILE *s);
1671
1528
extern char *find_source(const char *src, struct stat *stb, int *errcode, int is_extlib);
1672
1529
extern NODE *do_getline_redir(int intovar, enum redirval redirtype);
1673
1530
extern NODE *do_getline(int intovar, IOBUF *iop);
1674
1531
extern struct redirect *getredirect(const char *str, int len);
1675
extern bool inrec(IOBUF *iop, int *errcode);
1532
extern int inrec(IOBUF *iop, int *errcode);
1676
1533
extern int nextfile(IOBUF **curfile, bool skipping);
1677
extern bool is_non_fatal_std(FILE *fp);
1678
extern bool is_non_fatal_redirect(const char *str, size_t len);
1679
extern bool non_fatal_flush_std_file(FILE *fp);
1680
extern size_t gawk_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque);
1681
#ifndef PIPES_SIMULATED
1682
extern int wait_any(int interesting);
1686
1535
extern int arg_assign(char *arg, bool initing);
1687
1536
extern int is_std_var(const char *var);
1785
1625
extern Regexp *re_update(NODE *t);
1786
1626
extern void resyntax(int syntax);
1787
1627
extern void resetup(void);
1628
extern int avoid_dfa(NODE *re, char *str, size_t len);
1788
1629
extern int reisstring(const char *text, size_t len, Regexp *re, const char *buf);
1789
extern int get_numbase(const char *str, size_t len, bool use_locale);
1790
extern bool using_utf8(void);
1630
extern int get_numbase(const char *str, bool use_locale);
1793
1633
extern void load_symbols();
1794
1634
extern void init_symbol_table();
1795
1635
extern NODE *symbol_table;
1796
1636
extern NODE *func_table;
1797
extern NODE *install_symbol(const char *name, NODETYPE type);
1637
extern NODE *install_symbol(char *name, NODETYPE type);
1798
1638
extern NODE *remove_symbol(NODE *r);
1799
1639
extern void destroy_symbol(NODE *r);
1800
1640
extern void release_symbols(NODE *symlist, int keep_globals);
1957
1785
return r_dupnode(n);
1962
* force_string_fmt --- force a node to have a string value in a given format.
1963
* The string representation of a number may change due to whether it was most
1964
* recently rendered with CONVFMT or OFMT, or due to changes in the CONVFMT
1965
* and OFMT values. But if the value entered gawk as a string or strnum, then
1966
* stfmt should be set to STFMT_UNUSED, and the string representation should
1969
* Additional twist: If ROUNDMODE changed at some point we have to
1973
static inline NODE *
1974
force_string_fmt(NODE *s, const char *fmtstr, int fmtidx)
1976
if (s->type == Node_elem_new) {
1982
if ((s->flags & STRCUR) != 0
1983
&& (s->stfmt == STFMT_UNUSED || (s->stfmt == fmtidx
1985
&& s->strndmode == MPFR_round_mode
1989
return format_val(fmtstr, fmtidx, s);
1992
/* conceptually should be force_string_convfmt, but this is the typical case */
1993
#define force_string(s) force_string_fmt((s), CONVFMT, CONVFMTidx)
1995
#define force_string_ofmt(s) force_string_fmt((s), OFMT, OFMTidx)
1998
#define unref r_unref
1999
#define force_number str2number
2000
#else /* not GAWKDEBUG */
2002
/* unref --- decrease the reference count and/or free a node */
2007
assert(r == NULL || r->valref > 0);
2008
if (r != NULL && --r->valref <= 0)
2012
/* force_number --- force a node to have a numeric value */
2014
static inline NODE *
2015
force_number(NODE *n)
2017
if (n->type == Node_elem_new) {
2022
return (n->flags & NUMCUR) != 0 ? n : str2number(n);
2025
#endif /* GAWKDEBUG */
2028
/* fixtype --- make a node decide if it's a number or a string */
2031
* In certain contexts, the true type of a scalar value matters, and we
2032
* must ascertain whether it is a NUMBER or a STRING. In such situations,
2033
* please use this function to resolve the type.
2035
* It is safe to assume that the return value will be the same NODE,
2036
* since force_number on a USER_INPUT should always return the same NODE,
2037
* and force_string on an INTIND should as well.
2040
static inline NODE *
2043
assert(n->type == Node_val);
2044
if ((n->flags & (NUMCUR|USER_INPUT)) == USER_INPUT)
2045
return force_number(n);
2046
if ((n->flags & INTIND) != 0)
2047
return force_string(n);
2051
/* boolval --- return true/false based on awk's criteria */
2054
* In awk, a value is considered to be true if it is nonzero _or_
2055
* non-null. Otherwise, the value is false.
2061
if (t->type == Node_var) // could have come from converted Node_elem_new
2065
if ((t->flags & NUMBER) != 0)
2066
return ! is_zero(t);
2067
return (t->stlen > 0);
2070
/* emalloc_real --- malloc with error checking */
2072
static inline void *
2073
emalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
2078
fatal("%s:%d: emalloc called with zero bytes", file, line);
2080
ret = (void *) malloc(count);
2082
fatal(_("%s:%d:%s: %s: cannot allocate %ld bytes of memory: %s"),
2083
file, line, where, var, (long) count, strerror(errno));
2088
/* ezalloc_real --- malloc zero-filled bytes with error checking */
2090
static inline void *
2091
ezalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
2096
fatal("%s:%d: ezalloc called with zero bytes", file, line);
2098
ret = (void *) calloc(1, count);
2100
fatal(_("%s:%d:%s: %s: cannot allocate %ld bytes of memory: %s"),
2101
file, line, where, var, (long) count, strerror(errno));
2106
/* erealloc_real --- realloc with error checking */
2108
static inline void *
2109
erealloc_real(void *ptr, size_t count, const char *where, const char *var, const char *file, int line)
2114
fatal("%s:%d: erealloc called with zero bytes", file, line);
2116
ret = (void *) realloc(ptr, count);
2118
fatal(_("%s:%d:%s: %s: cannot reallocate %ld bytes of memory: %s"),
2119
file, line, where, var, (long) count, strerror(errno));
2124
/* make_number_node --- make node with the given flags */
2126
static inline NODE *
2127
make_number_node(unsigned int flags)
2131
memset(r, 0, sizeof(*r));
2134
r->flags = (flags|MALLOC|NUMBER|NUMCUR);
2138
/* assoc_set -- set an element in an array. Does unref(sub)! */
2141
assoc_set(NODE *array, NODE *sub, NODE *value)
2144
NODE **lhs = assoc_lookup(array, sub);
2147
if (array->astore != NULL)
2148
(*array->astore)(array, sub);
2153
* str_terminate_f, str_terminate, str_restore: function and macros to
2154
* reduce chances of typos when terminating and restoring strings.
2155
* This also helps to enforce that the NODE must be in scope when we restore.
2159
str_terminate_f(NODE *n, char *savep)
2161
*savep = n->stptr[n->stlen];
2162
n->stptr[n->stlen] = '\0';
2165
#define str_terminate(n, save) str_terminate_f((n), &save)
2166
#define str_restore(n, save) (n)->stptr[(n)->stlen] = save
2169
#define ignore_sigpipe() signal(SIGPIPE, SIG_IGN)
2170
#define set_sigpipe_to_default() signal(SIGPIPE, SIG_DFL)
2171
#define die_via_sigpipe() (signal(SIGPIPE, SIG_DFL), kill(getpid(), SIGPIPE))
2173
#define ignore_sigpipe()
2174
#define set_sigpipe_to_default()
2176
/* 0xC0000008 is EXCEPTION_INVALID_HANDLE, somewhat appropriate for EPIPE */
2177
#define die_via_sigpipe() exit(0xC0000008)
2178
#else /* !__MINGW32__ */
2179
#define die_via_sigpipe() exit(EXIT_FATAL)
2180
#endif /* !__MINGW32__ */