~vcs-imports/gawk/master

291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1
/*
302 by john haque
Finish builtins for MPFR.
2
 * interpret.h ---  run a list of instructions.
3
 */
4
5
/* 
1261 by Arnold D. Robbins
Update copyright years on changed files.
6
 * Copyright (C) 1986, 1988, 1989, 1991-2020,
7
 * the Free Software Foundation, Inc.
302 by john haque
Finish builtins for MPFR.
8
 * 
9
 * This file is part of GAWK, the GNU implementation of the
10
 * AWK Programming Language.
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
11
 *
302 by john haque
Finish builtins for MPFR.
12
 * GAWK is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 3 of the License, or
15
 * (at your option) any later version.
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
16
 *
302 by john haque
Finish builtins for MPFR.
17
 * GAWK is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
21
 *
302 by john haque
Finish builtins for MPFR.
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
25
 */
26
408.30.3 by Andrew J. Schorr
Remove FIELD flag, since it is the inverse of the MALLOC flag.
27
/*
28
 * If "r" is a field, valref should normally be > 1, because the field is
29
 * created initially with valref 1, and valref should be bumped when it is
30
 * pushed onto the stack by Op_field_spec. On the other hand, if we are
31
 * assigning to $n, then Op_store_field calls unref(*lhs) before assigning
32
 * the new value, so that decrements valref. So if the RHS is a field with
33
 * valref 1, that effectively means that this is an assignment like "$n = $n",
34
 * so a no-op, other than triggering $0 reconstitution.
35
 */
731.11.338 by Arnold D. Robbins
Copy MPZ/MPFR bits also, in r_dupnode.
36
37
// not a macro so we can step into it with a debugger
38
#ifndef UNFIELD_DEFINED
39
#define UNFIELD_DEFINED 1
40
static inline void
41
unfield(NODE **l, NODE **r)
42
{
43
	/* if was a field, turn it into a var */
44
	if (((*r)->flags & MALLOC) != 0 || (*r)->valref == 1) {
45
		(*l) = (*r);
46
	} else {
47
		(*l) = dupnode(*r);
48
		DEREF(*r);
49
	}
408.13.4 by Arnold D. Robbins
Add unfield code in several spots.
50
}
731.11.338 by Arnold D. Robbins
Copy MPZ/MPFR bits also, in r_dupnode.
51
52
#define UNFIELD(l, r)	unfield(& (l), & (r))
53
#endif
54
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
55
int
56
r_interpret(INSTRUCTION *code)
57
{
58
	INSTRUCTION *pc;   /* current instruction */
301 by john haque
New interpreter routine for MPFR.
59
	OPCODE op;	/* current opcode */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
60
	NODE *r = NULL;
61
	NODE *m;
62
	INSTRUCTION *ni;
63
	NODE *t1, *t2;
64
	NODE **lhs;
302.1.1 by john haque
Finish MPFR changes and clean up code.
65
	AWKNUM x, x2;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
66
	int di;
67
	Regexp *rp;
322 by john haque
Improve array interface.
68
	NODE *set_array = NULL;	/* array with a post-assignment routine */
69
	NODE *set_idx = NULL;	/* the index of the array element */
70
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
71
72
/* array subscript */
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
73
#define mk_sub(n)  	(n == 1 ? POP_SCALAR() : concat_exp(n, true))
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
74
302.1.1 by john haque
Finish MPFR changes and clean up code.
75
#ifdef EXEC_HOOK
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
76
#define JUMPTO(x)	do { if (post_execute) post_execute(pc); pc = (x); goto top; } while (false)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
77
#else
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
78
#define JUMPTO(x)	do { pc = (x); goto top; } while (false)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
79
#endif
80
81
	pc = code;
82
83
	/* N.B.: always use JUMPTO for next instruction, otherwise bad things
84
	 * may happen. DO NOT add a real loop (for/while) below to
85
	 * replace ' forever {'; this catches failure to use JUMPTO to execute
86
	 * next instruction (e.g. continue statement).
87
	 */
88
89
	/* loop until hit Op_stop instruction */
90
91
	/* forever {  */
92
top:
93
		if (pc->source_line > 0)
94
			sourceline = pc->source_line;
95
302.1.1 by john haque
Finish MPFR changes and clean up code.
96
#ifdef EXEC_HOOK
97
		for (di = 0; di < num_exec_hook; di++) {
98
			if (! pre_execute[di](& pc))
99
				goto top;
100
		}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
101
#endif
102
1379.1.7 by Arnold D. Robbins
Add instruction trace option.
103
		op = pc->opcode;
104
		if (do_itrace) {
105
			fprintf(stderr, "+ %s\n", opcode2str(op));
106
			fflush(stderr);
107
		}
108
109
		switch (op) {
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
110
		case Op_rule:
111
			currule = pc->in_rule;   /* for sole use in Op_K_next, Op_K_nextfile, Op_K_getline */
112
			/* fall through */
113
		case Op_func:
114
			source = pc->source_file;
115
			break;
116
117
		case Op_atexit:
301 by john haque
New interpreter routine for MPFR.
118
		{
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
119
			bool stdio_problem = false;
731.11.368 by Arnold D. Robbins
Fix a corner case with EPIPE to stdout/stderr.
120
			bool got_EPIPE = false;
301 by john haque
New interpreter routine for MPFR.
121
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
122
			/* avoid false source indications */
123
			source = NULL;
124
			sourceline = 0;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
125
			(void) nextfile(& curfile, true);	/* close input data file */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
126
			/*
127
			 * This used to be:
128
			 *
129
			 * if (close_io() != 0 && ! exiting && exit_val == 0)
130
			 *      exit_val = 1;
131
			 *
132
			 * Other awks don't care about problems closing open files
133
			 * and pipes, in that it doesn't affect their exit status.
134
			 * So we no longer do either.
135
			 */
731.11.368 by Arnold D. Robbins
Fix a corner case with EPIPE to stdout/stderr.
136
			(void) close_io(& stdio_problem, & got_EPIPE);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
137
			/*
138
			 * However, we do want to exit non-zero if there was a problem
139
			 * with stdout/stderr, so we reinstate a slightly different
140
			 * version of the above:
141
			 */
142
			if (stdio_problem && ! exiting && exit_val == 0)
143
				exit_val = 1;
323 by john haque
Add optional shutdown routine for an extension lib.
144
145
			close_extensions();
731.11.368 by Arnold D. Robbins
Fix a corner case with EPIPE to stdout/stderr.
146
147
			if (got_EPIPE)
148
				die_via_sigpipe();
301 by john haque
New interpreter routine for MPFR.
149
		}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
150
			break;
151
152
		case Op_stop:
153
			return 0;
154
155
		case Op_push_i:
156
			m = pc->memory;
157
			if (! do_traditional && (m->flags & INTLSTR) != 0) {
408.30.14 by Andrew J. Schorr
Optimization: support unterminated field strings inside gawk, but make terminated copies for the API.
158
				char *orig, *trans, save;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
159
408.30.14 by Andrew J. Schorr
Optimization: support unterminated field strings inside gawk, but make terminated copies for the API.
160
				save = m->stptr[m->stlen];
161
				m->stptr[m->stlen] = '\0';
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
162
				orig = m->stptr;
163
				trans = dgettext(TEXTDOMAIN, orig);
408.30.14 by Andrew J. Schorr
Optimization: support unterminated field strings inside gawk, but make terminated copies for the API.
164
				m->stptr[m->stlen] = save;
731.18.36 by Arnold D. Robbins
Small optimization for translatable strings.
165
				if (trans != orig)	// got a translation
166
					m = make_string(trans, strlen(trans));
167
				else
168
					UPREF(m);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
169
			} else
170
				UPREF(m);
171
			PUSH(m);
172
			break;
173
174
		case Op_push:
175
		case Op_push_arg:
408.20.44 by Arnold D. Robbins
Fix typeof to not change untyped param to scalar.
176
		case Op_push_arg_untyped:
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
177
		{
178
			NODE *save_symbol;
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
179
			bool isparam = false;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
180
181
			save_symbol = m = pc->memory;
182
			if (m->type == Node_param_list) {
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
183
				isparam = true;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
184
				save_symbol = m = GET_PARAM(m->param_cnt);
350 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable'
185
				if (m->type == Node_array_ref) {
186
					if (m->orig_array->type == Node_var) {
187
						/* gawk 'func f(x) { a = 10; print x; } BEGIN{ f(a) }' */
188
						goto uninitialized_scalar;
189
					}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
190
					m = m->orig_array;
350 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable'
191
				}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
192
			}
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
193
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
194
			switch (m->type) {
195
			case Node_var:
196
				if (do_lint && var_uninitialized(m))
197
					lintwarn(isparam ?
198
						_("reference to uninitialized argument `%s'") :
199
						_("reference to uninitialized variable `%s'"),
200
								save_symbol->vname);
201
				m = m->var_value;
202
				UPREF(m);
203
				PUSH(m);
204
				break;
205
206
			case Node_var_new:
350 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable'
207
uninitialized_scalar:
408.20.44 by Arnold D. Robbins
Fix typeof to not change untyped param to scalar.
208
				if (op != Op_push_arg_untyped) {
408.20.48 by Arnold D. Robbins
More work straightening out typeof, including tests.
209
					/* convert untyped to scalar */
408.20.44 by Arnold D. Robbins
Fix typeof to not change untyped param to scalar.
210
					m->type = Node_var;
211
					m->var_value = dupnode(Nnull_string);
212
				}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
213
				if (do_lint)
214
					lintwarn(isparam ?
215
						_("reference to uninitialized argument `%s'") :
216
						_("reference to uninitialized variable `%s'"),
217
								save_symbol->vname);
408.20.48 by Arnold D. Robbins
More work straightening out typeof, including tests.
218
				if (op != Op_push_arg_untyped)
219
					m = dupnode(Nnull_string);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
220
				PUSH(m);
221
				break;
222
223
			case Node_var_array:
408.20.44 by Arnold D. Robbins
Fix typeof to not change untyped param to scalar.
224
				if (op == Op_push_arg || op == Op_push_arg_untyped)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
225
					PUSH(m);
226
				else
227
					fatal(_("attempt to use array `%s' in a scalar context"),
228
							array_vname(save_symbol));
229
				break;
230
231
			default:
232
				cant_happen();
233
			}
234
		}
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
235
			break;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
236
237
		case Op_push_param:		/* function argument */
238
			m = pc->memory;
239
			if (m->type == Node_param_list)
240
				m = GET_PARAM(m->param_cnt);
241
			if (m->type == Node_var) {
242
				m = m->var_value;
243
				UPREF(m);
244
				PUSH(m);
245
		 		break;
246
			}
247
 			/* else
248
				fall through */
249
		case Op_push_array:
250
			PUSH(pc->memory);
251
			break;
252
253
		case Op_push_lhs:
254
			lhs = get_lhs(pc->memory, pc->do_reference);
255
			PUSH_ADDRESS(lhs);
256
			break;
257
258
		case Op_subscript:
259
			t2 = mk_sub(pc->sub_count);
731.17.41 by Arnold D. Robbins
Add more lint warnings.
260
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
261
262
			if (do_lint && in_array(t1, t2) == NULL) {
263
				t2 = force_string(t2);
264
				lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
265
					array_vname(t1), (int) t2->stlen, t2->stptr);
266
				if (t2->stlen == 0)
267
					lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
268
			}
269
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
270
			/* for FUNCTAB, get the name as the element value */
271
			if (t1 == func_table) {
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
272
				static bool warned = false;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
273
1146.1.49 by Arnold D. Robbins
Fix four more lint extension warnings.
274
				if (do_lint_extensions && ! warned) {
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
275
					warned = true;
276
					lintwarn(_("FUNCTAB is a gawk extension"));
277
				}
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
278
				r = t2;
279
			} else {
347 by Arnold D. Robbins
Make indirectly updated vars accessable to SYMTAB, API.
280
				/* make sure stuff like NF, NR, are up to date */
281
				if (t1 == symbol_table)
282
					update_global_values();
283
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
284
				r = *assoc_lookup(t1, t2);
285
			}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
286
			DEREF(t2);
319.9.1 by Arnold D. Robbins
First cut at SYMTAB and FUNCTAB.
287
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
288
			/* for SYMTAB, step through to the actual variable */
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
289
			if (t1 == symbol_table) {
290
				static bool warned = false;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
291
1146.1.49 by Arnold D. Robbins
Fix four more lint extension warnings.
292
				if (do_lint_extensions && ! warned) {
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
293
					warned = true;
294
					lintwarn(_("SYMTAB is a gawk extension"));
295
				}
296
				if (r->type == Node_var)
297
					r = r->var_value;
1252 by Arnold D. Robbins
Fix a bug in retrieving unset variables through SYMTAB.
298
				else if (r->type == Node_var_new) {
299
					// variable may exist but have never been set.
300
					r->var_value = dupnode(Nnull_string);
301
					r = r->var_value;
302
				}
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
303
			}
319.9.1 by Arnold D. Robbins
First cut at SYMTAB and FUNCTAB.
304
408.31.40 by Arnold D. Robbins
First steps reworking code away from node type.
305
			if (r->type == Node_val)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
306
				UPREF(r);
307
			PUSH(r);
308
			break;
309
310
		case Op_sub_array:
311
			t2 = mk_sub(pc->sub_count);
731.17.41 by Arnold D. Robbins
Add more lint warnings.
312
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
313
			r = in_array(t1, t2);
314
			if (r == NULL) {
315
				r = make_array();
316
				r->parent_array = t1;
317
				t2 = force_string(t2);
318
				r->vname = estrdup(t2->stptr, t2->stlen);	/* the subscript in parent array */
1061 by Arnold D. Robbins
Finish transition to using assoc_set.
319
				assoc_set(t1, t2, r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
320
			} else if (r->type != Node_var_array) {
321
				t2 = force_string(t2);
322
				fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"),
323
						array_vname(t1), (int) t2->stlen, t2->stptr);
1063 by Arnold D. Robbins
Cleanups for assoc_set.
324
			} else
325
				DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
326
327
			PUSH(r);
328
			break;
329
330
		case Op_subscript_lhs:
331
			t2 = mk_sub(pc->sub_count);
731.17.41 by Arnold D. Robbins
Add more lint warnings.
332
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
333
			if (do_lint && in_array(t1, t2) == NULL) {
334
				t2 = force_string(t2);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
335
				if (pc->do_reference)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
336
					lintwarn(_("reference to uninitialized element `%s[\"%.*s\"]'"),
337
						array_vname(t1), (int) t2->stlen, t2->stptr);
338
				if (t2->stlen == 0)
339
					lintwarn(_("subscript of array `%s' is null string"), array_vname(t1));
340
			}
341
342
			lhs = assoc_lookup(t1, t2);
343
			if ((*lhs)->type == Node_var_array) {
344
				t2 = force_string(t2);
345
				fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
346
						array_vname(t1), (int) t2->stlen, t2->stptr);
347
			}
