~vcs-imports/gawk/master

« back to all changes in this revision

Viewing changes to awk.h

Update README.solaris.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * awk.h -- Definitions for gawk.
 
2
 * awk.h -- Definitions for gawk. 
3
3
 */
4
4
 
5
 
/*
6
 
 * Copyright (C) 1986, 1988, 1989, 1991-2024 the Free Software Foundation, Inc.
7
 
 *
 
5
/* 
 
6
 * Copyright (C) 1986, 1988, 1989, 1991-2013 the Free Software Foundation, Inc.
 
7
 * 
8
8
 * This file is part of GAWK, the GNU implementation of the
9
9
 * AWK Programming Language.
10
 
 *
 
10
 * 
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.
15
 
 *
 
15
 * 
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.
20
 
 *
 
20
 * 
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
43
43
#include <config.h>
44
44
#endif
45
45
 
 
46
#ifndef _GNU_SOURCE
 
47
#define _GNU_SOURCE     1       /* enable GNU extensions */
 
48
#endif /* _GNU_SOURCE */
 
49
 
46
50
#if defined(tandem_for_real) && ! defined(_SCO_DS)
47
51
#define _XOPEN_SOURCE_EXTENDED 1
48
52
#endif
49
53
 
50
54
#include <stdio.h>
51
55
#include <assert.h>
 
56
#ifdef HAVE_LIMITS_H
52
57
#include <limits.h>
 
58
#endif /* HAVE_LIMITS_H */
53
59
#include <ctype.h>
54
60
#include <setjmp.h>
55
 
#include <math.h>
56
61
 
57
62
#include "gettext.h"
58
63
#define _(msgid)  gettext(msgid)
64
69
#endif /* LOCALEDIR */
65
70
#endif
66
71
 
67
 
#if !defined(__SUNPRO_C)
68
72
#if !defined(__STDC__) || __STDC__ < 1
69
73
#error "gawk no longer supports non-C89 environments (no __STDC__ or __STDC__ < 1)"
70
74
#endif
71
 
#endif
72
75
 
 
76
#if defined(HAVE_STDARG_H)
73
77
#include <stdarg.h>
 
78
#else
 
79
#error "gawk no longer supports <varargs.h>. Please update your compiler and runtime"
 
80
#endif
74
81
#include <signal.h>
75
82
#include <time.h>
76
83
#include <errno.h>
82
89
#include <stdlib.h>
83
90
#endif  /* not STDC_HEADERS */
84
91
 
85
 
 
 
92
#ifdef HAVE_STDBOOL_H
 
93
#include <stdbool.h>
 
94
#else
 
95
#include "missing_d/gawkbool.h"
 
96
#endif
 
97
 
 
98
#include "mbsupport.h" /* defines MBS_SUPPORT */
 
99
 
 
100
#if MBS_SUPPORT
86
101
/* We can handle multibyte strings.  */
87
102
#include <wchar.h>
88
103
#include <wctype.h>
89
 
#ifdef __CYGWIN__ /* Define helper function for large Unicode values */
90
 
extern size_t wcitomb (char *s, int wc, mbstate_t *ps);
91
104
#endif
92
105
 
93
106
#ifdef STDC_HEADERS
97
110
#undef CHARBITS
98
111
#undef INTBITS
99
112
 
 
113
#if !defined(ZOS_USS)
100
114
#if HAVE_INTTYPES_H
101
115
# include <inttypes.h>
102
116
#endif
103
117
#if HAVE_STDINT_H
104
118
# include <stdint.h>
105
119
#endif
 
120
#else /* ZOS_USS */
 
121
#include <limits.h>
 
122
#include <sys/time.h>
 
123
#define INT32_MAX INT_MAX
 
124
#define INT32_MIN INT_MIN
 
125
#ifndef __uint32_t
 
126
#define __uint32_t 1
 
127
typedef  unsigned long uint32_t;
 
128
#endif
 
129
typedef  long int32_t;
 
130
#endif /* !ZOS_USS */
106
131
 
107
132
/* ----------------- System dependencies (with more includes) -----------*/
108
133
 
136
161
#ifdef NEED_MEMORY_H
137
162
#include <memory.h>
138
163
#endif  /* NEED_MEMORY_H */
139
 
#endif /* HAVE_STRING_H */
 
164
#else   /* not HAVE_STRING_H */
140
165
#ifdef HAVE_STRINGS_H
141
166
#include <strings.h>
142
167
#endif  /* HAVE_STRINGS_H */
 
168
#endif  /* not HAVE_STRING_H */
143
169
 
144
170
#if HAVE_UNISTD_H
145
171
#include <unistd.h>
158
184
#define setlocale(locale, val)  /* nothing */
159
185
#endif /* HAVE_SETLOCALE */
160
186
 
161
 
#ifdef HAVE_FWRITE_UNLOCKED
162
 
#define fwrite  fwrite_unlocked
163
 
#endif /* HAVE_FWRITE_UNLOCKED */
164
 
 
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
 
190
#endif
 
191
#if HAVE_MEMSET_ULONG
 
192
extern void *memset_ulong(void *dest, int val, unsigned long l);
 
193
#define memset memset_ulong
 
194
#endif
 
195
 
 
196
#ifdef HAVE_LIBSIGSEGV
 
197
#include <sigsegv.h>
 
198
#else
 
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
 
203
#endif
 
204
 
 
205
#if defined(__EMX__) || defined(__MINGW32__)
166
206
#include "nonposix.h"
167
 
#endif /* defined(__MINGW32__) */
 
207
#endif /* defined(__EMX__) || defined(__MINGW32__) */
168
208
 
169
209
/* use this as lintwarn("...")
170
210
   this is a hack but it gives us the right semantics */
190
230
        struct re_pattern_buffer pat;
191
231
        struct re_registers regs;
192
232
        struct dfa *dfareg;
193
 
        bool has_meta;          /* re has meta chars so (probably) isn't simple string */
194
 
        bool maybe_long;        /* re has meta chars that can match long text */
 
233
        short dfa;
 
234
        short has_anchor;       /* speed up of avoid_dfa kludge, temporary */
 
235
        short non_empty;        /* for use in fpat_parse_field */
 
236
        short has_meta;         /* re has meta chars so (probably) isn't simple string */
 
237
        short maybe_long;       /* re has meta chars that can match long text */
195
238
} Regexp;
196
239
#define RESTART(rp,s)   (rp)->regs.start[0]
197
240
#define REEND(rp,s)     (rp)->regs.end[0]
200
243
#define NUMSUBPATS(rp,s)        (rp)->regs.num_regs
201
244
 
202
245
/* regexp matching flags: */
203
 
#define RE_NO_FLAGS     0       /* empty flags */
204
246
#define RE_NEED_START   1       /* need to know start/end of match */
205
247
#define RE_NO_BOL       2       /* not allowed to match ^ in regexp */
206
248
 
207
249
#include "gawkapi.h"
208
250
 
209
 
#include "floatmagic.h"
210
 
 
211
251
/* Stuff for losing systems. */
212
252
#if !defined(HAVE_STRTOD)
213
253
extern double gawk_strtod();
215
255
#endif
216
256
 
217
257
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
218
 
# define __attribute__(arg)
 
258
# define __attribute__(x)
219
259
#endif
220
260
 
