source: vendor/gawk/3.1.5/awk.h@ 3513

Last change on this file since 3513 was 3076, checked in by bird, 18 years ago

gawk 3.1.5

File size: 37.0 KB
Line 
1/*
2 * awk.h -- Definitions for gawk.
3 */
4
5/*
6 * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
7 *
8 * This file is part of GAWK, the GNU implementation of the
9 * AWK Programming Language.
10 *
11 * GAWK is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * GAWK is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26/* ------------------------------ Includes ------------------------------ */
27
28/*
29 * config.h absolutely, positively, *M*U*S*T* be included before
30 * any system headers. Otherwise, extreme death, destruction
31 * and loss of life results.
32 *
33 * Well, OK, gawk just won't work on systems using egcs and LFS. But
34 * that's almost as bad.
35 */
36#ifdef HAVE_CONFIG_H
37#include <config.h>
38#endif
39
40#ifndef _GNU_SOURCE
41#define _GNU_SOURCE 1 /* enable GNU extensions */
42#endif /* _GNU_SOURCE */
43
44#include <stdio.h>
45#include <assert.h>
46#ifdef HAVE_LIMITS_H
47#include <limits.h>
48#endif /* HAVE_LIMITS_H */
49#include <ctype.h>
50#include <setjmp.h>
51
52#include "gettext.h"
53#define _(msgid) gettext(msgid)
54#define N_(msgid) msgid
55
56#if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0)
57#ifndef LOCALEDIR
58#define LOCALEDIR NULL
59#endif /* LOCALEDIR */
60#endif
61
62#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
63#include <stdarg.h>
64#else
65#include <varargs.h>
66#endif
67#include <signal.h>
68#include <time.h>
69#include <errno.h>
70#if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
71extern int errno;
72#endif
73#ifdef HAVE_SIGNUM_H
74#include <signum.h>
75#endif
76
77#ifndef NO_MBSUPPORT
78#include "mbsupport.h" /* defines MBS_SUPPORT */
79#endif
80
81#if defined(MBS_SUPPORT)
82/* We can handle multibyte strings. */
83#include <wchar.h>
84#include <wctype.h>
85#endif
86
87#ifdef STDC_HEADERS
88#include <float.h>
89#endif
90
91/* ----------------- System dependencies (with more includes) -----------*/
92
93/* This section is the messiest one in the file, not a lot that can be done */
94
95/* First, get the ctype stuff right; from Jim Meyering */
96#if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
97#define IN_CTYPE_DOMAIN(c) 1
98#else
99#define IN_CTYPE_DOMAIN(c) isascii((unsigned char) c)
100#endif
101
102#ifdef isblank
103#define ISBLANK(c) (IN_CTYPE_DOMAIN(c) && isblank((unsigned char) c))
104#else
105#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
106#endif
107#ifdef isgraph
108#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isgraph((unsigned char) c))
109#else
110#define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isprint((unsigned char) c) && !isspace((unsigned char) c))
111#endif
112
113#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char) c))
114#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char) c))
115#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char) c))
116#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char) c))
117#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char) c))
118#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char) c))
119#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (unsigned char) (c))
120#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char) c))
121#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char) c))
122#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char) c))
123
124#ifndef TOUPPER
125#define TOUPPER(c) toupper((unsigned char) c)
126#endif
127#ifndef TOLOWER
128#define TOLOWER(c) tolower((unsigned char) c)
129#endif
130
131#ifdef __STDC__
132#define P(s) s
133#define MALLOC_ARG_T size_t
134#else /* not __STDC__ */
135#define P(s) ()
136#define MALLOC_ARG_T unsigned
137#define volatile
138#endif /* not __STDC__ */
139
140#ifndef VMS
141#include <sys/types.h>
142#include <sys/stat.h>
143#else /* VMS */
144#include <stddef.h>
145#include <stat.h>
146#include <file.h> /* avoid <fcntl.h> in io.c */
147#endif /* VMS */
148
149#if ! defined(S_ISREG) && defined(S_IFREG)
150#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
151#endif
152
153#ifdef STDC_HEADERS
154#include <stdlib.h>
155#else /* not STDC_HEADERS */
156#include "protos.h"
157#endif /* not STDC_HEADERS */
158
159#ifdef HAVE_STRING_H
160#include <string.h>
161#ifdef NEED_MEMORY_H
162#include <memory.h>
163#endif /* NEED_MEMORY_H */
164#else /* not HAVE_STRING_H */
165#ifdef HAVE_STRINGS_H
166#include <strings.h>
167#endif /* HAVE_STRINGS_H */
168#endif /* not HAVE_STRING_H */
169
170#ifdef NeXT
171#if __GNUC__ < 2 || __GNUC_MINOR__ < 7
172#include <libc.h>
173#endif
174#undef atof
175#define getopt GNU_getopt
176#define GFMT_WORKAROUND
177#endif /* NeXT */
178
179#if defined(atarist) || defined(VMS)
180#include <unixlib.h>
181#endif /* atarist || VMS */
182
183#if ! defined(MSDOS) && ! defined(OS2) && ! defined(WIN32) && ! defined(__EMX__) && ! defined(__CYGWIN__) && ! defined(O_BINARY) /*duh*/
184#define O_BINARY 0
185#endif
186
187#if defined(TANDEM)
188#define variable variabl
189#define open(name, how, mode) open(name, how) /* !!! ANSI C !!! */
190#endif
191
192#if HAVE_UNISTD_H
193#include <unistd.h>
194#endif /* HAVE_UNISTD_H */
195
196#ifndef HAVE_VPRINTF
197/* if you don't have vprintf, try this and cross your fingers. */
198#ifdef HAVE_DOPRNT
199#define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
200#else /* not HAVE_DOPRNT */
201you
202lose
203#endif /* not HAVE_DOPRNT */
204#endif /* HAVE_VPRINTF */
205
206#ifndef HAVE_SETLOCALE
207#define setlocale(locale, val) /* nothing */
208#endif /* HAVE_SETLOCALE */
209
210/* use this as lintwarn("...")
211 this is a hack but it gives us the right semantics */
212#define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
213
214#ifdef VMS
215#include "vms/redirect.h"
216#endif /*VMS*/
217
218#ifdef atarist
219#include "unsupported/atari/redirect.h"
220#endif
221
222#define GNU_REGEX
223#ifdef GNU_REGEX
224#include "regex.h"
225#include "dfa.h"
226typedef struct Regexp {
227 struct re_pattern_buffer pat;
228 struct re_registers regs;
229 struct dfa dfareg;
230 short dfa;
231 short has_anchor; /* speed up of avoid_dfa kludge, temporary */
232} Regexp;
233#define RESTART(rp,s) (rp)->regs.start[0]
234#define REEND(rp,s) (rp)->regs.end[0]
235#define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
236#define SUBPATEND(rp,s,n) (rp)->regs.end[n]
237#define NUMSUBPATS(rp,s) (rp)->regs.num_regs
238#endif /* GNU_REGEX */
239/* regexp matching flags: */
240#define RE_NEED_START 1 /* need to know start/end of match */
241#define RE_NO_BOL 2 /* for RS, not allowed to match ^ in regexp */
242
243/* Stuff for losing systems. */
244#ifdef STRTOD_NOT_C89
245extern double gawk_strtod();
246#define strtod gawk_strtod
247#endif
248
249#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
250# define __attribute__(x)
251#endif
252
253#ifndef ATTRIBUTE_UNUSED
254#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
255#endif /* ATTRIBUTE_UNUSED */
256
257#ifndef ATTRIBUTE_NORETURN
258#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
259#endif /* ATTRIBUTE_NORETURN */
260
261#ifndef ATTRIBUTE_PRINTF
262#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
263#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
264#endif /* ATTRIBUTE_PRINTF */
265
266/* We use __extension__ in some places to suppress -pedantic warnings
267 about GCC extensions. This feature didn't work properly before
268 gcc 2.8. */
269#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
270#define __extension__
271#endif
272
273/* this is defined by Windows32 extension libraries. It must be added to
274 * every variable which is exported (including function pointers) */
275#if defined(WIN32_EXTENSION) && !defined(ATTRIBUTE_EXPORTED)
276# define ATTRIBUTE_EXPORTED __declspec(dllimport)
277#else
278# define ATTRIBUTE_EXPORTED
279#endif
280
281
282/* ------------------ Constants, Structures, Typedefs ------------------ */
283
284#if 0
285/* This isn't right. Figure it out the right way for the next release */
286#ifndef AWKNUM
287#ifdef LDBL_MANT_DIG
288#define AWKNUM long double
289#else
290#endif
291#endif
292#endif
293
294#define AWKNUM double
295
296#ifndef TRUE
297/* a bit hackneyed, but what the heck */
298#define TRUE 1
299#define FALSE 0
300#endif
301
302#define LINT_INVALID 1 /* only warn about invalid */
303#define LINT_ALL 2 /* warn about all things */
304
305/* Figure out what '\a' really is. */
306#ifdef __STDC__
307#define BELL '\a' /* sure makes life easy, don't it? */
308#else
309# if 'z' - 'a' == 25 /* ascii */
310# if 'a' != 97 /* machine is dumb enough to use mark parity */
311# define BELL '\207'
312# else
313# define BELL '\07'
314# endif
315# else
316# define BELL '\057'
317# endif
318#endif
319
320typedef enum nodevals {
321 /* illegal entry == 0 */
322 Node_illegal,
323
324 /* binary operators lnode and rnode are the expressions to work on */
325 Node_times,
326 Node_quotient,
327 Node_mod,
328 Node_plus,
329 Node_minus,
330 Node_cond_pair, /* conditional pair (see Node_line_range) */
331 Node_subscript,
332 Node_concat,
333 Node_exp,
334
335 /* unary operators subnode is the expression to work on */
336 Node_preincrement,
337 Node_predecrement,
338 Node_postincrement,
339 Node_postdecrement,
340 Node_unary_minus,
341 Node_field_spec,
342
343 /* assignments lnode is the var to assign to, rnode is the exp */
344 Node_assign,
345 Node_assign_times,
346 Node_assign_quotient,
347 Node_assign_mod,
348 Node_assign_plus,
349 Node_assign_minus,
350 Node_assign_exp,
351 Node_assign_concat,
352
353 /* boolean binaries lnode and rnode are expressions */
354 Node_and,
355 Node_or,
356
357 /* binary relationals compares lnode and rnode */
358 Node_equal,
359 Node_notequal,
360 Node_less,
361 Node_greater,
362 Node_leq,
363 Node_geq,
364 Node_match,
365 Node_nomatch,
366
367 /* unary relationals works on subnode */
368 Node_not,
369
370 /* program structures */
371 Node_rule_list, /* lnode is a rule, rnode is rest of list */
372 Node_rule_node, /* lnode is pattern, rnode is statement */
373 Node_statement_list, /* lnode is statement, rnode is more list */
374 Node_switch_body, /* lnode is the case list, rnode is default list */
375 Node_case_list, /* lnode is the case, rnode is a statement list */
376 Node_if_branches, /* lnode is to run on true, rnode on false */
377 Node_expression_list, /* lnode is an exp, rnode is more list */
378 Node_param_list, /* lnode is a variable, rnode is more list */
379
380 /* keywords */
381 Node_K_if, /* lnode is conditonal, rnode is if_branches */
382 Node_K_switch, /* lnode is switch value, rnode is body of case statements */
383 Node_K_case, /* lnode is case value, rnode is stuff to run */
384 Node_K_default, /* lnode is empty, rnode is stuff to run */
385 Node_K_while, /* lnode is condtional, rnode is stuff to run */
386 Node_K_for, /* lnode is for_struct, rnode is stuff to run */
387 Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
388 Node_K_break, /* no subs */
389 Node_K_continue, /* no subs */
390 Node_K_print, /* lnode is exp_list, rnode is redirect */
391 Node_K_print_rec, /* lnode is NULL, rnode is redirect */
392 Node_K_printf, /* lnode is exp_list, rnode is redirect */
393 Node_K_next, /* no subs */
394 Node_K_exit, /* subnode is return value, or NULL */
395 Node_K_do, /* lnode is conditional, rnode stuff to run */
396 Node_K_return, /* lnode is return value */
397 Node_K_delete, /* lnode is array, rnode is subscript */
398 Node_K_delete_loop, /* lnode is array, rnode is subscript */
399 Node_K_getline, /* lnode is opt var, rnode is redirection */
400 Node_K_function, /* lnode is statement list, rnode is params */
401 Node_K_nextfile, /* no subs */
402
403 /* I/O redirection for print statements */
404 Node_redirect_output, /* subnode is where to redirect */
405 Node_redirect_append, /* subnode is where to redirect */
406 Node_redirect_pipe, /* subnode is where to redirect */
407 Node_redirect_pipein, /* subnode is where to redirect */
408 Node_redirect_input, /* subnode is where to redirect */
409 Node_redirect_twoway, /* subnode is where to redirect */
410
411 /* Variables */
412 Node_var_new, /* newly created variable, may become an array */
413 Node_var, /* scalar variable, lnode is value */
414 Node_var_array, /* array is ptr to elements, table_size num of eles */
415 Node_val, /* node is a value - type in flags */
416
417 /* Builtins subnode is explist to work on, builtin is func to call */
418 Node_builtin,
419
420 /*
421 * pattern: conditional ',' conditional ; lnode of Node_line_range
422 * is the two conditionals (Node_cond_pair), other word (rnode place)
423 * is a flag indicating whether or not this range has been entered.
424 */
425 Node_line_range,
426
427 /*
428 * boolean test of membership in array
429 * lnode is string-valued, expression rnode is array name
430 */
431 Node_in_array,
432
433 Node_func, /* lnode is param. list, rnode is body */
434 Node_func_call, /* lnode is name, rnode is argument list */
435
436 Node_cond_exp, /* lnode is conditonal, rnode is if_branches */
437 Node_regex, /* a regexp, text, compiled, flags, etc */
438 Node_dynregex, /* a dynamic regexp */
439 Node_hashnode, /* an identifier in the symbol table */
440 Node_ahash, /* an array element */
441 Node_array_ref, /* array passed by ref as parameter */
442
443 Node_BINMODE, /* variables recognized in the grammar */
444 Node_CONVFMT,
445 Node_FIELDWIDTHS,
446 Node_FNR,
447 Node_FS,
448 Node_IGNORECASE,
449 Node_LINT,
450 Node_NF,
451 Node_NR,
452 Node_OFMT,
453 Node_OFS,
454 Node_ORS,
455 Node_RS,
456 Node_TEXTDOMAIN,
457 Node_SUBSEP,
458 Node_final /* sentry value, not legal */
459} NODETYPE;
460
461/*
462 * NOTE - this struct is a rather kludgey -- it is packed to minimize
463 * space usage, at the expense of cleanliness. Alter at own risk.
464 */
465typedef struct exp_node {
466 union {
467 struct {
468 union {
469 struct exp_node *lptr;
470 char *param_name;
471 long ll;
472 } l;
473 union {
474 struct exp_node *rptr;
475 struct exp_node *(*pptr) P((struct exp_node *));
476 Regexp *preg;
477 struct for_loop_header *hd;
478 struct exp_node **av;
479 int r_ent; /* range entered */
480 } r;
481 union {
482 struct exp_node *extra;
483 long xl;
484 char **param_list;
485 } x;
486 char *name;
487 short number;
488 unsigned long reflags;
489# define CASE 1
490# define CONST 2
491# define FS_DFLT 4
492 } nodep;
493 struct {
494 AWKNUM fltnum; /* this is here for optimal packing of
495 * the structure on many machines
496 */
497 char *sp;
498 size_t slen;
499 long sref;
500 int idx;
501#ifdef MBS_SUPPORT
502 wchar_t *wsp;
503 size_t wslen;
504#endif
505 } val;
506 struct {
507 struct exp_node *next;
508 char *name;
509 size_t length;
510 struct exp_node *value;
511 long ref;
512 } hash;
513#define hnext sub.hash.next
514#define hname sub.hash.name
515#define hlength sub.hash.length
516#define hvalue sub.hash.value
517
518#define ahnext sub.hash.next
519#define ahname_str sub.hash.name
520#define ahname_len sub.hash.length
521#define ahvalue sub.hash.value
522#define ahname_ref sub.hash.ref
523 } sub;
524 NODETYPE type;
525 unsigned short flags;
526# define MALLOC 1 /* can be free'd */
527# define TEMP 2 /* should be free'd */
528# define PERM 4 /* can't be free'd */
529# define STRING 8 /* assigned as string */
530# define STRCUR 16 /* string value is current */
531# define NUMCUR 32 /* numeric value is current */
532# define NUMBER 64 /* assigned as number */
533# define MAYBE_NUM 128 /* user input: if NUMERIC then
534 * a NUMBER */
535# define ARRAYMAXED 256 /* array is at max size */
536# define FUNC 512 /* this parameter is really a
537 * function name; see awkgram.y */
538# define FIELD 1024 /* this is a field */
539# define INTLSTR 2048 /* use localized version */
540#ifdef MBS_SUPPORT
541# define WSTRCUR 4096 /* wide str value is current */
542#endif
543} NODE;
544
545#define vname sub.nodep.name
546#define exec_count sub.nodep.reflags
547
548#define lnode sub.nodep.l.lptr
549#define nextp sub.nodep.l.lptr
550#define rnode sub.nodep.r.rptr
551#define source_file sub.nodep.name
552#define source_line sub.nodep.number
553#define param_cnt sub.nodep.number
554#define param sub.nodep.l.param_name
555#define parmlist sub.nodep.x.param_list
556
557#define subnode lnode
558#define builtin sub.nodep.r.pptr
559#define callresult sub.nodep.x.extra
560#define funcbody sub.nodep.x.extra
561
562#define re_reg sub.nodep.r.preg
563#define re_flags sub.nodep.reflags
564#define re_text lnode
565#define re_exp sub.nodep.x.extra
566#define re_cnt sub.nodep.number
567
568#define forloop rnode->sub.nodep.r.hd
569
570#define stptr sub.val.sp
571#define stlen sub.val.slen
572#define stref sub.val.sref
573#define stfmt sub.val.idx
574
575#define wstptr sub.val.wsp
576#define wstlen sub.val.wslen
577
578#define numbr sub.val.fltnum
579
580/* Node_var: */
581#define var_value lnode
582
583/* Node_var_array: */
584#define var_array sub.nodep.r.av
585#define array_size sub.nodep.l.ll
586#define table_size sub.nodep.x.xl
587
588/* Node_array_ref: */
589#define orig_array sub.nodep.x.extra
590#define prev_array rnode
591
592#define printf_count sub.nodep.x.xl
593
594#define condpair lnode
595#define triggered sub.nodep.r.r_ent
596
597/* a regular for loop */
598typedef struct for_loop_header {
599 NODE *init;
600 NODE *cond;
601 NODE *incr;
602} FOR_LOOP_HEADER;
603
604typedef struct iobuf {
605 const char *name; /* filename */
606 int fd; /* file descriptor */
607 struct stat sbuf; /* stat buf */
608 char *buf; /* start data buffer */
609 char *off; /* start of current record in buffer */
610 char *dataend; /* first byte in buffer to hold new data,
611 NULL if not read yet */
612 char *end; /* end of buffer */
613 size_t readsize; /* set from fstat call */
614 size_t size; /* buffer size */
615 ssize_t count; /* amount read last time */
616 size_t scanoff; /* where we were in the buffer when we had
617 to regrow/refill */
618
619 void *opaque; /* private data for open hooks */
620 int (*get_record) P((char **out, struct iobuf *, int *errcode));
621 void (*close_func) P((struct iobuf *)); /* open and close hooks */
622
623 int flag;
624# define IOP_IS_TTY 1
625# define IOP_IS_INTERNAL 2
626# define IOP_NO_FREE 4
627# define IOP_NOFREE_OBJ 8
628# define IOP_AT_EOF 16
629# define IOP_CLOSED 32
630# define IOP_AT_START 64
631} IOBUF;
632
633typedef void (*Func_ptr) P((void));
634
635/* structure used to dynamically maintain a linked-list of open files/pipes */
636struct redirect {
637 unsigned int flag;
638# define RED_FILE 1
639# define RED_PIPE 2
640# define RED_READ 4
641# define RED_WRITE 8
642# define RED_APPEND 16
643# define RED_NOBUF 32
644# define RED_USED 64 /* closed temporarily to reuse fd */
645# define RED_EOF 128
646# define RED_TWOWAY 256
647# define RED_PTY 512
648# define RED_SOCKET 1024
649# define RED_TCP 2048
650 char *value;
651 FILE *fp;
652 FILE *ifp; /* input fp, needed for PIPES_SIMULATED */
653 IOBUF *iop;
654 int pid;
655 int status;
656 struct redirect *prev;
657 struct redirect *next;
658 const char *mode;
659};
660
661/*
662 * structure for our source, either a command line string or a source file.
663 * the same structure is used to remember variable pre-assignments.
664 */
665struct src {
666 enum srctype { CMDLINE = 1, SOURCEFILE,
667 PRE_ASSIGN, PRE_ASSIGN_FS } stype;
668 char *val;
669};
670
671/* for debugging purposes */
672struct flagtab {
673 int val;
674 const char *name;
675};
676
677/* longjmp return codes, must be nonzero */
678/* Continue means either for loop/while continue, or next input record */
679#define TAG_CONTINUE 1
680/* Break means either for/while break, or stop reading input */
681#define TAG_BREAK 2
682/* Return means return from a function call; leave value in ret_node */
683#define TAG_RETURN 3
684
685#ifndef LONG_MAX
686#define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
687#endif
688#ifndef ULONG_MAX
689#define ULONG_MAX (~(unsigned long)0)
690#endif
691#ifndef LONG_MIN
692#define LONG_MIN ((long)(-LONG_MAX - 1L))
693#endif
694#define UNLIMITED LONG_MAX
695
696/* -------------------------- External variables -------------------------- */
697/* gawk builtin variables */
698extern long NF;
699extern long NR;
700extern long FNR;
701extern int BINMODE;
702extern int IGNORECASE;
703extern int RS_is_null;
704extern char *OFS;
705extern int OFSlen;
706extern char *ORS;
707extern int ORSlen;
708extern char *OFMT;
709extern char *CONVFMT;
710ATTRIBUTE_EXPORTED extern int CONVFMTidx;
711extern int OFMTidx;
712extern char *TEXTDOMAIN;
713extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
714extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
715extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
716extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
717extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node;
718ATTRIBUTE_EXPORTED extern NODE **stack_ptr;
719extern NODE *Nnull_string;
720extern NODE *Null_field;
721extern NODE **fields_arr;
722extern int sourceline;
723extern char *source;
724extern NODE *expression_value;
725
726#if __GNUC__ < 2
727# if defined(WIN32_EXTENSION)
728static
729# else
730extern
731#endif
732NODE *_t; /* used as temporary in tree_eval */
733#endif
734
735extern NODE *nextfree;
736extern int field0_valid;
737extern int do_traditional;
738extern int do_posix;
739extern int do_intervals;
740extern int do_intl;
741extern int do_non_decimal_data;
742extern int do_dump_vars;
743extern int do_tidy_mem;
744extern int in_begin_rule;
745extern int in_end_rule;
746extern int whiny_users;
747#ifdef NO_LINT
748#define do_lint 0
749#define do_lint_old 0
750#else
751ATTRIBUTE_EXPORTED extern int do_lint;
752extern int do_lint_old;
753#endif
754#ifdef MBS_SUPPORT
755extern int gawk_mb_cur_max;
756#else
757extern const int gawk_mb_cur_max;
758#endif
759
760#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
761extern GETGROUPS_T *groupset;
762extern int ngroups;
763#endif
764
765#ifdef HAVE_LOCALE_H
766extern struct lconv loc;
767#endif /* HAVE_LOCALE_H */
768
769extern const char *myname;
770
771extern char quote;
772extern char *defpath;
773extern char envsep;
774
775extern char casetable[]; /* for case-independent regexp matching */
776
777/* ------------------------- Pseudo-functions ------------------------- */
778
779#define is_identchar(c) (isalnum(c) || (c) == '_')
780
781#define var_uninitialized(n) ((n)->var_value == Nnull_string)
782
783#ifdef MPROF
784#define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), (n)->flags = 0, (n)-exec_count = 0;
785#define freenode(n) free(n)
786#else /* not MPROF */
787#define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
788 else n = more_nodes()
789#ifndef NO_PROFILING
790#define freenode(n) ((n)->flags = 0,\
791 (n)->exec_count = 0, (n)->nextp = nextfree, nextfree = (n))
792#else /* not PROFILING */
793#define freenode(n) ((n)->flags = 0,\
794 (n)->nextp = nextfree, nextfree = (n))
795#endif /* not PROFILING */
796#endif /* not MPROF */
797
798#ifndef GAWKDEBUG
799#define DUPNODE_MACRO 1
800/*
801 * Speed up the path leading to r_dupnode, as well as duplicating TEMP nodes,
802 * on expense of slowing down the access to PERM nodes (by two instructions).
803 * This is right since PERM nodes are realtively rare.
804 *
805 * The code also sets MALLOC flag for PERM nodes, which should not matter.
806 */
807#define DUPNODE_COMMON (_t->flags & (TEMP|PERM)) != 0 ? \
808 (_t->flags &= ~TEMP, _t->flags |= MALLOC, _t) : \
809 r_dupnode(_t)
810#if __GNUC__ >= 2
811#define dupnode(n) ({NODE * _t = (n); DUPNODE_COMMON;})
812#else
813#define dupnode(n) (_t = (n), DUPNODE_COMMON)
814#endif
815#else /* GAWKDEBUG */
816#define dupnode(n) r_dupnode(n)
817#endif /* GAWKDEBUG */
818
819#define get_array(t) get_actual(t, TRUE) /* allowed to die fatally */
820#define get_param(t) get_actual(t, FALSE) /* not allowed */
821
822#ifdef MEMDEBUG
823#undef freenode
824#define get_lhs(p, a, r) r_get_lhs((p), (a), (r))
825#define m_tree_eval(t, iscond) r_tree_eval(t, iscond)
826#else
827#define get_lhs(p, a, r) ((p)->type == Node_var && \
828 ! var_uninitialized(p) ? \
829 (&(p)->var_value) : \
830 r_get_lhs((p), (a), (r)))
831#define TREE_EVAL_MACRO 1
832#if __GNUC__ >= 2
833#define m_tree_eval(t, iscond) __extension__ \
834 ({NODE * _t = (t); \
835 if (_t == (NODE*)NULL) \
836 cant_happen(); \
837 switch(_t->type) { \
838 case Node_val: \
839 if (_t->flags&INTLSTR) \
840 _t = r_force_string(_t); \
841 break; \
842 case Node_var: \
843 if (! var_uninitialized(_t)) { \
844 _t = _t->var_value; \
845 break; \
846 } \
847 /*FALLTHROUGH*/ \
848 default: \
849 _t = r_tree_eval(_t, iscond);\
850 break; \
851 } \
852 _t;})
853#else
854#define m_tree_eval(t, iscond) (_t = (t), _t == (NODE*)NULL ? (cant_happen(), (NODE*)NULL) : \
855 (_t->type == Node_param_list ? \
856 r_tree_eval(_t, iscond) : \
857 ((_t->type == Node_val && (_t->flags&INTLSTR)) ? \
858 r_force_string(_t) : \
859 (_t->type == Node_val ? _t : \
860 (_t->type == Node_var && \
861 ! var_uninitialized(_t) ? _t->var_value : \
862 r_tree_eval(_t, iscond))))))
863#endif /* __GNUC__ */
864#endif /* not MEMDEBUG */
865#define tree_eval(t) m_tree_eval(t, FALSE)
866
867#define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
868#define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUMCUR|NUMBER))
869
870#define free_temp(n) do { NODE *_n = (n); if (_n->flags&TEMP) unref(_n);} \
871 while (FALSE)
872
873#define make_string(s, l) make_str_node((s), (size_t) (l), 0)
874#define SCAN 1
875#define ALREADY_MALLOCED 2
876
877#define cant_happen() r_fatal("internal error line %d, file: %s", \
878 __LINE__, __FILE__)
879
880/*
881 * For SunOS 4.1.x which is pre-Standard C, `realloc' doesn't
882 * accept NULL. Sigh. The check must be done for both cases,
883 * since could be using GCC but with stock C library. Sigh, again.
884 */
885#ifdef HAVE_STRINGIZE
886#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
887 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
888 (str), #var, (long) (x), strerror(errno)),0))
889#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
890 ? (ty)malloc((MALLOC_ARG_T)(x)) \
891 : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
892 ||\
893 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
894 (str), #var, (long) (x), strerror(errno)),0))
895#else /* HAVE_STRINGIZE */
896#define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
897 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
898 (str), "var", (long) (x), strerror(errno)),0))
899#define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
900 ? (ty)malloc((MALLOC_ARG_T)(x)) \
901 : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
902 ||\
903 (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
904 (str), "var", (long) (x), strerror(errno)),0))
905#endif /* HAVE_STRINGIZE */
906
907#ifdef GAWKDEBUG
908#define force_number r_force_number
909#define force_string r_force_string
910#else /* not GAWKDEBUG */
911#ifdef lint
912extern AWKNUM force_number();
913#endif
914#if __GNUC__ >= 2
915#define force_number(n) __extension__ ({NODE *_tn = (n);\
916 (_tn->flags & NUMCUR) ?_tn->numbr : r_force_number(_tn);})
917#define force_string(s) __extension__ ({NODE *_ts = (s);\
918 ((_ts->flags & INTLSTR) ? \
919 r_force_string(_ts) : \
920 ((_ts->flags & STRCUR) && \
921 (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
922 _ts : r_force_string(_ts));})
923#else
924#ifdef MSDOS
925extern double _msc51bug;
926#define force_number(n) (_msc51bug=(_t = (n),\
927 (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t)))
928#else /* not MSDOS */
929#define force_number(n) (_t = (n),\
930 (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t))
931#endif /* not MSDOS */
932#define force_string(s) (_t = (s),(_t->flags & INTLSTR) ? \
933 r_force_string(_t) :\
934 ((_t->flags & STRCUR) && \
935 (_t->stfmt == -1 || \
936 _t->stfmt == CONVFMTidx))? \
937 _t : r_force_string(_t))
938
939#endif /* not __GNUC__ */
940#endif /* not GAWKDEBUG */
941
942#define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
943#define STREQN(a,b,n) ((n) && *(a)== *(b) && \
944 strncmp((a), (b), (size_t) (n)) == 0)
945
946#define fatal set_loc(__FILE__, __LINE__), r_fatal
947
948/* ------------- Function prototypes or defs (as appropriate) ------------- */
949
950/* array.c */
951extern NODE *get_actual P((NODE *symbol, int canfatal));
952extern char *array_vname P((const NODE *symbol));
953extern void array_init P((void));
954extern NODE *concat_exp P((NODE *tree));
955extern void assoc_clear P((NODE *symbol));
956extern NODE *in_array P((NODE *symbol, NODE *subs));
957extern NODE **assoc_lookup P((NODE *symbol, NODE *subs, int reference));
958extern void do_delete P((NODE *symbol, NODE *tree));
959extern void do_delete_loop P((NODE *symbol, NODE *tree));
960extern void set_SUBSEP P((void));
961extern NODE *assoc_dump P((NODE *symbol));
962extern NODE *do_adump P((NODE *tree));
963extern NODE *do_asort P((NODE *tree));
964extern NODE *do_asorti P((NODE *tree));
965extern unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize));
966/* awkgram.c */
967extern char *tokexpand P((void));
968extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
969extern NODE *install P((char *name, NODE *value));
970extern NODE *lookup P((const char *name));
971extern NODE *variable P((char *name, int can_free, NODETYPE type));
972extern int yyparse P((void));
973extern void dump_funcs P((void));
974extern void dump_vars P((const char *fname));
975extern void release_all_vars P((void));
976extern const char *getfname P((NODE *(*)(NODE *)));
977extern NODE *stopme P((NODE *tree));
978extern void shadow_funcs P((void));
979extern int check_special P((const char *name));
980extern void register_deferred_variable P((const char *name,
981 NODE *(*load_func)(void)));
982/* builtin.c */
983extern double double_to_int P((double d));
984extern NODE *do_exp P((NODE *tree));
985extern NODE *do_fflush P((NODE *tree));
986extern NODE *do_index P((NODE *tree));
987extern NODE *do_int P((NODE *tree));
988extern NODE *do_length P((NODE *tree));
989extern NODE *do_log P((NODE *tree));
990extern NODE *do_mktime P((NODE *tree));
991extern NODE *do_sprintf P((NODE *tree));
992extern void do_printf P((NODE *tree));
993extern void print_simple P((NODE *tree, FILE *fp));
994extern NODE *do_sqrt P((NODE *tree));
995extern NODE *do_substr P((NODE *tree));
996extern NODE *do_strftime P((NODE *tree));
997extern NODE *do_systime P((NODE *tree));
998extern NODE *do_system P((NODE *tree));
999extern void do_print P((NODE *tree));
1000extern void do_print_rec P((NODE *tree));
1001extern NODE *do_tolower P((NODE *tree));
1002extern NODE *do_toupper P((NODE *tree));
1003extern NODE *do_atan2 P((NODE *tree));
1004extern NODE *do_sin P((NODE *tree));
1005extern NODE *do_cos P((NODE *tree));
1006extern NODE *do_rand P((NODE *tree));
1007extern NODE *do_srand P((NODE *tree));
1008extern NODE *do_match P((NODE *tree));
1009extern NODE *do_gsub P((NODE *tree));
1010extern NODE *do_sub P((NODE *tree));
1011extern NODE *do_gensub P((NODE *tree));
1012extern NODE *format_tree P((const char *, size_t, NODE *, long));
1013extern NODE *do_lshift P((NODE *tree));
1014extern NODE *do_rshift P((NODE *tree));
1015extern NODE *do_and P((NODE *tree));
1016extern NODE *do_or P((NODE *tree));
1017extern NODE *do_xor P((NODE *tree));
1018extern NODE *do_compl P((NODE *tree));
1019extern NODE *do_strtonum P((NODE *tree));
1020extern AWKNUM nondec2awknum P((char *str, size_t len));
1021extern NODE *do_dcgettext P((NODE *tree));
1022extern NODE *do_dcngettext P((NODE *tree));
1023extern NODE *do_bindtextdomain P((NODE *tree));
1024#ifdef MBS_SUPPORT
1025extern int strncasecmpmbs P((const char *, mbstate_t, const char *,
1026 mbstate_t, size_t));
1027#endif
1028/* eval.c */
1029extern int interpret P((NODE *volatile tree));
1030extern NODE *r_tree_eval P((NODE *tree, int iscond));
1031extern int cmp_nodes P((NODE *t1, NODE *t2));
1032extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign, int reference));
1033extern void set_IGNORECASE P((void));
1034extern void set_OFS P((void));
1035extern void set_ORS P((void));
1036extern void set_OFMT P((void));
1037extern void set_CONVFMT P((void));
1038extern void set_BINMODE P((void));
1039extern void set_LINT P((void));
1040extern void set_TEXTDOMAIN P((void));
1041extern void update_ERRNO P((void));
1042extern void update_ERRNO_saved P((int));
1043extern const char *redflags2str P((int));
1044extern const char *flags2str P((int));
1045extern const char *genflags2str P((int flagval, const struct flagtab *tab));
1046extern const char *nodetype2str P((NODETYPE type));
1047extern NODE *assign_val P((NODE **lhs_p, NODE *rhs));
1048extern void load_casetable P((void));
1049extern size_t get_curfunc_arg_count P((void));
1050#ifdef PROFILING
1051extern void dump_fcall_stack P((FILE *fp));
1052#endif
1053/* ext.c */
1054NODE *do_ext P((NODE *));
1055#ifdef DYNAMIC
1056void make_builtin P((char *, NODE *(*)(NODE *), int));
1057NODE *get_argument P((NODE *, int));
1058NODE *get_actual_argument P((NODE *, unsigned int, int, int));
1059#define get_scalar_argument(t, i, opt) get_actual_argument((t), (i), (opt), FALSE)
1060#define get_array_argument(t, i, opt) get_actual_argument((t), (i), (opt), TRUE)
1061void set_value P((NODE *));
1062#endif
1063/* field.c */
1064extern void init_fields P((void));
1065extern void set_record P((const char *buf, int cnt));
1066extern void reset_record P((void));
1067extern void set_NF P((void));
1068extern NODE **get_field P((long num, Func_ptr *assign));
1069extern NODE *do_split P((NODE *tree));
1070extern void set_FS P((void));
1071extern void set_RS P((void));
1072extern void set_FIELDWIDTHS P((void));
1073extern int using_fieldwidths P((void));
1074/* gawkmisc.c */
1075extern char *gawk_name P((const char *filespec));
1076extern void os_arg_fixup P((int *argcp, char ***argvp));
1077extern int os_devopen P((const char *name, int flag));
1078extern void os_close_on_exec P((int fd, const char *name, const char *what,
1079 const char *dir));
1080extern int os_isdir P((int fd));
1081extern int os_is_setuid P((void));
1082extern int os_setbinmode P((int fd, int mode));
1083extern void os_restore_mode P((int fd));
1084extern size_t optimal_bufsize P((int fd, struct stat *sbuf));
1085extern int ispath P((const char *file));
1086extern int isdirpunct P((int c));
1087#if defined(_MSC_VER) && !defined(_WIN32)
1088extern char *memcpy_ulong P((char *dest, const char *src, unsigned long l));
1089extern void *memset_ulong P((void *dest, int val, unsigned long l));
1090#define memcpy memcpy_ulong
1091#define memset memset_ulong
1092#endif
1093/* io.c */
1094extern void register_open_hook P((void *(*open_func)(IOBUF *)));
1095extern void set_FNR P((void));
1096extern void set_NR P((void));
1097extern void do_input P((void));
1098extern struct redirect *redirect P((NODE *tree, int *errflg));
1099extern NODE *do_close P((NODE *tree));
1100extern int flush_io P((void));
1101extern int close_io P((int *stdio_problem));
1102extern int devopen P((const char *name, const char *mode));
1103extern int pathopen P((const char *file));
1104extern NODE *do_getline P((NODE *tree));
1105extern void do_nextfile P((void)) ATTRIBUTE_NORETURN;
1106extern struct redirect *getredirect P((const char *str, int len));
1107/* main.c */
1108extern int main P((int argc, char **argv));
1109extern int arg_assign P((char *arg, int initing));
1110/* msg.c */
1111extern void err P((const char *s, const char *emsg, va_list argp)) ATTRIBUTE_PRINTF(2, 0);
1112#if _MSC_VER == 510
1113extern void msg P((va_list va_alist, ...));
1114extern void error P((va_list va_alist, ...));
1115extern void warning P((va_list va_alist, ...));
1116extern void set_loc P((const char *file, int line));
1117extern void r_fatal P((va_list va_alist, ...));
1118extern void (*lintfunc) P((va_list va_alist, ...));
1119#else
1120#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
1121extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1122extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1123extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1124extern void set_loc (const char *file, int line);
1125extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
1126ATTRIBUTE_EXPORTED
1127#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
1128extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1129#else
1130extern void (*lintfunc) (const char *mesg, ...);
1131#endif
1132#else
1133extern void msg ();
1134extern void error ();
1135extern void warning ();
1136extern void set_loc ();
1137extern void r_fatal ();
1138extern void (*lintfunc) ();
1139#endif
1140#endif
1141/* profile.c */
1142extern void init_profiling P((int *flag, const char *def_file));
1143extern void init_profiling_signals P((void));
1144extern void set_prof_file P((const char *filename));
1145extern void dump_prog P((NODE *begin, NODE *prog, NODE *end));
1146extern void pp_func P((const char *name, size_t namelen, NODE *f));
1147extern void pp_string_fp P((FILE *fp, const char *str, size_t namelen,
1148 int delim, int breaklines));
1149/* node.c */
1150extern AWKNUM r_force_number P((NODE *n));
1151extern NODE *format_val P((const char *format, int index, NODE *s));
1152extern NODE *r_force_string P((NODE *s));
1153extern NODE *r_dupnode P((NODE *n));
1154extern NODE *copynode P((NODE *n));
1155extern NODE *mk_number P((AWKNUM x, unsigned int flags));
1156extern NODE *make_str_node P((char *s, unsigned long len, int scan ));
1157extern NODE *tmp_string P((char *s, size_t len ));
1158extern NODE *more_nodes P((void));
1159#ifdef MEMDEBUG
1160extern void freenode P((NODE *it));
1161#endif
1162extern void unref P((NODE *tmp));
1163extern int parse_escape P((const char **string_ptr));
1164#ifdef MBS_SUPPORT
1165extern NODE *str2wstr P((NODE *n, size_t **ptr));
1166#define force_wstring(n) str2wstr(n, NULL)
1167extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
1168extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
1169#endif
1170/* re.c */
1171extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa));
1172extern int research P((Regexp *rp, char *str, int start,
1173 size_t len, int flags));
1174extern void refree P((Regexp *rp));
1175extern void reg_error P((const char *s));
1176extern Regexp *re_update P((NODE *t));
1177extern void resyntax P((int syntax));
1178extern void resetup P((void));
1179extern int avoid_dfa P((NODE *re, char *str, size_t len)); /* temporary */
1180extern int reisstring P((const char *text, size_t len, Regexp *re, const char *buf));
1181extern int remaybelong P((const char *text, size_t len));
1182extern int isnondecimal P((const char *str, int use_locale));
1183
1184/* strncasecmp.c */
1185#ifndef BROKEN_STRNCASECMP
1186extern int strcasecmp P((const char *s1, const char *s2));
1187extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
1188#endif
1189
1190#if defined(atarist)
1191#if defined(PIPES_SIMULATED)
1192/* unsupported/atari/tmpnam.c */
1193extern char *tmpnam P((char *buf));
1194extern char *tempnam P((const char *path, const char *base));
1195#else
1196#include <wait.h>
1197#endif
1198#include <fcntl.h>
1199#define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1)
1200#else
1201#define INVALID_HANDLE (-1)
1202#endif /* atarist */
1203
1204#ifdef HAVE_SYS_WAIT_H
1205#include <sys/wait.h>
1206#endif
1207#ifndef WEXITSTATUS
1208#define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
1209#endif
1210
1211#ifndef STATIC
1212#define STATIC static
1213#endif
Note: See TracBrowser for help on using the repository browser.