1/*
2 * eval.c - gawk parse tree interpreter
3 */
4
5/*
6 * Copyright (C) 1986, 1988, 1989, 1991-2003 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
26#include "awk.h"
27
28extern double pow P((double x, double y));
29extern double modf P((double x, double *yp));
30extern double fmod P((double x, double y));
31
32static int eval_condition P((NODE *tree));
33static NODE *op_assign P((NODE *tree));
34static NODE *func_call P((NODE *tree));
35static NODE *match_op P((NODE *tree));
36static void pop_forloop P((void));
37static inline void pop_all_forloops P((void));
38static void push_forloop P((const char *varname, NODE **elems, size_t nelems));
39static void push_args P((int count, NODE *arglist, NODE **oldstack,
40			const char *func_name, char **varnames));
41static inline void pop_fcall_stack P((void));
42static void pop_fcall P((void));
43static int comp_func P((const void *p1, const void *p2));
44
45#if __GNUC__ < 2
46NODE *_t;		/* used as a temporary in macros */
47#endif
48#ifdef MSDOS
49double _msc51bug;	/* to get around a bug in MSC 5.1 */
50#endif
51NODE *ret_node;
52int OFSlen;
53int ORSlen;
54int OFMTidx;
55int CONVFMTidx;
56
57/* Profiling stuff */
58#ifdef PROFILING
59#define INCREMENT(n)	n++
60#else
61#define INCREMENT(n)	/* nothing */
62#endif
63
64/* Macros and variables to save and restore function and loop bindings */
65/*
66 * the val variable allows return/continue/break-out-of-context to be
67 * caught and diagnosed
68 */
69#define PUSH_BINDING(stack, x, val) (memcpy((char *)(stack), (const char *)(x), sizeof(jmp_buf)), val++)
70#define RESTORE_BINDING(stack, x, val) (memcpy((char *)(x), (const char *)(stack), sizeof(jmp_buf)), val--)
71
72static jmp_buf loop_tag;		/* always the current binding */
73static int loop_tag_valid = FALSE;	/* nonzero when loop_tag valid */
74static int func_tag_valid = FALSE;
75static jmp_buf func_tag;
76extern int exiting, exit_val;
77
78/* This rather ugly macro is for VMS C */
79#ifdef C
80#undef C
81#endif
82#define C(c) ((char)c)
83/*
84 * This table is used by the regexp routines to do case independant
85 * matching. Basically, every ascii character maps to itself, except
86 * uppercase letters map to lower case ones. This table has 256
87 * entries, for ISO 8859-1. Note also that if the system this
88 * is compiled on doesn't use 7-bit ascii, casetable[] should not be
89 * defined to the linker, so gawk should not load.
90 *
91 * Do NOT make this array static, it is used in several spots, not
92 * just in this file.
93 */
94#if 'a' == 97	/* it's ascii */
95const char casetable[] = {
96	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
97	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
98	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
99	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
100	/* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
101	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
102	/* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
103	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
104	/* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
105	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
106	/* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
107	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
108	/* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
109	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
110	/* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
111	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
112	/* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
113	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
114	/* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
115	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
116	/* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
117	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
118	/* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
119	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
120	/* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
121	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
122	/* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
123	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
124
125	/* Latin 1: */
126	C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
127	C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
128	C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
129	C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
130	C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
131	C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
132	C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
133	C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
134	C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
135	C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
136	C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
137	C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
138	C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
139	C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
140	C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
141	C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
142};
143#else
144#include "You lose. You will need a translation table for your character set."
145#endif
146
147#undef C
148
149/*
150 * This table maps node types to strings for debugging.
151 * KEEP IN SYNC WITH awk.h!!!!
152 */
153static const char *const nodetypes[] = {
154	"Node_illegal",
155	"Node_times",
156	"Node_quotient",
157	"Node_mod",
158	"Node_plus",
159	"Node_minus",
160	"Node_cond_pair",
161	"Node_subscript",
162	"Node_concat",
163	"Node_exp",
164	"Node_preincrement",
165	"Node_predecrement",
166	"Node_postincrement",
167	"Node_postdecrement",
168	"Node_unary_minus",
169	"Node_field_spec",
170	"Node_assign",
171	"Node_assign_times",
172	"Node_assign_quotient",
173	"Node_assign_mod",
174	"Node_assign_plus",
175	"Node_assign_minus",
176	"Node_assign_exp",
177	"Node_and",
178	"Node_or",
179	"Node_equal",
180	"Node_notequal",
181	"Node_less",
182	"Node_greater",
183	"Node_leq",
184	"Node_geq",
185	"Node_match",
186	"Node_nomatch",
187	"Node_not",
188	"Node_rule_list",
189	"Node_rule_node",
190	"Node_statement_list",
191	"Node_switch_body",
192	"Node_case_list",
193	"Node_if_branches",
194	"Node_expression_list",
195	"Node_param_list",
196	"Node_K_if",
197	"Node_K_switch",
198	"Node_K_case",
199	"Node_K_default",
200	"Node_K_while",
201	"Node_K_for",
202	"Node_K_arrayfor",
203	"Node_K_break",
204	"Node_K_continue",
205	"Node_K_print",
206	"Node_K_print_rec",
207	"Node_K_printf",
208	"Node_K_next",
209	"Node_K_exit",
210	"Node_K_do",
211	"Node_K_return",
212	"Node_K_delete",
213	"Node_K_delete_loop",
214	"Node_K_getline",
215	"Node_K_function",
216	"Node_K_nextfile",
217	"Node_redirect_output",
218	"Node_redirect_append",
219	"Node_redirect_pipe",
220	"Node_redirect_pipein",
221	"Node_redirect_input",
222	"Node_redirect_twoway",
223	"Node_var_new",
224	"Node_var",
225	"Node_var_array",
226	"Node_val",
227	"Node_builtin",
228	"Node_line_range",
229	"Node_in_array",
230	"Node_func",
231	"Node_func_call",
232	"Node_cond_exp",
233	"Node_regex",
234	"Node_dynregex",
235	"Node_hashnode",
236	"Node_ahash",
237	"Node_array_ref",
238	"Node_BINMODE",
239	"Node_CONVFMT",
240	"Node_FIELDWIDTHS",
241	"Node_FNR",
242	"Node_FS",
243	"Node_IGNORECASE",
244	"Node_LINT",
245	"Node_NF",
246	"Node_NR",
247	"Node_OFMT",
248	"Node_OFS",
249	"Node_ORS",
250	"Node_RS",
251	"Node_TEXTDOMAIN",
252	"Node_final --- this should never appear",
253	NULL
254};
255
256/* nodetype2str --- convert a node type into a printable value */
257
258const char *
259nodetype2str(NODETYPE type)
260{
261	static char buf[40];
262
263	if (type >= Node_illegal && type <= Node_final)
264		return nodetypes[(int) type];
265
266	sprintf(buf, _("unknown nodetype %d"), (int) type);
267	return buf;
268}
269
270/* flags2str --- make a flags value readable */
271
272const char *
273flags2str(int flagval)
274{
275	static const struct flagtab values[] = {
276		{ MALLOC, "MALLOC" },
277		{ TEMP, "TEMP" },
278		{ PERM, "PERM" },
279		{ STRING, "STRING" },
280		{ STRCUR, "STRCUR" },
281		{ NUMCUR, "NUMCUR" },
282		{ NUMBER, "NUMBER" },
283		{ MAYBE_NUM, "MAYBE_NUM" },
284		{ ARRAYMAXED, "ARRAYMAXED" },
285		{ FUNC, "FUNC" },
286		{ FIELD, "FIELD" },
287		{ INTLSTR, "INTLSTR" },
288		{ 0,	NULL },
289	};
290
291	return genflags2str(flagval, values);
292}
293
294/* genflags2str --- general routine to convert a flag value to a string */
295
296const char *
297genflags2str(int flagval, const struct flagtab *tab)
298{
299	static char buffer[BUFSIZ];
300	char *sp;
301	int i, space_left, space_needed;
302
303	sp = buffer;
304	space_left = BUFSIZ;
305	for (i = 0; tab[i].name != NULL; i++) {
306		/*
307		 * note the trick, we want 1 or 0 for whether we need
308		 * the '|' character.
309		 */
310		space_needed = (strlen(tab[i].name) + (sp != buffer));
311		if (space_left < space_needed)
312			fatal(_("buffer overflow in genflags2str"));
313
314		if ((flagval & tab[i].val) != 0) {
315			if (sp != buffer) {
316				*sp++ = '|';
317				space_left--;
318			}
319			strcpy(sp, tab[i].name);
320			/* note ordering! */
321			space_left -= strlen(sp);
322			sp += strlen(sp);
323		}
324	}
325
326	return buffer;
327}
328
329/*
330 * interpret:
331 * Tree is a bunch of rules to run. Returns zero if it hit an exit()
332 * statement
333 */
334int
335interpret(register NODE *volatile tree)
336{
337	jmp_buf volatile loop_tag_stack; /* shallow binding stack for loop_tag */
338	static jmp_buf rule_tag; /* tag the rule currently being run, for NEXT
339				  * and EXIT statements.  It is static because
340				  * there are no nested rules */
341	register NODE *volatile t = NULL;	/* temporary */
342	NODE **volatile lhs;	/* lhs == Left Hand Side for assigns, etc */
343	NODE *volatile stable_tree;
344	int volatile traverse = TRUE;	/* True => loop thru tree (Node_rule_list) */
345
346	/* avoid false source indications */
347	source = NULL;
348	sourceline = 0;
349
350	if (tree == NULL)
351		return 1;
352	sourceline = tree->source_line;
353	source = tree->source_file;
354	switch (tree->type) {
355	case Node_rule_node:
356		traverse = FALSE;  /* False => one for-loop iteration only */
357		/* FALL THROUGH */
358	case Node_rule_list:
359		for (t = tree; t != NULL; t = t->rnode) {
360			if (traverse)
361				tree = t->lnode;
362			sourceline = tree->source_line;
363			source = tree->source_file;
364			INCREMENT(tree->exec_count);
365			switch (setjmp(rule_tag)) {
366			case 0:	/* normal non-jump */
367				/* test pattern, if any */
368				if (tree->lnode == NULL ||
369				    eval_condition(tree->lnode)) {
370					/* using the lnode exec_count is kludgey */
371					if (tree->lnode != NULL)
372						INCREMENT(tree->lnode->exec_count);
373					(void) interpret(tree->rnode);
374				}
375				break;
376			case TAG_CONTINUE:	/* NEXT statement */
377				pop_all_forloops();
378				pop_fcall_stack();
379				return 1;
380			case TAG_BREAK:		/* EXIT statement */
381				pop_all_forloops();
382				pop_fcall_stack();
383				return 0;
384			default:
385				cant_happen();
386			}
387			if (! traverse) 	/* case Node_rule_node */
388				break;		/* don't loop */
389		}
390		break;
391
392	case Node_statement_list:
393		for (t = tree; t != NULL; t = t->rnode)
394			(void) interpret(t->lnode);
395		break;
396
397	case Node_K_if:
398		INCREMENT(tree->exec_count);
399		if (eval_condition(tree->lnode)) {
400			INCREMENT(tree->rnode->exec_count);
401			(void) interpret(tree->rnode->lnode);
402		} else {
403			(void) interpret(tree->rnode->rnode);
404		}
405		break;
406
407	case Node_K_switch:
408		{
409		NODE *switch_value;
410		NODE *switch_body;
411		NODE *case_list;
412		NODE *default_list;
413		NODE *case_stmt;
414
415		int match_found = FALSE;
416
417		PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
418		INCREMENT(tree->exec_count);
419		stable_tree = tree;
420
421		switch_value = tree_eval(stable_tree->lnode);
422		switch_body = stable_tree->rnode;
423		case_list = switch_body->lnode;
424		default_list  = switch_body->rnode;
425
426		for (; case_list != NULL; case_list = case_list->rnode) {
427			case_stmt = case_list->lnode;
428
429			/*
430			 * Once a match is found, all cases will be processed as they fall through,
431			 * so continue to execute statements until a break is reached.
432			 */
433			if (! match_found) {
434				if (case_stmt->type == Node_K_default)
435					;	/* do nothing */
436				else if (case_stmt->lnode->type == Node_regex) {
437					NODE *t1;
438					Regexp *rp;
439
440					t1 = force_string(switch_value);
441					rp = re_update(case_stmt->lnode);
442
443					match_found = (research(rp, t1->stptr, 0, t1->stlen, FALSE) >= 0);
444					if (t1 != switch_value)
445						free_temp(t1);
446				} else {
447					match_found = (cmp_nodes(switch_value, case_stmt->lnode) == 0);
448				}
449			}
450
451			/* If a match was found, execute the statements associated with the case. */
452			if (match_found) {
453				INCREMENT(case_stmt->exec_count);
454				switch (setjmp(loop_tag)) {
455				case 0:                /* Normal non-jump    */
456					(void) interpret(case_stmt->rnode);
457					break;
458				case TAG_CONTINUE:     /* continue statement */
459					free_temp(switch_value);
460					RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
461					longjmp(loop_tag, TAG_CONTINUE);
462					break;
463				case TAG_BREAK:        /* break statement    */
464					free_temp(switch_value);
465					RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
466					return 1;
467				default:
468					cant_happen();
469				}
470			}
471
472		}
473
474		free_temp(switch_value);
475
476		/*
477		 * If a default section was found, execute the statements associated with it
478		 * and execute any trailing case statements if the default falls through.
479		 */
480		if (! match_found && default_list != NULL) {
481			for (case_list = default_list;
482					case_list != NULL; case_list = case_list->rnode) {
483				case_stmt = case_list->lnode;
484
485				INCREMENT(case_stmt->exec_count);
486				switch (setjmp(loop_tag)) {
487				case 0:                /* Normal non-jump    */
488					(void) interpret(case_stmt->rnode);
489					break;
490				case TAG_CONTINUE:     /* continue statement */
491					RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
492					longjmp(loop_tag, TAG_CONTINUE);
493					break;
494				case TAG_BREAK:        /* break statement    */
495					RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
496					return 1;
497				default:
498					cant_happen();
499				}
500			}
501		}
502
503		RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
504		}
505		break;
506
507	case Node_K_while:
508		PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
509
510		stable_tree = tree;
511		while (eval_condition(stable_tree->lnode)) {
512			INCREMENT(stable_tree->exec_count);
513			switch (setjmp(loop_tag)) {
514			case 0:	/* normal non-jump */
515				(void) interpret(stable_tree->rnode);
516				break;
517			case TAG_CONTINUE:	/* continue statement */
518				break;
519			case TAG_BREAK:	/* break statement */
520				RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
521				return 1;
522			default:
523				cant_happen();
524			}
525		}
526		RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
527		break;
528
529	case Node_K_do:
530		PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
531		stable_tree = tree;
532		do {
533			INCREMENT(stable_tree->exec_count);
534			switch (setjmp(loop_tag)) {
535			case 0:	/* normal non-jump */
536				(void) interpret(stable_tree->rnode);
537				break;
538			case TAG_CONTINUE:	/* continue statement */
539				break;
540			case TAG_BREAK:	/* break statement */
541				RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
542				return 1;
543			default:
544				cant_happen();
545			}
546		} while (eval_condition(stable_tree->lnode));
547		RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
548		break;
549
550	case Node_K_for:
551		PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
552		(void) interpret(tree->forloop->init);
553		stable_tree = tree;
554		while (eval_condition(stable_tree->forloop->cond)) {
555			INCREMENT(stable_tree->exec_count);
556			switch (setjmp(loop_tag)) {
557			case 0:	/* normal non-jump */
558				(void) interpret(stable_tree->lnode);
559				/* fall through */
560			case TAG_CONTINUE:	/* continue statement */
561				(void) interpret(stable_tree->forloop->incr);
562				break;
563			case TAG_BREAK:	/* break statement */
564				RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
565				return 1;
566			default:
567				cant_happen();
568			}
569		}
570		RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
571		break;
572
573	case Node_K_arrayfor:
574		{
575		Func_ptr after_assign = NULL;
576		NODE **list = NULL;
577		NODE *volatile array;
578		NODE *volatile save_array;
579		volatile size_t i, num_elems;
580		size_t j;
581		volatile int retval = 0;
582		int sort_indices = whiny_users;
583
584#define hakvar forloop->init
585#define arrvar forloop->incr
586		/* get the array */
587		save_array = tree->arrvar;
588		array = get_array(save_array);
589
590		/* sanity: do nothing if empty */
591		if (array->var_array == NULL || array->table_size == 0)
592			break;	/* from switch */
593
594		/* allocate space for array */
595		num_elems = array->table_size;
596		emalloc(list, NODE **, num_elems * sizeof(NODE *), "for_loop");
597
598		/* populate it */
599		for (i = j = 0; i < array->array_size; i++) {
600			NODE *t = array->var_array[i];
601
602			if (t == NULL)
603				continue;
604
605			for (; t != NULL; t = t->ahnext) {
606				list[j++] = dupnode(t);
607				assert(list[j-1] == t);
608			}
609		}
610
611
612		if (sort_indices)
613			qsort(list, num_elems, sizeof(NODE *), comp_func); /* shazzam! */
614
615		/* now we can run the loop */
616		push_forloop(array->vname, list, num_elems);
617		PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
618
619		lhs = get_lhs(tree->hakvar, &after_assign, FALSE);
620		stable_tree = tree;
621		for (i = 0; i < num_elems; i++) {
622			INCREMENT(stable_tree->exec_count);
623			unref(*((NODE **) lhs));
624			*lhs = make_string(list[i]->ahname_str, list[i]->ahname_len);
625			if (after_assign)
626				(*after_assign)();
627			switch (setjmp(loop_tag)) {
628			case 0:
629				(void) interpret(stable_tree->lnode);
630			case TAG_CONTINUE:
631				break;
632
633			case TAG_BREAK:
634				retval = 1;
635				goto done;
636
637			default:
638				cant_happen();
639			}
640		}
641
642	done:
643		RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
644		pop_forloop();
645
646		if (do_lint && num_elems != array->table_size)
647			lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
648				array_vname(save_array), (long) num_elems, (long) array->table_size);
649
650		if (retval == 1)
651			return 1;
652		break;
653		}
654#undef hakvar
655#undef arrvar
656
657	case Node_K_break:
658		INCREMENT(tree->exec_count);
659		if (! loop_tag_valid) {
660			/*
661			 * Old AT&T nawk treats break outside of loops like
662			 * next. New ones catch it at parse time. Allow it if
663			 * do_traditional is on, and complain if lint.
664			 */
665			static int warned = FALSE;
666
667			if (do_lint && ! warned) {
668				lintwarn(_("`break' outside a loop is not portable"));
669				warned = TRUE;
670			}
671			if (! do_traditional || do_posix)
672				fatal(_("`break' outside a loop is not allowed"));
673			longjmp(rule_tag, TAG_CONTINUE);
674		} else
675			longjmp(loop_tag, TAG_BREAK);
676		break;
677
678	case Node_K_continue:
679		INCREMENT(tree->exec_count);
680		if (! loop_tag_valid) {
681			/*
682			 * Old AT&T nawk treats continue outside of loops like
683			 * next. New ones catch it at parse time. Allow it if
684			 * do_traditional is on, and complain if lint.
685			 */
686			static int warned = FALSE;
687
688			if (do_lint && ! warned) {
689				lintwarn(_("`continue' outside a loop is not portable"));
690				warned = TRUE;
691			}
692			if (! do_traditional || do_posix)
693				fatal(_("`continue' outside a loop is not allowed"));
694			longjmp(rule_tag, TAG_CONTINUE);
695		} else
696			longjmp(loop_tag, TAG_CONTINUE);
697		break;
698
699	case Node_K_print:
700		INCREMENT(tree->exec_count);
701		do_print(tree);
702		break;
703
704	case Node_K_print_rec:
705		INCREMENT(tree->exec_count);
706		do_print_rec(tree);
707		break;
708
709	case Node_K_printf:
710		INCREMENT(tree->exec_count);
711		do_printf(tree);
712		break;
713
714	case Node_K_delete:
715		INCREMENT(tree->exec_count);
716		do_delete(tree->lnode, tree->rnode);
717		break;
718
719	case Node_K_delete_loop:
720		INCREMENT(tree->exec_count);
721		do_delete_loop(tree->lnode, tree->rnode);
722		break;
723
724	case Node_K_next:
725		INCREMENT(tree->exec_count);
726		if (in_begin_rule)
727			fatal(_("`next' cannot be called from a BEGIN rule"));
728		else if (in_end_rule)
729			fatal(_("`next' cannot be called from an END rule"));
730
731		/* could add a lint check here for in a loop or function */
732		longjmp(rule_tag, TAG_CONTINUE);
733		break;
734
735	case Node_K_nextfile:
736		INCREMENT(tree->exec_count);
737		if (in_begin_rule)
738			fatal(_("`nextfile' cannot be called from a BEGIN rule"));
739		else if (in_end_rule)
740			fatal(_("`nextfile' cannot be called from an END rule"));
741
742		/* could add a lint check here for in a loop or function */
743		/*
744		 * Have to do this cleanup here, since we don't longjump
745		 * back to the main awk rule loop (rule_tag).
746		 */
747		pop_all_forloops();
748		pop_fcall_stack();
749
750		do_nextfile();
751		break;
752
753	case Node_K_exit:
754		INCREMENT(tree->exec_count);
755		/*
756		 * In A,K,&W, p. 49, it says that an exit statement "...
757		 * causes the program to behave as if the end of input had
758		 * occurred; no more input is read, and the END actions, if
759		 * any are executed." This implies that the rest of the rules
760		 * are not done. So we immediately break out of the main loop.
761		 */
762		exiting = TRUE;
763		if (tree->lnode != NULL) {
764			t = tree_eval(tree->lnode);
765			exit_val = (int) force_number(t);
766			free_temp(t);
767		}
768		longjmp(rule_tag, TAG_BREAK);
769		break;
770
771	case Node_K_return:
772		INCREMENT(tree->exec_count);
773		t = tree_eval(tree->lnode);
774		ret_node = dupnode(t);
775		free_temp(t);
776		longjmp(func_tag, TAG_RETURN);
777		break;
778
779	default:
780		/*
781		 * Appears to be an expression statement.  Throw away the
782		 * value.
783		 */
784		if (do_lint && (tree->type == Node_var || tree->type == Node_var_new))
785			lintwarn(_("statement has no effect"));
786		INCREMENT(tree->exec_count);
787		t = tree_eval(tree);
788		if (t)	/* stopme() returns NULL */
789			free_temp(t);
790		break;
791	}
792	return 1;
793}
794
795/* r_tree_eval --- evaluate a subtree */
796
797NODE *
798r_tree_eval(register NODE *tree, int iscond)
799{
800	register NODE *r, *t1, *t2;	/* return value & temporary subtrees */
801	register NODE **lhs;
802	register int di;
803	AWKNUM x, x1, x2;
804	long lx;
805#ifdef _CRAY
806	long lx2;
807#endif
808
809#ifndef TREE_EVAL_MACRO
810	if (tree == NULL)
811		return Nnull_string;
812	else if (tree->type == Node_val) {
813		if (tree->stref <= 0)
814			cant_happen();
815		return ((tree->flags & INTLSTR) != 0
816			? r_force_string(tree)
817			: tree);
818	} else if (tree->type == Node_var) {
819		if (tree->var_value->stref <= 0)
820			cant_happen();
821		if (! var_uninitialized(tree))
822			return tree->var_value;
823	}
824#endif
825
826	if (tree->type == Node_param_list) {
827		if ((tree->flags & FUNC) != 0)
828			fatal(_("can't use function name `%s' as variable or array"),
829					tree->vname);
830
831		tree = stack_ptr[tree->param_cnt];
832
833		if (tree == NULL) {
834			if (do_lint)
835				lintwarn(_("reference to uninitialized argument `%s'"),
836						tree->vname);
837			return Nnull_string;
838		}
839
840		if (do_lint && var_uninitialized(tree))
841			lintwarn(_("reference to uninitialized argument `%s'"),
842			      tree->vname);
843	}
844
845	switch (tree->type) {
846	case Node_array_ref:
847		if (tree->orig_array->type == Node_var_array)
848			fatal(_("attempt to use array `%s' in a scalar context"),
849				array_vname(tree));
850		tree->orig_array->type = Node_var;
851		/* fall through */
852	case Node_var_new:
853		tree->type = Node_var;
854		tree->var_value = Nnull_string;
855		/* fall through */
856	case Node_var:
857		if (do_lint && var_uninitialized(tree))
858			lintwarn(_("reference to uninitialized variable `%s'"),
859			      tree->vname);
860		return tree->var_value;
861
862	case Node_and:
863		return tmp_number((AWKNUM) (eval_condition(tree->lnode)
864					    && eval_condition(tree->rnode)));
865
866	case Node_or:
867		return tmp_number((AWKNUM) (eval_condition(tree->lnode)
868					    || eval_condition(tree->rnode)));
869
870	case Node_not:
871		return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
872
873		/* Builtins */
874	case Node_builtin:
875		return (*tree->builtin)(tree->subnode);
876
877	case Node_K_getline:
878		return (do_getline(tree));
879
880	case Node_in_array:
881		return tmp_number((AWKNUM) (in_array(tree->lnode, tree->rnode) != NULL));
882
883	case Node_func_call:
884		return func_call(tree);
885
886		/* unary operations */
887	case Node_NR:
888	case Node_FNR:
889	case Node_NF:
890	case Node_FIELDWIDTHS:
891	case Node_FS:
892	case Node_RS:
893	case Node_field_spec:
894	case Node_subscript:
895	case Node_IGNORECASE:
896	case Node_OFS:
897	case Node_ORS:
898	case Node_OFMT:
899	case Node_CONVFMT:
900	case Node_BINMODE:
901	case Node_LINT:
902	case Node_TEXTDOMAIN:
903		lhs = get_lhs(tree, (Func_ptr *) NULL, TRUE);
904		return *lhs;
905
906	case Node_var_array:
907		fatal(_("attempt to use array `%s' in a scalar context"),
908			array_vname(tree));
909
910	case Node_unary_minus:
911		t1 = tree_eval(tree->subnode);
912		x = -force_number(t1);
913		free_temp(t1);
914		return tmp_number(x);
915
916	case Node_cond_exp:
917		if (eval_condition(tree->lnode))
918			return tree_eval(tree->rnode->lnode);
919		return tree_eval(tree->rnode->rnode);
920
921	case Node_match:
922	case Node_nomatch:
923	case Node_regex:
924	case Node_dynregex:
925		return match_op(tree);
926
927	case Node_concat:
928		{
929		NODE **treelist;
930		NODE **strlist;
931		NODE *save_tree;
932		register NODE **treep;
933		register NODE **strp;
934		register size_t len;
935		register size_t supposed_len;
936		char *str;
937		register char *dest;
938		int alloc_count, str_count;
939		int i;
940
941		/*
942		 * This is an efficiency hack for multiple adjacent string
943		 * concatenations, to avoid recursion and string copies.
944		 *
945		 * Node_concat trees grow downward to the left, so
946		 * descend to lowest (first) node, accumulating nodes
947		 * to evaluate to strings as we go.
948		 */
949
950		/*
951		 * But first, no arbitrary limits. Count the number of
952		 * nodes and malloc the treelist and strlist arrays.
953		 * There will be alloc_count + 1 items to concatenate. We
954		 * also leave room for an extra pointer at the end to
955		 * use as a sentinel.  Thus, start alloc_count at 2.
956		 */
957		save_tree = tree;
958		for (alloc_count = 2; tree != NULL && tree->type == Node_concat;
959				tree = tree->lnode)
960			alloc_count++;
961		tree = save_tree;
962		emalloc(treelist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
963		emalloc(strlist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
964
965		/* Now, here we go. */
966		treep = treelist;
967		while (tree != NULL && tree->type == Node_concat) {
968			*treep++ = tree->rnode;
969			tree = tree->lnode;
970		}
971		*treep = tree;
972		/*
973		 * Now, evaluate to strings in LIFO order, accumulating
974		 * the string length, so we can do a single malloc at the
975		 * end.
976		 *
977		 * Evaluate the expressions first, then get their
978		 * lengthes, in case one of the expressions has a
979		 * side effect that changes one of the others.
980		 * See test/nasty.awk.
981		 *
982		 * dupnode the results a la do_print, to give us
983		 * more predicable behavior; compare gawk 3.0.6 to
984		 * nawk/mawk on test/nasty.awk.
985		 */
986		strp = strlist;
987		supposed_len = len = 0;
988		while (treep >= treelist) {
989			NODE *n;
990
991			/* Here lies the wumpus's brother. R.I.P. */
992			n = force_string(tree_eval(*treep--));
993			*strp = dupnode(n);
994			free_temp(n);
995			supposed_len += (*strp)->stlen;
996			strp++;
997		}
998		*strp = NULL;
999
1000		str_count = strp - strlist;
1001		strp = strlist;
1002		for (i = 0; i < str_count; i++) {
1003			len += (*strp)->stlen;
1004			strp++;
1005		}
1006		if (do_lint && supposed_len != len)
1007			lintwarn(_("concatenation: side effects in one expression have changed the length of another!"));
1008		emalloc(str, char *, len+2, "tree_eval");
1009		str[len] = str[len+1] = '\0';	/* for good measure */
1010		dest = str;
1011		strp = strlist;
1012		while (*strp != NULL) {
1013			memcpy(dest, (*strp)->stptr, (*strp)->stlen);
1014			dest += (*strp)->stlen;
1015			unref(*strp);
1016			strp++;
1017		}
1018		r = make_str_node(str, len, ALREADY_MALLOCED);
1019		r->flags |= TEMP;
1020
1021		free(strlist);
1022		free(treelist);
1023		}
1024		return r;
1025
1026	/* assignments */
1027	case Node_assign:
1028		{
1029		Func_ptr after_assign = NULL;
1030
1031		if (do_lint && iscond)
1032			lintwarn(_("assignment used in conditional context"));
1033		r = tree_eval(tree->rnode);
1034		lhs = get_lhs(tree->lnode, &after_assign, FALSE);
1035
1036		assign_val(lhs, r);
1037		if (after_assign)
1038			(*after_assign)();
1039		return *lhs;
1040		}
1041
1042	/* other assignment types are easier because they are numeric */
1043	case Node_preincrement:
1044	case Node_predecrement:
1045	case Node_postincrement:
1046	case Node_postdecrement:
1047	case Node_assign_exp:
1048	case Node_assign_times:
1049	case Node_assign_quotient:
1050	case Node_assign_mod:
1051	case Node_assign_plus:
1052	case Node_assign_minus:
1053		return op_assign(tree);
1054	default:
1055		break;	/* handled below */
1056	}
1057
1058	/*
1059	 * Evaluate subtrees in order to do binary operation, then keep going.
1060	 * Use dupnode to make sure that these values don't disappear out
1061	 * from under us during recursive subexpression evaluation.
1062	 */
1063	t1 = dupnode(tree_eval(tree->lnode));
1064	t2 = dupnode(tree_eval(tree->rnode));
1065
1066	switch (tree->type) {
1067	case Node_geq:
1068	case Node_leq:
1069	case Node_greater:
1070	case Node_less:
1071	case Node_notequal:
1072	case Node_equal:
1073		di = cmp_nodes(t1, t2);
1074		unref(t1);
1075		unref(t2);
1076		switch (tree->type) {
1077		case Node_equal:
1078			return tmp_number((AWKNUM) (di == 0));
1079		case Node_notequal:
1080			return tmp_number((AWKNUM) (di != 0));
1081		case Node_less:
1082			return tmp_number((AWKNUM) (di < 0));
1083		case Node_greater:
1084			return tmp_number((AWKNUM) (di > 0));
1085		case Node_leq:
1086			return tmp_number((AWKNUM) (di <= 0));
1087		case Node_geq:
1088			return tmp_number((AWKNUM) (di >= 0));
1089		default:
1090			cant_happen();
1091		}
1092		break;
1093	default:
1094		break;	/* handled below */
1095	}
1096
1097	x1 = force_number(t1);
1098	x2 = force_number(t2);
1099	unref(t1);
1100	unref(t2);
1101	switch (tree->type) {
1102	case Node_exp:
1103		if ((lx = x2) == x2 && lx >= 0) {	/* integer exponent */
1104			if (lx == 0)
1105				x = 1;
1106			else if (lx == 1)
1107				x = x1;
1108			else {
1109				/* doing it this way should be more precise */
1110				for (x = x1; --lx; )
1111					x *= x1;
1112			}
1113		} else
1114			x = pow((double) x1, (double) x2);
1115		return tmp_number(x);
1116
1117	case Node_times:
1118		return tmp_number(x1 * x2);
1119
1120	case Node_quotient:
1121		if (x2 == 0)
1122			fatal(_("division by zero attempted"));
1123#ifdef _CRAY
1124		/* special case for integer division, put in for Cray */
1125		lx2 = x2;
1126		if (lx2 == 0)
1127			return tmp_number(x1 / x2);
1128		lx = (long) x1 / lx2;
1129		if (lx * x2 == x1)
1130			return tmp_number((AWKNUM) lx);
1131		else
1132#endif
1133			return tmp_number(x1 / x2);
1134
1135	case Node_mod:
1136		if (x2 == 0)
1137			fatal(_("division by zero attempted in `%%'"));
1138#ifdef HAVE_FMOD
1139		return tmp_number(fmod(x1, x2));
1140#else	/* ! HAVE_FMOD */
1141		(void) modf(x1 / x2, &x);
1142		return tmp_number(x1 - x * x2);
1143#endif	/* ! HAVE_FMOD */
1144
1145	case Node_plus:
1146		return tmp_number(x1 + x2);
1147
1148	case Node_minus:
1149		return tmp_number(x1 - x2);
1150
1151	default:
1152		fatal(_("illegal type (%s) in tree_eval"), nodetype2str(tree->type));
1153	}
1154	return 0;
1155}
1156
1157/* eval_condition --- is TREE true or false? Returns 0==false, non-zero==true */
1158
1159static int
1160eval_condition(register NODE *tree)
1161{
1162	register NODE *t1;
1163	register int ret;
1164
1165	if (tree == NULL)	/* Null trees are the easiest kinds */
1166		return TRUE;
1167	if (tree->type == Node_line_range) {
1168		/*
1169		 * Node_line_range is kind of like Node_match, EXCEPT: the
1170		 * lnode field (more properly, the condpair field) is a node
1171		 * of a Node_cond_pair; whether we evaluate the lnode of that
1172		 * node or the rnode depends on the triggered word.  More
1173		 * precisely:  if we are not yet triggered, we tree_eval the
1174		 * lnode; if that returns true, we set the triggered word.
1175		 * If we are triggered (not ELSE IF, note), we tree_eval the
1176		 * rnode, clear triggered if it succeeds, and perform our
1177		 * action (regardless of success or failure).  We want to be
1178		 * able to begin and end on a single input record, so this
1179		 * isn't an ELSE IF, as noted above.
1180		 */
1181		if (! tree->triggered) {
1182			if (! eval_condition(tree->condpair->lnode))
1183				return FALSE;
1184			else
1185				tree->triggered = TRUE;
1186		}
1187		/* Else we are triggered */
1188		if (eval_condition(tree->condpair->rnode))
1189			tree->triggered = FALSE;
1190		return TRUE;
1191	}
1192
1193	/*
1194	 * Could just be J.random expression. in which case, null and 0 are
1195	 * false, anything else is true
1196	 */
1197
1198	t1 = m_tree_eval(tree, TRUE);
1199	if (t1->flags & MAYBE_NUM)
1200		(void) force_number(t1);
1201	if (t1->flags & NUMBER)
1202		ret = (t1->numbr != 0.0);
1203	else
1204		ret = (t1->stlen != 0);
1205	free_temp(t1);
1206	return ret;
1207}
1208
1209/* cmp_nodes --- compare two nodes, returning negative, 0, positive */
1210
1211int
1212cmp_nodes(register NODE *t1, register NODE *t2)
1213{
1214	register int ret;
1215	register size_t len1, len2;
1216	register int l;
1217	int ldiff;
1218
1219	if (t1 == t2)
1220		return 0;
1221	if (t1->flags & MAYBE_NUM)
1222		(void) force_number(t1);
1223	if (t2->flags & MAYBE_NUM)
1224		(void) force_number(t2);
1225	if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
1226		if (t1->numbr == t2->numbr)
1227			return 0;
1228		/* don't subtract, in case one or both are infinite */
1229		else if (t1->numbr < t2->numbr)
1230			return -1;
1231		else
1232			return 1;
1233	}
1234	(void) force_string(t1);
1235	(void) force_string(t2);
1236	len1 = t1->stlen;
1237	len2 = t2->stlen;
1238	ldiff = len1 - len2;
1239	if (len1 == 0 || len2 == 0)
1240		return ldiff;
1241	l = (ldiff <= 0 ? len1 : len2);
1242	if (IGNORECASE) {
1243		const unsigned char *cp1 = (const unsigned char *) t1->stptr;
1244		const unsigned char *cp2 = (const unsigned char *) t2->stptr;
1245
1246#ifdef MBS_SUPPORT
1247		if (gawk_mb_cur_max > 1) {
1248			mbstate_t mbs;
1249			memset(&mbs, 0, sizeof(mbstate_t));
1250			ret = strncasecmpmbs((const char *) cp1, mbs,
1251					     (const char *) cp2, mbs, l);
1252		} else
1253#endif
1254		for (ret = 0; l-- > 0 && ret == 0; cp1++, cp2++)
1255			ret = casetable[*cp1] - casetable[*cp2];
1256	} else
1257		ret = memcmp(t1->stptr, t2->stptr, l);
1258	return (ret == 0 ? ldiff : ret);
1259}
1260
1261/* op_assign --- do +=, -=, etc. */
1262
1263static NODE *
1264op_assign(register NODE *tree)
1265{
1266	AWKNUM rval, lval;
1267	NODE **lhs;
1268	AWKNUM t1, t2;
1269	long ltemp;
1270	NODE *tmp;
1271	Func_ptr after_assign = NULL;
1272	int post = FALSE;
1273
1274	/*
1275	 * For += etc, do the rhs first, since it can rearrange things,
1276	 * and *then* get the lhs.
1277	 */
1278	if (tree->rnode != NULL) {
1279		tmp = tree_eval(tree->rnode);
1280		rval = force_number(tmp);
1281		free_temp(tmp);
1282	} else
1283		rval = (AWKNUM) 1.0;
1284
1285	lhs = get_lhs(tree->lnode, &after_assign, TRUE);
1286	lval = force_number(*lhs);
1287	unref(*lhs);
1288
1289	switch(tree->type) {
1290	case Node_postincrement:
1291		post = TRUE;
1292		/* fall through */
1293	case Node_preincrement:
1294	case Node_assign_plus:
1295		*lhs = make_number(lval + rval);
1296		break;
1297
1298	case Node_postdecrement:
1299		post = TRUE;
1300		/* fall through */
1301	case Node_predecrement:
1302	case Node_assign_minus:
1303		*lhs = make_number(lval - rval);
1304		break;
1305
1306	case Node_assign_exp:
1307		if ((ltemp = rval) == rval) {	/* integer exponent */
1308			if (ltemp == 0)
1309				*lhs = make_number((AWKNUM) 1);
1310			else if (ltemp == 1)
1311				*lhs = make_number(lval);
1312			else {
1313				/* doing it this way should be more precise */
1314				for (t1 = t2 = lval; --ltemp; )
1315					t1 *= t2;
1316				*lhs = make_number(t1);
1317			}
1318		} else
1319			*lhs = make_number((AWKNUM) pow((double) lval, (double) rval));
1320		break;
1321
1322	case Node_assign_times:
1323		*lhs = make_number(lval * rval);
1324		break;
1325
1326	case Node_assign_quotient:
1327		if (rval == (AWKNUM) 0)
1328			fatal(_("division by zero attempted in `/='"));
1329#ifdef _CRAY
1330		/* special case for integer division, put in for Cray */
1331		ltemp = rval;
1332		if (ltemp == 0) {
1333			*lhs = make_number(lval / rval);
1334			break;
1335		}
1336		ltemp = (long) lval / ltemp;
1337		if (ltemp * lval == rval)
1338			*lhs = make_number((AWKNUM) ltemp);
1339		else
1340#endif	/* _CRAY */
1341			*lhs = make_number(lval / rval);
1342		break;
1343
1344	case Node_assign_mod:
1345		if (rval == (AWKNUM) 0)
1346			fatal(_("division by zero attempted in `%%='"));
1347#ifdef HAVE_FMOD
1348		*lhs = make_number(fmod(lval, rval));
1349#else	/* ! HAVE_FMOD */
1350		(void) modf(lval / rval, &t1);
1351		t2 = lval - rval * t1;
1352		*lhs = make_number(t2);
1353#endif	/* ! HAVE_FMOD */
1354		break;
1355
1356	default:
1357		cant_happen();
1358	}
1359
1360	if (after_assign)
1361		(*after_assign)();
1362
1363	/* for postincrement or postdecrement, return the old value */
1364	return (post ? tmp_number(lval) : *lhs);
1365}
1366
1367/*
1368 * Avoiding memory leaks is difficult.  In paticular, any of `next',
1369 * `nextfile', `break' or `continue' (when not in a loop), can longjmp
1370 * out to the outermost level.  This leaks memory if it happens in a
1371 * called function. It also leaks memory if it happens in a
1372 * `for (iggy in foo)' loop, since such loops malloc an array of the
1373 * current array indices to loop over, which provides stability.
1374 *
1375 * The following code takes care of these problems.  First comes the
1376 * array-loop management code.  This can be a stack of arrays being looped
1377 * on at any one time.  This stack serves for both mainline code and
1378 * function body code. As each loop starts and finishes, it pushes its
1379 * info onto this stack and off of it; whether the loop is in a function
1380 * body or not isn't relevant.
1381 *
1382 * Since the list of indices is created using dupnode(), when popping
1383 * this stack it should be safe to unref() things, and then memory
1384 * will get finally released when the function call stack is popped.
1385 * This means that the loop_stack should be popped first upon a `next'.
1386 */
1387
1388static struct loop_info {
1389	const char *varname;	/* variable name, for debugging */
1390	NODE **elems;		/* list of indices */
1391	size_t nelems;		/* how many there are */
1392} *loop_stack = NULL;
1393size_t nloops = 0;		/* how many slots there are in the stack */
1394size_t nloops_active = 0;	/* how many loops are actively stacked */
1395
1396/* pop_forloop --- pop one for loop off the stack */
1397
1398static void
1399pop_forloop()
1400{
1401	int i, curloop;
1402	struct loop_info *loop;
1403
1404	assert(nloops_active > 0);
1405
1406	curloop = --nloops_active;	/* 0-based indexing */
1407	loop = & loop_stack[curloop];
1408
1409	for (i = 0; i < loop->nelems; i++)
1410		unref(loop->elems[i]);
1411
1412	free(loop->elems);
1413
1414	loop->elems = NULL;
1415	loop->varname = NULL;
1416	loop->nelems = 0;
1417}
1418
1419/* pop_forloops --- pop the for loops stack all the way */
1420
1421static inline void
1422pop_all_forloops()
1423{
1424	while (nloops_active > 0)
1425		pop_forloop();	/* decrements nloops_active for us */
1426}
1427
1428/* push_forloop --- add a single for loop to the stack */
1429
1430static void
1431push_forloop(const char *varname, NODE **elems, size_t nelems)
1432{
1433#define NLOOPS	4	/* seems like a good guess */
1434	if (loop_stack == NULL) {
1435		/* allocate stack, set vars */
1436		nloops = NLOOPS;
1437		emalloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
1438				"push_forloop");
1439	} else if (nloops_active == nloops) {
1440		/* grow stack, set vars */
1441		nloops *= 2;
1442		erealloc(loop_stack, struct loop_info *, nloops * sizeof(struct loop_info),
1443				"push_forloop");
1444	}
1445
1446	loop_stack[nloops_active].varname = varname;
1447	loop_stack[nloops_active].elems = elems;
1448	loop_stack[nloops_active].nelems = nelems;
1449	nloops_active++;
1450}
1451
1452static struct fcall {
1453	const char *fname;	/* function name */
1454	unsigned long count;	/* how many args */
1455	NODE *arglist;		/* list thereof */
1456	NODE **prevstack;	/* function stack frame of previous function */
1457	NODE **stack;		/* function stack frame of current function */
1458} *fcall_list = NULL;
1459
1460static long fcall_list_size = 0;
1461static long curfcall = -1;
1462
1463/* pop_fcall --- pop off a single function call */
1464
1465static void
1466pop_fcall()
1467{
1468	NODE *n, **sp;
1469	int count;
1470	struct fcall *f;
1471
1472	assert(curfcall >= 0);
1473	f = & fcall_list[curfcall];
1474	stack_ptr = f->prevstack;
1475
1476	sp = f->stack;
1477
1478	for (count = f->count; count > 0; count--) {
1479		n = *sp++;
1480		if (n->type == Node_var)		/* local variable */
1481			unref(n->var_value);
1482		else if (n->type == Node_var_array)	/* local array */
1483			assoc_clear(n);
1484		freenode(n);
1485	}
1486	if (f->stack)
1487		free((char *) f->stack);
1488	/* memset(f, '\0', sizeof(struct fcall)); */
1489	curfcall--;
1490}
1491
1492/* pop_fcall_stack --- pop off all function args, don't leak memory */
1493
1494static inline void
1495pop_fcall_stack()
1496{
1497	while (curfcall >= 0)
1498		pop_fcall();
1499}
1500
1501/* push_args --- push function arguments onto the stack */
1502
1503static void
1504push_args(int count,
1505	NODE *argp,
1506	NODE **oldstack,
1507	const char *func_name,
1508	char **varnames)
1509{
1510	struct fcall *f;
1511	NODE *arg, *r, **sp;
1512	int i;
1513
1514	if (fcall_list_size == 0) {	/* first time */
1515		emalloc(fcall_list, struct fcall *, 10 * sizeof(struct fcall),
1516			"push_args");
1517		fcall_list_size = 10;
1518	}
1519
1520	if (++curfcall >= fcall_list_size) {
1521		fcall_list_size *= 2;
1522		erealloc(fcall_list, struct fcall *,
1523			fcall_list_size * sizeof(struct fcall), "push_args");
1524	}
1525	f = & fcall_list[curfcall];
1526
1527	if (count > 0)
1528		emalloc(f->stack, NODE **, count*sizeof(NODE *), "push_args");
1529	else
1530		f->stack = NULL;
1531	f->count = count;
1532	f->fname = func_name;	/* not used, for debugging, just in case */
1533	f->arglist = argp;
1534	f->prevstack = oldstack;
1535
1536	sp = f->stack;
1537
1538	/* for each calling arg. add NODE * on stack */
1539	for (i = 0; i < count; i++) {
1540		getnode(r);
1541		*sp++ = r;
1542		if (argp == NULL) {
1543			/* local variable */
1544			r->type = Node_var_new;
1545			r->vname = varnames[i];
1546			continue;
1547		}
1548		arg = argp->lnode;
1549		/* call by reference for arrays; see below also */
1550		if (arg->type == Node_param_list) {
1551			/* we must also reassign f here; see below */
1552			f = & fcall_list[curfcall];
1553			arg = f->prevstack[arg->param_cnt];
1554		}
1555		if (arg->type == Node_var_array || arg->type == Node_var_new) {
1556			r->type = Node_array_ref;
1557			r->orig_array = arg;
1558			r->prev_array = arg;
1559		} else if (arg->type == Node_array_ref) {
1560  			*r = *arg;
1561			r->prev_array = arg;
1562		} else {
1563			NODE *n = tree_eval(arg);
1564
1565			r->type = Node_var;
1566			r->lnode = dupnode(n);
1567			r->rnode = (NODE *) NULL;
1568			free_temp(n);
1569  		}
1570		r->vname = varnames[i];
1571		argp = argp->rnode;
1572	}
1573
1574	/*
1575	 * We have to reassign f.  Why, you may ask?  It is possible that
1576	 * other functions were called during the course of tree_eval()-ing
1577	 * the arguments to this function.  As a result of that, fcall_list
1578	 * may have been realloc()'ed, with the result that f is now
1579	 * pointing into free()'d space.  This was a nasty one to track down.
1580	 */
1581	f = & fcall_list[curfcall];
1582
1583	if (argp != NULL) {
1584		/* Left over calling args. */
1585		warning(
1586		    _("function `%s' called with more arguments than declared"),
1587		    func_name);
1588		/* Evaluate them, they may have side effects: */
1589		do {
1590			arg = argp->lnode;
1591			if (arg->type == Node_param_list)
1592				arg = f->prevstack[arg->param_cnt];
1593			if (arg->type != Node_var_array &&
1594			    arg->type != Node_array_ref &&
1595			    arg->type != Node_var_new)
1596				free_temp(tree_eval(arg));
1597
1598			/* reassign f, tree_eval could have moved it */
1599			f = & fcall_list[curfcall];
1600		} while ((argp = argp->rnode) != NULL);
1601	}
1602
1603	stack_ptr = f->stack;
1604}
1605
1606/* func_call --- call a function, call by reference for arrays */
1607
1608NODE **stack_ptr;
1609
1610static NODE *
1611func_call(NODE *tree)
1612{
1613	register NODE *r;
1614	NODE *name, *arg_list;
1615	NODE *f;
1616	jmp_buf volatile func_tag_stack;
1617	jmp_buf volatile loop_tag_stack;
1618	int volatile save_loop_tag_valid = FALSE;
1619	NODE *save_ret_node;
1620	extern NODE *ret_node;
1621
1622	/* tree->rnode is a Node_val giving function name */
1623	/* tree->lnode is Node_expression_list of calling args. */
1624	name = tree->rnode;
1625	arg_list = tree->lnode;
1626
1627	/* retrieve function definition node */
1628	if (tree->funcbody != NULL)
1629		f = tree->funcbody;
1630	else {
1631		f = lookup(name->stptr);
1632		if (f == NULL || f->type != Node_func)
1633			fatal(_("function `%s' not defined"), name->stptr);
1634
1635		tree->funcbody = f;	/* save for next call */
1636	}
1637
1638#ifdef FUNC_TRACE
1639	fprintf(stderr, _("function %s called\n"), name->stptr);
1640#endif
1641	push_args(f->lnode->param_cnt, arg_list, stack_ptr, name->stptr,
1642			f->parmlist);
1643
1644	/*
1645	 * Execute function body, saving context, as a return statement
1646	 * will longjmp back here.
1647	 *
1648	 * Have to save and restore the loop_tag stuff so that a return
1649	 * inside a loop in a function body doesn't scrog any loops going
1650	 * on in the main program.  We save the necessary info in variables
1651	 * local to this function so that function nesting works OK.
1652	 * We also only bother to save the loop stuff if we're in a loop
1653	 * when the function is called.
1654	 */
1655	if (loop_tag_valid) {
1656		int junk = 0;
1657
1658		save_loop_tag_valid = (volatile int) loop_tag_valid;
1659		PUSH_BINDING(loop_tag_stack, loop_tag, junk);
1660		loop_tag_valid = FALSE;
1661	}
1662	PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
1663	save_ret_node = ret_node;
1664	ret_node = Nnull_string;	/* default return value */
1665	INCREMENT(f->exec_count);	/* count function calls */
1666	if (setjmp(func_tag) == 0)
1667		(void) interpret(f->rnode);
1668
1669	r = ret_node;
1670	ret_node = (NODE *) save_ret_node;
1671	RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
1672	pop_fcall();
1673
1674	/* Restore the loop_tag stuff if necessary. */
1675	if (save_loop_tag_valid) {
1676		int junk = 0;
1677
1678		loop_tag_valid = (int) save_loop_tag_valid;
1679		RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
1680	}
1681
1682	if ((r->flags & PERM) == 0)
1683		r->flags |= TEMP;
1684	return r;
1685}
1686
1687#ifdef PROFILING
1688/* dump_fcall_stack --- print a backtrace of the awk function calls */
1689
1690void
1691dump_fcall_stack(FILE *fp)
1692{
1693	int i;
1694
1695	if (curfcall < 0)
1696		return;
1697
1698	fprintf(fp, _("\n\t# Function Call Stack:\n\n"));
1699	for (i = curfcall; i >= 0; i--)
1700		fprintf(fp, "\t# %3d. %s\n", i+1, fcall_list[i].fname);
1701	fprintf(fp, _("\t# -- main --\n"));
1702}
1703#endif /* PROFILING */
1704
1705/*
1706 * r_get_lhs:
1707 * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
1708 * value of the var, or where to store the var's new value
1709 *
1710 * For the special variables, don't unref their current value if it's
1711 * the same as the internal copy; perhaps the current one is used in
1712 * a concatenation or some other expression somewhere higher up in the
1713 * call chain.  Ouch.
1714 */
1715
1716NODE **
1717r_get_lhs(register NODE *ptr, Func_ptr *assign, int reference)
1718{
1719	register NODE **aptr = NULL;
1720	register NODE *n;
1721
1722	if (assign)
1723		*assign = NULL;	/* for safety */
1724	if (ptr->type == Node_param_list) {
1725		if ((ptr->flags & FUNC) != 0)
1726			fatal(_("can't use function name `%s' as variable or array"), ptr->vname);
1727		ptr = stack_ptr[ptr->param_cnt];
1728	}
1729
1730	switch (ptr->type) {
1731	case Node_var_array:
1732		fatal(_("attempt to use array `%s' in a scalar context"),
1733			array_vname(ptr));
1734
1735	/*
1736	 * The following goop ensures that uninitialized variables
1737	 * used as parameters eventually get their type set correctly
1738	 * to scalar (i.e., Node_var).
1739	 */
1740	case Node_array_ref:
1741		if (ptr->orig_array->type == Node_var_array)
1742			fatal(_("attempt to use array `%s' in a scalar context"),
1743				array_vname(ptr));
1744		ptr->orig_array->type = Node_var;
1745		/* fall through */
1746	case Node_var_new:
1747		ptr->type = Node_var;
1748		ptr->var_value = Nnull_string;
1749		/* fall through */
1750	case Node_var:
1751		if (do_lint && reference && var_uninitialized(ptr))
1752			lintwarn(_("reference to uninitialized variable `%s'"),
1753					      ptr->vname);
1754
1755		aptr = &(ptr->var_value);
1756#ifdef GAWKDEBUG
1757		if (ptr->var_value->stref <= 0)
1758			cant_happen();
1759#endif
1760		break;
1761
1762	case Node_FIELDWIDTHS:
1763		aptr = &(FIELDWIDTHS_node->var_value);
1764		if (assign != NULL)
1765			*assign = set_FIELDWIDTHS;
1766		break;
1767
1768	case Node_RS:
1769		aptr = &(RS_node->var_value);
1770		if (assign != NULL)
1771			*assign = set_RS;
1772		break;
1773
1774	case Node_FS:
1775		aptr = &(FS_node->var_value);
1776		if (assign != NULL)
1777			*assign = set_FS;
1778		break;
1779
1780	case Node_FNR:
1781		if (FNR_node->var_value->numbr != FNR) {
1782			unref(FNR_node->var_value);
1783			FNR_node->var_value = make_number((AWKNUM) FNR);
1784		}
1785		aptr = &(FNR_node->var_value);
1786		if (assign != NULL)
1787			*assign = set_FNR;
1788		break;
1789
1790	case Node_NR:
1791		if (NR_node->var_value->numbr != NR) {
1792			unref(NR_node->var_value);
1793			NR_node->var_value = make_number((AWKNUM) NR);
1794		}
1795		aptr = &(NR_node->var_value);
1796		if (assign != NULL)
1797			*assign = set_NR;
1798		break;
1799
1800	case Node_NF:
1801		if (NF == -1 || NF_node->var_value->numbr != NF) {
1802			if (NF == -1)
1803				(void) get_field(HUGE-1, assign); /* parse record */
1804			unref(NF_node->var_value);
1805			NF_node->var_value = make_number((AWKNUM) NF);
1806		}
1807		aptr = &(NF_node->var_value);
1808		if (assign != NULL)
1809			*assign = set_NF;
1810		break;
1811
1812	case Node_IGNORECASE:
1813		aptr = &(IGNORECASE_node->var_value);
1814		if (assign != NULL)
1815			*assign = set_IGNORECASE;
1816		break;
1817
1818	case Node_BINMODE:
1819		aptr = &(BINMODE_node->var_value);
1820		if (assign != NULL)
1821			*assign = set_BINMODE;
1822		break;
1823
1824	case Node_LINT:
1825		aptr = &(LINT_node->var_value);
1826		if (assign != NULL)
1827			*assign = set_LINT;
1828		break;
1829
1830	case Node_OFMT:
1831		aptr = &(OFMT_node->var_value);
1832		if (assign != NULL)
1833			*assign = set_OFMT;
1834		break;
1835
1836	case Node_CONVFMT:
1837		aptr = &(CONVFMT_node->var_value);
1838		if (assign != NULL)
1839			*assign = set_CONVFMT;
1840		break;
1841
1842	case Node_ORS:
1843		aptr = &(ORS_node->var_value);
1844		if (assign != NULL)
1845			*assign = set_ORS;
1846		break;
1847
1848	case Node_OFS:
1849		aptr = &(OFS_node->var_value);
1850		if (assign != NULL)
1851			*assign = set_OFS;
1852		break;
1853
1854	case Node_TEXTDOMAIN:
1855		aptr = &(TEXTDOMAIN_node->var_value);
1856		if (assign != NULL)
1857			*assign = set_TEXTDOMAIN;
1858		break;
1859
1860	case Node_field_spec:
1861		{
1862		int field_num;
1863
1864		n = tree_eval(ptr->lnode);
1865		if (do_lint) {
1866			if ((n->flags & NUMBER) == 0) {
1867				lintwarn(_("attempt to field reference from non-numeric value"));
1868				if (n->stlen == 0)
1869					lintwarn(_("attempt to reference from null string"));
1870			}
1871		}
1872		field_num = (int) force_number(n);
1873		free_temp(n);
1874		if (field_num < 0)
1875			fatal(_("attempt to access field %d"), field_num);
1876		if (field_num == 0 && field0_valid) {	/* short circuit */
1877			aptr = &fields_arr[0];
1878			if (assign != NULL)
1879				*assign = reset_record;
1880		} else
1881			aptr = get_field(field_num, assign);
1882		if (do_lint && reference && (*aptr == Null_field || *aptr == Nnull_string))
1883			lintwarn(_("reference to uninitialized field `$%d'"),
1884					      field_num);
1885		break;
1886		}
1887
1888	case Node_subscript:
1889		n = get_array(ptr->lnode);
1890		aptr = assoc_lookup(n, concat_exp(ptr->rnode), reference);
1891		break;
1892
1893	case Node_builtin:
1894#if 1
1895		/* in gawk for a while */
1896		fatal(_("assignment is not allowed to result of builtin function"));
1897#else
1898		/*
1899		 * This is how Christos at Deshaw did it.
1900		 * Does this buy us anything?
1901		 */
1902		if (ptr->builtin == NULL)
1903			fatal(_("assignment is not allowed to result of builtin function"));
1904		ptr->callresult = (*ptr->builtin)(ptr->subnode);
1905		aptr = &ptr->callresult;
1906		break;
1907#endif
1908
1909	default:
1910		fprintf(stderr, "type = %s\n", nodetype2str(ptr->type));
1911		fflush(stderr);
1912		cant_happen();
1913	}
1914	return aptr;
1915}
1916
1917/* match_op --- do ~ and !~ */
1918
1919static NODE *
1920match_op(register NODE *tree)
1921{
1922	register NODE *t1;
1923	register Regexp *rp;
1924	int i;
1925	int match = TRUE;
1926
1927	if (tree->type == Node_nomatch)
1928		match = FALSE;
1929	if (tree->type == Node_regex)
1930		t1 = *get_field(0, (Func_ptr *) 0);
1931	else {
1932		t1 = force_string(tree_eval(tree->lnode));
1933		tree = tree->rnode;
1934	}
1935	rp = re_update(tree);
1936	i = research(rp, t1->stptr, 0, t1->stlen, FALSE);
1937	i = (i == -1) ^ (match == TRUE);
1938	free_temp(t1);
1939	return tmp_number((AWKNUM) i);
1940}
1941
1942/* set_IGNORECASE --- update IGNORECASE as appropriate */
1943
1944void
1945set_IGNORECASE()
1946{
1947	static int warned = FALSE;
1948
1949	if ((do_lint || do_traditional) && ! warned) {
1950		warned = TRUE;
1951		lintwarn(_("`IGNORECASE' is a gawk extension"));
1952	}
1953	if (do_traditional)
1954		IGNORECASE = FALSE;
1955	else if ((IGNORECASE_node->var_value->flags & (STRING|STRCUR)) != 0) {
1956		if ((IGNORECASE_node->var_value->flags & MAYBE_NUM) == 0)
1957			IGNORECASE = (force_string(IGNORECASE_node->var_value)->stlen > 0);
1958		else
1959			IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
1960	} else if ((IGNORECASE_node->var_value->flags & (NUMCUR|NUMBER)) != 0)
1961		IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
1962	else
1963		IGNORECASE = FALSE;		/* shouldn't happen */
1964
1965	set_RS();	/* set_RS() calls set_FS() if need be, for us */
1966}
1967
1968/* set_BINMODE --- set translation mode (OS/2, DOS, others) */
1969
1970void
1971set_BINMODE()
1972{
1973	static int warned = FALSE;
1974	char *p, *cp, save;
1975	NODE *v;
1976	int digits = FALSE;
1977
1978	if ((do_lint || do_traditional) && ! warned) {
1979		warned = TRUE;
1980		lintwarn(_("`BINMODE' is a gawk extension"));
1981	}
1982	if (do_traditional)
1983		BINMODE = 0;
1984	else if ((BINMODE_node->var_value->flags & STRING) != 0) {
1985		v = BINMODE_node->var_value;
1986		p = v->stptr;
1987		save = p[v->stlen];
1988		p[v->stlen] = '\0';
1989
1990		for (cp = p; *cp != '\0'; cp++) {
1991			if (ISDIGIT(*cp)) {
1992				digits = TRUE;
1993				break;
1994			}
1995		}
1996
1997		if (! digits || (BINMODE_node->var_value->flags & MAYBE_NUM) == 0) {
1998			BINMODE = 0;
1999			if (strcmp(p, "r") == 0)
2000				BINMODE = 1;
2001			else if (strcmp(p, "w") == 0)
2002				BINMODE = 2;
2003			else if (strcmp(p, "rw") == 0 || strcmp(p, "wr") == 0)
2004				BINMODE = 3;
2005
2006			if (BINMODE == 0 && v->stlen != 0) {
2007				/* arbitrary string, assume both */
2008				BINMODE = 3;
2009				warning("BINMODE: arbitary string value treated as \"rw\"");
2010			}
2011		} else
2012			BINMODE = (int) force_number(BINMODE_node->var_value);
2013
2014		p[v->stlen] = save;
2015	} else if ((BINMODE_node->var_value->flags & NUMBER) != 0)
2016		BINMODE = (int) force_number(BINMODE_node->var_value);
2017	else
2018		BINMODE = 0;		/* shouldn't happen */
2019}
2020
2021/* set_OFS --- update OFS related variables when OFS assigned to */
2022
2023void
2024set_OFS()
2025{
2026	OFS = force_string(OFS_node->var_value)->stptr;
2027	OFSlen = OFS_node->var_value->stlen;
2028	OFS[OFSlen] = '\0';
2029}
2030
2031/* set_ORS --- update ORS related variables when ORS assigned to */
2032
2033void
2034set_ORS()
2035{
2036	ORS = force_string(ORS_node->var_value)->stptr;
2037	ORSlen = ORS_node->var_value->stlen;
2038	ORS[ORSlen] = '\0';
2039}
2040
2041/* fmt_ok --- is the conversion format a valid one? */
2042
2043NODE **fmt_list = NULL;
2044static int fmt_ok P((NODE *n));
2045static int fmt_index P((NODE *n));
2046
2047static int
2048fmt_ok(NODE *n)
2049{
2050	NODE *tmp = force_string(n);
2051	const char *p = tmp->stptr;
2052
2053	if (*p++ != '%')
2054		return 0;
2055	while (*p && strchr(" +-#", *p) != NULL)	/* flags */
2056		p++;
2057	while (*p && ISDIGIT(*p))	/* width - %*.*g is NOT allowed */
2058		p++;
2059	if (*p == '\0' || (*p != '.' && ! ISDIGIT(*p)))
2060		return 0;
2061	if (*p == '.')
2062		p++;
2063	while (*p && ISDIGIT(*p))	/* precision */
2064		p++;
2065	if (*p == '\0' || strchr("efgEG", *p) == NULL)
2066		return 0;
2067	if (*++p != '\0')
2068		return 0;
2069	return 1;
2070}
2071
2072/* fmt_index --- track values of OFMT and CONVFMT to keep semantics correct */
2073
2074static int
2075fmt_index(NODE *n)
2076{
2077	register int ix = 0;
2078	static int fmt_num = 4;
2079	static int fmt_hiwater = 0;
2080
2081	if (fmt_list == NULL)
2082		emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
2083	(void) force_string(n);
2084	while (ix < fmt_hiwater) {
2085		if (cmp_nodes(fmt_list[ix], n) == 0)
2086			return ix;
2087		ix++;
2088	}
2089	/* not found */
2090	n->stptr[n->stlen] = '\0';
2091	if (do_lint && ! fmt_ok(n))
2092		lintwarn(_("bad `%sFMT' specification `%s'"),
2093			    n == CONVFMT_node->var_value ? "CONV"
2094			  : n == OFMT_node->var_value ? "O"
2095			  : "", n->stptr);
2096
2097	if (fmt_hiwater >= fmt_num) {
2098		fmt_num *= 2;
2099		erealloc(fmt_list, NODE **, fmt_num * sizeof(*fmt_list), "fmt_index");
2100	}
2101	fmt_list[fmt_hiwater] = dupnode(n);
2102	return fmt_hiwater++;
2103}
2104
2105/* set_OFMT --- track OFMT correctly */
2106
2107void
2108set_OFMT()
2109{
2110	OFMTidx = fmt_index(OFMT_node->var_value);
2111	OFMT = fmt_list[OFMTidx]->stptr;
2112}
2113
2114/* set_CONVFMT --- track CONVFMT correctly */
2115
2116void
2117set_CONVFMT()
2118{
2119	CONVFMTidx = fmt_index(CONVFMT_node->var_value);
2120	CONVFMT = fmt_list[CONVFMTidx]->stptr;
2121}
2122
2123/* set_LINT --- update LINT as appropriate */
2124
2125void
2126set_LINT()
2127{
2128#ifndef NO_LINT
2129	int old_lint = do_lint;
2130
2131	if ((LINT_node->var_value->flags & (STRING|STRCUR)) != 0) {
2132		if ((LINT_node->var_value->flags & MAYBE_NUM) == 0) {
2133			const char *lintval;
2134			size_t lintlen;
2135
2136			do_lint = (force_string(LINT_node->var_value)->stlen > 0);
2137			lintval = LINT_node->var_value->stptr;
2138			lintlen = LINT_node->var_value->stlen;
2139			if (do_lint) {
2140				do_lint = LINT_ALL;
2141				if (lintlen == 5 && strncmp(lintval, "fatal", 5) == 0)
2142					lintfunc = r_fatal;
2143				else if (lintlen == 7 && strncmp(lintval, "invalid", 7) == 0)
2144					do_lint = LINT_INVALID;
2145				else
2146					lintfunc = warning;
2147			} else
2148				lintfunc = warning;
2149		} else {
2150			if (force_number(LINT_node->var_value) != 0.0)
2151				do_lint = LINT_ALL;
2152			else
2153				do_lint = FALSE;
2154			lintfunc = warning;
2155		}
2156	} else if ((LINT_node->var_value->flags & (NUMCUR|NUMBER)) != 0) {
2157		if (force_number(LINT_node->var_value) != 0.0)
2158			do_lint = LINT_ALL;
2159		else
2160			do_lint = FALSE;
2161		lintfunc = warning;
2162	} else
2163		do_lint = FALSE;		/* shouldn't happen */
2164
2165	if (! do_lint)
2166		lintfunc = warning;
2167
2168	/* explicitly use warning() here, in case lintfunc == r_fatal */
2169	if (old_lint != do_lint && old_lint && do_lint == FALSE)
2170		warning(_("turning off `--lint' due to assignment to `LINT'"));
2171#endif /* ! NO_LINT */
2172}
2173
2174/* set_TEXTDOMAIN --- update TEXTDOMAIN variable when TEXTDOMAIN assigned to */
2175
2176void
2177set_TEXTDOMAIN()
2178{
2179	int len;
2180
2181	TEXTDOMAIN = force_string(TEXTDOMAIN_node->var_value)->stptr;
2182	len = TEXTDOMAIN_node->var_value->stlen;
2183	TEXTDOMAIN[len] = '\0';
2184	/*
2185	 * Note: don't call textdomain(); this value is for
2186	 * the awk program, not for gawk itself.
2187	 */
2188}
2189
2190/*
2191 * assign_val --- do mechanics of assignment, for calling from multiple
2192 *		  places.
2193 */
2194
2195NODE *
2196assign_val(NODE **lhs_p, NODE *rhs)
2197{
2198	if (rhs != *lhs_p) {
2199		/*
2200		 * Since we know that the nodes are different,
2201		 * we can do the unref() before the dupnode().
2202		 */
2203		unref(*lhs_p);
2204		*lhs_p = dupnode(rhs);
2205	}
2206	return *lhs_p;
2207}
2208
2209/* update_ERRNO --- update the value of ERRNO */
2210
2211void
2212update_ERRNO()
2213{
2214	char *cp;
2215
2216	cp = strerror(errno);
2217	cp = gettext(cp);
2218	unref(ERRNO_node->var_value);
2219	ERRNO_node->var_value = make_string(cp, strlen(cp));
2220}
2221
2222/* comp_func --- array index comparison function for qsort */
2223
2224static int
2225comp_func(const void *p1, const void *p2)
2226{
2227	size_t len1, len2;
2228	const char *str1, *str2;
2229	const NODE *t1, *t2;
2230	int cmp1;
2231
2232	t1 = *((const NODE *const *) p1);
2233	t2 = *((const NODE *const *) p2);
2234
2235/*
2236	t1 = force_string(t1);
2237	t2 = force_string(t2);
2238*/
2239	len1 = t1->ahname_len;
2240	str1 = t1->ahname_str;
2241
2242	len2 = t2->ahname_len;
2243	str2 = t2->ahname_str;
2244
2245	/* Array indexes are strings, compare as such, always! */
2246	cmp1 = memcmp(str1, str2, len1 < len2 ? len1 : len2);
2247	/* if prefixes are equal, size matters */
2248	return (cmp1 != 0 ? cmp1 :
2249		len1 < len2 ? -1 : (len1 > len2));
2250}
2251