221
261
#ifndef ATTRIBUTE_UNUSED
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 */
261
300
 
262
301
        Node_array_ref,         /* array passed by ref as parameter */
263
302
        Node_array_tree,        /* Hashed array tree (HAT) */
291
330
        } hi;
292
331
} BUCKET;
293
332
 
294
 
enum commenttype {
295
 
        EOL_COMMENT = 1,
296
 
        BLOCK_COMMENT,
297
 
        FOR_COMMENT     // special case
298
 
};
299
 
 
300
 
enum escape_results {
301
 
        ESCAPE_OK,              // nbytes == 1 to MB_CUR_MAX: the length of the translated escape sequence
302
 
        ESCAPE_CONV_ERR,        // wcrtomb conversion error
303
 
        ESCAPE_TERM_BACKSLASH,  // terminal backslash (to be preserved in cmdline strings)
304
 
        ESCAPE_LINE_CONTINUATION        // line continuation  (backslash-newline pair)
305
 
};
306
 
 
307
333
/* string hash table */
308
334
#define ahnext          hs.next
309
335
#define ahname          hs.name /* a string index node */
322
348
 
323
349
typedef int (*Func_print)(FILE *, const char *, ...);
324
350
typedef struct exp_node **(*afunc_t)(struct exp_node *, struct exp_node *);
325
 
typedef struct {
326
 
        const char *name;
327
 
        afunc_t init;
328
 
        afunc_t type_of;        /* avoid reserved word typeof */
329
 
        afunc_t lookup;
330
 
        afunc_t exists;
331
 
        afunc_t clear;
332
 
        afunc_t remove;
333
 
        afunc_t list;
334
 
        afunc_t copy;
335
 
        afunc_t dump;
336
 
        afunc_t store;
337
 
} array_funcs_t;
338
351
 
339
352
/*
340
353
 * NOTE - this struct is a rather kludgey -- it is packed to minimize
347
360
                                struct exp_node *lptr;
348
361
                                struct exp_instruction *li;
349
362
                                long ll;
350
 
                                const array_funcs_t *lp;
 
363
                                afunc_t *lp;
351
364
                        } l;
352
365
                        union {
353
366
                                struct exp_node *rptr;
354
 
                                Regexp *preg[2];
 
367
                                Regexp *preg;
355
368
                                struct exp_node **av;
356
369
                                BUCKET **bv;
 
370
                                void *aq;
357
371
                                void (*uptr)(void);
358
372
                                struct exp_instruction *iptr;
359
373
                        } r;
361
375
                                struct exp_node *extra;
362
376
                                void (*aptr)(void);
363
377
                                long xl;
364
 
                                void *cmnt;     // used by pretty printer
 
378
                                char **param_list;
365
379
                        } x;
366
380
                        char *name;
367
381
                        size_t reserved;
368
382
                        struct exp_node *rn;
369
383
                        unsigned long cnt;
370
 
                        enum reflagvals {
371
 
                                CONSTANT = 1,
372
 
                                FS_DFLT  = 2,
373
 
                        } reflags;
 
384
                        unsigned long reflags;
 
385
#                               define  CASE            1
 
386
#                               define  CONSTANT        2
 
387
#                               define  FS_DFLT         4
374
388
                } nodep;
375
389
 
376
390
                struct {
380
394
                                mpfr_t mpnum;
381
395
                                mpz_t mpi;
382
396
                        } nm;
383
 
                        int rndmode;
384
397
#else
385
 
                        AWKNUM fltnum;
 
398
                        AWKNUM fltnum;  /* this is here for optimal packing of
 
399
                                         * the structure on many machines
 
400
                                         */
386
401
#endif
387
402
                        char *sp;
388
403
                        size_t slen;
 
404
                        long sref;
389
405
                        int idx;
 
406
#if MBS_SUPPORT
390
407
                        wchar_t *wsp;
391
408
                        size_t wslen;
392
 
                        struct exp_node *typre;
393
 
                        enum commenttype comtype;
 
409
#endif
394
410
                } val;
395
411
        } sub;
396
412
        NODETYPE type;
397
 
        enum flagvals {
398
 
        /* type = Node_val */
399
 
                /*
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.
405
 
                 *
406
 
                 * STRCUR and NUMCUR are not mutually exclusive. They represent that
407
 
                 * the particular type of value is up to date.  For example,
408
 
                 *
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!
412
 
                 *
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!
416
 
                 *
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
426
 
                 * "numeric string".
427
 
                 *
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.
433
 
                 *
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.
441
 
                 *
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.
445
 
                 *
446
 
                 * We hope that the rest of the flags are self-explanatory. :-)
447
 
                 */
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
454
 
                                         * a NUMBER */
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.
460
 
                                         */
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 */
466
 
 
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 */
471
 
                XARRAY          = 0x020000,
472
 
                NUMCONSTSTR     = 0x040000,     /* have string value for numeric constant */
473
 
                REGEX           = 0x080000,     /* this is a typed regex */
474
 
        } flags;
475
 
        long valref;
 
413
        unsigned int flags;
 
414
 
 
415
/* any type */
 
416
#               define  MALLOC  0x0001       /* can be free'd */
 
417
 
 
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
 
424
                                              * a NUMBER */
 
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.
 
430
                                              */
 
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 */
 
436
 
 
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
476
442
} NODE;
477
443
 
478
444
#define vname sub.nodep.name
479
445
 
480
446
#define lnode   sub.nodep.l.lptr
 
447
#define nextp   sub.nodep.l.lptr
481
448
#define rnode   sub.nodep.r.rptr
482
449
 
483
450
/* Node_param_list */
499
466
#define re_cnt  flags
500
467
 
501
468
/* Node_val */
502
 
/*
503
 
 * Note that the string in stptr may not be NUL-terminated, but it is
504
 
 * guaranteed to have at least one extra byte that may be temporarily set
505
 
 * to '\0'. This is helpful when calling functions such as strtod that require
506
 
 * a NUL-terminated argument. In particular, field values $n for n > 0 and
507
 
 * n < NF will not have a NUL terminator, since they point into the $0 buffer.
508
 
 * All other strings are NUL-terminated.
509
 
 */
510
469
#define stptr   sub.val.sp
511
470
#define stlen   sub.val.slen
 
471
#define valref  sub.val.sref
512
472
#define stfmt   sub.val.idx
513
 
#define strndmode sub.val.rndmode
514
473
#define wstptr  sub.val.wsp
515
474
#define wstlen  sub.val.wslen
516
475
#ifdef HAVE_MPFR
520
479
#else
521
480
#define numbr           sub.val.fltnum
522
481
#endif
523
 
#define typed_re        sub.val.typre
524
 
 
525
 
/*
526
 
 * If stfmt is set to STFMT_UNUSED, it means that the string representation
527
 
 * stored in stptr is not a function of the value of CONVFMT or OFMT. That
528
 
 * indicates that either the string value was explicitly assigned, or it
529
 
 * was converted from a NUMBER that has an integer value. When stfmt is not
530
 
 * set to STFMT_UNUSED, it is an offset into the fmt_list array of distinct
531
 
 * CONVFMT and OFMT node pointers.
532
 
 */
533
 
#define STFMT_UNUSED    -1
534
482
 