348
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
349
			/*
350
			 * Changing something in FUNCTAB is not allowed.
351
			 *
352
			 * SYMTAB is a little more messy.  Three kinds of values may
353
			 * be stored in SYMTAB:
354
			 * 	1. Variables that don"t yet have a value (Node_var_new)
355
			 * 	2. Variables that have a value (Node_var)
356
			 * 	3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
357
			 * For 1, since we are giving it a value, we have to change the type to Node_var.
358
			 * For 1 and 2, we have to step through the Node_var to get to the value.
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
359
			 * For 3, we fatal out. This avoids confusion on things like
360
			 * SYMTAB["a foo"] = 42	# variable with a space in its name?
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
361
			 */
362
			if (t1 == func_table)
363
				fatal(_("cannot assign to elements of FUNCTAB"));
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
364
			else if (t1 == symbol_table) {
365
				if ((   (*lhs)->type == Node_var
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
366
				     || (*lhs)->type == Node_var_new)) {
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
367
					update_global_values();		/* make sure stuff like NF, NR, are up to date */
368
					(*lhs)->type = Node_var;	/* in case was Node_var_new */
369
					lhs = & ((*lhs)->var_value);	/* extra level of indirection */
370
				} else
371
					fatal(_("cannot assign to arbitrary elements of SYMTAB"));
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
372
			}
373
322 by john haque
Improve array interface.
374
			assert(set_idx == NULL);
375
376
			if (t1->astore) {
377
				/* array has post-assignment routine */
378
				set_array = t1;
379
				set_idx = t2;
380
			} else
381
				DEREF(t2);
382
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
383
			PUSH_ADDRESS(lhs);
384
			break;
385
386
		case Op_field_spec:
387
			t1 = TOP_SCALAR();
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
388
			lhs = r_get_field(t1, (Func_ptr *) 0, true);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
389
			decr_sp();
390
			DEREF(t1);
408.30.8 by Andrew J. Schorr
Now that all fields are NUL-terminated, we can eliminate $n copying in the interpreter.
391
			r = *lhs;
