Introduced -devel and -extras subpackages for gawk
[platform/upstream/gawk.git] / awk.h
1 /*
2  * awk.h -- Definitions for gawk. 
3  */
4
5 /* 
6  * Copyright (C) 1986, 1988, 1989, 1991-2011 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 3 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 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #ifndef _GNU_SOURCE
38 #define _GNU_SOURCE     1       /* enable GNU extensions */
39 #endif /* _GNU_SOURCE */
40
41 #if defined(_TANDEM_SOURCE) && ! defined(_SCO_DS)
42 #define _XOPEN_SOURCE_EXTENDED 1
43 #endif
44
45 #include <stdio.h>
46 #include <assert.h>
47 #ifdef HAVE_LIMITS_H
48 #include <limits.h>
49 #endif /* HAVE_LIMITS_H */
50 #include <ctype.h>
51 #include <setjmp.h>
52
53 #include "gettext.h"
54 #define _(msgid)  gettext(msgid)
55 #define N_(msgid) msgid
56
57 #if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0)
58 #ifndef LOCALEDIR
59 #define LOCALEDIR NULL
60 #endif /* LOCALEDIR */
61 #endif
62
63 #if !defined(__STDC__) || __STDC__ < 1
64 #error "gawk no longer supports non-C89 environments (no __STDC__ or __STDC__ < 1)"
65 #endif
66
67 #if defined(HAVE_STDARG_H)
68 #include <stdarg.h>
69 #else
70 #error "gawk no longer supports <varargs.h>. Please update your compiler and runtime"
71 #endif
72 #include <signal.h>
73 #include <time.h>
74 #include <errno.h>
75 #if ! defined(errno)
76 extern int errno;
77 #endif
78
79 #ifdef STDC_HEADERS
80 #include <stdlib.h>
81 #endif  /* not STDC_HEADERS */
82
83 #include "mbsupport.h" /* defines MBS_SUPPORT */
84
85 #if MBS_SUPPORT
86 /* We can handle multibyte strings.  */
87 #include <wchar.h>
88 #include <wctype.h>
89 #endif
90
91 #ifdef STDC_HEADERS
92 #include <float.h>
93 #endif
94
95 #undef CHARBITS
96 #undef INTBITS
97
98 #if !defined(ZOS_USS)
99 #if HAVE_INTTYPES_H
100 # include <inttypes.h>
101 #endif
102 #if HAVE_STDINT_H
103 # include <stdint.h>
104 #endif
105 #endif /* !ZOS_USS */
106
107 /* ----------------- System dependencies (with more includes) -----------*/
108
109 /* This section is the messiest one in the file, not a lot that can be done */
110
111 #define MALLOC_ARG_T size_t
112
113 #ifndef VMS
114 #ifdef HAVE_FCNTL_H
115 #include <fcntl.h>
116 #endif
117 #include <sys/types.h>
118 #include <sys/stat.h>
119 #else   /* VMS */
120 #include <stddef.h>
121 #include <stat.h>
122 #include <file.h>       /* avoid <fcntl.h> in io.c */
123 /* debug.c needs this; when _DECC_V4_SOURCE is defined (as it is
124    in our config.h [vms/vms-conf.h]), off_t won't get declared */
125 # if !defined(__OFF_T) && !defined(_OFF_T)
126 #  if defined(____OFF_T) || defined(___OFF_T)
127 typedef __off_t off_t;  /* __off_t is either int or __int64 */
128 #  else
129 typedef int off_t;
130 #  endif
131 # endif
132 #endif  /* VMS */
133
134 #if ! defined(S_ISREG) && defined(S_IFREG)
135 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
136 #endif
137
138 #include "protos.h"
139
140 #ifdef HAVE_STRING_H
141 #include <string.h>
142 #ifdef NEED_MEMORY_H
143 #include <memory.h>
144 #endif  /* NEED_MEMORY_H */
145 #else   /* not HAVE_STRING_H */
146 #ifdef HAVE_STRINGS_H
147 #include <strings.h>
148 #endif  /* HAVE_STRINGS_H */
149 #endif  /* not HAVE_STRING_H */
150
151 #if HAVE_UNISTD_H
152 #include <unistd.h>
153 #endif  /* HAVE_UNISTD_H */
154
155 #ifdef VMS
156 #include <unixlib.h>
157 #include "vms/redirect.h"
158 #endif  /*VMS*/
159
160 #ifndef O_BINARY
161 #define O_BINARY        0
162 #endif
163
164 #ifndef HAVE_VPRINTF
165 #error "you lose: you need a system with vfprintf"
166 #endif  /* HAVE_VPRINTF */
167
168 #ifndef HAVE_SETLOCALE
169 #define setlocale(locale, val)  /* nothing */
170 #endif /* HAVE_SETLOCALE */
171
172 #ifndef HAVE_SETSID
173 #define setsid()        /* nothing */
174 #endif /* HAVE_SETSID */
175
176 #if HAVE_MEMCPY_ULONG
177 extern char *memcpy_ulong(char *dest, const char *src, unsigned long l);
178 #define memcpy memcpy_ulong
179 #endif
180 #if HAVE_MEMSET_ULONG
181 extern void *memset_ulong(void *dest, int val, unsigned long l);
182 #define memset memset_ulong
183 #endif
184
185 #ifdef HAVE_LIBSIGSEGV
186 #include <sigsegv.h>
187 #else
188 typedef void *stackoverflow_context_t;
189 #define sigsegv_install_handler(catchsegv) signal(SIGSEGV, catchsig)
190 /* define as 0 rather than empty so that (void) cast on it works */
191 #define stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE) 0
192 #endif
193
194 /* use this as lintwarn("...")
195    this is a hack but it gives us the right semantics */
196 #define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
197
198 #include "regex.h"
199 #include "dfa.h"
200 typedef struct Regexp {
201         struct re_pattern_buffer pat;
202         struct re_registers regs;
203         struct dfa *dfareg;
204         short dfa;
205         short has_anchor;       /* speed up of avoid_dfa kludge, temporary */
206         short non_empty;        /* for use in fpat_parse_field */
207 } Regexp;
208 #define RESTART(rp,s)   (rp)->regs.start[0]
209 #define REEND(rp,s)     (rp)->regs.end[0]
210 #define SUBPATSTART(rp,s,n)     (rp)->regs.start[n]
211 #define SUBPATEND(rp,s,n)       (rp)->regs.end[n]
212 #define NUMSUBPATS(rp,s)        (rp)->regs.num_regs
213
214 /* regexp matching flags: */
215 #define RE_NEED_START   1       /* need to know start/end of match */
216 #define RE_NO_BOL       2       /* not allowed to match ^ in regexp */
217
218 /* Stuff for losing systems. */
219 #if !defined(HAVE_STRTOD)
220 extern double gawk_strtod();
221 #define strtod gawk_strtod
222 #endif
223
224 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
225 # define __attribute__(x)
226 #endif
227
228 #ifndef ATTRIBUTE_UNUSED
229 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
230 #endif /* ATTRIBUTE_UNUSED */
231
232 #ifndef ATTRIBUTE_NORETURN
233 #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
234 #endif /* ATTRIBUTE_NORETURN */
235
236 #ifndef ATTRIBUTE_PRINTF
237 #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
238 #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
239 #define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
240 #endif /* ATTRIBUTE_PRINTF */
241
242 /* We use __extension__ in some places to suppress -pedantic warnings
243    about GCC extensions.  This feature didn't work properly before
244    gcc 2.8.  */
245 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
246 #define __extension__
247 #endif
248
249 /* ------------------ Constants, Structures, Typedefs  ------------------ */
250
251 #define AWKNUM  double
252
253 #ifndef TRUE
254 /* a bit hackneyed, but what the heck */
255 #define TRUE    1
256 #define FALSE   0
257 #endif
258
259 #define LINT_INVALID    1       /* only warn about invalid */
260 #define LINT_ALL        2       /* warn about all things */
261
262 enum defrule {BEGIN = 1, Rule, END, BEGINFILE, ENDFILE,
263         MAXRULE /* sentinel, not legal */ };
264 extern const char *const ruletab[];
265
266
267 typedef enum nodevals {
268         /* illegal entry == 0 */
269         Node_illegal,
270
271         Node_val,               /* node is a value - type in flags */
272         Node_regex,             /* a regexp, text, compiled, flags, etc */
273         Node_dynregex,          /* a dynamic regexp */
274
275         /* symbol table values */
276         Node_var,               /* scalar variable, lnode is value */
277         Node_var_array,         /* array is ptr to elements, table_size num of eles */
278         Node_var_new,           /* newly created variable, may become an array */
279         Node_param_list,        /* lnode is a variable, rnode is more list */
280         Node_func,              /* lnode is param. list, rnode is body */
281
282         Node_hashnode,          /* an identifier in the symbol table */
283         Node_ahash,             /* an array element */
284         Node_array_ref,         /* array passed by ref as parameter */
285
286         /* program execution -- stack item types */
287         Node_arrayfor,
288         Node_frame,
289         Node_instruction,
290
291         Node_final              /* sentry value, not legal */
292 } NODETYPE;
293
294
295 struct exp_instruction;
296
297 /*
298  * NOTE - this struct is a rather kludgey -- it is packed to minimize
299  * space usage, at the expense of cleanliness.  Alter at own risk.
300  */
301 typedef struct exp_node {
302         union {
303                 struct {
304                         union {
305                                 struct exp_node *lptr;
306                                 struct exp_instruction *li;
307                                 long ll;
308                         } l;
309                         union {
310                                 struct exp_node *rptr;
311                                 Regexp *preg;
312                                 struct exp_node **av;
313                                 void (*uptr)(void);
314                                 struct exp_instruction *ri;
315                         } r;
316                         union {
317                                 struct exp_node *extra;
318                                 void (*aptr)(void);
319                                 long xl;
320                                 char **param_list;
321                         } x;
322                         char *name;
323                         struct exp_node *rn;
324                         unsigned long reflags;
325 #                               define  CASE            1
326 #                               define  CONSTANT        2
327 #                               define  FS_DFLT         4
328                 } nodep;
329                 struct {
330                         AWKNUM fltnum;  /* this is here for optimal packing of
331                                          * the structure on many machines
332                                          */
333                         char *sp;
334                         size_t slen;
335                         long sref;
336                         int idx;
337 #if MBS_SUPPORT
338                         wchar_t *wsp;
339                         size_t wslen;
340 #endif
341                 } val;
342                 struct {
343                         AWKNUM num;
344                         struct exp_node *next;
345                         char *name;
346                         size_t length;
347                         struct exp_node *value;
348                         long ref;
349                         size_t code;
350                 } hash;
351 #define hnext   sub.hash.next
352 #define hname   sub.hash.name
353 #define hlength sub.hash.length
354 #define hvalue  sub.hash.value
355
356 #define ahnext          sub.hash.next
357 #define ahname_str      sub.hash.name
358 #define ahname_len      sub.hash.length
359 #define ahname_num      sub.hash.num
360 #define ahvalue sub.hash.value
361 #define ahname_ref      sub.hash.ref
362 #define ahcode  sub.hash.code
363         } sub;
364         NODETYPE type;
365         unsigned short flags;
366 #               define  MALLOC  1       /* can be free'd */
367 #               define  PERM    2       /* can't be free'd */
368 #               define  STRING  4       /* assigned as string */
369 #               define  STRCUR  8       /* string value is current */
370 #               define  NUMCUR  16      /* numeric value is current */
371 #               define  NUMBER  32      /* assigned as number */
372 #               define  MAYBE_NUM 64    /* user input: if NUMERIC then
373                                          * a NUMBER */
374 #               define  ARRAYMAXED 128  /* array is at max size */
375 #               define  FUNC    256     /* this parameter is really a
376                                          * function name; see awkgram.y */
377 #               define  FIELD   512     /* this is a field */
378 #               define  INTLSTR 1024    /* use localized version */
379 #               define  NUMIND  2048    /* numeric val of index is current */
380 #               define  WSTRCUR 4096    /* wide str value is current */
381 } NODE;
382
383
384 #define vname sub.nodep.name
385
386 #define lnode   sub.nodep.l.lptr
387 #define nextp   sub.nodep.l.lptr
388 #define rnode   sub.nodep.r.rptr
389
390 #define param_cnt       sub.nodep.l.ll
391 #define param           vname
392
393 #define parmlist    sub.nodep.x.param_list
394 #define code_ptr    sub.nodep.r.ri
395
396 #define re_reg  sub.nodep.r.preg
397 #define re_flags sub.nodep.reflags
398 #define re_text lnode
399 #define re_exp  sub.nodep.x.extra
400 #define re_cnt  flags
401
402 #define stptr   sub.val.sp
403 #define stlen   sub.val.slen
404 #define valref  sub.val.sref
405 #define stfmt   sub.val.idx
406
407 #define wstptr  sub.val.wsp
408 #define wstlen  sub.val.wslen
409
410 #define numbr   sub.val.fltnum
411
412 /* Node_frame: */
413 #define stack        sub.nodep.r.av
414 #define func_node    sub.nodep.x.extra
415 #define prev_frame_size sub.nodep.reflags
416 #define reti         sub.nodep.l.li
417
418 /* Node_var: */
419 #define var_value lnode
420 #define var_update   sub.nodep.r.uptr
421 #define var_assign   sub.nodep.x.aptr
422
423 /* Node_var_array: */
424 #define var_array    sub.nodep.r.av
425 #define array_size   sub.nodep.l.ll
426 #define table_size   sub.nodep.x.xl
427 #define parent_array sub.nodep.rn
428
429 /* Node_array_ref: */
430 #define orig_array lnode
431 #define prev_array rnode
432
433 /* --------------------------------lint warning types----------------------------*/
434 typedef enum lintvals {
435         LINT_illegal,
436         LINT_assign_in_cond,
437         LINT_no_effect
438 } LINTTYPE;
439
440 /* --------------------------------Instruction ---------------------------------- */
441
442 typedef enum opcodeval {
443         /* illegal entry == 0 */
444         Op_illegal,
445
446         /* binary operators */
447         Op_times,
448         Op_times_i,
449         Op_quotient,
450         Op_quotient_i,
451         Op_mod,
452         Op_mod_i,
453         Op_plus,
454         Op_plus_i,
455         Op_minus,
456         Op_minus_i,
457         Op_exp,
458         Op_exp_i,
459         Op_concat,
460
461         /* line range instruction pair */
462         Op_line_range,          /* flags for Op_cond_pair */
463         Op_cond_pair,           /* conditional pair */
464
465         Op_subscript,
466         Op_sub_array,
467
468         /* unary operators */
469         Op_preincrement,
470         Op_predecrement,
471         Op_postincrement,
472         Op_postdecrement,
473         Op_unary_minus,
474         Op_field_spec,
475
476         /* unary relationals */
477         Op_not,
478
479         /* assignments */
480         Op_assign,
481         Op_store_var,           /* simple variable assignment optimization */
482         Op_store_sub,           /* array[subscript] assignment optimization */
483         Op_store_field,         /* $n assignment optimization */
484         Op_assign_times,
485         Op_assign_quotient,
486         Op_assign_mod,
487         Op_assign_plus,
488         Op_assign_minus,
489         Op_assign_exp,
490         Op_assign_concat,
491
492         /* boolean binaries */
493         Op_and,                 /* a left subexpression in && */
494         Op_and_final,           /* right subexpression of && */
495         Op_or,
496         Op_or_final,
497
498         /* binary relationals */
499         Op_equal,
500         Op_notequal,
501         Op_less,
502         Op_greater,
503         Op_leq,
504         Op_geq,
505         Op_match,
506         Op_match_rec,           /* match $0 */
507         Op_nomatch,
508
509         Op_rule,
510         
511         /* keywords */
512         Op_K_case,
513         Op_K_default,
514         Op_K_break,
515         Op_K_continue,
516         Op_K_print,
517         Op_K_print_rec,
518         Op_K_printf,
519         Op_K_next,
520         Op_K_exit,
521         Op_K_return,
522         Op_K_delete,
523         Op_K_delete_loop,
524         Op_K_getline_redir,
525         Op_K_getline,
526         Op_K_nextfile,
527
528         Op_builtin,
529         Op_sub_builtin,         /* sub, gsub and gensub */
530         Op_in_array,            /* boolean test of membership in array */
531
532         /* function call instruction */
533         Op_func_call,
534         Op_indirect_func_call,
535
536         Op_push,                /* scalar variable */
537         Op_push_arg,    /* variable type (scalar or array) argument to built-in */
538         Op_push_i,              /* number, string */
539         Op_push_re,             /* regex */
540         Op_push_array,
541         Op_push_param,
542         Op_push_lhs,
543         Op_subscript_lhs,
544         Op_field_spec_lhs,
545         Op_no_op,               /* jump target */
546         Op_pop,                 /* pop an item from the runtime stack */
547         Op_jmp,
548         Op_jmp_true,
549         Op_jmp_false,
550         Op_get_record,
551         Op_newfile,
552         Op_arrayfor_init,
553         Op_arrayfor_incr,
554         Op_arrayfor_final,
555
556         Op_var_update,          /* update value of NR, NF or FNR */
557         Op_var_assign,
558         Op_field_assign,
559         Op_after_beginfile,
560         Op_after_endfile,
561
562         Op_ext_func,
563         Op_func,
564
565         Op_exec_count,
566         Op_breakpoint,
567         Op_lint,
568         Op_atexit,
569         Op_stop,
570
571         /* parsing (yylex and yyparse), should never appear in valid compiled code */
572         Op_token,       
573         Op_symbol,
574         Op_list,
575
576         /* program structures -- for use in the profiler/pretty printer */
577         Op_K_do,
578         Op_K_for,                       
579         Op_K_arrayfor,
580         Op_K_while,
581         Op_K_switch,
582         Op_K_if,
583         Op_K_else,
584         Op_K_function,
585         Op_cond_exp,
586         Op_final                        /* sentry value, not legal */
587 } OPCODE;
588
589 enum redirval {
590         /* I/O redirections */
591         redirect_output = 1,
592         redirect_append,
593         redirect_pipe,
594         redirect_pipein,
595         redirect_input,
596         redirect_twoway
597 };
598
599 struct break_point;
600
601 typedef struct exp_instruction {
602         struct exp_instruction *nexti;
603         union {
604                 NODE *dn;
605                 struct exp_instruction *di;
606                 NODE *(*fptr)(int);
607                 long dl;
608                 char *name;
609         } d;
610
611         union {
612                 long  xl;
613                 NODE *xn;
614                 void (*aptr)(void);
615                 struct exp_instruction *xi;
616                 struct break_point *bpt;
617         } x;
618
619         short source_line;
620         OPCODE opcode;
621 } INSTRUCTION;
622
623 #define func_name       d.name
624
625 #define memory          d.dn
626 #define builtin         d.fptr
627 #define builtin_idx     d.dl
628
629 #define expr_count      x.xl
630
631 #define target_continue d.di
632 #define target_jmp      d.di
633 #define target_break    x.xi
634
635 /* Op_sub_builtin */
636 #define sub_flags       d.dl
637 #define GSUB            0x01    /* builtin is gsub */
638 #define GENSUB          0x02    /* builtin is gensub */
639 #define LITERAL         0x04    /* target is a literal string */
640
641
642 /* Op_K_exit */
643 #define target_end      d.di
644 #define target_atexit   x.xi    
645
646 /* Op_newfile, Op_K_getline, Op_nextfile */
647 #define target_endfile  x.xi
648
649 /* Op_newfile */
650 #define target_get_record       x.xi
651
652 /* Op_get_record, Op_K_nextfile */
653 #define target_newfile  d.di
654
655 /* Op_K_getline */
656 #define target_beginfile        d.di
657
658 /* Op_get_record */
659 #define has_endfile             x.xl
660
661 /* Op_token */
662 #define lextok          d.name
663
664 /* Op_rule */
665 #define in_rule         x.xl
666 #define source_file     d.name
667
668  /* Op_K_case, Op_K_default */
669 #define case_stmt       x.xi
670 #define case_exp        d.di
671 #define stmt_start              case_exp
672 #define stmt_end                case_stmt
673 #define match_exp               x.xl
674
675 #define target_stmt       x.xi
676
677 /* Op_K_switch */
678 #define switch_end      x.xi
679 #define switch_start    d.di
680
681 /* Op_K_getline, Op_K_getline_redir */
682 #define into_var        x.xl
683
684 /* Op_K_getline_redir, Op_K_print, Op_K_print_rec, Op_K_printf */
685 #define redir_type      d.dl
686
687 /* Op_arrayfor_incr     */
688 #define array_var       x.xn
689
690 /* Op_line_range */
691 #define triggered       x.xl
692
693 /* Op_cond_pair */
694 #define line_range      x.xi
695
696 /* Op_func_call, Op_func */
697 #define func_body       x.xn
698
699 /* Op_func_call */
700 #define inrule          d.dl
701
702 /* Op_subscript */
703 #define sub_count       d.dl
704
705 /* Op_push_lhs, Op_subscript_lhs, Op_field_spec_lhs */
706 #define do_reference    x.xl
707
708 /* Op_list, Op_rule, Op_func */
709 #define lasti           d.di
710 #define firsti          x.xi
711
712 /* Op_rule, Op_func */
713 #define last_line       x.xl
714 #define first_line      source_line
715
716 /* Op_lint */
717 #define lint_type       d.dl
718
719 /* Op_field_spec_lhs */
720 #define target_assign   d.di
721
722 /* Op_var_assign */
723 #define assign_var      x.aptr
724
725 /* Op_var_update */
726 #define update_var      x.aptr
727
728 /* Op_field_assign */
729 #define field_assign    x.aptr
730
731 /* Op_field_assign, Op_var_assign */
732 #define assign_ctxt     d.dl    
733
734 /* Op_concat */
735 #define concat_flag         d.dl
736 #define CSUBSEP                 1
737 #define CSVAR                   2
738
739 /* Op_breakpoint */
740 #define break_pt        x.bpt
741
742 /*------------------ pretty printing/profiling --------*/
743 /* Op_exec_count */
744 #define exec_count      d.dl
745
746 /* Op_K_while */
747 #define while_body      d.di
748
749 /* Op_K_do */
750 #define doloop_cond     d.di
751
752 /* Op_K_for */
753 #define forloop_cond    d.di
754 #define forloop_body    x.xi
755
756 /* Op_K_if */
757 #define branch_if       d.di
758 #define branch_else     x.xi
759
760 /* Op_K_else */
761 #define branch_end      x.xi
762
763 /* Op_line_range */
764 #define condpair_left   d.di
765 #define condpair_right  x.xi 
766
767 typedef struct iobuf {
768         const char *name;       /* filename */
769         int fd;                 /* file descriptor */
770         struct stat sbuf;       /* stat buf */
771         char *buf;              /* start data buffer */
772         char *off;              /* start of current record in buffer */
773         char *dataend;          /* first byte in buffer to hold new data,
774                                    NULL if not read yet */
775         char *end;              /* end of buffer */
776         size_t readsize;        /* set from fstat call */
777         size_t size;            /* buffer size */
778         ssize_t count;          /* amount read last time */
779         size_t scanoff;         /* where we were in the buffer when we had
780                                    to regrow/refill */
781
782         void *opaque;           /* private data for open hooks */
783         int (*get_record)(char **out, struct iobuf *, int *errcode);
784         void (*close_func)(struct iobuf *);             /* open and close hooks */
785         
786         int errcode;
787
788         int flag;
789 #               define  IOP_IS_TTY      1
790 #               define  IOP_NOFREE_OBJ  2
791 #               define  IOP_AT_EOF      4
792 #               define  IOP_CLOSED      8
793 #               define  IOP_AT_START    16                      
794 } IOBUF;
795
796 typedef void (*Func_ptr)(void);
797
798 /* structure used to dynamically maintain a linked-list of open files/pipes */
799 struct redirect {
800         unsigned int flag;
801 #               define  RED_FILE        1
802 #               define  RED_PIPE        2
803 #               define  RED_READ        4
804 #               define  RED_WRITE       8
805 #               define  RED_APPEND      16
806 #               define  RED_NOBUF       32
807 #               define  RED_USED        64      /* closed temporarily to reuse fd */
808 #               define  RED_EOF         128
809 #               define  RED_TWOWAY      256
810 #               define  RED_PTY         512
811 #               define  RED_SOCKET      1024
812 #               define  RED_TCP         2048
813         char *value;
814         FILE *fp;
815         FILE *ifp;      /* input fp, needed for PIPES_SIMULATED */
816         IOBUF *iop;
817         int pid;
818         int status;
819         struct redirect *prev;
820         struct redirect *next;
821         const char *mode;
822 };
823
824 /*
825  * structure for our source, either a command line string or a source file.
826  */
827
828 typedef struct srcfile {
829         struct srcfile *next;
830         struct srcfile *prev;
831
832         enum srctype { SRC_CMDLINE = 1, SRC_STDIN, SRC_FILE, SRC_INC } stype;
833         char *src;      /* name on command line or inclde statement */
834         char *fullpath; /* full path after AWKPATH search */
835         time_t mtime;
836         struct stat sbuf;
837         int srclines;   /* no of lines in source */
838         size_t bufsize;
839         char *buf;
840         int *line_offset;       /* offset to the beginning of each line */
841         int fd;
842         int maxlen;     /* size of the longest line */
843
844         char *lexptr;
845         char *lexend;
846         char *lexeme;
847         char *lexptr_begin;
848         int lasttok;
849 } SRCFILE;
850
851 /* structure for execution context */
852 typedef struct context {
853         INSTRUCTION pools;
854         NODE symbols;
855         INSTRUCTION rule_list;
856         SRCFILE srcfiles;
857         int sourceline;
858         char *source;
859         void (*install_func)(char *);
860         struct context *prev;
861 } AWK_CONTEXT;
862
863 /* for debugging purposes */
864 struct flagtab {
865         int val;
866         const char *name;
867 };
868
869 #ifndef LONG_MAX
870 #define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
871 #endif
872 #ifndef ULONG_MAX
873 #define ULONG_MAX (~(unsigned long)0)
874 #endif
875 #ifndef LONG_MIN
876 #define LONG_MIN ((long)(-LONG_MAX - 1L))
877 #endif
878 #define UNLIMITED    LONG_MAX 
879
880 /* -------------------------- External variables -------------------------- */
881 /* gawk builtin variables */
882 extern long NF;
883 extern long NR;
884 extern long FNR;
885 extern int BINMODE;
886 extern int IGNORECASE;
887 extern int RS_is_null;
888 extern char *OFS;
889 extern int OFSlen;
890 extern char *ORS;
891 extern int ORSlen;
892 extern char *OFMT;
893 extern char *CONVFMT;
894 extern int CONVFMTidx;
895 extern int OFMTidx;
896 extern char *TEXTDOMAIN;
897 extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
898 extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
899 extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
900 extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
901 extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node, *FPAT_node;
902 extern NODE *Nnull_string;
903 extern NODE *Null_field;
904 extern NODE **fields_arr;
905 extern int sourceline;
906 extern char *source;
907
908 #if __GNUC__ < 2
909 extern NODE *_t;        /* used as temporary in tree_eval */
910 #endif
911 extern NODE *_r;        /* used as temporary in stack macros */
912
913 extern NODE *nextfree;
914 extern int field0_valid;
915 extern int do_traditional;
916 extern int do_posix;
917 extern int do_intervals;
918 extern int do_intl;
919 extern int do_non_decimal_data;
920 extern int do_profiling;
921 extern int do_dump_vars;
922 extern int do_tidy_mem;
923 extern int do_sandbox;
924 extern int do_optimize;
925 extern int use_lc_numeric;
926 extern int exit_val;
927
928 #ifdef NO_LINT
929 #define do_lint 0
930 #define do_lint_old 0
931 #else
932 extern int do_lint;
933 extern int do_lint_old;
934 #endif
935 #if MBS_SUPPORT
936 extern int gawk_mb_cur_max;
937 #else
938 #define gawk_mb_cur_max (1)
939 #endif
940
941 #if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
942 extern GETGROUPS_T *groupset;
943 extern int ngroups;
944 #endif
945
946 #ifdef HAVE_LOCALE_H
947 extern struct lconv loc;
948 #endif /* HAVE_LOCALE_H */
949
950 extern const char *myname;
951 extern const char def_strftime_format[];
952
953 extern char quote;
954 extern char *defpath;
955 extern char envsep;
956
957 extern char casetable[];        /* for case-independent regexp matching */
958
959 /*
960  * Provide a way for code to know which program is executing:
961  * gawk vs dgawk vs pgawk.
962  */
963 enum exe_mode { exe_normal = 1, exe_debugging, exe_profiling };
964 extern enum exe_mode which_gawk;        /* (defined in eval.c) */
965
966 /* ------------------------- Runtime stack -------------------------------- */
967
968 typedef union stack_item {
969         NODE *rptr;             /* variable etc. */
970         NODE **lptr;            /* address of a variable etc. */
971 } STACK_ITEM;
972
973 extern STACK_ITEM *stack_ptr;
974 extern NODE *frame_ptr;
975 extern STACK_ITEM *stack_bottom;
976 extern STACK_ITEM *stack_top;
977
978 #define decr_sp()                       (stack_ptr--)
979 #define incr_sp()               ((stack_ptr < stack_top) ? ++stack_ptr : grow_stack())
980 #define stack_adj(n)                    (stack_ptr += (n))
981 #define stack_empty()                   (stack_ptr < stack_bottom)
982
983 #define POP()                           decr_sp()->rptr
984 #define POP_ADDRESS()                   decr_sp()->lptr
985 #define PEEK(n)                         (stack_ptr - (n))->rptr
986 #define TOP()                           stack_ptr->rptr         /* same as PEEK(0) */
987 #define TOP_ADDRESS()                   stack_ptr->lptr 
988 #define PUSH(r)                         (void) (incr_sp()->rptr = (r))
989 #define PUSH_ADDRESS(l)                 (void) (incr_sp()->lptr = (l))
990 #define REPLACE(r)                      (void) (stack_ptr->rptr = (r))
991 #define REPLACE_ADDRESS(l)              (void) (stack_ptr->lptr = (l))
992
993
994 /* function param */
995 #define GET_PARAM(n)                    frame_ptr->stack[n]
996
997 /*
998  * UPREF and DEREF --- simplified versions of dupnode and unref
999  * UPREF does not handle FIELD node. Most appropriate use is
1000  * for elements on the runtime stack. When in doubt, use dupnode.
1001  */   
1002
1003 #define DEREF(r)        ( _r = (r), (!(_r->flags & PERM) && (--_r->valref == 0)) ?  unref(_r) : (void)0 )
1004
1005 #if __GNUC__ >= 2
1006 #define UPREF(r)        ({ NODE *_t = (r); !(_t->flags & PERM) && _t->valref++;})
1007
1008 #define POP_ARRAY()     ({ NODE *_t = POP(); \
1009                         _t->type == Node_var_array ? \
1010                                 _t : get_array(_t, TRUE); })
1011
1012 #define POP_PARAM()     ({ NODE *_t = POP(); \
1013                         _t->type == Node_var_array ? \
1014                                 _t : get_array(_t, FALSE); })
1015
1016 #define POP_NUMBER(x) ({ NODE *_t = POP_SCALAR(); \
1017                                 x = force_number(_t); DEREF(_t); })
1018 #define TOP_NUMBER(x) ({ NODE *_t = TOP_SCALAR(); \
1019                                 x = force_number(_t); DEREF(_t); })
1020
1021 #define POP_SCALAR()                    ({ NODE *_t = POP(); _t->type != Node_var_array ? _t \
1022                         : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
1023 #define TOP_SCALAR()                    ({ NODE *_t = TOP(); _t->type != Node_var_array ? _t \
1024                         : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t);})
1025
1026 #else   /* not __GNUC__ */
1027
1028 #define UPREF(r)        (_t = (r), !(_t->flags & PERM) && _t->valref++)
1029
1030 #define POP_ARRAY()     (_t = POP(), \
1031                         _t->type == Node_var_array ? \
1032                                 _t : get_array(_t, TRUE))
1033
1034 #define POP_PARAM()     (_t = POP(), \
1035                         _t->type == Node_var_array ? \
1036                                 _t : get_array(_t, FALSE))
1037
1038 #define POP_NUMBER(x) (_t = POP_SCALAR(), \
1039                                 x = force_number(_t), DEREF(_t))
1040 #define TOP_NUMBER(x) (_t = TOP_SCALAR(), \
1041                                 x = force_number(_t), DEREF(_t))
1042
1043 #define POP_SCALAR()    (_t = POP(), _t->type != Node_var_array ? _t \
1044                         : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
1045 #define TOP_SCALAR()    (_t = TOP(), _t->type != Node_var_array ? _t \
1046                         : (fatal(_("attempt to use array `%s' in a scalar context"), array_vname(_t)), _t))
1047
1048 #endif  /* __GNUC__ */
1049
1050
1051 #define POP_STRING() force_string(POP_SCALAR())
1052 #define TOP_STRING() force_string(TOP_SCALAR())
1053
1054 /* ------------------------- Pseudo-functions ------------------------- */
1055
1056 #define is_identchar(c)         (isalnum(c) || (c) == '_')
1057
1058 #define var_uninitialized(n)    ((n)->var_value == Nnull_string)
1059
1060 #define get_lhs(n, r)    (n)->type == Node_var && ! var_uninitialized(n) ? \
1061                                 &((n)->var_value) : r_get_lhs((n), (r))
1062
1063 #ifdef MPROF
1064 #define getnode(n)      emalloc((n), NODE *, sizeof(NODE), "getnode"), \
1065                           (n)->flags = 0
1066 #define freenode(n)     efree(n)
1067 #else   /* not MPROF */
1068 #define getnode(n)  (void) (nextfree ? \
1069                               (n = nextfree, nextfree = nextfree->nextp) \
1070                               : (n = more_nodes()))
1071 #define freenode(n)     ((n)->flags = 0, (n)->nextp = nextfree, nextfree = (n))
1072 #endif  /* not MPROF */
1073
1074 #define make_number(x)  mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
1075
1076 #define make_string(s, l)               r_make_str_node((s), (size_t) (l), 0)
1077 #define make_str_node(s, l, f)  r_make_str_node((s), (size_t) (l), (f))
1078
1079 #define         SCAN                    1
1080 #define         ALREADY_MALLOCED        2
1081
1082 #define cant_happen()   r_fatal("internal error line %d, file: %s", \
1083                                 __LINE__, __FILE__)
1084
1085 #define emalloc(var,ty,x,str)   (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
1086                                  (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
1087                                         (str), #var, (long) (x), strerror(errno)),0))
1088 #define erealloc(var,ty,x,str)  (void)((var = (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) \
1089                                 ||\
1090                                  (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
1091                                         (str), #var, (long) (x), strerror(errno)),0))
1092
1093 #define efree(p)        free(p)
1094
1095 #ifdef GAWKDEBUG
1096 #define force_number    r_force_number
1097 #define force_string    r_force_string
1098 #else /* not GAWKDEBUG */
1099 #if __GNUC__ >= 2
1100 #define force_number(n) __extension__ ({NODE *_tn = (n);\
1101                         (_tn->flags & NUMCUR) ? _tn->numbr : r_force_number(_tn);})
1102
1103 #define force_string(s) __extension__ ({NODE *_ts = (s);\
1104                            ((_ts->flags & STRCUR) && \
1105                            (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
1106                           _ts : format_val(CONVFMT, CONVFMTidx, _ts);})
1107 #else /* not __GNUC__ */
1108 #define force_number    r_force_number
1109 #define force_string    r_force_string
1110 #endif /* __GNUC__ */
1111 #endif /* GAWKDEBUG */
1112
1113 #define fatal           set_loc(__FILE__, __LINE__), r_fatal
1114
1115 extern jmp_buf fatal_tag;
1116 extern int fatal_tag_valid;
1117
1118 #define PUSH_BINDING(stack, tag, val)   \
1119 if (val++) \
1120         memcpy((char *) (stack), (const char *) tag, sizeof(jmp_buf))
1121 #define POP_BINDING(stack, tag, val)    \
1122 if (--val)      \
1123         memcpy((char *) tag, (const char *) (stack), sizeof(jmp_buf))
1124
1125 /* ------------- Function prototypes or defs (as appropriate) ------------- */
1126 typedef int (*Func_print)(FILE *, const char *, ...);
1127
1128 /* array.c */
1129 typedef enum sort_context { SORTED_IN = 1, ASORT, ASORTI } SORT_CTXT;
1130 extern NODE **assoc_list(NODE *array, const char *sort_str, SORT_CTXT sort_ctxt);
1131 extern NODE *get_array(NODE *symbol, int canfatal);
1132 extern char *array_vname(const NODE *symbol);
1133 extern void array_init(void);
1134 extern void set_SUBSEP(void);
1135 extern NODE *concat_exp(int nargs, int do_subsep);
1136 extern void ahash_unref(NODE *tmp);
1137 extern void assoc_clear(NODE *symbol);
1138 extern NODE *in_array(NODE *symbol, NODE *subs);
1139 extern NODE **assoc_lookup(NODE *symbol, NODE *subs, int reference);
1140 extern void do_delete(NODE *symbol, int nsubs);
1141 extern void do_delete_loop(NODE *symbol, NODE **lhs);
1142 extern NODE *assoc_dump(NODE *symbol, int indent_level);
1143 extern NODE *do_adump(int nargs);
1144 extern NODE *do_asort(int nargs);
1145 extern NODE *do_asorti(int nargs);
1146 extern unsigned long (*hash)(const char *s, size_t len, unsigned long hsize, size_t *code);
1147 /* awkgram.c */
1148 extern NODE *mk_symbol(NODETYPE type, NODE *value);
1149 extern NODE *install_symbol(char *name, NODE *value);
1150 extern NODE *remove_symbol(char *name);
1151 extern NODE *lookup(const char *name);
1152 extern NODE *variable(char *name, NODETYPE type);
1153 extern int parse_program(INSTRUCTION **pcode);
1154 extern void dump_funcs(void);
1155 extern void dump_vars(const char *fname);
1156 extern void release_all_vars(void);
1157 extern const char *getfname(NODE *(*)(int));
1158 extern NODE *stopme(int nargs);
1159 extern void shadow_funcs(void);
1160 extern int check_special(const char *name);
1161 extern int foreach_func(int (*)(INSTRUCTION *, void *), int, void *);
1162 extern INSTRUCTION *bcalloc(OPCODE op, int size, int srcline);
1163 extern void bcfree(INSTRUCTION *);
1164 extern SRCFILE *add_srcfile(int stype, char *src, SRCFILE *curr, int *already_included, int *errcode);
1165 extern void register_deferred_variable(const char *name, NODE *(*load_func)(void));
1166 extern int files_are_same(char *path, SRCFILE *src);
1167 extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
1168 extern void print_vars(Func_print print_func, FILE *fp);
1169 extern AWK_CONTEXT *new_context(void);
1170 extern void push_context(AWK_CONTEXT *ctxt);
1171 extern void pop_context();
1172 extern int in_main_context();
1173 extern void free_context(AWK_CONTEXT *ctxt, int );
1174 extern void append_symbol(char *name);
1175
1176 /* builtin.c */
1177 extern double double_to_int(double d);
1178 extern NODE *do_exp(int nargs);
1179 extern NODE *do_fflush(int nargs);
1180 extern NODE *do_index(int nargs);
1181 extern NODE *do_int(int nargs);
1182 extern NODE *do_isarray(int nargs);
1183 extern NODE *do_length(int nargs);
1184 extern NODE *do_log(int nargs);
1185 extern NODE *do_mktime(int nargs);
1186 extern NODE *do_sprintf(int nargs);
1187 extern void do_printf(int nargs, int redirtype);
1188 extern void print_simple(NODE *tree, FILE *fp);
1189 extern NODE *do_sqrt(int nargs);
1190 extern NODE *do_substr(int nargs);
1191 extern NODE *do_strftime(int nargs);
1192 extern NODE *do_systime(int nargs);
1193 extern NODE *do_system(int nargs);
1194 extern void do_print(int nargs, int redirtype);
1195 extern void do_print_rec(int args, int redirtype);
1196 extern NODE *do_tolower(int nargs);
1197 extern NODE *do_toupper(int nargs);
1198 extern NODE *do_atan2(int nargs);
1199 extern NODE *do_sin(int nargs);
1200 extern NODE *do_cos(int nargs);
1201 extern NODE *do_rand(int nargs);
1202 extern NODE *do_srand(int nargs);
1203 extern NODE *do_match(int nargs);
1204 extern NODE *do_sub(int nargs, unsigned int flags);
1205 extern NODE *format_tree(const char *, size_t, NODE **, long);
1206 extern NODE *do_lshift(int nargs);
1207 extern NODE *do_rshift(int nargs);
1208 extern NODE *do_and(int nargs);
1209 extern NODE *do_or(int nargs);
1210 extern NODE *do_xor(int nargs);
1211 extern NODE *do_compl(int nargs);
1212 extern NODE *do_strtonum(int nargs);
1213 extern AWKNUM nondec2awknum(char *str, size_t len);
1214 extern NODE *do_dcgettext(int nargs);
1215 extern NODE *do_dcngettext(int nargs);
1216 extern NODE *do_bindtextdomain(int nargs);
1217 #if MBS_SUPPORT
1218 extern int strncasecmpmbs(const unsigned char *,
1219                           const unsigned char *, size_t);
1220 #endif
1221 /* eval.c */
1222 extern void PUSH_CODE(INSTRUCTION *cp);
1223 extern INSTRUCTION *POP_CODE(void);
1224 extern int interpret(INSTRUCTION *);
1225 extern int cmp_nodes(NODE *, NODE *);
1226 extern void set_IGNORECASE(void);
1227 extern void set_OFS(void);
1228 extern void set_ORS(void);
1229 extern void set_OFMT(void);
1230 extern void set_CONVFMT(void);
1231 extern void set_BINMODE(void);
1232 extern void set_LINT(void);
1233 extern void set_TEXTDOMAIN(void);
1234 extern void update_ERRNO(void);
1235 extern void update_ERRNO_saved(int);
1236 extern void update_NR(void);
1237 extern void update_NF(void);
1238 extern void update_FNR(void);
1239 extern const char *redflags2str(int);
1240 extern const char *flags2str(int);
1241 extern const char *genflags2str(int flagval, const struct flagtab *tab);
1242 extern const char *nodetype2str(NODETYPE type);
1243 extern void load_casetable(void);
1244
1245 extern AWKNUM calc_exp(AWKNUM x1, AWKNUM x2);
1246 extern const char *opcode2str(OPCODE type);
1247 extern const char *op2str(OPCODE type);
1248 extern NODE **r_get_lhs(NODE *n, int reference);
1249 extern STACK_ITEM *grow_stack(void);
1250 #ifdef PROFILING
1251 extern void dump_fcall_stack(FILE *fp);
1252 #endif
1253 /* ext.c */
1254 NODE *do_ext(int nargs);
1255 #ifdef DYNAMIC
1256 void make_builtin(const char *, NODE *(*)(int), int);
1257 size_t get_curfunc_arg_count(void);
1258 NODE *get_argument(int);
1259 NODE *get_actual_argument(int, int, int);
1260 #define get_scalar_argument(i, opt)  get_actual_argument((i), (opt), FALSE)
1261 #define get_array_argument(i, opt)   get_actual_argument((i), (opt), TRUE)
1262 #endif
1263 /* field.c */
1264 extern void init_fields(void);
1265 extern void set_record(const char *buf, int cnt);
1266 extern void reset_record(void);
1267 extern void set_NF(void);
1268 extern NODE **get_field(long num, Func_ptr *assign);
1269 extern NODE *do_split(int nargs);
1270 extern NODE *do_patsplit(int nargs);
1271 extern void set_FS(void);
1272 extern void set_RS(void);
1273 extern void set_FIELDWIDTHS(void);
1274 extern void set_FPAT(void);
1275 extern void update_PROCINFO_str(const char *subscript, const char *str);
1276 extern void update_PROCINFO_num(const char *subscript, AWKNUM val);
1277
1278 typedef enum {
1279         Using_FS,
1280         Using_FIELDWIDTHS,
1281         Using_FPAT
1282 } field_sep_type;
1283 extern field_sep_type current_field_sep(void);
1284
1285 /* gawkmisc.c */
1286 extern char *gawk_name(const char *filespec);
1287 extern void os_arg_fixup(int *argcp, char ***argvp);
1288 extern int os_devopen(const char *name, int flag);
1289 extern void os_close_on_exec(int fd, const char *name, const char *what, const char *dir);
1290 extern int os_isatty(int fd);
1291 extern int os_isdir(int fd);
1292 extern int os_is_setuid(void);
1293 extern int os_setbinmode(int fd, int mode);
1294 extern void os_restore_mode(int fd);
1295 extern size_t optimal_bufsize(int fd, struct stat *sbuf);
1296 extern int ispath(const char *file);
1297 extern int isdirpunct(int c);
1298
1299 /* io.c */
1300 extern void register_open_hook(void *(*open_func)(IOBUF *));
1301 extern void set_FNR(void);
1302 extern void set_NR(void);
1303
1304 extern struct redirect *redirect(NODE *redir_exp, int redirtype, int *errflg);
1305 extern NODE *do_close(int nargs);
1306 extern int flush_io(void);
1307 extern int close_io(int *stdio_problem);
1308 extern int devopen(const char *name, const char *mode);
1309 extern int srcopen(SRCFILE *s);
1310 extern char *find_source(const char *src, struct stat *stb, int *errcode);
1311 extern NODE *do_getline_redir(int intovar, int redirtype);
1312 extern NODE *do_getline(int intovar, IOBUF *iop);
1313 extern struct redirect *getredirect(const char *str, int len);
1314 extern int inrec(IOBUF *iop, int *errcode);
1315 extern int nextfile(IOBUF **curfile, int skipping);
1316 /* main.c */
1317 extern int arg_assign(char *arg, int initing);
1318 extern int is_std_var(const char *var);
1319 extern char *estrdup(const char *str, size_t len);
1320 extern void update_global_values();
1321 /* msg.c */
1322 extern void gawk_exit(int status);
1323 extern void err(const char *s, const char *emsg, va_list argp) ATTRIBUTE_PRINTF(2, 0);
1324 extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1325 extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1326 extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1327 extern void set_loc (const char *file, int line);
1328 extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1329 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
1330 extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
1331 #else
1332 extern void (*lintfunc) (const char *mesg, ...);
1333 #endif
1334 /* profile.c */
1335 extern void init_profiling(int *flag, const char *def_file);
1336 extern void init_profiling_signals(void);
1337 extern void set_prof_file(const char *filename);
1338 extern void dump_prog(INSTRUCTION *code);
1339 extern char *pp_number(AWKNUM d);
1340 extern char *pp_string(const char *in_str, size_t len, int delim);
1341 extern char *pp_node(NODE *n);
1342 extern int pp_func(INSTRUCTION *pc, void *);
1343 extern void pp_string_fp(Func_print print_func, FILE *fp, const char *str,
1344                 size_t namelen, int delim, int breaklines);
1345 /* node.c */
1346 extern AWKNUM r_force_number(NODE *n);
1347 extern NODE *format_val(const char *format, int index, NODE *s);
1348 extern NODE *r_force_string(NODE *s);
1349 extern NODE *dupnode(NODE *n);
1350 extern NODE *mk_number(AWKNUM x, unsigned int flags);
1351 extern NODE *r_make_str_node(const char *s, unsigned long len, int scan);
1352 extern NODE *more_nodes(void);
1353 extern void unref(NODE *tmp);
1354 extern int parse_escape(const char **string_ptr);
1355 #if MBS_SUPPORT
1356 extern NODE *str2wstr(NODE *n, size_t **ptr);
1357 extern NODE *wstr2str(NODE *n);
1358 #define force_wstring(n)        str2wstr(n, NULL)
1359 extern const wchar_t *wstrstr(const wchar_t *haystack, size_t hs_len,
1360                 const wchar_t *needle, size_t needle_len);
1361 extern const wchar_t *wcasestrstr(const wchar_t *haystack, size_t hs_len,
1362                 const wchar_t *needle, size_t needle_len);
1363 extern void free_wstr(NODE *n);
1364 extern wint_t btowc_cache[];
1365 #define btowc_cache(x) btowc_cache[(x)&0xFF]
1366 extern void init_btowc_cache();
1367 #define is_valid_character(b)   (btowc_cache[(b)&0xFF] != WEOF)
1368 #else
1369 #define free_wstr(NODE) /* empty */
1370 #endif
1371 /* re.c */
1372 extern Regexp *make_regexp(const char *s, size_t len, int ignorecase, int dfa, int canfatal);
1373 extern int research(Regexp *rp, char *str, int start, size_t len, int flags);
1374 extern void refree(Regexp *rp);
1375 extern void reg_error(const char *s);
1376 extern Regexp *re_update(NODE *t);
1377 extern void resyntax(int syntax);
1378 extern void resetup(void);
1379 extern int avoid_dfa(NODE *re, char *str, size_t len);
1380 extern int reisstring(const char *text, size_t len, Regexp *re, const char *buf);
1381 extern int remaybelong(const char *text, size_t len);
1382 extern int isnondecimal(const char *str, int use_locale);
1383
1384 /* floatcomp.c */
1385 #ifdef VMS      /* VMS linker weirdness? */
1386 #define Ceil    gawk_ceil
1387 #define Floor   gawk_floor
1388 #endif
1389
1390 extern AWKNUM Floor(AWKNUM n);
1391 extern AWKNUM Ceil(AWKNUM n);
1392 #ifdef HAVE_UINTMAX_T
1393 extern uintmax_t adjust_uint(uintmax_t n);
1394 #else
1395 #define adjust_uint(n) (n)
1396 #endif
1397
1398 #define INVALID_HANDLE (-1)
1399
1400 #ifdef HAVE_SYS_WAIT_H
1401 #include <sys/wait.h>
1402 #endif
1403 #ifndef WEXITSTATUS
1404 #if defined(VMS)
1405 #define WEXITSTATUS(stat_val) (stat_val)
1406 #else /* ! defined(VMS) */
1407 #define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
1408 #endif /* ! defined(VMS)) */
1409 #endif /* WEXITSTATUS */
1410
1411 /* EXIT_SUCCESS and EXIT_FAILURE normally come from <stdlib.h> */
1412 #ifndef EXIT_SUCCESS
1413 # define EXIT_SUCCESS 0
1414 #endif
1415 #ifndef EXIT_FAILURE
1416 # define EXIT_FAILURE 1
1417 #endif
1418 /* EXIT_FATAL is specific to gawk, not part of Standard C */
1419 #ifndef EXIT_FATAL
1420 # define EXIT_FATAL   2
1421 #endif
1422
1423 /* For z/OS, from Dave Pitts. EXIT_FAILURE is normally 8, make it 1. */
1424 #ifdef ZOS_USS
1425 #undef DYNAMIC
1426
1427 #ifdef EXIT_FAILURE
1428 #undef EXIT_FAILURE
1429 #endif
1430
1431 #define EXIT_FAILURE 1
1432 #endif