535
483
/* Node_arrayfor */
536
484
#define for_list        sub.nodep.r.av
543
491
#define func_node    sub.nodep.x.extra
544
492
#define prev_frame_size sub.nodep.reflags
545
493
#define reti         sub.nodep.l.li
 
494
#define num_tail_calls    sub.nodep.cnt
546
495
 
547
496
/* Node_var: */
548
497
#define var_value    lnode
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 
562
512
 
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]
 
514
#define ainit_ind       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]
 
524
#define aclear_ind      5
 
525
#define aremove         array_funcs[6]
 
526
#define aremove_ind     6
 
527
#define alist           array_funcs[7]
 
528
#define alist_ind       7
 
529
#define acopy           array_funcs[8]
 
530
#define acopy_ind       8
 
531
#define adump           array_funcs[9]
 
532
#define adump_ind       9
 
533
#define astore          array_funcs[10]
 
534
#define astore_ind      10
 
535
#define NUM_AFUNCS      11              /* # of entries in array_funcs */
573
536
 
574
537
/* Node_array_ref: */
575
538
#define orig_array lnode
579
542
#define adepth     sub.nodep.l.ll
580
543
#define alevel     sub.nodep.x.xl
581
544
 
582
 
/* Op_comment   */
583
 
#define comment_type    sub.val.comtype
584
 
 
585
545
/* --------------------------------lint warning types----------------------------*/
586
546
typedef enum lintvals {
587
547
        LINT_illegal,
592
552
/* --------------------------------Instruction ---------------------------------- */
593
553
 
594
554
typedef enum opcodeval {
595
 
        Op_illegal = 0,         /* illegal entry */
 
555
        /* illegal entry == 0 */
 
556
        Op_illegal,
596
557
 
597
558
        /* binary operators */
598
559
        Op_times,
622
583
        Op_postincrement,
623
584
        Op_postdecrement,
624
585
        Op_unary_minus,
625
 
        Op_unary_plus,
626
586
        Op_field_spec,
627
587
 
628
588
        /* unary relationals */
633
593
        Op_store_var,           /* simple variable assignment optimization */
634
594
        Op_store_sub,           /* array[subscript] assignment optimization */
635
595
        Op_store_field,         /* $n assignment optimization */
636
 
        Op_store_field_exp,     /* $n assignment optimization in an expression */
637
596
        Op_assign_times,
638
597
        Op_assign_quotient,
639
598
        Op_assign_mod,
660
619
        Op_nomatch,
661
620
 
662
621
        Op_rule,
663
 
 
 
622
        
664
623
        /* keywords */
665
624
        Op_K_case,
666
625
        Op_K_default,
672
631
        Op_K_next,
673
632
        Op_K_exit,
674
633
        Op_K_return,
675
 
        Op_K_return_from_eval,
676
634
        Op_K_delete,
677
635
        Op_K_delete_loop,
678
636
        Op_K_getline_redir,
679
637
        Op_K_getline,
680
638
        Op_K_nextfile,
681
 
        Op_K_namespace,
682
639
 
683
640
        Op_builtin,
684
641
        Op_sub_builtin,         /* sub, gsub and gensub */
685
642
        Op_ext_builtin,
 
643
        Op_old_ext_builtin,     /* temporary */
686
644
        Op_in_array,            /* boolean test of membership in array */
687
645
 
688
646
        /* function call instruction */
691
649
 
692
650
        Op_push,                /* scalar variable */
693
651
        Op_push_arg,            /* variable type (scalar or array) argument to built-in */
694
 
        Op_push_arg_untyped,    /* like Op_push_arg, but for typeof */
695
652
        Op_push_i,              /* number, string */
696
653
        Op_push_re,             /* regex */
697
654
        Op_push_array,
719
676
 
720
677
        Op_func,
721
678
 
722
 
        Op_comment,             /* for pretty printing */
723
679
        Op_exec_count,
724
680
        Op_breakpoint,
725
681
        Op_lint,
726
 
        Op_lint_plus,
727
682
        Op_atexit,
728
683
        Op_stop,
729
684
 
730
685
        /* parsing (yylex and yyparse), should never appear in valid compiled code */
731
 
        Op_token,
 
686
        Op_token,       
732
687
        Op_symbol,
733
688
        Op_list,
734
689
 
735
690
        /* program structures -- for use in the profiler/pretty printer */
736
691
        Op_K_do,
737
 
        Op_K_for,
 
692
        Op_K_for,                       
738
693
        Op_K_arrayfor,
739
694
        Op_K_while,
740
695
        Op_K_switch,
742
697
        Op_K_else,
743
698
        Op_K_function,
744
699
        Op_cond_exp,
745
 
        Op_parens,
746
700
        Op_final                        /* sentry value, not legal */
747
701
} OPCODE;
748
702
 
759
713
 
760
714
struct break_point;
761
715
 
762
 
#if __DECC && __VAX
763
 
typedef unsigned long exec_count_t;     // for exec_count
764
 
#define EXEC_COUNT_FMT  "%lu"
765
 
#define EXEC_COUNT_PROFILE_FMT  "%6lu"
766
 
#else
767
 
typedef unsigned long long exec_count_t;        // for exec_count
768
 
#define EXEC_COUNT_FMT  "%llu"
769
 
#define EXEC_COUNT_PROFILE_FMT  "%6llu"
770
 
#endif
771
 
 
772
716
typedef struct exp_instruction {
773
717
        struct exp_instruction *nexti;
774
718
        union {
775
719
                NODE *dn;
776
720
                struct exp_instruction *di;
777
721
                NODE *(*fptr)(int);
778
 
                awk_value_t *(*efptr)(int num_actual_args,
779
 
                                        awk_value_t *result,
780
 
                                        struct awk_ext_func *finfo);
 
722
                awk_value_t *(*efptr)(int, awk_value_t *);
781
723
                long dl;
782
 
                exec_count_t ldl;       // for exec_count
783
724
                char *name;
784
725
        } d;
785
726
 
789
730
                void (*aptr)(void);
790
731
                struct exp_instruction *xi;
791
732
                struct break_point *bpt;
792
 
                awk_ext_func_t *exf;
793
733
        } x;
794
734
 
795
 
        struct exp_instruction *comment;
796
735
        short source_line;
797
 
        short pool_size;        // memory management in symbol.c
798
736
        OPCODE opcode;
799
737
} INSTRUCTION;
800
738
 
807
745
 
808
746
#define expr_count      x.xl
809
747
 
810
 
#define c_function      x.exf
811
 
 
812
748
#define target_continue d.di
813
749
#define target_jmp      d.di
814
750
#define target_break    x.xi
822
758
 
823
759
/* Op_K_exit */
824
760
#define target_end      d.di
825
 
#define target_atexit   x.xi
 
761
#define target_atexit   x.xi    
826
762
 
827
763
/* Op_newfile, Op_K_getline, Op_nextfile */
828
764
#define target_endfile  x.xi
878
814
/* Op_func_call, Op_func */
879
815
#define func_body       x.xn
880
816
 
 
817
/* Op_func_call */
 
818
#define tail_call       d.dl
 
819
 
881
820
/* Op_subscript */
882
821
#define sub_count       d.dl
883
822
 
908
847
#define field_assign    x.aptr
909
848
 
