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 |
}
|