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