910
849
/* Op_field_assign, Op_var_assign */
911
 
#define assign_ctxt     d.dl
 
850
#define assign_ctxt     d.dl    
912
851
 
913
852
/* Op_concat */
914
853
#define concat_flag     d.dl
920
859
 
921
860
/*------------------ pretty printing/profiling --------*/
922
861
/* Op_exec_count */
923
 
#define exec_count      d.ldl
 
862
#define exec_count      d.dl
924
863
 
925
864
/* Op_K_while */
926
865
#define while_body      d.di
941
880
 
942
881
/* Op_line_range */
943
882
#define condpair_left   d.di
944
 
#define condpair_right  x.xi
945
 
 
946
 
/* Op_Rule, Op_Func */
947
 
#define ns_name         d.name
 
883
#define condpair_right  x.xi 
948
884
 
949
885
/* Op_store_var */
950
886
#define initval         x.xn
964
900
        bool valid;
965
901
        int errcode;
966
902
 
967
 
        enum iobuf_flags {
968
 
                IOP_IS_TTY      = 1,
969
 
                IOP_AT_EOF      = 2,
970
 
                IOP_CLOSED      = 4,
971
 
                IOP_AT_START    = 8,
972
 
        } flag;
 
903
        int flag;
 
904
#               define  IOP_IS_TTY      1
 
905
#               define  IOP_AT_EOF      2
 
906
#               define  IOP_CLOSED      4
 
907
#               define  IOP_AT_START    8
973
908
} IOBUF;
974
909
 
975
910
typedef void (*Func_ptr)(void);
976
911
 
977
912
/* structure used to dynamically maintain a linked-list of open files/pipes */
978
913
struct redirect {
979
 
        enum redirect_flags {
980
 
                RED_NONE        = 0,
981
 
                RED_FILE        = 1,
982
 
                RED_PIPE        = 2,
983
 
                RED_READ        = 4,
984
 
                RED_WRITE       = 8,
985
 
                RED_APPEND      = 16,
986
 
                RED_FLUSH       = 32,
987
 
                RED_USED        = 64,   /* closed temporarily to reuse fd */
988
 
                RED_EOF         = 128,
989
 
                RED_TWOWAY      = 256,
990
 
                RED_PTY         = 512,
991
 
                RED_SOCKET      = 1024,
992
 
                RED_TCP         = 2048,
993
 
        } flag;
 
914
        unsigned int flag;
 
915
#               define  RED_FILE        1
 
916
#               define  RED_PIPE        2
 
917
#               define  RED_READ        4
 
918
#               define  RED_WRITE       8
 
919
#               define  RED_APPEND      16
 
920
#               define  RED_NOBUF       32
 
921
#               define  RED_USED        64      /* closed temporarily to reuse fd */
 
922
#               define  RED_EOF         128
 
923
#               define  RED_TWOWAY      256
 
924
#               define  RED_PTY         512
 
925
#               define  RED_SOCKET      1024
 
926
#               define  RED_TCP         2048
994
927
        char *value;
995
928
        FILE *ifp;      /* input fp, needed for PIPES_SIMULATED */
996
929
        IOBUF *iop;
1001
934
        const char *mode;
1002
935
        awk_output_buf_t output;
1003
936
};
1004
 
typedef enum redirect_flags redirect_flags_t;
1005
937
 
1006
938
/* values for BINMODE, used as bit flags */
1007
939
 
1008
940
enum binmode_values {
1009
 
        TEXT_TRANSLATE  = 0,    /* usual \r\n ---> \n translation */
1010
 
        BINMODE_INPUT   = 1,    /* no translation for input files */
1011
 
        BINMODE_OUTPUT  = 2,    /* no translation for output files */
1012
 
        BINMODE_BOTH    = 3     /* no translation for either */
 
941
        TEXT_TRANSLATE = 0,     /* usual \r\n ---> \n translation */
 
942
        BINMODE_INPUT = 1,      /* no translation for input files */
 
943
        BINMODE_OUTPUT = 2,     /* no translation for output files */
 
944
        BINMODE_BOTH = 3        /* no translation for either */
1013
945
};
1014
946
 
1015
947
/*
1038
970
        int fd;
1039
971
        int maxlen;     /* size of the longest line */
1040
972
 
1041
 
        void (*fini_func)();    /* dynamic extension of type SRC_EXTLIB */
 
973
        void (*fini_func)();    /* dynamic extension of type SRC_EXTLIB */ 
1042
974
 
1043
975
        char *lexptr;
1044
976
        char *lexend;
1045
977
        char *lexeme;
1046
978
        char *lexptr_begin;
1047
979
        int lasttok;
1048
 
        INSTRUCTION *comment;   /* comment on @load line */
1049
 
        const char *namespace;
1050
980
} SRCFILE;
1051
981
 
1052
 
// structure for INSTRUCTION pool, needed mainly for debugger
1053
 
typedef struct instruction_pool {
1054
 
#define MAX_INSTRUCTION_ALLOC   4       // we don't call bcalloc with more than this
1055
 
        struct instruction_mem_pool {
1056
 
                struct instruction_block *block_list;
1057
 
                INSTRUCTION *free_space;        // free location in active block
1058
 
                INSTRUCTION *free_list;
1059
 
        } pool[MAX_INSTRUCTION_ALLOC];
1060
 
} INSTRUCTION_POOL;
1061
 
 
1062
982
/* structure for execution context */
1063
983
typedef struct context {
1064
 
        INSTRUCTION_POOL pools;
 
984
        INSTRUCTION pools;
1065
985
        NODE symbols;
1066
986
        INSTRUCTION rule_list;
1067
987
        SRCFILE srcfiles;
1078
998
};
1079
999
 
1080
1000
 
1081
 
struct block_item {
1082
 
        struct block_item *freep;
1083
 
};
1084
 
 
1085
 
struct block_header {
1086
 
        struct block_item *freep;
 
1001
typedef struct block_item {
1087
1002
        size_t size;
1088
 
        const char *name;
1089
 
        long highwater;
1090
 
#ifdef MEMDEBUG
1091
 
        long active;
1092
 
#endif
1093
 
};
 
1003
        struct block_item *freep;
 
1004
} BLOCK;
1094
1005
 
1095
1006
enum block_id {
1096
 
        BLOCK_NODE = 0,
 
1007
        BLOCK_INVALID = 0,      /* not legal */
 
1008
        BLOCK_NODE,
1097
1009
        BLOCK_BUCKET,
1098
1010
        BLOCK_MAX       /* count */
1099
 
};
 
1011
};      
1100
1012
 
1101
1013
typedef int (*Func_pre_exec)(INSTRUCTION **);
1102
1014
typedef void (*Func_post_exec)(INSTRUCTION *);
1110
1022
#ifndef LONG_MIN
1111
1023
#define LONG_MIN ((long)(-LONG_MAX - 1L))
1112
1024
#endif
1113
 
#define UNLIMITED    LONG_MAX
 
1025
#define UNLIMITED    LONG_MAX 
1114
1026
 
1115
1027
/* -------------------------- External variables -------------------------- */
1116
1028
/* gawk builtin variables */
1118
1030
extern long NR;
1119
1031
extern long FNR;
1120
1032
extern int BINMODE;
1121
 
extern bool IGNORECASE;
 