392
			UPREF(r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
393
			PUSH(r);
394
			break;
395
396
		case Op_field_spec_lhs:
397
			t1 = TOP_SCALAR();
398
			lhs = r_get_field(t1, &pc->target_assign->field_assign, pc->do_reference);
399
			decr_sp();
400
			DEREF(t1);
401
			PUSH_ADDRESS(lhs);
402
			break;
403
404
		case Op_lint:
405
			if (do_lint) {
406
				switch (pc->lint_type) {
407
				case LINT_assign_in_cond:
408
					lintwarn(_("assignment used in conditional context"));
409
					break;
410
411
				case LINT_no_effect:
412
					lintwarn(_("statement has no effect"));
413
					break;
414
415
				default:
416
					cant_happen();
417
				}
418
			}
419
			break;
420
1349 by Arnold D. Robbins
Add lint check for string + string.
421
		case Op_lint_plus:
422
			// no need to check do_lint, this opcode won't
423
			// be generated if that's not true
424
			t1 = TOP();
425
			t2 = PEEK(1);
426
			if ((t1->flags & STRING) != 0 && (t2->flags & STRING) != 0)
427
				lintwarn(_("operator `+' used on two string values"));
428
			break;
429
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
430
		case Op_K_break:
431
		case Op_K_continue:
432
		case Op_jmp:
319.1.61 by Arnold D. Robbins
SYMTAB enhancements, bug fix. Doc additions.
433
			assert(pc->target_jmp != NULL);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
434
			JUMPTO(pc->target_jmp);
435
436
		case Op_jmp_false:
437
			r = POP_SCALAR();
438
			di = eval_condition(r);
439
			DEREF(r);
440
			if (! di)
441
				JUMPTO(pc->target_jmp);
442
			break;
443
444
		case Op_jmp_true:
445
			r = POP_SCALAR();
446
			di = eval_condition(r);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
447
			DEREF(r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
448
			if (di)
449
				JUMPTO(pc->target_jmp);
450
			break;
451
452
		case Op_and:
453
		case Op_or:
454
			t1 = POP_SCALAR();
455
			di = eval_condition(t1);
456
			DEREF(t1);
301 by john haque
New interpreter routine for MPFR.
457
			if ((op == Op_and && di) || (op == Op_or && ! di))
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
458
				break;
459
			r = node_Boolean[di];
460
			UPREF(r);
461
			PUSH(r);
462
			ni = pc->target_jmp;
463
			JUMPTO(ni->nexti);
464
465
		case Op_and_final:
466
		case Op_or_final:
467
			t1 = TOP_SCALAR();
468
			r = node_Boolean[eval_condition(t1)];
469
			DEREF(t1);
470
			UPREF(r);
471
			REPLACE(r);
472
			break;
473
474
		case Op_not:
475
			t1 = TOP_SCALAR();
476
			r = node_Boolean[! eval_condition(t1)];
477
			DEREF(t1);
478
			UPREF(r);
479
			REPLACE(r);
480
			break;
481
482
		case Op_equal:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
483
			r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) == 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
484
			UPREF(r);
485
			REPLACE(r);
486
			break;
487
488
		case Op_notequal:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
489
			r = node_Boolean[cmp_scalars(SCALAR_EQ_NEQ) != 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
490
			UPREF(r);
491
			REPLACE(r);
492
			break;
493
494
		case Op_less:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
495
			r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) < 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
496
			UPREF(r);
497
			REPLACE(r);
498
			break;
499
500
		case Op_greater:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
501
			r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) > 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
502
			UPREF(r);
503
			REPLACE(r);
504
			break;
505
506
		case Op_leq:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
507
			r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) <= 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
508
			UPREF(r);
509
			REPLACE(r);
510
			break;
511
512
		case Op_geq:
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
513
			r = node_Boolean[cmp_scalars(SCALAR_RELATIONAL) >= 0];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
514
			UPREF(r);
515
			REPLACE(r);
516
			break;
517
518
		case Op_plus_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
519
			x2 = force_number(pc->memory)->numbr;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
520
			goto plus;
521
		case Op_plus:
301 by john haque
New interpreter routine for MPFR.
522
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
523
			x2 = t2->numbr;
524
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
525
plus:
301 by john haque
New interpreter routine for MPFR.
526
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
527
			r = make_number(t1->numbr + x2);
301 by john haque
New interpreter routine for MPFR.
528
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
529
			REPLACE(r);
530
			break;
531
532
		case Op_minus_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
533
			x2 = force_number(pc->memory)->numbr;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
534
			goto minus;
535
		case Op_minus:
301 by john haque
New interpreter routine for MPFR.
536
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
537
			x2 = t2->numbr;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
538
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
539
minus:
301 by john haque
New interpreter routine for MPFR.
540
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
541
			r = make_number(t1->numbr - x2);
301 by john haque
New interpreter routine for MPFR.
542
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
543
			REPLACE(r);
544
			break;
545
546
		case Op_times_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
547
			x2 = force_number(pc->memory)->numbr;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
548
			goto times;
549
		case Op_times:
301 by john haque
New interpreter routine for MPFR.
550
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
551
			x2 = t2->numbr;
552
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
553
times:
301 by john haque
New interpreter routine for MPFR.
554
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
555
			r = make_number(t1->numbr * x2);
301 by john haque
New interpreter routine for MPFR.
556
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
557
			REPLACE(r);
558
			break;
559
560
		case Op_exp_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
561
			x2 = force_number(pc->memory)->numbr;
301 by john haque
New interpreter routine for MPFR.
562
			goto exp;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
563
		case Op_exp:
301 by john haque
New interpreter routine for MPFR.
564
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
565
			x2 = t2->numbr;
566
			DEREF(t2);
301 by john haque
New interpreter routine for MPFR.
567
exp:
568
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
569
			r = make_number(calc_exp(t1->numbr, x2));
301 by john haque
New interpreter routine for MPFR.
570
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
571
			REPLACE(r);
572
			break;
573
574
		case Op_quotient_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
575
			x2 = force_number(pc->memory)->numbr;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
576
			goto quotient;
577
		case Op_quotient:
301 by john haque
New interpreter routine for MPFR.
578
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
579
			x2 = t2->numbr;
580
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
581
quotient:
301 by john haque
New interpreter routine for MPFR.
582
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
583
			if (x2 == 0)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
584
				fatal(_("division by zero attempted"));
302.1.1 by john haque
Finish MPFR changes and clean up code.
585
			r = make_number(t1->numbr / x2);
301 by john haque
New interpreter routine for MPFR.
586
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
587
			REPLACE(r);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
588
			break;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
589
590
		case Op_mod_i:
302.1.1 by john haque
Finish MPFR changes and clean up code.
591
			x2 = force_number(pc->memory)->numbr;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
592
			goto mod;
593
		case Op_mod:
301 by john haque
New interpreter routine for MPFR.
594
			t2 = POP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
595
			x2 = t2->numbr;
596
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
597
mod:
301 by john haque
New interpreter routine for MPFR.
598
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
599
			if (x2 == 0)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
600
				fatal(_("division by zero attempted in `%%'"));
