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