1033
extern int IGNORECASE;
1122
1034
extern bool RS_is_null;
1123
1035
extern char *OFS;
1124
1036
extern int OFSlen;
1125
1037
extern char *ORS;
1126
1038
extern int ORSlen;
1127
1039
extern char *OFMT;
1128
 
extern const char *CONVFMT;
 
1040
extern char *CONVFMT;
1129
1041
extern int CONVFMTidx;
1130
1042
extern int OFMTidx;
1131
 
#ifdef HAVE_MPFR
1132
 
extern int MPFR_round_mode;
1133
 
#endif
1134
1043
extern char *TEXTDOMAIN;
1135
1044
extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
1136
1045
extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
1143
1052
extern NODE **fields_arr;
1144
1053
extern int sourceline;
1145
1054
extern char *source;
1146
 
extern int errcount;
1147
1055
extern int (*interpret)(INSTRUCTION *); /* interpreter routine */
1148
1056
extern NODE *(*make_number)(double);    /* double instead of AWKNUM on purpose */
1149
1057
extern NODE *(*str2number)(NODE *);
1151
1059
extern int (*cmp_numbers)(const NODE *, const NODE *);
1152
1060
 
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;
1157
 
 
1158
 
/* special node used to indicate success in array routines (not NULL) */
1159
 
extern NODE *success_node;
1160
 
 
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[];
 
1065
 
 
1066
extern BLOCK nextfree[];
1162
1067
extern bool field0_valid;
1163
1068
 
1164
 
extern bool do_itrace;  /* separate so can poke from a debugger */
 
1069
extern int do_flags;
1165
1070
 
1166
1071
extern SRCFILE *srcfiles; /* source files */
1167
1072
 
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 */
1187
 
} do_flags;
 
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 */
 
1089
};
1188
1090
 
1189
1091
#define do_traditional      (do_flags & DO_TRADITIONAL)
1190
1092
#define do_posix            (do_flags & DO_POSIX)
1198
1100
#define do_sandbox          (do_flags & DO_SANDBOX)
1199
1101
#define do_debug            (do_flags & DO_DEBUG)
1200
1102
#define do_mpfr             (do_flags & DO_MPFR)
1201
 
#define do_csv              (do_flags & DO_CSV)
1202
1103
 
1203
1104
extern bool do_optimize;
1204
1105
extern int use_lc_numeric;
1205
1106
extern int exit_val;
1206
 
extern bool using_persistent_malloc;
1207
1107
 
1208
1108
#ifdef NO_LINT
1209
1109
#define do_lint 0
1210
1110
#define do_lint_old 0
1211
 
#define do_lint_extensions 0
1212
1111
#else
1213
1112
#define do_lint             (do_flags & (DO_LINT_INVALID|DO_LINT_ALL))
1214
1113
#define do_lint_old         (do_flags & DO_LINT_OLD)
1215
 
#define do_lint_extensions  (do_flags & DO_LINT_EXTENSIONS)
1216
1114
#endif
 
1115
#if MBS_SUPPORT
1217
1116
extern int gawk_mb_cur_max;
 
1117
#else
 
1118
#define gawk_mb_cur_max (1)
 
1119
#endif
1218
1120
 
1219
1121
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
1220
1122
extern GETGROUPS_T *groupset;
1238
1140
extern const char *myname;
1239
1141
extern const char def_strftime_format[];
1240
1142
 
1241
 
extern const char quote;
1242
 
extern const char *defpath;
1243
 
extern const char *deflibpath;
1244
 
extern const char envsep;
 
1143
extern char quote;
 
1144
extern char *defpath;
 
1145
extern char *deflibpath;
 
1146
extern char envsep;
1245
1147
 
1246
1148
extern char casetable[];        /* for case-independent regexp matching */
1247
1149
 
1248
 
extern const char awk_namespace[];      /* "awk" */
1249
 
extern const char *current_namespace;
1250
 
extern bool namespace_changed;
1251
 
 
1252
1150
/* ------------------------- Runtime stack -------------------------------- */
1253
1151
 
1254
1152
typedef union stack_item {
1270
1168
#define POP_ADDRESS()           (decr_sp()->lptr)
1271
1169
#define PEEK(n)                 ((stack_ptr - (n))->rptr)
1272
1170
#define TOP()                   (stack_ptr->rptr)               /* same as PEEK(0) */
1273
 
#define TOP_ADDRESS()           (stack_ptr->lptr)
 
1171
#define TOP_ADDRESS()           (stack_ptr->lptr) 
1274
1172
#define PUSH(r)                 (void) (incr_sp()->rptr = (r))
1275
1173
#define PUSH_ADDRESS(l)         (void) (incr_sp()->lptr = (l))
1276
1174
#define REPLACE(r)              (void) (stack_ptr->rptr = (r))
1292
1190
static inline void
1293
1191
DEREF(NODE *r)
1294
1192
{
1295
 
        assert(r->valref > 0);
1296
 
#ifndef GAWKDEBUG
1297
 
        if (--r->valref > 0)
1298
 
                return;
1299
 
#endif
1300
 
        r_unref(r);
 
1193
        if (--r->valref == 0)
 
1194
                r_unref(r);
1301
1195
}
1302
1196
 
1303
1197
#define POP_NUMBER() force_number(POP_SCALAR())
1305
1199
 
1306
1200
/* ------------------------- Pseudo-functions ------------------------- */
1307
1201
#ifdef HAVE_MPFR
1308
 
 
1309
 
#if 0
1310
 
 
1311
 
/*
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.
1316
 
 */
1317
 
#define numtype_choose(n, mpfrval, mpzval, dblval)      \
1318
 
 (!do_mpfr ? (dblval) : (((n)->flags & MPFN) ? (mpfrval) : (mpzval)))
1319
 
 
1320
 
#endif
1321
 
 
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)))
1325
 
 
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)
1328
 
 
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)
1330
 
 
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)
1332
 
 
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)
1334
 
 
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)
 
1215
 
 
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))
1336
1219
 
1337
1220
#define IEEE_FMT(r, t)          (void) (do_ieee_fmt && format_ieee(r, t))
1338
1221
 
1350
1233
#define is_mpg_number(n)        0
1351
1234
#define is_mpg_float(n)         0
1352
1235
#define is_mpg_integer(n)       0
1353
 
#define is_zero(n)              ((n)->numbr == 0.0)
 
1236
#define iszero(n)               ((n)->numbr == 0.0)
1354
1237
#endif
1355
1238
 
1356
1239
#define var_uninitialized(n)    ((n)->var_value == Nnull_string)
1358
1241
#define get_lhs(n, r)    (n)->type == Node_var && ! var_uninitialized(n) ? \
1359
1242
                                &((n)->var_value) : r_get_lhs((n), (r))
1360
1243
 
1361
 
#ifdef MEMDEBUG
1362
 
 
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))
1367
 
 
1368
 
#else /* MEMDEBUG */
1369
 
 
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)
1375
 
 
1376
 
#endif /* MEMDEBUG */
 
1247
#define freeblock(p, id)         (void) (((BLOCK *) p)->freep = nextfree[id].freep, \
 
1248
                                        nextfree[id].freep = (BLOCK *) p)
1377
1249
 
