Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / awk / awk.h
1 /*
2  * awk.h -- Definitions for gawk. 
3  */
4
5 /* 
6  * Copyright (C) 1986, 1988, 1989, 1991-2000 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
24  *
25  * $FreeBSD: src/contrib/awk/awk.h,v 1.5.2.1 2001/01/23 22:08:30 asmodai Exp $
26  */
27
28 /* ------------------------------ Includes ------------------------------ */
29
30 /*
31  * config.h absolutely, positively, *M*U*S*T* be included before
32  * any system headers.  Otherwise, extreme death, destruction
33  * and loss of life results.
34  *
35  * Well, OK, gawk just won't work on systems using egcs and LFS.  But
36  * that's almost as bad.
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifndef _GNU_SOURCE
43 #define _GNU_SOURCE     1       /* enable GNU extensions */
44 #endif /* _GNU_SOURCE */
45
46 #include <stdio.h>
47 #include <assert.h>
48 #ifdef HAVE_LIMITS_H
49 #include <limits.h>
50 #endif /* HAVE_LIMITS_H */
51 #include <ctype.h>
52 #include <setjmp.h>
53 #ifdef HAVE_LOCALE_H
54 #include <locale.h>
55 #endif /* HAVE_LOCALE_H */
56 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
57 #include <stdarg.h>
58 #else
59 #include <varargs.h>
60 #endif
61 #include <signal.h>
62 #include <time.h>
63 #include <errno.h>
64 #if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
65 extern int errno;
66 #endif
67 #ifdef HAVE_SIGNUM_H
68 #include <signum.h>
69 #endif
70
71 /* ----------------- System dependencies (with more includes) -----------*/
72
73 /* This section is the messiest one in the file, not a lot that can be done */
74
75 /* First, get the ctype stuff right; from Jim Meyering */
76 #if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
77 #define ISASCII(c) 1
78 #else
79 #define ISASCII(c) isascii(c)
80 #endif
81
82 #ifdef isblank
83 #define ISBLANK(c) (ISASCII(c) && isblank(c))
84 #else
85 #define ISBLANK(c) ((c) == ' ' || (c) == '\t')
86 #endif
87 #ifdef isgraph
88 #define ISGRAPH(c) (ISASCII(c) && isgraph(c))
89 #else
90 #define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
91 #endif
92
93 #define ISPRINT(c) (ISASCII (c) && isprint (c))
94 #define ISDIGIT(c) (ISASCII (c) && isdigit (c))
95 #define ISALNUM(c) (ISASCII (c) && isalnum (c))
96 #define ISALPHA(c) (ISASCII (c) && isalpha (c))
97 #define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
98 #define ISLOWER(c) (ISASCII (c) && islower (c))
99 #define ISPUNCT(c) (ISASCII (c) && ispunct (c))
100 #define ISSPACE(c) (ISASCII (c) && isspace (c))
101 #define ISUPPER(c) (ISASCII (c) && isupper (c))
102 #define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
103
104
105 #ifdef __STDC__
106 #define P(s)    s
107 #define MALLOC_ARG_T size_t
108 #else   /* not __STDC__ */
109 #define P(s)    ()
110 #define MALLOC_ARG_T unsigned
111 #define volatile
112 #define const
113 #endif  /* not __STDC__ */
114
115 #if ! defined(VMS) || (! defined(VAXC) && ! defined(__DECC))
116 #include <sys/types.h>
117 #include <sys/stat.h>
118 #else   /* VMS w/ VAXC or DECC */
119 #include <types.h>
120 #include <stat.h>
121 #include <file.h>       /* avoid <fcntl.h> in io.c */
122 #ifdef __DECC
123 /* DEC C implies DECC$SHR, which doesn't have the %g problem of VAXCRTL */
124 #undef GFMT_WORKAROUND
125 #endif
126 #endif  /* VMS w/ VAXC or DECC */
127
128 #ifdef STDC_HEADERS
129 #include <stdlib.h>
130 #else   /* not STDC_HEADERS */
131 #include "protos.h"
132 #endif  /* not STDC_HEADERS */
133
134 #ifdef HAVE_STRING_H
135 #include <string.h>
136 #ifdef NEED_MEMORY_H
137 #include <memory.h>
138 #endif  /* NEED_MEMORY_H */
139 #else   /* not HAVE_STRING_H */
140 #ifdef HAVE_STRINGS_H
141 #include <strings.h>
142 #endif  /* HAVE_STRINGS_H */
143 #endif  /* not HAVE_STRING_H */
144
145 #ifdef NeXT
146 #if __GNUC__ < 2 || __GNUC_MINOR__ < 7
147 #include <libc.h>
148 #endif
149 #undef atof
150 #define getopt GNU_getopt
151 #define GFMT_WORKAROUND
152 #endif  /* NeXT */
153
154 #if defined(atarist) || defined(VMS)
155 #include <unixlib.h>
156 #endif  /* atarist || VMS */
157
158 #if HAVE_UNISTD_H
159 #include <unistd.h>
160 #endif  /* HAVE_UNISTD_H */
161
162 #ifndef HAVE_VPRINTF
163 /* if you don't have vprintf, try this and cross your fingers. */
164 #ifdef  HAVE_DOPRNT
165 #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
166 #else   /* not HAVE_DOPRNT */
167 you
168 lose
169 #endif  /* not HAVE_DOPRNT */
170 #endif  /* HAVE_VPRINTF */
171
172 #ifndef HAVE_SETLOCALE
173 #define setlocale(locale, val)  /* nothing */
174 #endif /* HAVE_SETLOCALE */
175
176 #ifdef VMS
177 #include "vms/redirect.h"
178 #endif  /*VMS*/
179
180 #ifdef atarist
181 #include "atari/redirect.h"
182 #endif
183
184 #define GNU_REGEX
185 #ifdef GNU_REGEX
186 #ifdef __FreeBSD__
187 #include <gnuregex.h>
188 #else
189 #include "regex.h"
190 #endif
191 #include "dfa.h"
192 typedef struct Regexp {
193         struct re_pattern_buffer pat;
194         struct re_registers regs;
195         struct dfa dfareg;
196         int dfa;
197 } Regexp;
198 #define RESTART(rp,s)   (rp)->regs.start[0]
199 #define REEND(rp,s)     (rp)->regs.end[0]
200 #define SUBPATSTART(rp,s,n)     (rp)->regs.start[n]
201 #define SUBPATEND(rp,s,n)       (rp)->regs.end[n]
202 #endif  /* GNU_REGEX */
203
204 /* ------------------ Constants, Structures, Typedefs  ------------------ */
205
206 #ifndef AWKNUM
207 #define AWKNUM  double
208 #endif
209
210 #ifndef TRUE
211 /* a bit hackneyed, but what the heck */
212 #define TRUE    1
213 #define FALSE   0
214 #endif
215
216 /* Figure out what '\a' really is. */
217 #ifdef __STDC__
218 #define BELL    '\a'            /* sure makes life easy, don't it? */
219 #else
220 #       if 'z' - 'a' == 25      /* ascii */
221 #               if 'a' != 97    /* machine is dumb enough to use mark parity */
222 #                       define BELL     '\207'
223 #               else
224 #                       define BELL     '\07'
225 #               endif
226 #       else
227 #               define BELL     '\057'
228 #       endif
229 #endif
230
231 typedef enum nodevals {
232         /* illegal entry == 0 */
233         Node_illegal,
234
235         /* binary operators  lnode and rnode are the expressions to work on */
236         Node_times,
237         Node_quotient,
238         Node_mod,
239         Node_plus,
240         Node_minus,
241         Node_cond_pair,         /* conditional pair (see Node_line_range) */
242         Node_subscript,
243         Node_concat,
244         Node_exp,
245
246         /* unary operators   subnode is the expression to work on */
247         Node_preincrement,
248         Node_predecrement,
249         Node_postincrement,
250         Node_postdecrement,
251         Node_unary_minus,
252         Node_field_spec,
253
254         /* assignments   lnode is the var to assign to, rnode is the exp */
255         Node_assign,
256         Node_assign_times,
257         Node_assign_quotient,
258         Node_assign_mod,
259         Node_assign_plus,
260         Node_assign_minus,
261         Node_assign_exp,
262
263         /* boolean binaries   lnode and rnode are expressions */
264         Node_and,
265         Node_or,
266
267         /* binary relationals   compares lnode and rnode */
268         Node_equal,
269         Node_notequal,
270         Node_less,
271         Node_greater,
272         Node_leq,
273         Node_geq,
274         Node_match,
275         Node_nomatch,
276
277         /* unary relationals   works on subnode */
278         Node_not,
279
280         /* program structures */
281         Node_rule_list,         /* lnode is a rule, rnode is rest of list */
282         Node_rule_node,         /* lnode is pattern, rnode is statement */
283         Node_statement_list,    /* lnode is statement, rnode is more list */
284         Node_if_branches,       /* lnode is to run on true, rnode on false */
285         Node_expression_list,   /* lnode is an exp, rnode is more list */
286         Node_param_list,        /* lnode is a variable, rnode is more list */
287
288         /* keywords */
289         Node_K_if,              /* lnode is conditonal, rnode is if_branches */
290         Node_K_while,           /* lnode is condtional, rnode is stuff to run */
291         Node_K_for,             /* lnode is for_struct, rnode is stuff to run */
292         Node_K_arrayfor,        /* lnode is for_struct, rnode is stuff to run */
293         Node_K_break,           /* no subs */
294         Node_K_continue,        /* no subs */
295         Node_K_print,           /* lnode is exp_list, rnode is redirect */
296         Node_K_printf,          /* lnode is exp_list, rnode is redirect */
297         Node_K_next,            /* no subs */
298         Node_K_exit,            /* subnode is return value, or NULL */
299         Node_K_do,              /* lnode is conditional, rnode stuff to run */
300         Node_K_return,          /* lnode is return value */
301         Node_K_delete,          /* lnode is array, rnode is subscript */
302         Node_K_delete_loop,     /* lnode is array, rnode is subscript */
303         Node_K_getline,         /* lnode is opt var, rnode is redirection */
304         Node_K_function,        /* lnode is statement list, rnode is params */
305         Node_K_nextfile,        /* no subs */
306
307         /* I/O redirection for print statements */
308         Node_redirect_output,   /* subnode is where to redirect */
309         Node_redirect_append,   /* subnode is where to redirect */
310         Node_redirect_pipe,     /* subnode is where to redirect */
311         Node_redirect_pipein,   /* subnode is where to redirect */
312         Node_redirect_input,    /* subnode is where to redirect */
313
314         /* Variables */
315         Node_var,               /* rnode is value, lnode is array stuff */
316         Node_var_array,         /* array is ptr to elements, asize num of eles */
317         Node_val,               /* node is a value - type in flags */
318
319         /* Builtins   subnode is explist to work on, proc is func to call */
320         Node_builtin,
321
322         /*
323          * pattern: conditional ',' conditional ;  lnode of Node_line_range
324          * is the two conditionals (Node_cond_pair), other word (rnode place)
325          * is a flag indicating whether or not this range has been entered.
326          */
327         Node_line_range,
328
329         /*
330          * boolean test of membership in array lnode is string-valued
331          * expression rnode is array name 
332          */
333         Node_in_array,
334
335         Node_func,              /* lnode is param. list, rnode is body */
336         Node_func_call,         /* lnode is name, rnode is argument list */
337
338         Node_cond_exp,          /* lnode is conditonal, rnode is if_branches */
339         Node_regex,             /* a regexp, text, compiled, flags, etc */
340         Node_hashnode,          /* an identifier in the symbol table */
341         Node_ahash,             /* an array element */
342         Node_array_ref,         /* array passed by ref as parameter */
343         Node_NF,                /* variables recognized in the grammar */
344         Node_NR,
345         Node_FNR,
346         Node_FS,
347         Node_RS,
348         Node_FIELDWIDTHS,
349         Node_IGNORECASE,
350         Node_OFS,
351         Node_ORS,
352         Node_OFMT,
353         Node_CONVFMT,
354         Node_final              /* sentry value, not legal */
355 } NODETYPE;
356
357 /*
358  * NOTE - this struct is a rather kludgey -- it is packed to minimize
359  * space usage, at the expense of cleanliness.  Alter at own risk.
360  */
361 typedef struct exp_node {
362         union {
363                 struct {
364                         union {
365                                 struct exp_node *lptr;
366                                 char *param_name;
367                                 long ll;
368                         } l;
369                         union {
370                                 struct exp_node *rptr;
371                                 struct exp_node *(*pptr)();
372                                 Regexp *preg;
373                                 struct for_loop_header *hd;
374                                 struct exp_node **av;
375                                 int r_ent;      /* range entered */
376                         } r;
377                         union {
378                                 struct exp_node *extra;
379                                 long xl;
380                         } x;
381                         char *name;
382                         short number;
383                         unsigned char reflags;
384 #                               define  CASE    1
385 #                               define  CONST   2
386 #                               define  FS_DFLT 4
387                 } nodep;
388                 struct {
389                         AWKNUM fltnum;  /* this is here for optimal packing of
390                                          * the structure on many machines
391                                          */
392                         char *sp;
393                         size_t slen;
394                         long sref;
395                         int idx;
396                 } val;
397                 struct {
398                         struct exp_node *next;
399                         char *name;
400                         size_t length;
401                         struct exp_node *value;
402                 } hash;
403 #define hnext   sub.hash.next
404 #define hname   sub.hash.name
405 #define hlength sub.hash.length
406 #define hvalue  sub.hash.value
407                 struct {
408                         struct exp_node *next;
409                         struct exp_node *name;
410                         struct exp_node *value;
411                 } ahash;
412 #define ahnext  sub.ahash.next
413 #define ahname  sub.ahash.name
414 #define ahvalue sub.ahash.value
415         } sub;
416         NODETYPE type;
417         unsigned short flags;
418 #               define  MALLOC  1       /* can be free'd */
419 #               define  TEMP    2       /* should be free'd */
420 #               define  PERM    4       /* can't be free'd */
421 #               define  STRING  8       /* assigned as string */
422 #               define  STR     16      /* string value is current */
423 #               define  NUM     32      /* numeric value is current */
424 #               define  NUMBER  64      /* assigned as number */
425 #               define  MAYBE_NUM 128   /* user input: if NUMERIC then
426                                          * a NUMBER */
427 #               define  ARRAYMAXED 256  /* array is at max size */
428 #               define  SCALAR     512  /* used as scalar, can't be array */
429 #               define  FUNC    1024    /* this parameter is really a
430                                          * function name; see awk.y */
431 #               define  FIELD   2048    /* this is a field */
432
433         char *vname;    /* variable's name */
434 } NODE;
435
436 #define lnode   sub.nodep.l.lptr
437 #define nextp   sub.nodep.l.lptr
438 #define rnode   sub.nodep.r.rptr
439 #define source_file     sub.nodep.name
440 #define source_line     sub.nodep.number
441 #define param_cnt       sub.nodep.number
442 #define param   sub.nodep.l.param_name
443
444 #define subnode lnode
445 #define proc    sub.nodep.r.pptr
446
447 #define re_reg  sub.nodep.r.preg
448 #define re_flags sub.nodep.reflags
449 #define re_text lnode
450 #define re_exp  sub.nodep.x.extra
451 #define re_cnt  sub.nodep.number
452
453 #define forsub  lnode
454 #define forloop rnode->sub.nodep.r.hd
455
456 #define stptr   sub.val.sp
457 #define stlen   sub.val.slen
458 #define stref   sub.val.sref
459 #define stfmt   sub.val.idx
460
461 #define numbr   sub.val.fltnum
462
463 #define var_value lnode
464 #define var_array sub.nodep.r.av
465 #define array_size sub.nodep.l.ll
466 #define table_size sub.nodep.x.xl
467
468 #define orig_array sub.nodep.x.extra
469
470 #define condpair lnode
471 #define triggered sub.nodep.r.r_ent
472
473 /* a regular for loop */
474 typedef struct for_loop_header {
475         NODE *init;
476         NODE *cond;
477         NODE *incr;
478 } FOR_LOOP_HEADER;
479
480 /* for "for(iggy in foo) {" */
481 struct search {
482         NODE *sym;
483         size_t idx;
484         NODE *bucket;
485         NODE *retval;
486 };
487
488 /* for faster input, bypass stdio */
489 typedef struct iobuf {
490         const char *name;
491         int fd;
492         char *buf;
493         char *off;
494         char *end;
495         size_t size;    /* this will be determined by an fstat() call */
496         int cnt;
497         long secsiz;
498         int flag;
499 #               define  IOP_IS_TTY      1
500 #               define  IOP_IS_INTERNAL 2
501 #               define  IOP_NO_FREE     4
502 #               define  IOP_MMAPPED     8
503 #               define  IOP_NOFREE_OBJ  16
504         int (*getrec)();
505 } IOBUF;
506
507 typedef void (*Func_ptr)();
508
509 /* structure used to dynamically maintain a linked-list of open files/pipes */
510 struct redirect {
511         unsigned int flag;
512 #               define  RED_FILE        1
513 #               define  RED_PIPE        2
514 #               define  RED_READ        4
515 #               define  RED_WRITE       8
516 #               define  RED_APPEND      16
517 #               define  RED_NOBUF       32
518 #               define  RED_USED        64      /* closed temporarily to reuse fd */
519 #               define  RED_EOF         128
520         char *value;
521         FILE *fp;
522         FILE *ifp;      /* input fp, needed for PIPES_SIMULATED */
523         IOBUF *iop;
524         int pid;
525         int status;
526         struct redirect *prev;
527         struct redirect *next;
528 };
529
530 /* structure for our source, either a command line string or a source file */
531 struct src {
532        enum srctype { CMDLINE = 1, SOURCEFILE } stype;
533        char *val;
534 };
535
536 /* longjmp return codes, must be nonzero */
537 /* Continue means either for loop/while continue, or next input record */
538 #define TAG_CONTINUE 1
539 /* Break means either for/while break, or stop reading input */
540 #define TAG_BREAK 2
541 /* Return means return from a function call; leave value in ret_node */
542 #define TAG_RETURN 3
543
544 #ifndef LONG_MAX
545 #define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
546 #endif
547 #ifndef ULONG_MAX
548 #define ULONG_MAX (~(unsigned long)0)
549 #endif
550 #ifndef LONG_MIN
551 #define LONG_MIN ((long)(-LONG_MAX - 1L))
552 #endif
553 #define HUGE    LONG_MAX 
554
555 /* -------------------------- External variables -------------------------- */
556 /* gawk builtin variables */
557 extern long NF;
558 extern long NR;
559 extern long FNR;
560 extern int IGNORECASE;
561 extern int RS_is_null;
562 extern char *OFS;
563 extern int OFSlen;
564 extern char *ORS;
565 extern int ORSlen;
566 extern char *OFMT;
567 extern char *CONVFMT;
568 extern int CONVFMTidx;
569 extern int OFMTidx;
570 extern NODE *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
571 extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
572 extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
573 extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node; 
574 extern NODE **stack_ptr;
575 extern NODE *Nnull_string;
576 extern NODE **fields_arr;
577 extern int sourceline;
578 extern char *source;
579 extern NODE *expression_value;
580
581 #if __GNUC__ < 2
582 extern NODE *_t;        /* used as temporary in tree_eval */
583 #endif
584
585 extern NODE *nextfree;
586 extern int field0_valid;
587 extern int do_traditional;
588 extern int do_posix;
589 extern int do_lint;
590 extern int do_lint_old;
591 extern int do_intervals;
592 extern int in_begin_rule;
593 extern int in_end_rule;
594
595 extern const char *myname;
596
597 extern char quote;
598 extern char *defpath;
599 extern char envsep;
600
601 extern char casetable[];        /* for case-independent regexp matching */
602
603 /* ------------------------- Pseudo-functions ------------------------- */
604
605 #define is_identchar(c)         (isalnum(c) || (c) == '_')
606 #define isnondecimal(str)       (((str)[0]) == '0' && (ISDIGIT((str)[1]) \
607                                         || (str)[1] == 'x' || (str)[1] == 'X'))
608
609 #ifdef MPROF
610 #define getnode(n)      emalloc(n, NODE *, sizeof(NODE), "getnode")
611 #define freenode(n)     free(n)
612 #else   /* not MPROF */
613 #define getnode(n)      if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
614                         else n = more_nodes()
615 #define freenode(n)     ((n)->flags &= ~SCALAR, (n)->nextp = nextfree, nextfree = (n))
616 #endif  /* not MPROF */
617
618 #ifdef DEBUG
619 #undef freenode
620 #define get_lhs(p, a)   r_get_lhs((p), (a))
621 #define m_tree_eval(t, iscond)  r_tree_eval(t, iscond)
622 #else
623 #define get_lhs(p, a)   ((p)->type == Node_var ? (&(p)->var_value) : \
624                         r_get_lhs((p), (a)))
625 #if __GNUC__ >= 2
626 #define m_tree_eval(t, iscond) \
627                         ({NODE * _t = (t);                 \
628                            if (_t == NULL)                 \
629                                _t = Nnull_string;          \
630                            else {                          \
631                                switch(_t->type) {          \
632                                case Node_val:              \
633                                    break;                  \
634                                case Node_var:              \
635                                    _t = _t->var_value;     \
636                                    break;                  \
637                                default:                    \
638                                    _t = r_tree_eval(_t, iscond);\
639                                    break;                  \
640                                }                           \
641                            }                               \
642                            _t;})
643 #else
644 #define m_tree_eval(t, iscond)  (_t = (t), _t == NULL ? Nnull_string : \
645                         (_t->type == Node_param_list ? \
646                           r_tree_eval(_t, iscond) : \
647                         (_t->type == Node_val ? _t : \
648                         (_t->type == Node_var ? _t->var_value : \
649                           r_tree_eval(_t, iscond)))))
650 #endif /* __GNUC__ */
651 #endif /* not DEBUG */
652 #define tree_eval(t)    m_tree_eval(t, FALSE)
653
654 #define make_number(x)  mk_number((x), (unsigned int)(MALLOC|NUM|NUMBER))
655 #define tmp_number(x)   mk_number((x), (unsigned int)(MALLOC|TEMP|NUM|NUMBER))
656
657 #define free_temp(n)    do { if ((n)->flags&TEMP) { unref(n); }} while (FALSE)
658 #define make_string(s, l)       make_str_node((s), (size_t) (l), FALSE)
659 #define         SCAN                    1
660 #define         ALREADY_MALLOCED        2
661
662 #define cant_happen()   r_fatal("internal error line %d, file: %s", \
663                                 __LINE__, __FILE__);
664
665 #ifdef HAVE_STRINGIZE
666 #define emalloc(var,ty,x,str)   (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
667                                  (fatal("%s: %s: can't allocate memory (%s)",\
668                                         (str), #var, strerror(errno)),0))
669 #define erealloc(var,ty,x,str)  (void)((var=(ty)realloc((char *)var,\
670                                                   (MALLOC_ARG_T)(x))) ||\
671                                  (fatal("%s: %s: can't allocate memory (%s)",\
672                                         (str), #var, strerror(errno)),0))
673 #else /* HAVE_STRINGIZE */
674 #define emalloc(var,ty,x,str)   (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
675                                  (fatal("%s: %s: can't allocate memory (%s)",\
676                                         (str), "var", strerror(errno)),0))
677 #define erealloc(var,ty,x,str)  (void)((var=(ty)realloc((char *)var,\
678                                                   (MALLOC_ARG_T)(x))) ||\
679                                  (fatal("%s: %s: can't allocate memory (%s)",\
680                                         (str), "var", strerror(errno)),0))
681 #endif /* HAVE_STRINGIZE */
682
683 #ifdef DEBUG
684 #define force_number    r_force_number
685 #define force_string    r_force_string
686 #else /* not DEBUG */
687 #ifdef lint
688 extern AWKNUM force_number();
689 #endif
690 #if __GNUC__ >= 2
691 #define force_number(n) ({NODE *_tn = (n);\
692                         (_tn->flags & NUM) ?_tn->numbr : r_force_number(_tn);})
693 #define force_string(s) ({NODE *_ts = (s);\
694                           ((_ts->flags & STR) && \
695                            (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
696                           _ts : r_force_string(_ts);})
697 #else
698 #ifdef MSDOS
699 extern double _msc51bug;
700 #define force_number(n) (_msc51bug=(_t = (n),\
701                           (_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
702 #else /* not MSDOS */
703 #define force_number(n) (_t = (n),\
704                          (_t->flags & NUM) ? _t->numbr : r_force_number(_t))
705 #endif /* not MSDOS */
706 #define force_string(s) (_t = (s),((_t->flags & STR) && \
707                                    (_t->stfmt == -1 || \
708                                     _t->stfmt == CONVFMTidx))? \
709                          _t : r_force_string(_t))
710 #endif /* not __GNUC__ */
711 #endif /* not DEBUG */
712
713 #define STREQ(a,b)      (*(a) == *(b) && strcmp((a), (b)) == 0)
714 #define STREQN(a,b,n)   ((n) && *(a)== *(b) && \
715                          strncmp((a), (b), (size_t) (n)) == 0)
716
717 #define fatal           set_loc(__FILE__, __LINE__), r_fatal
718
719 /* ------------- Function prototypes or defs (as appropriate) ------------- */
720
721 /* array.c */
722 extern NODE *concat_exp P((NODE *tree));
723 extern void assoc_clear P((NODE *symbol));
724 extern unsigned int hash P((const char *s, size_t len, unsigned long hsize));
725 extern int in_array P((NODE *symbol, NODE *subs));
726 extern NODE **assoc_lookup P((NODE *symbol, NODE *subs));
727 extern void do_delete P((NODE *symbol, NODE *tree));
728 extern void do_delete_loop P((NODE *symbol, NODE *tree));
729 extern void assoc_scan P((NODE *symbol, struct search *lookat));
730 extern void assoc_next P((struct search *lookat));
731 extern NODE *assoc_dump P((NODE *symbol));
732 extern NODE *do_adump P((NODE *tree));
733 /* awktab.c */
734 extern char *tokexpand P((void));
735 extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
736 extern NODE *install P((char *name, NODE *value));
737 extern NODE *lookup P((const char *name));
738 extern NODE *variable P((char *name, int can_free, NODETYPE type));
739 extern int yyparse P((void));
740 extern NODE *stopme P((NODE *tree));
741 /* builtin.c */
742 extern double double_to_int P((double d));
743 extern NODE *do_exp P((NODE *tree));
744 extern NODE *do_fflush P((NODE *tree));
745 extern NODE *do_index P((NODE *tree));
746 extern NODE *do_int P((NODE *tree));
747 extern NODE *do_length P((NODE *tree));
748 extern NODE *do_log P((NODE *tree));
749 extern NODE *do_sprintf P((NODE *tree));
750 extern void do_printf P((NODE *tree));
751 extern void print_simple P((NODE *tree, FILE *fp));
752 extern NODE *do_sqrt P((NODE *tree));
753 extern NODE *do_substr P((NODE *tree));
754 extern NODE *do_strftime P((NODE *tree));
755 extern NODE *do_systime P((NODE *tree));
756 extern NODE *do_system P((NODE *tree));
757 extern void do_print P((NODE *tree));
758 extern NODE *do_tolower P((NODE *tree));
759 extern NODE *do_toupper P((NODE *tree));
760 extern NODE *do_atan2 P((NODE *tree));
761 extern NODE *do_sin P((NODE *tree));
762 extern NODE *do_cos P((NODE *tree));
763 extern NODE *do_rand P((NODE *tree));
764 extern NODE *do_srand P((NODE *tree));
765 extern NODE *do_match P((NODE *tree));
766 extern NODE *do_gsub P((NODE *tree));
767 extern NODE *do_sub P((NODE *tree));
768 extern NODE *do_gensub P((NODE *tree));
769 #ifdef BITOPS
770 extern NODE *do_lshift P((NODE *tree));
771 extern NODE *do_rshift P((NODE *tree));
772 extern NODE *do_and P((NODE *tree));
773 extern NODE *do_or P((NODE *tree));
774 extern NODE *do_xor P((NODE *tree));
775 extern NODE *do_compl P((NODE *tree));
776 extern NODE *do_strtonum P((NODE *tree));
777 #endif /* BITOPS */
778 #if defined(BITOPS) || defined(NONDECDATA)
779 extern AWKNUM nondec2awknum P((char *str, size_t len));
780 #endif /* defined(BITOPS) || defined(NONDECDATA) */
781 /* eval.c */
782 extern int interpret P((NODE *volatile tree));
783 extern NODE *r_tree_eval P((NODE *tree, int iscond));
784 extern int cmp_nodes P((NODE *t1, NODE *t2));
785 extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign));
786 extern void set_IGNORECASE P((void));
787 void set_OFS P((void));
788 void set_ORS P((void));
789 void set_OFMT P((void));
790 void set_CONVFMT P((void));
791 extern char *flags2str P((int));
792 /* field.c */
793 extern void init_fields P((void));
794 extern void set_record P((char *buf, int cnt, int freeold));
795 extern void reset_record P((void));
796 extern void set_NF P((void));
797 extern NODE **get_field P((long num, Func_ptr *assign));
798 extern NODE *do_split P((NODE *tree));
799 extern void set_FS P((void));
800 extern void set_FS_if_not_FIELDWIDTHS P((void));
801 extern void set_RS P((void));
802 extern void set_FIELDWIDTHS P((void));
803 extern int using_fieldwidths P((void));
804 /* gawkmisc.c */
805 extern char *gawk_name P((const char *filespec));
806 extern void os_arg_fixup P((int *argcp, char ***argvp));
807 extern int os_devopen P((const char *name, int flag));
808 extern int optimal_bufsize P((int fd, struct stat *sbuf));
809 extern int ispath P((const char *file));
810 extern int isdirpunct P((int c));
811 /* io.c */
812 extern void set_FNR P((void));
813 extern void set_NR P((void));
814 extern void do_input P((void));
815 extern struct redirect *redirect P((NODE *tree, int *errflg));
816 extern NODE *do_close P((NODE *tree));
817 extern int flush_io P((void));
818 extern int close_io P((void));
819 extern int devopen P((const char *name, const char *mode));
820 extern int pathopen P((const char *file));
821 extern NODE *do_getline P((NODE *tree));
822 extern void do_nextfile P((void));
823 extern struct redirect *getredirect P((char *str, int len));
824 /* main.c */
825 extern int main P((int argc, char **argv));
826 extern void load_environ P((void));
827 extern char *arg_assign P((char *arg));
828 extern RETSIGTYPE catchsig P((int sig, int code));
829 /* msg.c */
830 extern void err P((const char *s, const char *emsg, va_list argp));
831 #if _MSC_VER == 510
832 extern void msg P((va_list va_alist, ...));
833 extern void error P((va_list va_alist, ...));
834 extern void warning P((va_list va_alist, ...));
835 extern void set_loc P((char *file, int line));
836 extern void r_fatal P((va_list va_alist, ...));
837 #else
838 #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
839 extern void msg (char *mesg, ...);
840 extern void error (char *mesg, ...);
841 extern void warning (char *mesg, ...);
842 extern void set_loc (char *file, int line);
843 extern void r_fatal (char *mesg, ...);
844 #else
845 extern void msg ();
846 extern void error ();
847 extern void warning ();
848 extern void set_loc ();
849 extern void r_fatal ();
850 #endif
851 #endif
852 /* node.c */
853 extern AWKNUM r_force_number P((NODE *n));
854 extern NODE *format_val P((char *format, int index, NODE *s));
855 extern NODE *r_force_string P((NODE *s));
856 extern NODE *dupnode P((NODE *n));
857 extern NODE *mk_number P((AWKNUM x, unsigned int flags));
858 extern NODE *make_str_node P((char *s, size_t len, int scan ));
859 extern NODE *tmp_string P((char *s, size_t len ));
860 extern NODE *more_nodes P((void));
861 #ifdef DEBUG
862 extern void freenode P((NODE *it));
863 #endif
864 extern void unref P((NODE *tmp));
865 extern int parse_escape P((char **string_ptr));
866 /* re.c */
867 extern Regexp *make_regexp P((char *s, size_t len, int ignorecase, int dfa));
868 extern int research P((Regexp *rp, char *str, int start,
869                        size_t len, int need_start));
870 extern void refree P((Regexp *rp));
871 extern void reg_error P((const char *s));
872 extern Regexp *re_update P((NODE *t));
873 extern void resyntax P((int syntax));
874 extern void resetup P((void));
875 extern int avoid_dfa P((NODE *re, char *str, size_t len));      /* temporary */
876
877 /* strncasecmp.c */
878 extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
879
880 #if defined(atarist)
881 #if defined(PIPES_SIMULATED)
882 /* atari/tmpnam.c */
883 extern char *tmpnam P((char *buf));
884 extern char *tempnam P((const char *path, const char *base));
885 #else
886 #include <wait.h>
887 #endif
888 #include <fcntl.h>
889 #define INVALID_HANDLE  (__SMALLEST_VALID_HANDLE - 1)
890 #else
891 #define INVALID_HANDLE (-1)
892 #endif /* atarist */
893
894 #ifndef STATIC
895 #define STATIC static
896 #endif
897
898 #ifdef C_ALLOCA
899 /* The __hpux check is to avoid conflicts with bison's definition of
900    alloca() in awktab.c.*/
901 #if (defined(__STDC__) && __STDC__) || defined (__hpux)
902 extern void *alloca P((unsigned));
903 #else
904 extern char *alloca P((unsigned));
905 #endif
906 #endif