601
#ifdef HAVE_FMOD
302.1.1 by john haque
Finish MPFR changes and clean up code.
602
			x = fmod(t1->numbr, x2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
603
#else	/* ! HAVE_FMOD */
302.1.1 by john haque
Finish MPFR changes and clean up code.
604
			(void) modf(t1->numbr / x2, &x);
605
			x = t1->numbr - x * x2;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
606
#endif	/* ! HAVE_FMOD */
607
			r = make_number(x);
302.1.1 by john haque
Finish MPFR changes and clean up code.
608
301 by john haque
New interpreter routine for MPFR.
609
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
610
			REPLACE(r);
301 by john haque
New interpreter routine for MPFR.
611
			break;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
612
613
		case Op_preincrement:
614
		case Op_predecrement:
301 by john haque
New interpreter routine for MPFR.
615
			x = op == Op_preincrement ? 1.0 : -1.0;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
616
			lhs = TOP_ADDRESS();
617
			t1 = *lhs;
301 by john haque
New interpreter routine for MPFR.
618
			force_number(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
619
			if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
620
				/* optimization */
302.1.1 by john haque
Finish MPFR changes and clean up code.
621
				t1->numbr += x;
301 by john haque
New interpreter routine for MPFR.
622
				r = t1;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
623
			} else {
302.1.1 by john haque
Finish MPFR changes and clean up code.
624
				r = *lhs = make_number(t1->numbr + x);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
625
				unref(t1);
626
			}
301 by john haque
New interpreter routine for MPFR.
627
			UPREF(r);
628
			REPLACE(r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
629
			break;
630
631
		case Op_postincrement:
632
		case Op_postdecrement:
301 by john haque
New interpreter routine for MPFR.
633
			x = op == Op_postincrement ? 1.0 : -1.0;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
634
			lhs = TOP_ADDRESS();
635
			t1 = *lhs;
301 by john haque
New interpreter routine for MPFR.
636
			force_number(t1);
302.1.1 by john haque
Finish MPFR changes and clean up code.
637
			r = make_number(t1->numbr);
301 by john haque
New interpreter routine for MPFR.
638
			if (t1->valref == 1 && t1->flags == (MALLOC|NUMCUR|NUMBER)) {
639
 				/* optimization */
302.1.1 by john haque
Finish MPFR changes and clean up code.
640
				t1->numbr += x;
301 by john haque
New interpreter routine for MPFR.
641
			} else {
302.1.1 by john haque
Finish MPFR changes and clean up code.
642
				*lhs = make_number(t1->numbr + x);
301 by john haque
New interpreter routine for MPFR.
643
				unref(t1);
644
			}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
645
			REPLACE(r);
646
			break;
647
648
		case Op_unary_minus:
301 by john haque
New interpreter routine for MPFR.
649
			t1 = TOP_NUMBER();
302.1.1 by john haque
Finish MPFR changes and clean up code.
650
			r = make_number(-t1->numbr);
301 by john haque
New interpreter routine for MPFR.
651
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
652
			REPLACE(r);
653
			break;
654
408.26.80 by Arnold D. Robbins
Implement unary plus for real, including for pretty printing.
655
		case Op_unary_plus:
656
			// Force argument to be numeric
657
			t1 = TOP_NUMBER();
731.11.303 by Andrew J. Schorr
Fix bug printing +"01" in regular and MPFR mode.
658
			r = make_number(t1->numbr);
659
			DEREF(t1);
660
			REPLACE(r);
408.26.80 by Arnold D. Robbins
Implement unary plus for real, including for pretty printing.
661
			break;
662
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
663
		case Op_store_sub:
321 by john haque
Polish array handling code.
664
			/*
665
			 * array[sub] assignment optimization,
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
666
			 * see awkgram.y (optimize_assignment)
667
			 */
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
668
			t1 = force_array(pc->memory, true);	/* array */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
669
			t2 = mk_sub(pc->expr_count);	/* subscript */
670
 			lhs = assoc_lookup(t1, t2);
671
			if ((*lhs)->type == Node_var_array) {
672
				t2 = force_string(t2);
673
				fatal(_("attempt to use array `%s[\"%.*s\"]' in a scalar context"),
674
						array_vname(t1), (int) t2->stlen, t2->stptr);
675
			}
676
			DEREF(t2);
319.9.1 by Arnold D. Robbins
First cut at SYMTAB and FUNCTAB.
677
319.1.96 by Arnold D. Robbins
Bug fixes for SYMTAB.
678
			/*
679
			 * Changing something in FUNCTAB is not allowed.
680
			 *
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
681
			 * SYMTAB is a little more messy.  Three possibilities for SYMTAB:
319.1.96 by Arnold D. Robbins
Bug fixes for SYMTAB.
682
			 * 	1. Variables that don"t yet have a value (Node_var_new)
683
			 * 	2. Variables that have a value (Node_var)
684
			 * 	3. Values that awk code stuck into SYMTAB not related to variables (Node_value)
685
			 * For 1, since we are giving it a value, we have to change the type to Node_var.
686
			 * For 1 and 2, we have to step through the Node_var to get to the value.
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
687
			 * For 3, we fatal out. This avoids confusion on things like
688
			 * SYMTAB["a foo"] = 42	# variable with a space in its name?
319.1.96 by Arnold D. Robbins
Bug fixes for SYMTAB.
689
			 */
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
690
			if (t1 == func_table)
691
				fatal(_("cannot assign to elements of FUNCTAB"));
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
692
			else if (t1 == symbol_table) {
693
				if ((   (*lhs)->type == Node_var
319.1.96 by Arnold D. Robbins
Bug fixes for SYMTAB.
694
				     || (*lhs)->type == Node_var_new)) {
731.15.96 by Arnold D. Robbins
Disable writing to arbitrary elements of SYMTAB.
695
					update_global_values();		/* make sure stuff like NF, NR, are up to date */
696
					(*lhs)->type = Node_var;	/* in case was Node_var_new */
697
					lhs = & ((*lhs)->var_value);	/* extra level of indirection */
698
				} else
699
					fatal(_("cannot assign to arbitrary elements of SYMTAB"));
319.1.96 by Arnold D. Robbins
Bug fixes for SYMTAB.
700
			}
319.9.1 by Arnold D. Robbins
First cut at SYMTAB and FUNCTAB.
701
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
702
			unref(*lhs);
408.13.10 by Arnold D. Robbins
Remove OLDMEM checks, preparatory to merging.
703
			r = POP_SCALAR();
704
			UNFIELD(*lhs, r);
322 by john haque
Improve array interface.
705
706
			/* execute post-assignment routine if any */
707
			if (t1->astore != NULL)
708
				(*t1->astore)(t1, t2);
709
710
			DEREF(t2);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
711
			break;
712
713
		case Op_store_var:
321 by john haque
Polish array handling code.
714
			/*
715
			 * simple variable assignment optimization,
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
716
			 * see awkgram.y (optimize_assignment)
717
			 */
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
718
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
719
			lhs = get_lhs(pc->memory, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
720
			unref(*lhs);
721
			r = pc->initval;	/* constant initializer */
408.13.10 by Arnold D. Robbins
Remove OLDMEM checks, preparatory to merging.
722
			if (r != NULL) {
723
				UPREF(r);
724
				*lhs = r;
408.13.1 by Arnold D. Robbins
Add field reference changes. Currently breaks sortglos test.
725
			} else {
408.13.10 by Arnold D. Robbins
Remove OLDMEM checks, preparatory to merging.
726
				r = POP_SCALAR();
727
				UNFIELD(*lhs, r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
728
			}
729
			break;
730
731
		case Op_store_field:
732
		{
733
			/* field assignment optimization,
734
			 * see awkgram.y (optimize_assignment)
735
			 */
736
737
			Func_ptr assign;
738
			t1 = TOP_SCALAR();
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
739
			lhs = r_get_field(t1, & assign, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
740
			decr_sp();
741
			DEREF(t1);
731.11.221 by Andrew J. Schorr
Fix field corruption when $0 is reassigned with open $n references.
742
			/*
743
			 * N.B. We must call assign() before unref, since
744
			 * we may need to copy $n values before freeing the
745
			 * $0 buffer.
746
			 */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
747
			assert(assign != NULL);
748
			assign();
731.11.221 by Andrew J. Schorr
Fix field corruption when $0 is reassigned with open $n references.
749
			unref(*lhs);
750
			r = POP_SCALAR();
751
			UNFIELD(*lhs, r);
1146.1.10 by Arnold D. Robbins
Speed field assignment back up.
752
			/* field variables need the string representation: */
753
			force_string(*lhs);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
754
		}
755
			break;
756
757
		case Op_assign_concat:
758
			/* x = x ... string concatenation optimization */
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
759
			lhs = get_lhs(pc->memory, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
760
			t1 = force_string(*lhs);
761
			t2 = POP_STRING();
762
763
			if (t1 != *lhs) {
764
				unref(*lhs);
1251 by Arnold D. Robbins
Fix a number of memory leaks.
765
				if (t1->valref == 1)
766
					*lhs = t1;
767
				else
768
					*lhs = dupnode(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
769
			}
770
731.3.27 by Andrew J. Schorr
Improve robustness of Op_assign_concat optimization.
771
			if (t1 != t2 && t1->valref == 1 && (t1->flags & (MALLOC|MPFN|MPZN)) == MALLOC) {
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
772
				size_t nlen = t1->stlen + t2->stlen;
773
408.17.1 by Andrew J. Schorr
Stop allocating an extra wasted byte at the end of various strings.
774
				erealloc(t1->stptr, char *, nlen + 1, "r_interpret");
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
775
				memcpy(t1->stptr + t1->stlen, t2->stptr, t2->stlen);
776
				t1->stlen = nlen;
777
				t1->stptr[nlen] = '\0';
731.3.27 by Andrew J. Schorr
Improve robustness of Op_assign_concat optimization.
778
				/* clear flags except WSTRCUR (used below) */
779
				t1->flags &= WSTRCUR;
780
				/* configure as a string as in make_str_node */
781
				t1->flags |= (MALLOC|STRING|STRCUR);
782
				t1->stfmt = STFMT_UNUSED;
731.11.254 by Arnold D. Robbins
Changes to ROUNDMODE now invalidate cached string values.
783
#ifdef HAVE_MPFR
784
				t1->strndmode = MPFR_round_mode;
785
#endif
319.1.129 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable'
786
787
				if ((t1->flags & WSTRCUR) != 0 && (t2->flags & WSTRCUR) != 0) {
788
					size_t wlen = t1->wstlen + t2->wstlen;
789
790
					erealloc(t1->wstptr, wchar_t *,
408.17.1 by Andrew J. Schorr
Stop allocating an extra wasted byte at the end of various strings.
791
							sizeof(wchar_t) * (wlen + 1), "r_interpret");
408.30.66 by Arnold D. Robbins
Audit use of stptr for NUL termination. Update doc before merge to master.
792
					memcpy(t1->wstptr + t1->wstlen, t2->wstptr, t2->wstlen * sizeof(wchar_t));
319.1.129 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable'
793
					t1->wstlen = wlen;
794
					t1->wstptr[wlen] = L'\0';
795
				} else
796
					free_wstr(*lhs);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
797
			} else {
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
798
				size_t nlen = t1->stlen + t2->stlen;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
799
				char *p;
800
408.17.1 by Andrew J. Schorr
Stop allocating an extra wasted byte at the end of various strings.
801
				emalloc(p, char *, nlen + 1, "r_interpret");
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
802
				memcpy(p, t1->stptr, t1->stlen);
803
				memcpy(p + t1->stlen, t2->stptr, t2->stlen);
408.17.1 by Andrew J. Schorr
Stop allocating an extra wasted byte at the end of various strings.
804
				/* N.B. No NUL-termination required, since make_str_node will do it. */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
805
				unref(*lhs);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
806
				t1 = *lhs = make_str_node(p, nlen, ALREADY_MALLOCED);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
807
			}
808
			DEREF(t2);
809
			break;
810
811
		case Op_assign:
812
			lhs = POP_ADDRESS();
813
			r = TOP_SCALAR();
814
			unref(*lhs);
408.13.10 by Arnold D. Robbins
Remove OLDMEM checks, preparatory to merging.
815
			UPREF(r);
816
			UNFIELD(*lhs, r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
817
			REPLACE(r);
818
			break;
819
322 by john haque
Improve array interface.
820
		case Op_subscript_assign:
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
821
			/* conditionally execute post-assignment routine for an array element */
322 by john haque
Improve array interface.
822
823
			if (set_idx != NULL) {
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
824
				di = true;
322 by john haque
Improve array interface.
825
				if (pc->assign_ctxt == Op_sub_builtin
826
					&& (r = TOP())
827
					&& get_number_si(r) == 0	/* no substitution performed */
828
				)
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
829
					di = false;
322 by john haque
Improve array interface.
830
				else if ((pc->assign_ctxt == Op_K_getline
831
						|| pc->assign_ctxt == Op_K_getline_redir)
832
					&& (r = TOP())
833
					&& get_number_si(r) <= 0 	/* EOF or error */
834
				)
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
835
					di = false;
322 by john haque
Improve array interface.
836
837
				if (di)
838
					(*set_array->astore)(set_array, set_idx);
839
				unref(set_idx);
840
				set_idx = NULL;
841
			}
842
			break;
843
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
844
		/* numeric assignments */
845
		case Op_assign_plus:
846
		case Op_assign_minus:
847
		case Op_assign_times:
848
		case Op_assign_quotient:
849
		case Op_assign_mod:
850
		case Op_assign_exp:
301 by john haque
New interpreter routine for MPFR.
851
			op_assign(op);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
852
			break;
853
854
		case Op_var_update:        /* update value of NR, FNR or NF */
855
			pc->update_var();
856
			break;
857
858
		case Op_var_assign:
859
		case Op_field_assign:
302.1.1 by john haque
Finish MPFR changes and clean up code.
860
			r = TOP();
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
861
			if (pc->assign_ctxt == Op_sub_builtin
302.1.1 by john haque
Finish MPFR changes and clean up code.
862
				&& get_number_si(r) == 0	/* top of stack has a number == 0 */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
863
			) {
864
				/* There wasn't any substitutions. If the target is a FIELD,
865
				 * this means no field re-splitting or $0 reconstruction.
866
				 * Skip the set_FOO routine if the target is a special variable.
867
				 */
868
869
				break;
870
			} else if ((pc->assign_ctxt == Op_K_getline
871
					|| pc->assign_ctxt == Op_K_getline_redir)
302.1.1 by john haque
Finish MPFR changes and clean up code.
872
				&& get_number_si(r) <= 0 	/* top of stack has a number <= 0 */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
873
			) {
874
				/* getline returned EOF or error */
875
876
				break;
877
			}
878
301 by john haque
New interpreter routine for MPFR.
879
			if (op == Op_var_assign)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
880
				pc->assign_var();
881
			else
882
				pc->field_assign();
883
			break;
884
885
		case Op_concat:
886
			r = concat_exp(pc->expr_count, pc->concat_flag & CSUBSEP);
887
			PUSH(r);
888
			break;
889
890
		case Op_K_case:
891
			if ((pc + 1)->match_exp) {
892
				/* match a constant regex against switch expression instead of $0. */
893
894
				m = POP();	/* regex */
895
				t2 = TOP_SCALAR();	/* switch expression */
896
				t2 = force_string(t2);
897
				rp = re_update(m);
408.26.63 by Arnold D. Robbins
Remove avoid_dfa. Simplify dfa usage and rearrange callers in re.c.
898
				di = (research(rp, t2->stptr, 0, t2->stlen, RE_NO_FLAGS) >= 0);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
899
			} else {
900
				t1 = POP_SCALAR();	/* case value */
901
				t2 = TOP_SCALAR();	/* switch expression */
408.26.64 by Arnold D. Robbins
New POSIX rules for string comparison.
902
				di = (cmp_nodes(t2, t1, true) == 0);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
903
				DEREF(t1);
904
			}
905
906
			if (di) {
907
				/* match found */
908
				t2 = POP_SCALAR();
909
				DEREF(t2);
910
				JUMPTO(pc->target_jmp);
911
			}
912
			break;
913
914
		case Op_K_delete:
731.17.41 by Arnold D. Robbins
Add more lint warnings.
915
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
916
			do_delete(t1, pc->expr_count);
917
			stack_adj(-pc->expr_count);
918
			break;
919
920
		case Op_K_delete_loop:
731.17.41 by Arnold D. Robbins
Add more lint warnings.
921
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
922
			lhs = POP_ADDRESS();	/* item */
923
			do_delete_loop(t1, lhs);
924
			break;
925
926
		case Op_in_array:
731.17.41 by Arnold D. Robbins
Add more lint warnings.
927
			t1 = POP_ARRAY(false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
928
			t2 = mk_sub(pc->expr_count);
301 by john haque
New interpreter routine for MPFR.
929
			r = node_Boolean[(in_array(t1, t2) != NULL)];
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
930
			DEREF(t2);
301 by john haque
New interpreter routine for MPFR.
931
			UPREF(r);
932
			PUSH(r);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
933
			break;
934
935
		case Op_arrayfor_init:
936
		{
937
			NODE **list = NULL;
938
			NODE *array, *sort_str;
939
			size_t num_elems = 0;
940
			static NODE *sorted_in = NULL;
941
			const char *how_to_sort = "@unsorted";
731.8.6 by Andrew J. Schorr
Protect against some unterminated string situations in interpret.h.
942
			char save;
943
			bool saved_end = false;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
944
945
			/* get the array */
731.17.41 by Arnold D. Robbins
Add more lint warnings.
946
			array = POP_ARRAY(true);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
947
948
			/* sanity: check if empty */
327 by Arnold D. Robbins
Merge branch 'master' into array-iface
949
			num_elems = assoc_length(array);
950
			if (num_elems == 0)
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
951
				goto arrayfor;
952
953
			if (sorted_in == NULL)		/* do this once */
954
				sorted_in = make_string("sorted_in", 9);
955
956
			sort_str = NULL;
957
			/*
958
			 * If posix, or if there's no PROCINFO[],
959
			 * there's no ["sorted_in"], so no sorting
960
			 */
961
			if (! do_posix && PROCINFO_node != NULL)
962
				sort_str = in_array(PROCINFO_node, sorted_in);
963
964
			if (sort_str != NULL) {
965
				sort_str = force_string(sort_str);
731.8.6 by Andrew J. Schorr
Protect against some unterminated string situations in interpret.h.
966
				if (sort_str->stlen > 0) {
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
967
					how_to_sort = sort_str->stptr;
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
968
					str_terminate(sort_str, save);
731.8.6 by Andrew J. Schorr
Protect against some unterminated string situations in interpret.h.
969
					saved_end = true;
970
				}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
971
			}
972
973
			list = assoc_list(array, how_to_sort, SORTED_IN);
731.8.6 by Andrew J. Schorr
Protect against some unterminated string situations in interpret.h.
974
			if (saved_end)
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
975
				str_restore(sort_str, save);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
976
977
arrayfor:
978
			getnode(r);
979
			r->type = Node_arrayfor;
980
			r->for_list = list;
981
			r->for_list_size = num_elems;		/* # of elements in list */
982
			r->cur_idx = -1;			/* current index */
983
			r->for_array = array;		/* array */
984
			PUSH(r);
985
986
			if (num_elems == 0)
987
				JUMPTO(pc->target_jmp);   /* Op_arrayfor_final */
988
		}
989
			break;
990
991
		case Op_arrayfor_incr:
992
			r = TOP();	/* Node_arrayfor */
993
			if (++r->cur_idx == r->for_list_size) {
994
				NODE *array;
995
				array = r->for_array;	/* actual array */
996
				if (do_lint && array->table_size != r->for_list_size)
997
					lintwarn(_("for loop: array `%s' changed size from %ld to %ld during loop execution"),
998
						array_vname(array), (long) r->for_list_size, (long) array->table_size);
999
				JUMPTO(pc->target_jmp);	/* Op_arrayfor_final */
1000
			}
1001
1002
			t1 = r->for_list[r->cur_idx];
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1003
			lhs = get_lhs(pc->array_var, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1004
			unref(*lhs);
1005
			*lhs = dupnode(t1);
1006
			break;
1007
1008
		case Op_arrayfor_final:
1009
			r = POP();
1010
			assert(r->type == Node_arrayfor);
1011
			free_arrayfor(r);
1012
			break;
1013
1014
		case Op_builtin:
1015
			r = pc->builtin(pc->expr_count);
1016
			PUSH(r);
1017
			break;
1018
1019
		case Op_ext_builtin:
1020
		{
731.2.5 by Arnold D. Robbins
Further improvements to min/max args code and doc.
1021
			size_t arg_count = pc->expr_count;
731.11.124 by Arnold D. Robbins
Integrate changes for z/OS.
1022
			awk_ext_func_t *f = pc[1].c_function;
731.2.5 by Arnold D. Robbins
Further improvements to min/max args code and doc.
1023
			size_t min_req = f->min_required_args;
1024
			size_t max_expect = f->max_expected_args;
319.2.13 by Andrew J. Schorr
First working version of new API mechanism (probably has memory leaks).
1025
			awk_value_t result;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1026
731.2.3 by Arnold D. Robbins
Improve handling of min and max args for extension functions.
1027
			if (arg_count < min_req)
731.2.5 by Arnold D. Robbins
Further improvements to min/max args code and doc.
1028
				fatal(_("%s: called with %lu arguments, expecting at least %lu"),
731.11.139 by Arnold D. Robbins
Remove warnings around some printf arguments in interpret.h.
1029
						pc[1].func_name,
1030
						(unsigned long) arg_count,
1031
						(unsigned long) min_req);
731.2.3 by Arnold D. Robbins
Improve handling of min and max args for extension functions.
1032
731.2.6 by Arnold D. Robbins
Further api doc updates. Simplify lint checking for max args.
1033
			if (do_lint && ! f->suppress_lint && arg_count > max_expect)
731.2.5 by Arnold D. Robbins
Further improvements to min/max args code and doc.
1034
				lintwarn(_("%s: called with %lu arguments, expecting no more than %lu"),
731.11.139 by Arnold D. Robbins
Remove warnings around some printf arguments in interpret.h.
1035
						pc[1].func_name,
1036
						(unsigned long) arg_count,
1037
						(unsigned long) max_expect);
731.2.1 by Arnold D. Robbins
Add min_required and max_expected arg counts to API.
1038
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1039
			PUSH_CODE(pc);
1379.1.27 by Arnold D. Robbins
Fix testext test for MPFR.
1040
			awk_value_t *ef_ret = pc->extfunc(arg_count, & result, f);
1041
			r = awk_value_to_node(ef_ret);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1042
			(void) POP_CODE();
1043
			while (arg_count-- > 0) {
1044
				t1 = POP();
1045
				if (t1->type == Node_val)
1046
					DEREF(t1);
1047
			}
408.30.14 by Andrew J. Schorr
Optimization: support unterminated field strings inside gawk, but make terminated copies for the API.
1048
			free_api_string_copies();
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1049
			PUSH(r);
1050
		}
1051
			break;
1052
1053
		case Op_sub_builtin:	/* sub, gsub and gensub */
1054
			r = do_sub(pc->expr_count, pc->sub_flags);
1055
			PUSH(r);
1056
			break;
1057
1058
		case Op_K_print:
1059
			do_print(pc->expr_count, pc->redir_type);
1060
			break;
1061
1062
		case Op_K_printf:
1063
			do_printf(pc->expr_count, pc->redir_type);
1064
			break;
1065
1066
		case Op_K_print_rec:
1067
			do_print_rec(pc->expr_count, pc->redir_type);
1068
			break;
1069
1070
		case Op_push_re:
1071
			m = pc->memory;
1072
			if (m->type == Node_dynregex) {
1073
				r = POP_STRING();
1074
				unref(m->re_exp);
1075
				m->re_exp = r;
408.31.40 by Arnold D. Robbins
First steps reworking code away from node type.
1076
			} else if (m->type == Node_val) {
1077
				assert((m->flags & REGEX) != 0);
408.31.1 by Arnold D. Robbins
Restore typed regexp code in a new branch.
1078
				UPREF(m);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1079
			}
1080
			PUSH(m);
1081
			break;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1082
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1083
		case Op_match_rec:
1084
			m = pc->memory;
1085
			t1 = *get_field(0, (Func_ptr *) 0);
1086
match_re:
1087
			rp = re_update(m);
408.26.63 by Arnold D. Robbins
Remove avoid_dfa. Simplify dfa usage and rearrange callers in re.c.
1088
			di = research(rp, t1->stptr, 0, t1->stlen, RE_NO_FLAGS);
301 by john haque
New interpreter routine for MPFR.
1089
			di = (di == -1) ^ (op != Op_nomatch);
1090
			if (op != Op_match_rec) {
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1091
				decr_sp();
1092
				DEREF(t1);
1206 by Arnold D. Robbins
Another memory issue fix.
1093
				if (m->type == Node_dynregex) {
1094
				 	DEREF(m->re_exp);
1095
					m->re_exp = NULL;
1096
				}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1097
			}
1098
			r = node_Boolean[di];
1099
			UPREF(r);
1100
			PUSH(r);
1101
			break;
1102
1103
		case Op_nomatch:
1104
			/* fall through */
1105
		case Op_match:
1106
			m = pc->memory;
1107
			t1 = TOP_STRING();
1108
			if (m->type == Node_dynregex) {
1109
				unref(m->re_exp);
1110
				m->re_exp = t1;
1111
				decr_sp();
1112
				t1 = TOP_STRING();
1113
			}
1114
			goto match_re;
1115
			break;
1116
1117
		case Op_indirect_func_call:
1118
		{
301 by john haque
New interpreter routine for MPFR.
1119
			NODE *f = NULL;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1120
			int arg_count;
731.8.6 by Andrew J. Schorr
Protect against some unterminated string situations in interpret.h.
1121
			char save;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1122
1123
			arg_count = (pc + 1)->expr_count;
1124
			t1 = PEEK(arg_count);	/* indirect var */
319.9.3 by Arnold D. Robbins
More SYMTAB and FUNCTAB improvements.
1125
1126
			if (t1->type != Node_val)	/* @a[1](p) not allowed in grammar */
1127
				fatal(_("indirect function call requires a simple scalar value"));
1128
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1129
			t1 = force_string(t1);
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
1130
			str_terminate(t1, save);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1131
			if (t1->stlen > 0) {
1132
				/* retrieve function definition node */
1133
				f = pc->func_body;
295 by Arnold D. Robbins
Merge branch 'gawk-4.0-stable', minor fixes after exe merge.
1134
				if (f != NULL && strcmp(f->vname, t1->stptr) == 0) {
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1135
					/* indirect var hasn't been reassigned */
1136
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
1137
					str_restore(t1, save);
301 by john haque
New interpreter routine for MPFR.
1138
					ni = setup_frame(pc);
1139
					JUMPTO(ni);	/* Op_func */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1140
				}
1056.2.8 by Arnold D. Robbins
Rework namespace handling to make simpler and correct. Add two test cases.
1141
				f = lookup(t1->stptr);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1142
			}
1143
408.5.257 by Arnold D. Robbins
Bug fix in handling indirect function calls.
1144
			if (f == NULL) {
408.5.265 by Arnold D. Robbins
Add builtin functions to FUNCTAB and PROCINFO["identifiers"] and doc.
1145
				fatal(_("`%s' is not a function, so it cannot be called indirectly"),
1146
						t1->stptr);
1147
			} else if (f->type == Node_builtin_func) {
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1148
				int arg_count = (pc + 1)->expr_count;
1149
				builtin_func_t the_func = lookup_builtin(t1->stptr);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1150
408.5.265 by Arnold D. Robbins
Add builtin functions to FUNCTAB and PROCINFO["identifiers"] and doc.
1151
				assert(the_func != NULL);
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1152
1153
				/* call it */
408.15.4 by Arnold D. Robbins
Further progress on indirect calls of builtins.
1154
				if (the_func == (builtin_func_t) do_sub)
408.15.6 by Arnold D. Robbins
Get indirect calls working!
1155
					r = call_sub(t1->stptr, arg_count);
1156
				else if (the_func == do_match)
1157
					r = call_match(arg_count);
1158
				else if (the_func == do_split || the_func == do_patsplit)
1159
					r = call_split_func(t1->stptr, arg_count);
408.15.1 by Arnold D. Robbins
Start on testing/fixing indirect calls of builtins.
1160
				else
1161
					r = the_func(arg_count);
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
1162
				str_restore(t1, save);
408.15.1 by Arnold D. Robbins
Start on testing/fixing indirect calls of builtins.
1163
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1164
				PUSH(r);
1165
				break;
1166
			} else if (f->type != Node_func) {
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
1167
				str_restore(t1, save);
408.20.54 by Arnold D. Robbins
Remove support for old-style extensions.
1168
				if (f->type == Node_ext_func) {
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1169
					/* code copied from below, keep in sync */
1170
					INSTRUCTION *bc;
1171
					char *fname = pc->func_name;
1172
					int arg_count = (pc + 1)->expr_count;
1173
					static INSTRUCTION npc[2];
1174
1175
					npc[0] = *pc;
1176
1177
					bc = f->code_ptr;
1178
					assert(bc->opcode == Op_symbol);
408.20.54 by Arnold D. Robbins
Remove support for old-style extensions.
1179
					npc[0].opcode = Op_ext_builtin;	/* self modifying code */
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1180
					npc[0].extfunc = bc->extfunc;
1181
					npc[0].expr_count = arg_count;		/* actual argument count */
1182
					npc[1] = pc[1];
1183
					npc[1].func_name = fname;	/* name of the builtin */
731.11.124 by Arnold D. Robbins
Integrate changes for z/OS.
1184
					npc[1].c_function = bc->c_function;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1185
					ni = npc;
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1186
					JUMPTO(ni);
1187
				} else
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
1188
					fatal(_("function called indirectly through `%s' does not exist"),
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1189
							pc->func_name);
319.9.4 by Arnold D. Robbins
Add tests for SYMTAB and FUNCTAB.
1190
			}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1191
			pc->func_body = f;     /* save for next call */
731.8.10 by Andrew J. Schorr
Introduce some helpful macros for terminating strings, and fix overrun in dcgettext.
1192
			str_restore(t1, save);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1193
301 by john haque
New interpreter routine for MPFR.
1194
			ni = setup_frame(pc);
1195
			JUMPTO(ni);	/* Op_func */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1196
		}
1197
1198
		case Op_func_call:
301 by john haque
New interpreter routine for MPFR.
1199
		{
1200
			NODE *f;
1201
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1202
			/* retrieve function definition node */
1203
			f = pc->func_body;
1204
			if (f == NULL) {
1056.2.8 by Arnold D. Robbins
Rework namespace handling to make simpler and correct. Add two test cases.
1205
				f = lookup(pc->func_name);
408.20.54 by Arnold D. Robbins
Remove support for old-style extensions.
1206
				if (f == NULL || (f->type != Node_func && f->type != Node_ext_func))
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1207
					fatal(_("function `%s' not defined"), pc->func_name);
1208
				pc->func_body = f;     /* save for next call */
1209
			}
1210
408.20.54 by Arnold D. Robbins
Remove support for old-style extensions.
1211
			if (f->type == Node_ext_func) {
408.5.261 by Arnold D. Robbins
Make indirect calls work on built-in and extension functions.
1212
				/* keep in sync with indirect call code */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1213
				INSTRUCTION *bc;
1214
				char *fname = pc->func_name;
1215
				int arg_count = (pc + 1)->expr_count;
1216
1217
				bc = f->code_ptr;
1218
				assert(bc->opcode == Op_symbol);
408.20.54 by Arnold D. Robbins
Remove support for old-style extensions.
1219
				pc->opcode = Op_ext_builtin;	/* self modifying code */
319.2.13 by Andrew J. Schorr
First working version of new API mechanism (probably has memory leaks).
1220
				pc->extfunc = bc->extfunc;
731.2.3 by Arnold D. Robbins
Improve handling of min and max args for extension functions.
1221
				pc->expr_count = arg_count;	/* actual argument count */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1222
				(pc + 1)->func_name = fname;	/* name of the builtin */
731.11.124 by Arnold D. Robbins
Integrate changes for z/OS.
1223
				(pc + 1)->c_function = bc->c_function;	/* min and max args */
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1224
				ni = pc;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1225
				JUMPTO(ni);
1226
			}
1227
1228
			ni = setup_frame(pc);
301 by john haque
New interpreter routine for MPFR.
1229
			JUMPTO(ni);	/* Op_func */
1230
		}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1231
1104 by Arnold D. Robbins
Fix calling user defined functions from eval.
1232
		case Op_K_return_from_eval:
1233
			cant_happen();
1234
			break;
1235
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1236
		case Op_K_return:
1237
			m = POP_SCALAR();       /* return value */
1238
1239
			ni = pop_fcall();
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1240
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1241
			/* put the return value back on stack */
1242
			PUSH(m);
1243
1244
			JUMPTO(ni);
1245
1246
		case Op_K_getline_redir:
1247
			r = do_getline_redir(pc->into_var, pc->redir_type);
1248
			PUSH(r);
1249
			break;
1250
1251
		case Op_K_getline:	/* no redirection */
1252
			if (! currule || currule == BEGINFILE || currule == ENDFILE)
1253
				fatal(_("non-redirected `getline' invalid inside `%s' rule"),
1254
						ruletab[currule]);
1255
1256
			do {
1257
				int ret;
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1258
				ret = nextfile(& curfile, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1259
				if (ret <= 0)
1260
					r = do_getline(pc->into_var, curfile);
1261
				else {
1262
1263
					/* Save execution state so that we can return to it
1264
					 * from Op_after_beginfile or Op_after_endfile.
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1265
					 */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1266
1267
					push_exec_state(pc, currule, source, stack_ptr);
1268
1269
					if (curfile == NULL)
1270
						JUMPTO((pc + 1)->target_endfile);
1271
					else
1272
						JUMPTO((pc + 1)->target_beginfile);
1273
				}
1274
			} while (r == NULL);	/* EOF */
1275
1276
			PUSH(r);
1277
			break;
1278
1279
		case Op_after_endfile:
1280
			/* Find the execution state to return to */
1281
			ni = pop_exec_state(& currule, & source, NULL);
1282
1283
			assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
1284
			JUMPTO(ni);
1285
1286
		case Op_after_beginfile:
1287
			after_beginfile(& curfile);
1288
1289
			/* Find the execution state to return to */
1290
			ni = pop_exec_state(& currule, & source, NULL);
1291
1292
			assert(ni->opcode == Op_newfile || ni->opcode == Op_K_getline);
1293
			if (ni->opcode == Op_K_getline
1294
					|| curfile == NULL      /* skipping directory argument */
1295
			)
1296
				JUMPTO(ni);
1297
1298
			break;	/* read a record, Op_get_record */
1299
1300
		case Op_newfile:
1301
		{
1302
			int ret;
1303
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1304
			ret = nextfile(& curfile, false);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1305
1306
			if (ret < 0)	/* end of input */
1307
				JUMPTO(pc->target_jmp);	/* end block or Op_atexit */
1308
1309
			if (ret == 0) /* read a record */
1310
				JUMPTO((pc + 1)->target_get_record);
1311
1312
			/* ret > 0 */
1313
			/* Save execution state for use in Op_after_beginfile or Op_after_endfile. */
1314
1315
			push_exec_state(pc, currule, source, stack_ptr);
1316
1317
			if (curfile == NULL)	/* EOF */
1318
				JUMPTO(pc->target_endfile);
1319
			/* else
1320
				execute beginfile block */
1321
		}
1322
			break;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1323
1324
		case Op_get_record:
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1325
		{
1326
			int errcode = 0;
1327
1328
			ni = pc->target_newfile;
1329
			if (curfile == NULL) {
1330
				/* from non-redirected getline, e.g.:
1331
				 *  {
1332
				 *		while (getline > 0) ;
1333
				 *  }
1334
				 */
1335
1336
				ni = ni->target_jmp;	/* end_block or Op_atexit */
1337
				JUMPTO(ni);
1338
			}
1339
408.5.222 by Arnold D. Robbins
Bug fix for I/O errors in the middle of a file.
1340
			if (! inrec(curfile, & errcode)) {
408.5.230 by Arnold D. Robbins
Improve inrec setting ERRNO, doc of API get_record for errors.
1341
				if (errcode > 0) {
1342
					update_ERRNO_int(errcode);
1343
					if (do_traditional || ! pc->has_endfile)
1344
						fatal(_("error reading input file `%s': %s"),
319.2.42 by Andrew J. Schorr
Hide private parts of IOBUF from extensions.
1345
						curfile->public.name, strerror(errcode));
408.5.230 by Arnold D. Robbins
Improve inrec setting ERRNO, doc of API get_record for errors.
1346
				}
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1347
1348
				JUMPTO(ni);
1349
			} /* else
1350
				prog (rule) block */
1351
		}
1352
			break;
1353
1354
		case Op_K_nextfile:
1355
		{
1356
			int ret;
1357
1358
			if (currule != Rule && currule != BEGINFILE)
1359
				fatal(_("`nextfile' cannot be called from a `%s' rule"),
1360
					ruletab[currule]);
1361
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1362
			ret = nextfile(& curfile, true);	/* skip current file */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1363
1364
			if (currule == BEGINFILE) {
408.5.81 by Arnold D. Robbins
Remove a warning from interpret.h, update NEWS.
1365
				long stack_size = 0;
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1366
1367
				ni = pop_exec_state(& currule, & source, & stack_size);
1368
1369
				assert(ni->opcode == Op_K_getline || ni->opcode == Op_newfile);
1370
1371
				/* pop stack returning to the state of Op_K_getline or Op_newfile. */
1372
				unwind_stack(stack_size);
1373
1374
				if (ret == 0) {
1375
					/* There was an error opening the file;
1376
					 * don't run ENDFILE block(s).
1377
					 */
1378
1379
					JUMPTO(ni);
1380
				} else {
1381
					/* do run ENDFILE block(s) first. */
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1382
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1383
					/* Execution state to return to in Op_after_endfile. */
1384
					push_exec_state(ni, currule, source, stack_ptr);
1385
1386
					JUMPTO(pc->target_endfile);
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1387
				}
1388
			} /* else
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1389
				Start over with the first rule. */
1390
1391
			/* empty the run-time stack to avoid memory leak */
1392
			pop_stack();
1393
1394
			/* Push an execution state for Op_after_endfile to return to */
1395
			push_exec_state(pc->target_newfile, currule, source, stack_ptr);
1396
1397
			JUMPTO(pc->target_endfile);
1398
		}
1399
			break;
1400
1401
		case Op_K_exit:
1402
			/* exit not allowed in user-defined comparison functions for "sorted_in";
1403
			 * This is done so that END blocks aren't executed more than once.
1404
			 */
1405
			if (! currule)
1406
				fatal(_("`exit' cannot be called in the current context"));
1407
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1408
			exiting = true;
408.13.106 by Andrew J. Schorr
Fix bug where exit with no argument was setting the exit status to zero.
1409
			if ((t1 = POP_NUMBER()) != Nnull_string) {
1410
				exit_val = (int) get_number_si(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1411
#ifdef VMS
408.13.106 by Andrew J. Schorr
Fix bug where exit with no argument was setting the exit status to zero.
1412
				if (exit_val == 0)
1413
					exit_val = EXIT_SUCCESS;
1414
				else if (exit_val == 1)
1415
					exit_val = EXIT_FAILURE;
1416
				/* else
1417
					just pass anything else on through */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1418
#endif
408.13.106 by Andrew J. Schorr
Fix bug where exit with no argument was setting the exit status to zero.
1419
			}
1420
			DEREF(t1);
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1421
1422
			if (currule == BEGINFILE || currule == ENDFILE) {
1423
1424
				/* Find the rule of the saved execution state (Op_K_getline/Op_newfile).
1425
				 * This is needed to prevent multiple execution of any END rules:
1426
				 * 	gawk 'BEGINFILE { exit(1) } \
1427
				 *         END { while (getline > 0); }' in1 in2
1428
				 */
1429
1430
				(void) pop_exec_state(& currule, & source, NULL);
1431
			}
1432
1433
			pop_stack();	/* empty stack, don't leak memory */
1434
1435
			/* Jump to either the first END block instruction
1436
			 * or to Op_atexit.
1437
			 */
1438
1439
			if (currule == END)
1440
				ni = pc->target_atexit;
1441
			else
1442
				ni = pc->target_end;
1443
			JUMPTO(ni);
1444
1445
		case Op_K_next:
1446
			if (currule != Rule)
1447
				fatal(_("`next' cannot be called from a `%s' rule"), ruletab[currule]);
1448
1449
			pop_stack();
1450
			JUMPTO(pc->target_jmp);	/* Op_get_record, read next record */
1451
1452
		case Op_pop:
1453
			r = POP_SCALAR();
1454
			DEREF(r);
1455
			break;
1456
1457
		case Op_line_range:
1458
			if (pc->triggered)		/* evaluate right expression */
1459
				JUMPTO(pc->target_jmp);
1460
			/* else
1461
				evaluate left expression */
1462
			break;
1463
1464
		case Op_cond_pair:
1465
		{
1466
			int result;
1467
			INSTRUCTION *ip;
1468
1469
			t1 = TOP_SCALAR();   /* from right hand side expression */
1470
			di = (eval_condition(t1) != 0);
1471
			DEREF(t1);
1472
1473
			ip = pc->line_range;            /* Op_line_range */
1474
1475
			if (! ip->triggered && di) {
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1476
				/* not already triggered and left expression is true */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1477
				decr_sp();
319.1.9 by Arnold D. Robbins
Move to use of bool type, true, false, everywhere.
1478
				ip->triggered = true;
408.26.83 by Arnold D. Robbins
Remove trailing whitespace everywhere. Fix Unicode into ASCII.
1479
				JUMPTO(ip->target_jmp);	/* evaluate right expression */
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1480
			}
1481
1482
			result = ip->triggered || di;
1483
			ip->triggered ^= di;          /* update triggered flag */
1484
			r = node_Boolean[result];      /* final value of condition pair */
1485
			UPREF(r);
1486
			REPLACE(r);
1487
			JUMPTO(pc->target_jmp);
1488
		}
1489
1490
		case Op_exec_count:
1491
			if (do_profile)
1492
				pc->exec_count++;
1493
			break;
1494
1495
		case Op_no_op:
1496
		case Op_K_do:
1497
		case Op_K_while:
1498
		case Op_K_for:
1499
		case Op_K_arrayfor:
1500
		case Op_K_switch:
1501
		case Op_K_default:
1502
		case Op_K_if:
1503
		case Op_K_else:
1504
		case Op_cond_exp:
408.9.1 by Arnold D. Robbins
Start new branch that adds comments to profiling.
1505
		case Op_comment:
731.9.27 by Arnold D. Robbins
Fix parenthesization in the pretty printer for real (we hope!).
1506
		case Op_parens:
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1507
			break;
1508
1509
		default:
301 by john haque
New interpreter routine for MPFR.
1510
			fatal(_("Sorry, don't know how to interpret `%s'"), opcode2str(op));
291 by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk.
1511
		}
1512
1513
		JUMPTO(pc->nexti);
1514
1515
/*	} forever */
1516
1517
	/* not reached */
1518
	return 0;
1519
1520
#undef mk_sub
1521
#undef JUMPTO
1522
}