1378
1250
#define getnode(n)      getblock(n, BLOCK_NODE, NODE *)
1379
1251
#define freenode(n)     freeblock(n, BLOCK_NODE)
1383
1255
 
1384
1256
#define make_string(s, l)       make_str_node((s), (l), 0)
1385
1257
 
1386
 
// Flags for making string nodes
1387
1258
#define         SCAN                    1
1388
1259
#define         ALREADY_MALLOCED        2
1389
1260
 
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", \
 
1262
                                __LINE__, __FILE__)
1392
1263
 
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)))
1397
 
#else
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__))
1401
 
#endif
 
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))) \
 
1268
                                ||\
 
1269
                                 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
 
1270
                                        (str), #var, (long) (x), strerror(errno)),0))
1402
1271
 
1403
1272
#define efree(p)        free(p)
1404
1273
 
1405
 
#define fatal           (*(set_loc(__FILE__, __LINE__), r_fatal))
 
1274
static inline NODE *
 
1275
force_string(NODE *s)
 
1276
{
 
1277
        if ((s->flags & STRCUR) != 0
 
1278
                    && (s->stfmt == -1 || s->stfmt == CONVFMTidx)
 
1279
        )
 
1280
                return s;
 
1281
        return format_val(CONVFMT, CONVFMTidx, s);
 
1282
}
 
1283
 
 
1284
#ifdef GAWKDEBUG
 
1285
#define unref   r_unref
 
1286
#define force_number    str2number
 
1287
#else /* not GAWKDEBUG */
 
1288
 
 
1289
static inline void
 
1290
unref(NODE *r)
 
1291
{
 
1292
        if (r != NULL && --r->valref <= 0)
 
1293
                r_unref(r);
 
1294
}
 
1295
 
 
1296
static inline NODE *
 
1297
force_number(NODE *n)
 
1298
{
 
1299
        return (n->flags & NUMCUR) ? n : str2number(n);
 
1300
}
 
1301
 
 
1302
#endif /* GAWKDEBUG */
 
1303
 
 
1304
#define fatal           set_loc(__FILE__, __LINE__), r_fatal
1406
1305
 
1407
1306
extern jmp_buf fatal_tag;
1408
 
extern int fatal_tag_valid;
1409
 
 
1410
 
#define assoc_length(a) ((a)->table_size)
 
1307
extern bool fatal_tag_valid;
 
1308
 
 
1309
#define PUSH_BINDING(stack, tag, val)   \
 
1310
if (val++) \
 
1311
        memcpy((char *) (stack), (const char *) tag, sizeof(jmp_buf))
 
1312
#define POP_BINDING(stack, tag, val)    \
 
1313
if (--val) \
 
1314
        memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
 
1315
 
 
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))
1413
1319
 
1417
1323
/* assoc_remove --- remove an index from symbol[] */
1418
1324
#define assoc_remove(a, s) ((a)->aremove(a, s) != NULL)
1419
1325
 
1420
 
 
1421
1326
/* ------------- Function prototypes or defs (as appropriate) ------------- */
1422
1327
/* array.c */
1423
1328
typedef enum { SORTED_IN = 1, ASORT, ASORTI } sort_context_t;
1424
1329
typedef enum {
1425
 
        ANONE   = 0x00,         /* "unused" value */
1426
 
        AINDEX  = 0x001,        /* list of indices */
 
1330
        AINDEX  = 0x001,        /* list of indices */ 
1427
1331
        AVALUE  = 0x002,        /* list of values */
1428
1332
        AINUM   = 0x004,        /* numeric index */
1429
1333
        AISTR   = 0x008,        /* string index */
1440
1344
extern const char *make_aname(const NODE *symbol);
1441
1345
extern const char *array_vname(const NODE *symbol);
1442
1346
extern void array_init(void);
 
1347
extern int register_array_func(afunc_t *afunc);
 
1348
extern NODE **null_length(NODE *symbol, NODE *subs);
1443
1349
extern NODE **null_afunc(NODE *symbol, NODE *subs);
1444
1350
extern void set_SUBSEP(void);
1445
1351
extern NODE *concat_exp(int nargs, bool do_subsep);
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);
1513
1404
extern NODE *do_srand(int nargs);
1514
1405
extern NODE *do_match(int nargs);
1515
1406
extern NODE *do_sub(int nargs, unsigned int flags);
1516
 
extern NODE *call_sub(const char *name, int nargs);
1517
 
extern NODE *call_match(int nargs);
1518
 
extern NODE *call_split_func(const char *name, int nargs);
1519
 
extern NODE *format_args(const char *, size_t, NODE **, long);
 
1407
extern NODE *format_tree(const char *, size_t, NODE **, long);
1520
1408
extern NODE *do_lshift(int nargs);
1521
1409
extern NODE *do_rshift(int nargs);
1522
1410
extern NODE *do_and(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);
 
1419
#if MBS_SUPPORT
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);
1540
 
/* debug.c */
1541
 
extern void init_debug(void);
1542
 
extern int debug_prog(INSTRUCTION *pc);
 
1422
#endif
1543
1423
/* eval.c */
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);
1577
1455
/* ext.c */
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);
1582
1460
#ifdef DYNAMIC
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)
1588
1467
#endif
1589
1468
/* field.c */
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);
1606
1483
typedef enum {
1607
1484
        Using_FS,
1608
1485
        Using_FIELDWIDTHS,
1609
 
        Using_FPAT,
1610
 
        Using_API
 
1486
        Using_FPAT
1611
1487
} field_sep_type;
1612
1488
extern field_sep_type current_field_sep(void);
1613
 
extern const char *current_field_sep_str(void);
1614
 
 
1615
 
typedef enum {
1616
 
        SCALAR_EQ,
1617
 
        SCALAR_NEQ,
1618
 
        SCALAR_LT,
1619
 
        SCALAR_LE,
1620
 
        SCALAR_GT,
1621
 
        SCALAR_GE,
1622
 
} scalar_cmp_t;
1623
1489
 
1624
1490
/* gawkapi.c: */
1625
1491
extern gawk_api_t api_impl;
1628
1494
extern NODE *awk_value_to_node(const awk_value_t *);
1629
1495
extern void run_ext_exit_handlers(int exitval);
1630
1496
extern void print_ext_versions(void);
1631
 
extern void free_api_string_copies(void);
1632
1497
 
1633
1498
/* gawkmisc.c */
1634
 
extern const char *gawk_name(const char *filespec);
 
1499
extern char *gawk_name(const char *filespec);
1635
1500
extern void os_arg_fixup(int *argcp, char ***argvp);
1636
1501
extern int os_devopen(const char *name, int flag);
1637
1502
extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir);
1641
1506
extern int os_is_setuid(void);
1642
1507
extern int os_setbinmode(int fd, int mode);
1643
1508
extern void os_restore_mode(int fd);
1644
 
extern void os_maybe_set_errno(void);
1645
1509
extern size_t optimal_bufsize(int fd, struct stat *sbuf);
1646
1510
extern int ispath(const char *file);
1647
1511
extern int isdirpunct(int c);
1649
1513
/* io.c */
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);
1658
1521
 
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);
1683
 
#endif
1684
 
 
1685
1534
/* main.c */
1686
1535
extern int arg_assign(char *arg, bool initing);
1687
1536
extern int is_std_var(const char *var);
1689
1538
extern char *estrdup(const char *str, size_t len);
1690
1539
extern void update_global_values();
1691
1540
extern long getenv_long(const char *name);
1692
 
extern void after_beginfile(IOBUF **curfile);
1693
 
extern void set_current_namespace(const char *new_namespace);
1694
1541
 
1695
1542
/* mpfr.c */
1696
1543
extern void set_PREC(void);
1707
1554
extern NODE *do_mpfr_cos(int);
1708
1555
extern NODE *do_mpfr_exp(int);
1709
1556
extern NODE *do_mpfr_int(int);
1710
 
extern NODE *do_mpfr_intdiv(int);
1711
1557
extern NODE *do_mpfr_log(int);
1712
1558
extern NODE *do_mpfr_lshift(int);
1713
1559
extern NODE *do_mpfr_or(int);
1719
1565
extern NODE *do_mpfr_strtonum(int);
1720
1566
extern NODE *do_mpfr_xor(int);
1721
1567
extern void init_mpfr(mpfr_prec_t, const char *);
1722
 
extern void cleanup_mpfr(void);
1723
1568
extern NODE *mpg_node(unsigned int);
1724
1569
extern const char *mpg_fmt(const char *, ...);
1725
1570
extern int mpg_strtoui(mpz_ptr, char *, size_t, char **, int);
1726
 
extern void mpg_zero(NODE *n);
1727
 
extern void *mpfr_mem_alloc(size_t alloc_size);
1728
 
extern void *mpfr_mem_realloc(void *ptr, size_t old_size, size_t new_size);
1729
 
extern void mpfr_mem_free(void *ptr, size_t size);
1730
1571
#endif
1731
1572
/* msg.c */
1732
1573
extern void gawk_exit(int status);
1757
1598
extern NODE *r_format_val(const char *format, int index, NODE *s);
1758
1599
extern NODE *r_dupnode(NODE *n);
1759
1600
extern NODE *make_str_node(const char *s, size_t len, int flags);
1760
 
extern NODE *make_bool_node(bool value);
1761
 
extern NODE *make_typed_regex(const char *re, size_t len);
1762
1601
extern void *more_blocks(int id);
1763
 
extern enum escape_results parse_escape(const char **string_ptr, const char **escseq, size_t *nbytes);
 
1602
extern int parse_escape(const char **string_ptr);
 
1603
#if MBS_SUPPORT
1764
1604
extern NODE *str2wstr(NODE *n, size_t **ptr);
1765
1605
extern NODE *wstr2str(NODE *n);
1766
1606
#define force_wstring(n)        str2wstr(n, NULL)
1774
1614
#define btowc_cache(x) btowc_cache[(x)&0xFF]
1775
1615
extern void init_btowc_cache();
1776
1616
#define is_valid_character(b)   (btowc_cache[(b)&0xFF] != WEOF)
1777
 
extern bool out_of_range(NODE *n);
1778
 
extern char *format_nan_inf(NODE *n, char format);
1779
 
extern bool is_ieee_magic_val(const char *val);
 
1617
#else
 
1618
#define free_wstr(NODE) /* empty */
 
1619
#endif
1780
1620
/* re.c */
1781
1621
extern Regexp *make_regexp(const char *s, size_t len, bool ignorecase, bool dfa, bool canfatal);
1782
1622
extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
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);
1791
1631
 
1792
1632
/* symbol.c */
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);
1815
1655
extern NODE **variable_list();
1816
1656
extern NODE **function_list(bool sort);
1817
1657
extern void print_vars(NODE **table, Func_print print_func, FILE *fp);
1818
 
extern bool check_param_names(void);
1819
 
extern bool is_all_upper(const char *name);
1820
 
extern void pma_mpfr_check(void);
1821
 
extern void pma_save_free_lists(void);
1822
1658
 
1823
1659
/* floatcomp.c */
1824
1660
#ifdef HAVE_UINTMAX_T
1838
1674
#endif /* ! defined(VMS)) */
1839
1675
#endif /* WEXITSTATUS */
1840
1676
 
1841
 
/* For z/OS, from Dave Pitts. EXIT_FAILURE is normally 8, make it 1. */
1842
 
#if defined(EXIT_FAILURE) && EXIT_FAILURE == 8
1843
 
# undef EXIT_FAILURE
1844
 
#endif
1845
 
 
1846
1677
/* EXIT_SUCCESS and EXIT_FAILURE normally come from <stdlib.h> */
1847
1678
#ifndef EXIT_SUCCESS
1848
1679
# define EXIT_SUCCESS 0
1855
1686
# define EXIT_FATAL   2
1856
1687
#endif
1857
1688
 
 
1689
/* For z/OS, from Dave Pitts. EXIT_FAILURE is normally 8, make it 1. */
 
1690
#ifdef ZOS_USS
 
1691
 
 
1692
#ifdef EXIT_FAILURE
 
1693
#undef EXIT_FAILURE
 
1694
#endif
 
1695
 
 
1696
#define EXIT_FAILURE 1
 
1697
#endif
 
1698
 
1858
1699
/* ------------------ Inline Functions ------------------ */
1859
1700
 
1860
1701
/*
1868
1709
/* POP_ARRAY --- get the array at the top of the stack */
1869
1710
 
1870
1711
static inline NODE *
1871
 
POP_ARRAY(bool check_for_untyped)
 
1712
POP_ARRAY()
1872
1713
{
1873
1714
        NODE *t = POP();
1874
 
        static bool warned = false;
1875
 
 
1876
 
        if (do_lint && ! warned && check_for_untyped
1877
 
            && (t->type == Node_var_new || t->type == Node_elem_new)) {
1878
 
                warned = true;
1879
 
                lintwarn(_("behavior of `for' loop on untyped variable is not defined by POSIX"));
1880
 
        }
1881
1715
 
1882
1716
        return (t->type == Node_var_array) ? t : force_array(t, true);
1883
1717
}
1901
1735
 
1902
1736
        if (t->type == Node_var_array)
1903
1737
                fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
1904
 
        else if (t->type == Node_elem_new)
1905
 
                t = elem_new_to_scalar(t);
1906
 
 
 
1738
        
1907
1739
        return t;
1908
1740
}
1909
1741
 
1916
1748
 
1917
1749
        if (t->type == Node_var_array)
1918
1750
                fatal(_("attempt to use array `%s' in a scalar context"), array_vname(t));
1919
 
        else if (t->type == Node_elem_new) {
1920
 
                t = elem_new_to_scalar(t);      // fix it up
1921
 
                REPLACE(t);                     // put it back on the stack
1922
 
        }
1923
 
 
 
1751
        
1924
1752
        return t;
1925
1753
}
1926
1754
 
1938
1766
        NODE **ret;
1939
1767
 
1940
1768
        ret = a->aexists(a, s);
1941
 
 
 
1769
        
1942
1770
        return ret ? *ret : NULL;
1943
1771
}
1944
1772
 
1957
1785
        return r_dupnode(n);
1958
1786
}
1959
1787
#endif
1960
 
 
1961
 
/*
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
1967
 
 * not change.
1968
 
 *
1969
 
 * Additional twist: If ROUNDMODE changed at some point we have to
1970
 
 * recompute also.
1971
 
 */
1972
 
 
1973
 
static inline NODE *
1974
 
force_string_fmt(NODE *s, const char *fmtstr, int fmtidx)
1975
 
{
1976
 
        if (s->type == Node_elem_new) {
1977
 
                s->type = Node_val;
1978
 
 
1979
 
                return s;
1980
 
        }
1981
 
 
1982
 
        if ((s->flags & STRCUR) != 0
1983
 
                && (s->stfmt == STFMT_UNUSED || (s->stfmt == fmtidx
1984
 
#ifdef HAVE_MPFR
1985
 
                                                && s->strndmode == MPFR_round_mode
1986
 
#endif
1987
 
                                )))
1988
 
                return s;
1989
 
        return format_val(fmtstr, fmtidx, s);
1990
 
}
1991
 
 
1992
 
/* conceptually should be force_string_convfmt, but this is the typical case */
1993
 
#define force_string(s)         force_string_fmt((s), CONVFMT, CONVFMTidx)
1994
 
 
1995
 
#define force_string_ofmt(s)    force_string_fmt((s), OFMT, OFMTidx)
1996
 
 
1997
 
#ifdef GAWKDEBUG
1998
 
#define unref   r_unref
1999
 
#define force_number    str2number
2000
 
#else /* not GAWKDEBUG */
2001
 
 
2002
 
/* unref --- decrease the reference count and/or free a node */
2003
 
 
2004
 
static inline void
2005
 
unref(NODE *r)
2006
 
{
2007
 
        assert(r == NULL || r->valref > 0);
2008
 
        if (r != NULL && --r->valref <= 0)
2009
 
                r_unref(r);
2010
 
}
2011
 
 
2012
 
/* force_number --- force a  node to have a numeric value */
2013
 
 
2014
 
static inline NODE *
2015
 
force_number(NODE *n)
2016
 
{
2017
 
        if (n->type == Node_elem_new) {
2018
 
                n->type = Node_val;
2019
 
 
2020
 
                return n;
2021
 
        }
2022
 
        return (n->flags & NUMCUR) != 0 ? n : str2number(n);
2023
 
}
2024
 
 
2025
 
#endif /* GAWKDEBUG */
2026
 
 
2027
 
 
2028
 
/* fixtype --- make a node decide if it's a number or a string */
2029
 
 
2030
 
/*
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.
2034
 
 *
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.
2038
 
 */
2039
 
 
2040
 
static inline NODE *
2041
 
fixtype(NODE *n)
2042
 
{
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);
2048
 
        return n;
2049
 
}
2050
 
 
2051
 
/* boolval --- return true/false based on awk's criteria */
2052
 
 
2053
 
/*
2054
 
 * In awk, a value is considered to be true if it is nonzero _or_
2055
 
 * non-null. Otherwise, the value is false.
2056
 
 */
2057
 
 
2058
 
static inline bool
2059
 
boolval(NODE *t)
2060
 
{
2061
 
        if (t->type == Node_var)        // could have come from converted Node_elem_new
2062
 
                t = t->var_value;
2063
 
 
2064
 
        (void) fixtype(t);
2065
 
        if ((t->flags & NUMBER) != 0)
2066
 
                return ! is_zero(t);
2067
 
        return (t->stlen > 0);
2068
 
}
2069
 
 
2070
 
/* emalloc_real --- malloc with error checking */
2071
 
 
2072
 
static inline void *
2073
 
emalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
2074
 
{
2075
 
        void *ret;
2076
 
 
2077
 
        if (count == 0)
2078
 
                fatal("%s:%d: emalloc called with zero bytes", file, line);
2079
 
 
2080
 
        ret = (void *) malloc(count);
2081
 
        if (ret == NULL)
2082
 
                fatal(_("%s:%d:%s: %s: cannot allocate %ld bytes of memory: %s"),
2083
 
                        file, line, where, var, (long) count, strerror(errno));
2084
 
 
2085
 
        return ret;
2086
 
}
2087
 
 
2088
 
/* ezalloc_real --- malloc zero-filled bytes with error checking */
2089
 
 
2090
 
static inline void *
2091
 
ezalloc_real(size_t count, const char *where, const char *var, const char *file, int line)
2092
 
{
2093
 
        void *ret;
2094
 
 
2095
 
        if (count == 0)
2096
 
                fatal("%s:%d: ezalloc called with zero bytes", file, line);
2097
 
 
2098
 
        ret = (void *) calloc(1, count);
2099
 
        if (ret == NULL)
2100
 
                fatal(_("%s:%d:%s: %s: cannot allocate %ld bytes of memory: %s"),
2101
 
                        file, line, where, var, (long) count, strerror(errno));
2102
 
 
2103
 
        return ret;
2104
 
}
2105
 
 
2106
 
/* erealloc_real --- realloc with error checking */
2107
 
 
2108
 
static inline void *
2109
 
erealloc_real(void *ptr, size_t count, const char *where, const char *var, const char *file, int line)
2110
 
{
2111
 
        void *ret;
2112
 
 
2113
 
        if (count == 0)
2114
 
                fatal("%s:%d: erealloc called with zero bytes", file, line);
2115
 
 
2116
 
        ret = (void *) realloc(ptr, count);
2117
 
        if (ret == NULL)
2118
 
                fatal(_("%s:%d:%s: %s: cannot reallocate %ld bytes of memory: %s"),
2119
 
                        file, line, where, var, (long) count, strerror(errno));
2120
 
 
2121
 
        return ret;
2122
 
}
2123
 
 
2124
 
/* make_number_node --- make node with the given flags */
2125
 
 
2126
 
static inline NODE *
2127
 
make_number_node(unsigned int flags)
2128
 
{
2129
 
        NODE *r;
2130
 
        getnode(r);
2131
 
        memset(r, 0, sizeof(*r));
2132
 
        r->type = Node_val;
2133
 
        r->valref = 1;
2134
 
        r->flags = (flags|MALLOC|NUMBER|NUMCUR);
2135
 
        return r;
2136
 
}
2137
 
 
2138
 
/* assoc_set -- set an element in an array. Does unref(sub)! */
2139
 
 
2140
 
static inline void
2141
 
assoc_set(NODE *array, NODE *sub, NODE *value)
2142
 
{
2143
 
 
2144
 
        NODE **lhs = assoc_lookup(array, sub);
2145
 
        unref(*lhs);
2146
 
        *lhs = value;
2147
 
        if (array->astore != NULL)
2148
 
                (*array->astore)(array, sub);
2149
 
        unref(sub);
2150
 
}
2151
 
 
2152
 
/*
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.
2156
 
 */
2157
 
 
2158
 
static inline void
2159
 
str_terminate_f(NODE *n, char *savep)
2160
 
{
2161
 
        *savep = n->stptr[n->stlen];
2162
 
        n->stptr[n->stlen] = '\0';
2163
 
}
2164
 
 
2165
 
#define str_terminate(n, save) str_terminate_f((n), &save)
2166
 
#define str_restore(n, save) (n)->stptr[(n)->stlen] = save
2167
 
 
2168
 
#ifdef SIGPIPE
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))
2172
 
#else
2173
 
#define ignore_sigpipe()
2174
 
#define set_sigpipe_to_default()
2175
 
#ifdef __MINGW32__
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__ */
2181
 
#endif