]>
Commit | Line | Data |
---|---|---|
efabfe5d KK |
1 | diff --git a/ChangeLog b/ChangeLog |
2 | index bf0f749..913b4a3 100644 | |
3 | --- a/ChangeLog | |
4 | +++ b/ChangeLog | |
5 | @@ -1,3 +1,21 @@ | |
6 | +2011-07-05 John Haque <address@hidden> | |
7 | + | |
8 | + * awk.h (Op_sub_builtin): New opcode. | |
9 | + (GSUB, GENSUB, AFTER_ASSIGN, LITERAL): New flags for | |
10 | + Op_sub_builtin. | |
11 | + * awkgram.y (struct tokentab): Change opcode to Op_sub_builtin | |
12 | + for sub, gsub and gensub. | |
13 | + (snode): Update processing of sub, gsub and gensub. | |
14 | + * builtin.c (do_sub, do_gsub, do_gensub): Nuke. | |
15 | + (sub_common): Renamed to do_sub. Relocate gensub argument | |
16 | + handling code from do_gensub to here; Simplify the code a | |
17 | + little bit. | |
18 | + * eval.c (r_interpret): Handle Op_sub_builtin. Avoid field | |
19 | + re-splitting or $0 rebuilding if (g)sub target string is | |
20 | + a field and no substitutions were done. | |
21 | + * pprint (profile.c): Add case for the new opcode. | |
22 | + * print_instruction (debug.c): Ditto. | |
23 | + | |
24 | 2011-06-24 Arnold D. Robbins <arnold@skeeve.com> | |
25 | ||
26 | * Makefile.am (EXTRA_DIST): Add ChangeLog.0. | |
27 | diff --git a/awk.h b/awk.h | |
28 | index 25abf41..e224061 100644 | |
29 | --- a/awk.h | |
30 | +++ b/awk.h | |
31 | @@ -521,6 +521,7 @@ typedef enum opcodeval { | |
32 | Op_K_nextfile, | |
33 | ||
34 | Op_builtin, | |
35 | + Op_sub_builtin, /* sub, gsub and gensub */ | |
36 | Op_in_array, /* boolean test of membership in array */ | |
37 | ||
38 | /* function call instruction */ | |
39 | @@ -626,6 +627,16 @@ typedef struct exp_instruction { | |
40 | #define target_jmp d.di | |
41 | #define target_break x.xi | |
42 | ||
43 | +/* Op_sub_builtin */ | |
44 | +#define sub_flags d.dl | |
45 | +#define GSUB 0x01 /* builtin is gsub */ | |
46 | +#define GENSUB 0x02 /* builtin is gensub */ | |
47 | +#define AFTER_ASSIGN 0x04 /* (g)sub target is a field or a special var with | |
48 | + * set_XX routine. | |
49 | + */ | |
50 | +#define LITERAL 0x08 /* target is a literal string */ | |
51 | + | |
52 | + | |
53 | /* Op_K_exit */ | |
54 | #define target_end d.di | |
55 | #define target_atexit x.xi | |
56 | @@ -1181,9 +1192,7 @@ extern NODE *do_cos(int nargs); | |
57 | extern NODE *do_rand(int nargs); | |
58 | extern NODE *do_srand(int nargs); | |
59 | extern NODE *do_match(int nargs); | |
60 | -extern NODE *do_gsub(int nargs); | |
61 | -extern NODE *do_sub(int nargs); | |
62 | -extern NODE *do_gensub(int nargs); | |
63 | +extern NODE *do_sub(int nargs, unsigned int flags, int *num_matches); | |
64 | extern NODE *format_tree(const char *, size_t, NODE **, long); | |
65 | extern NODE *do_lshift(int nargs); | |
66 | extern NODE *do_rshift(int nargs); | |
67 | diff --git a/awkgram.c b/awkgram.c | |
68 | index 4edec57..ac4ceaa 100644 | |
69 | --- a/awkgram.c | |
70 | +++ b/awkgram.c | |
71 | @@ -2065,7 +2065,7 @@ yyreduce: | |
72 | { | |
73 | case 3: | |
74 | ||
75 | -/* Line 1806 of yacc.c */ | |
76 | +/* Line 1821 of yacc.c */ | |
77 | #line 221 "awkgram.y" | |
78 | { | |
79 | rule = 0; | |
80 | @@ -2075,7 +2075,7 @@ yyreduce: | |
81 | ||
82 | case 5: | |
83 | ||
84 | -/* Line 1806 of yacc.c */ | |
85 | +/* Line 1821 of yacc.c */ | |
86 | #line 227 "awkgram.y" | |
87 | { | |
88 | next_sourcefile(); | |
89 | @@ -2084,7 +2084,7 @@ yyreduce: | |
90 | ||
91 | case 6: | |
92 | ||
93 | -/* Line 1806 of yacc.c */ | |
94 | +/* Line 1821 of yacc.c */ | |
95 | #line 231 "awkgram.y" | |
96 | { | |
97 | rule = 0; | |
98 | @@ -2098,7 +2098,7 @@ yyreduce: | |
99 | ||
100 | case 7: | |
101 | ||
102 | -/* Line 1806 of yacc.c */ | |
103 | +/* Line 1821 of yacc.c */ | |
104 | #line 243 "awkgram.y" | |
105 | { | |
106 | (void) append_rule((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); | |
107 | @@ -2107,7 +2107,7 @@ yyreduce: | |
108 | ||
109 | case 8: | |
110 | ||
111 | -/* Line 1806 of yacc.c */ | |
112 | +/* Line 1821 of yacc.c */ | |
113 | #line 247 "awkgram.y" | |
114 | { | |
115 | if (rule != Rule) { | |
116 | @@ -2123,7 +2123,7 @@ yyreduce: | |
117 | ||
118 | case 9: | |
119 | ||
120 | -/* Line 1806 of yacc.c */ | |
121 | +/* Line 1821 of yacc.c */ | |
122 | #line 258 "awkgram.y" | |
123 | { | |
124 | can_return = FALSE; | |
125 | @@ -2136,7 +2136,7 @@ yyreduce: | |
126 | ||
127 | case 10: | |
128 | ||
129 | -/* Line 1806 of yacc.c */ | |
130 | +/* Line 1821 of yacc.c */ | |
131 | #line 266 "awkgram.y" | |
132 | { | |
133 | want_source = FALSE; | |
134 | @@ -2146,7 +2146,7 @@ yyreduce: | |
135 | ||
136 | case 11: | |
137 | ||
138 | -/* Line 1806 of yacc.c */ | |
139 | +/* Line 1821 of yacc.c */ | |
140 | #line 274 "awkgram.y" | |
141 | { | |
142 | if (include_source((yyvsp[(1) - (1)])) < 0) | |
143 | @@ -2159,35 +2159,35 @@ yyreduce: | |
144 | ||
145 | case 12: | |
146 | ||
147 | -/* Line 1806 of yacc.c */ | |
148 | +/* Line 1821 of yacc.c */ | |
149 | #line 282 "awkgram.y" | |
150 | { (yyval) = NULL; } | |
151 | break; | |
152 | ||
153 | case 13: | |
154 | ||
155 | -/* Line 1806 of yacc.c */ | |
156 | +/* Line 1821 of yacc.c */ | |
157 | #line 284 "awkgram.y" | |
158 | { (yyval) = NULL; } | |
159 | break; | |
160 | ||
161 | case 14: | |
162 | ||
163 | -/* Line 1806 of yacc.c */ | |
164 | +/* Line 1821 of yacc.c */ | |
165 | #line 289 "awkgram.y" | |
166 | { (yyval) = NULL; rule = Rule; } | |
167 | break; | |
168 | ||
169 | case 15: | |
170 | ||
171 | -/* Line 1806 of yacc.c */ | |
172 | +/* Line 1821 of yacc.c */ | |
173 | #line 291 "awkgram.y" | |
174 | { (yyval) = (yyvsp[(1) - (1)]); rule = Rule; } | |
175 | break; | |
176 | ||
177 | case 16: | |
178 | ||
179 | -/* Line 1806 of yacc.c */ | |
180 | +/* Line 1821 of yacc.c */ | |
181 | #line 293 "awkgram.y" | |
182 | { | |
183 | INSTRUCTION *tp; | |
184 | @@ -2218,7 +2218,7 @@ yyreduce: | |
185 | ||
186 | case 17: | |
187 | ||
188 | -/* Line 1806 of yacc.c */ | |
189 | +/* Line 1821 of yacc.c */ | |
190 | #line 319 "awkgram.y" | |
191 | { | |
192 | static int begin_seen = 0; | |
193 | @@ -2234,7 +2234,7 @@ yyreduce: | |
194 | ||
195 | case 18: | |
196 | ||
197 | -/* Line 1806 of yacc.c */ | |
198 | +/* Line 1821 of yacc.c */ | |
199 | #line 330 "awkgram.y" | |
200 | { | |
201 | static int end_seen = 0; | |
202 | @@ -2250,7 +2250,7 @@ yyreduce: | |
203 | ||
204 | case 19: | |
205 | ||
206 | -/* Line 1806 of yacc.c */ | |
207 | +/* Line 1821 of yacc.c */ | |
208 | #line 341 "awkgram.y" | |
209 | { | |
210 | (yyvsp[(1) - (1)])->in_rule = rule = BEGINFILE; | |
211 | @@ -2261,7 +2261,7 @@ yyreduce: | |
212 | ||
213 | case 20: | |
214 | ||
215 | -/* Line 1806 of yacc.c */ | |
216 | +/* Line 1821 of yacc.c */ | |
217 | #line 347 "awkgram.y" | |
218 | { | |
219 | (yyvsp[(1) - (1)])->in_rule = rule = ENDFILE; | |
220 | @@ -2272,7 +2272,7 @@ yyreduce: | |
221 | ||
222 | case 21: | |
223 | ||
224 | -/* Line 1806 of yacc.c */ | |
225 | +/* Line 1821 of yacc.c */ | |
226 | #line 356 "awkgram.y" | |
227 | { | |
228 | if ((yyvsp[(2) - (5)]) == NULL) | |
229 | @@ -2284,21 +2284,21 @@ yyreduce: | |
230 | ||
231 | case 22: | |
232 | ||
233 | -/* Line 1806 of yacc.c */ | |
234 | +/* Line 1821 of yacc.c */ | |
235 | #line 366 "awkgram.y" | |
236 | { (yyval) = (yyvsp[(1) - (1)]); } | |
237 | break; | |
238 | ||
239 | case 23: | |
240 | ||
241 | -/* Line 1806 of yacc.c */ | |
242 | +/* Line 1821 of yacc.c */ | |
243 | #line 368 "awkgram.y" | |
244 | { (yyval) = (yyvsp[(1) - (1)]); } | |
245 | break; | |
246 | ||
247 | case 24: | |
248 | ||
249 | -/* Line 1806 of yacc.c */ | |
250 | +/* Line 1821 of yacc.c */ | |
251 | #line 370 "awkgram.y" | |
252 | { | |
253 | yyerror(_("`%s' is a built-in function, it cannot be redefined"), | |
254 | @@ -2314,14 +2314,14 @@ yyreduce: | |
255 | ||
256 | case 25: | |
257 | ||
258 | -/* Line 1806 of yacc.c */ | |
259 | +/* Line 1821 of yacc.c */ | |
260 | #line 381 "awkgram.y" | |
261 | { (yyval) = (yyvsp[(2) - (2)]); } | |
262 | break; | |
263 | ||
264 | case 28: | |
265 | ||
266 | -/* Line 1806 of yacc.c */ | |
267 | +/* Line 1821 of yacc.c */ | |
268 | #line 391 "awkgram.y" | |
269 | { | |
270 | param_counter = 0; | |
271 | @@ -2331,7 +2331,7 @@ yyreduce: | |
272 | ||
273 | case 29: | |
274 | ||
275 | -/* Line 1806 of yacc.c */ | |
276 | +/* Line 1821 of yacc.c */ | |
277 | #line 396 "awkgram.y" | |
278 | { | |
279 | NODE *t; | |
280 | @@ -2353,14 +2353,14 @@ yyreduce: | |
281 | ||
282 | case 30: | |
283 | ||
284 | -/* Line 1806 of yacc.c */ | |
285 | +/* Line 1821 of yacc.c */ | |
286 | #line 420 "awkgram.y" | |
287 | { ++want_regexp; } | |
288 | break; | |
289 | ||
290 | case 31: | |
291 | ||
292 | -/* Line 1806 of yacc.c */ | |
293 | +/* Line 1821 of yacc.c */ | |
294 | #line 422 "awkgram.y" | |
295 | { | |
296 | NODE *n, *exp; | |
297 | @@ -2393,21 +2393,21 @@ yyreduce: | |
298 | ||
299 | case 32: | |
300 | ||
301 | -/* Line 1806 of yacc.c */ | |
302 | +/* Line 1821 of yacc.c */ | |
303 | #line 453 "awkgram.y" | |
304 | { bcfree((yyvsp[(1) - (1)])); } | |
305 | break; | |
306 | ||
307 | case 34: | |
308 | ||
309 | -/* Line 1806 of yacc.c */ | |
310 | +/* Line 1821 of yacc.c */ | |
311 | #line 459 "awkgram.y" | |
312 | { (yyval) = NULL; } | |
313 | break; | |
314 | ||
315 | case 35: | |
316 | ||
317 | -/* Line 1806 of yacc.c */ | |
318 | +/* Line 1821 of yacc.c */ | |
319 | #line 461 "awkgram.y" | |
320 | { | |
321 | if ((yyvsp[(2) - (2)]) == NULL) | |
322 | @@ -2425,28 +2425,28 @@ yyreduce: | |
323 | ||
324 | case 36: | |
325 | ||
326 | -/* Line 1806 of yacc.c */ | |
327 | +/* Line 1821 of yacc.c */ | |
328 | #line 474 "awkgram.y" | |
329 | { (yyval) = NULL; } | |
330 | break; | |
331 | ||
332 | case 39: | |
333 | ||
334 | -/* Line 1806 of yacc.c */ | |
335 | +/* Line 1821 of yacc.c */ | |
336 | #line 484 "awkgram.y" | |
337 | { (yyval) = NULL; } | |
338 | break; | |
339 | ||
340 | case 40: | |
341 | ||
342 | -/* Line 1806 of yacc.c */ | |
343 | +/* Line 1821 of yacc.c */ | |
344 | #line 486 "awkgram.y" | |
345 | { (yyval) = (yyvsp[(2) - (3)]); } | |
346 | break; | |
347 | ||
348 | case 41: | |
349 | ||
350 | -/* Line 1806 of yacc.c */ | |
351 | +/* Line 1821 of yacc.c */ | |
352 | #line 488 "awkgram.y" | |
353 | { | |
354 | if (do_profiling) | |
355 | @@ -2458,7 +2458,7 @@ yyreduce: | |
356 | ||
357 | case 42: | |
358 | ||
359 | -/* Line 1806 of yacc.c */ | |
360 | +/* Line 1821 of yacc.c */ | |
361 | #line 495 "awkgram.y" | |
362 | { | |
363 | INSTRUCTION *dflt, *curr = NULL, *cexp, *cstmt; | |
364 | @@ -2553,7 +2553,7 @@ yyreduce: | |
365 | ||
366 | case 43: | |
367 | ||
368 | -/* Line 1806 of yacc.c */ | |
369 | +/* Line 1821 of yacc.c */ | |
370 | #line 585 "awkgram.y" | |
371 | { | |
372 | /* | |
373 | @@ -2600,7 +2600,7 @@ yyreduce: | |
374 | ||
375 | case 44: | |
376 | ||
377 | -/* Line 1806 of yacc.c */ | |
378 | +/* Line 1821 of yacc.c */ | |
379 | #line 627 "awkgram.y" | |
380 | { | |
381 | /* | |
382 | @@ -2647,7 +2647,7 @@ yyreduce: | |
383 | ||
384 | case 45: | |
385 | ||
386 | -/* Line 1806 of yacc.c */ | |
387 | +/* Line 1821 of yacc.c */ | |
388 | #line 669 "awkgram.y" | |
389 | { | |
390 | INSTRUCTION *ip; | |
391 | @@ -2767,7 +2767,7 @@ regular_loop: | |
392 | ||
393 | case 46: | |
394 | ||
395 | -/* Line 1806 of yacc.c */ | |
396 | +/* Line 1821 of yacc.c */ | |
397 | #line 784 "awkgram.y" | |
398 | { | |
399 | (yyval) = mk_for_loop((yyvsp[(1) - (12)]), (yyvsp[(3) - (12)]), (yyvsp[(6) - (12)]), (yyvsp[(9) - (12)]), (yyvsp[(12) - (12)])); | |
400 | @@ -2779,7 +2779,7 @@ regular_loop: | |
401 | ||
402 | case 47: | |
403 | ||
404 | -/* Line 1806 of yacc.c */ | |
405 | +/* Line 1821 of yacc.c */ | |
406 | #line 791 "awkgram.y" | |
407 | { | |
408 | (yyval) = mk_for_loop((yyvsp[(1) - (11)]), (yyvsp[(3) - (11)]), (INSTRUCTION *) NULL, (yyvsp[(8) - (11)]), (yyvsp[(11) - (11)])); | |
409 | @@ -2791,7 +2791,7 @@ regular_loop: | |
410 | ||
411 | case 48: | |
412 | ||
413 | -/* Line 1806 of yacc.c */ | |
414 | +/* Line 1821 of yacc.c */ | |
415 | #line 798 "awkgram.y" | |
416 | { | |
417 | if (do_profiling) | |
418 | @@ -2803,7 +2803,7 @@ regular_loop: | |
419 | ||
420 | case 49: | |
421 | ||
422 | -/* Line 1806 of yacc.c */ | |
423 | +/* Line 1821 of yacc.c */ | |
424 | #line 808 "awkgram.y" | |
425 | { | |
426 | if (! break_allowed) | |
427 | @@ -2817,7 +2817,7 @@ regular_loop: | |
428 | ||
429 | case 50: | |
430 | ||
431 | -/* Line 1806 of yacc.c */ | |
432 | +/* Line 1821 of yacc.c */ | |
433 | #line 817 "awkgram.y" | |
434 | { | |
435 | if (! continue_allowed) | |
436 | @@ -2831,7 +2831,7 @@ regular_loop: | |
437 | ||
438 | case 51: | |
439 | ||
440 | -/* Line 1806 of yacc.c */ | |
441 | +/* Line 1821 of yacc.c */ | |
442 | #line 826 "awkgram.y" | |
443 | { | |
444 | /* if inside function (rule = 0), resolve context at run-time */ | |
445 | @@ -2845,7 +2845,7 @@ regular_loop: | |
446 | ||
447 | case 52: | |
448 | ||
449 | -/* Line 1806 of yacc.c */ | |
450 | +/* Line 1821 of yacc.c */ | |
451 | #line 835 "awkgram.y" | |
452 | { | |
453 | if (do_traditional) | |
454 | @@ -2865,7 +2865,7 @@ regular_loop: | |
455 | ||
456 | case 53: | |
457 | ||
458 | -/* Line 1806 of yacc.c */ | |
459 | +/* Line 1821 of yacc.c */ | |
460 | #line 850 "awkgram.y" | |
461 | { | |
462 | /* Initialize the two possible jump targets, the actual target | |
463 | @@ -2885,7 +2885,7 @@ regular_loop: | |
464 | ||
465 | case 54: | |
466 | ||
467 | -/* Line 1806 of yacc.c */ | |
468 | +/* Line 1821 of yacc.c */ | |
469 | #line 865 "awkgram.y" | |
470 | { | |
471 | if (! can_return) | |
472 | @@ -2895,7 +2895,7 @@ regular_loop: | |
473 | ||
474 | case 55: | |
475 | ||
476 | -/* Line 1806 of yacc.c */ | |
477 | +/* Line 1821 of yacc.c */ | |
478 | #line 868 "awkgram.y" | |
479 | { | |
480 | if ((yyvsp[(3) - (4)]) == NULL) { | |
481 | @@ -2909,14 +2909,14 @@ regular_loop: | |
482 | ||
483 | case 57: | |
484 | ||
485 | -/* Line 1806 of yacc.c */ | |
486 | +/* Line 1821 of yacc.c */ | |
487 | #line 888 "awkgram.y" | |
488 | { in_print = TRUE; in_parens = 0; } | |
489 | break; | |
490 | ||
491 | case 58: | |
492 | ||
493 | -/* Line 1806 of yacc.c */ | |
494 | +/* Line 1821 of yacc.c */ | |
495 | #line 889 "awkgram.y" | |
496 | { | |
497 | /* | |
498 | @@ -3016,14 +3016,14 @@ regular_loop: | |
499 | ||
500 | case 59: | |
501 | ||
502 | -/* Line 1806 of yacc.c */ | |
503 | +/* Line 1821 of yacc.c */ | |
504 | #line 984 "awkgram.y" | |
505 | { sub_counter = 0; } | |
506 | break; | |
507 | ||
508 | case 60: | |
509 | ||
510 | -/* Line 1806 of yacc.c */ | |
511 | +/* Line 1821 of yacc.c */ | |
512 | #line 985 "awkgram.y" | |
513 | { | |
514 | char *arr = (yyvsp[(2) - (4)])->lextok; | |
515 | @@ -3053,7 +3053,7 @@ regular_loop: | |
516 | ||
517 | case 61: | |
518 | ||
519 | -/* Line 1806 of yacc.c */ | |
520 | +/* Line 1821 of yacc.c */ | |
521 | #line 1014 "awkgram.y" | |
522 | { | |
523 | static short warned = FALSE; | |
524 | @@ -3077,35 +3077,35 @@ regular_loop: | |
525 | ||
526 | case 62: | |
527 | ||
528 | -/* Line 1806 of yacc.c */ | |
529 | +/* Line 1821 of yacc.c */ | |
530 | #line 1033 "awkgram.y" | |
531 | { (yyval) = optimize_assignment((yyvsp[(1) - (1)])); } | |
532 | break; | |
533 | ||
534 | case 63: | |
535 | ||
536 | -/* Line 1806 of yacc.c */ | |
537 | +/* Line 1821 of yacc.c */ | |
538 | #line 1038 "awkgram.y" | |
539 | { (yyval) = NULL; } | |
540 | break; | |
541 | ||
542 | case 64: | |
543 | ||
544 | -/* Line 1806 of yacc.c */ | |
545 | +/* Line 1821 of yacc.c */ | |
546 | #line 1040 "awkgram.y" | |
547 | { (yyval) = (yyvsp[(1) - (1)]); } | |
548 | break; | |
549 | ||
550 | case 65: | |
551 | ||
552 | -/* Line 1806 of yacc.c */ | |
553 | +/* Line 1821 of yacc.c */ | |
554 | #line 1045 "awkgram.y" | |
555 | { (yyval) = NULL; } | |
556 | break; | |
557 | ||
558 | case 66: | |
559 | ||
560 | -/* Line 1806 of yacc.c */ | |
561 | +/* Line 1821 of yacc.c */ | |
562 | #line 1047 "awkgram.y" | |
563 | { | |
564 | if ((yyvsp[(1) - (2)]) == NULL) | |
565 | @@ -3117,14 +3117,14 @@ regular_loop: | |
566 | ||
567 | case 67: | |
568 | ||
569 | -/* Line 1806 of yacc.c */ | |
570 | +/* Line 1821 of yacc.c */ | |
571 | #line 1054 "awkgram.y" | |
572 | { (yyval) = NULL; } | |
573 | break; | |
574 | ||
575 | case 68: | |
576 | ||
577 | -/* Line 1806 of yacc.c */ | |
578 | +/* Line 1821 of yacc.c */ | |
579 | #line 1059 "awkgram.y" | |
580 | { | |
581 | INSTRUCTION *casestmt = (yyvsp[(5) - (5)]); | |
582 | @@ -3141,7 +3141,7 @@ regular_loop: | |
583 | ||
584 | case 69: | |
585 | ||
586 | -/* Line 1806 of yacc.c */ | |
587 | +/* Line 1821 of yacc.c */ | |
588 | #line 1071 "awkgram.y" | |
589 | { | |
590 | INSTRUCTION *casestmt = (yyvsp[(4) - (4)]); | |
591 | @@ -3157,14 +3157,14 @@ regular_loop: | |
592 | ||
593 | case 70: | |
594 | ||
595 | -/* Line 1806 of yacc.c */ | |
596 | +/* Line 1821 of yacc.c */ | |
597 | #line 1085 "awkgram.y" | |
598 | { (yyval) = (yyvsp[(1) - (1)]); } | |
599 | break; | |
600 | ||
601 | case 71: | |
602 | ||
603 | -/* Line 1806 of yacc.c */ | |
604 | +/* Line 1821 of yacc.c */ | |
605 | #line 1087 "awkgram.y" | |
606 | { | |
607 | (yyvsp[(2) - (2)])->memory->numbr = -(force_number((yyvsp[(2) - (2)])->memory)); | |
608 | @@ -3175,7 +3175,7 @@ regular_loop: | |
609 | ||
610 | case 72: | |
611 | ||
612 | -/* Line 1806 of yacc.c */ | |
613 | +/* Line 1821 of yacc.c */ | |
614 | #line 1093 "awkgram.y" | |
615 | { | |
616 | bcfree((yyvsp[(1) - (2)])); | |
617 | @@ -3185,14 +3185,14 @@ regular_loop: | |
618 | ||
619 | case 73: | |
620 | ||
621 | -/* Line 1806 of yacc.c */ | |
622 | +/* Line 1821 of yacc.c */ | |
623 | #line 1098 "awkgram.y" | |
624 | { (yyval) = (yyvsp[(1) - (1)]); } | |
625 | break; | |
626 | ||
627 | case 74: | |
628 | ||
629 | -/* Line 1806 of yacc.c */ | |
630 | +/* Line 1821 of yacc.c */ | |
631 | #line 1100 "awkgram.y" | |
632 | { | |
633 | (yyvsp[(1) - (1)])->opcode = Op_push_re; | |
634 | @@ -3202,21 +3202,21 @@ regular_loop: | |
635 | ||
636 | case 75: | |
637 | ||
638 | -/* Line 1806 of yacc.c */ | |
639 | +/* Line 1821 of yacc.c */ | |
640 | #line 1108 "awkgram.y" | |
641 | { (yyval) = (yyvsp[(1) - (1)]); } | |
642 | break; | |
643 | ||
644 | case 76: | |
645 | ||
646 | -/* Line 1806 of yacc.c */ | |
647 | +/* Line 1821 of yacc.c */ | |
648 | #line 1110 "awkgram.y" | |
649 | { (yyval) = (yyvsp[(1) - (1)]); } | |
650 | break; | |
651 | ||
652 | case 78: | |
653 | ||
654 | -/* Line 1806 of yacc.c */ | |
655 | +/* Line 1821 of yacc.c */ | |
656 | #line 1120 "awkgram.y" | |
657 | { | |
658 | (yyval) = (yyvsp[(2) - (3)]); | |
659 | @@ -3225,7 +3225,7 @@ regular_loop: | |
660 | ||
661 | case 79: | |
662 | ||
663 | -/* Line 1806 of yacc.c */ | |
664 | +/* Line 1821 of yacc.c */ | |
665 | #line 1127 "awkgram.y" | |
666 | { | |
667 | in_print = FALSE; | |
668 | @@ -3236,14 +3236,14 @@ regular_loop: | |
669 | ||
670 | case 80: | |
671 | ||
672 | -/* Line 1806 of yacc.c */ | |
673 | +/* Line 1821 of yacc.c */ | |
674 | #line 1132 "awkgram.y" | |
675 | { in_print = FALSE; in_parens = 0; } | |
676 | break; | |
677 | ||
678 | case 81: | |
679 | ||
680 | -/* Line 1806 of yacc.c */ | |
681 | +/* Line 1821 of yacc.c */ | |
682 | #line 1133 "awkgram.y" | |
683 | { | |
684 | if ((yyvsp[(1) - (3)])->redir_type == redirect_twoway | |
685 | @@ -3256,7 +3256,7 @@ regular_loop: | |
686 | ||
687 | case 82: | |
688 | ||
689 | -/* Line 1806 of yacc.c */ | |
690 | +/* Line 1821 of yacc.c */ | |
691 | #line 1144 "awkgram.y" | |
692 | { | |
693 | (yyval) = mk_condition((yyvsp[(3) - (6)]), (yyvsp[(1) - (6)]), (yyvsp[(6) - (6)]), NULL, NULL); | |
694 | @@ -3265,7 +3265,7 @@ regular_loop: | |
695 | ||
696 | case 83: | |
697 | ||
698 | -/* Line 1806 of yacc.c */ | |
699 | +/* Line 1821 of yacc.c */ | |
700 | #line 1149 "awkgram.y" | |
701 | { | |
702 | (yyval) = mk_condition((yyvsp[(3) - (9)]), (yyvsp[(1) - (9)]), (yyvsp[(6) - (9)]), (yyvsp[(7) - (9)]), (yyvsp[(9) - (9)])); | |
703 | @@ -3274,14 +3274,14 @@ regular_loop: | |
704 | ||
705 | case 88: | |
706 | ||
707 | -/* Line 1806 of yacc.c */ | |
708 | +/* Line 1821 of yacc.c */ | |
709 | #line 1166 "awkgram.y" | |
710 | { (yyval) = NULL; } | |
711 | break; | |
712 | ||
713 | case 89: | |
714 | ||
715 | -/* Line 1806 of yacc.c */ | |
716 | +/* Line 1821 of yacc.c */ | |
717 | #line 1168 "awkgram.y" | |
718 | { | |
719 | bcfree((yyvsp[(1) - (2)])); | |
720 | @@ -3291,7 +3291,7 @@ regular_loop: | |
721 | ||
722 | case 92: | |
723 | ||
724 | -/* Line 1806 of yacc.c */ | |
725 | +/* Line 1821 of yacc.c */ | |
726 | #line 1181 "awkgram.y" | |
727 | { | |
728 | append_param((yyvsp[(1) - (1)])->lextok); | |
729 | @@ -3302,7 +3302,7 @@ regular_loop: | |
730 | ||
731 | case 93: | |
732 | ||
733 | -/* Line 1806 of yacc.c */ | |
734 | +/* Line 1821 of yacc.c */ | |
735 | #line 1187 "awkgram.y" | |
736 | { | |
737 | append_param((yyvsp[(3) - (3)])->lextok); | |
738 | @@ -3314,63 +3314,63 @@ regular_loop: | |
739 | ||
740 | case 94: | |
741 | ||
742 | -/* Line 1806 of yacc.c */ | |
743 | +/* Line 1821 of yacc.c */ | |
744 | #line 1194 "awkgram.y" | |
745 | { /* func_params = NULL; */ } | |
746 | break; | |
747 | ||
748 | case 95: | |
749 | ||
750 | -/* Line 1806 of yacc.c */ | |
751 | +/* Line 1821 of yacc.c */ | |
752 | #line 1196 "awkgram.y" | |
753 | { /* func_params = NULL; */ } | |
754 | break; | |
755 | ||
756 | case 96: | |
757 | ||
758 | -/* Line 1806 of yacc.c */ | |
759 | +/* Line 1821 of yacc.c */ | |
760 | #line 1198 "awkgram.y" | |
761 | { /* func_params = NULL; */ } | |
762 | break; | |
763 | ||
764 | case 97: | |
765 | ||
766 | -/* Line 1806 of yacc.c */ | |
767 | +/* Line 1821 of yacc.c */ | |
768 | #line 1204 "awkgram.y" | |
769 | { (yyval) = NULL; } | |
770 | break; | |
771 | ||
772 | case 98: | |
773 | ||
774 | -/* Line 1806 of yacc.c */ | |
775 | +/* Line 1821 of yacc.c */ | |
776 | #line 1206 "awkgram.y" | |
777 | { (yyval) = (yyvsp[(1) - (1)]); } | |
778 | break; | |
779 | ||
780 | case 99: | |
781 | ||
782 | -/* Line 1806 of yacc.c */ | |
783 | +/* Line 1821 of yacc.c */ | |
784 | #line 1211 "awkgram.y" | |
785 | { (yyval) = NULL; } | |
786 | break; | |
787 | ||
788 | case 100: | |
789 | ||
790 | -/* Line 1806 of yacc.c */ | |
791 | +/* Line 1821 of yacc.c */ | |
792 | #line 1213 "awkgram.y" | |
793 | { (yyval) = (yyvsp[(1) - (1)]); } | |
794 | break; | |
795 | ||
796 | case 101: | |
797 | ||
798 | -/* Line 1806 of yacc.c */ | |
799 | +/* Line 1821 of yacc.c */ | |
800 | #line 1218 "awkgram.y" | |
801 | { (yyval) = mk_expression_list(NULL, (yyvsp[(1) - (1)])); } | |
802 | break; | |
803 | ||
804 | case 102: | |
805 | ||
806 | -/* Line 1806 of yacc.c */ | |
807 | +/* Line 1821 of yacc.c */ | |
808 | #line 1220 "awkgram.y" | |
809 | { | |
810 | (yyval) = mk_expression_list((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)])); | |
811 | @@ -3380,35 +3380,35 @@ regular_loop: | |
812 | ||
813 | case 103: | |
814 | ||
815 | -/* Line 1806 of yacc.c */ | |
816 | +/* Line 1821 of yacc.c */ | |
817 | #line 1225 "awkgram.y" | |
818 | { (yyval) = NULL; } | |
819 | break; | |
820 | ||
821 | case 104: | |
822 | ||
823 | -/* Line 1806 of yacc.c */ | |
824 | +/* Line 1821 of yacc.c */ | |
825 | #line 1227 "awkgram.y" | |
826 | { (yyval) = NULL; } | |
827 | break; | |
828 | ||
829 | case 105: | |
830 | ||
831 | -/* Line 1806 of yacc.c */ | |
832 | +/* Line 1821 of yacc.c */ | |
833 | #line 1229 "awkgram.y" | |
834 | { (yyval) = NULL; } | |
835 | break; | |
836 | ||
837 | case 106: | |
838 | ||
839 | -/* Line 1806 of yacc.c */ | |
840 | +/* Line 1821 of yacc.c */ | |
841 | #line 1231 "awkgram.y" | |
842 | { (yyval) = NULL; } | |
843 | break; | |
844 | ||
845 | case 107: | |
846 | ||
847 | -/* Line 1806 of yacc.c */ | |
848 | +/* Line 1821 of yacc.c */ | |
849 | #line 1237 "awkgram.y" | |
850 | { | |
851 | if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) | |
852 | @@ -3420,21 +3420,21 @@ regular_loop: | |
853 | ||
854 | case 108: | |
855 | ||
856 | -/* Line 1806 of yacc.c */ | |
857 | +/* Line 1821 of yacc.c */ | |
858 | #line 1244 "awkgram.y" | |
859 | { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
860 | break; | |
861 | ||
862 | case 109: | |
863 | ||
864 | -/* Line 1806 of yacc.c */ | |
865 | +/* Line 1821 of yacc.c */ | |
866 | #line 1246 "awkgram.y" | |
867 | { (yyval) = mk_boolean((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
868 | break; | |
869 | ||
870 | case 110: | |
871 | ||
872 | -/* Line 1806 of yacc.c */ | |
873 | +/* Line 1821 of yacc.c */ | |
874 | #line 1248 "awkgram.y" | |
875 | { | |
876 | if ((yyvsp[(1) - (3)])->lasti->opcode == Op_match_rec) | |
877 | @@ -3455,7 +3455,7 @@ regular_loop: | |
878 | ||
879 | case 111: | |
880 | ||
881 | -/* Line 1806 of yacc.c */ | |
882 | +/* Line 1821 of yacc.c */ | |
883 | #line 1264 "awkgram.y" | |
884 | { | |
885 | if (do_lint_old) | |
886 | @@ -3470,7 +3470,7 @@ regular_loop: | |
887 | ||
888 | case 112: | |
889 | ||
890 | -/* Line 1806 of yacc.c */ | |
891 | +/* Line 1821 of yacc.c */ | |
892 | #line 1274 "awkgram.y" | |
893 | { | |
894 | if (do_lint && (yyvsp[(3) - (3)])->lasti->opcode == Op_match_rec) | |
895 | @@ -3482,35 +3482,35 @@ regular_loop: | |
896 | ||
897 | case 113: | |
898 | ||
899 | -/* Line 1806 of yacc.c */ | |
900 | +/* Line 1821 of yacc.c */ | |
901 | #line 1281 "awkgram.y" | |
902 | { (yyval) = mk_condition((yyvsp[(1) - (5)]), (yyvsp[(2) - (5)]), (yyvsp[(3) - (5)]), (yyvsp[(4) - (5)]), (yyvsp[(5) - (5)])); } | |
903 | break; | |
904 | ||
905 | case 114: | |
906 | ||
907 | -/* Line 1806 of yacc.c */ | |
908 | +/* Line 1821 of yacc.c */ | |
909 | #line 1283 "awkgram.y" | |
910 | { (yyval) = (yyvsp[(1) - (1)]); } | |
911 | break; | |
912 | ||
913 | case 115: | |
914 | ||
915 | -/* Line 1806 of yacc.c */ | |
916 | +/* Line 1821 of yacc.c */ | |
917 | #line 1288 "awkgram.y" | |
918 | { (yyval) = (yyvsp[(1) - (1)]); } | |
919 | break; | |
920 | ||
921 | case 116: | |
922 | ||
923 | -/* Line 1806 of yacc.c */ | |
924 | +/* Line 1821 of yacc.c */ | |
925 | #line 1290 "awkgram.y" | |
926 | { (yyval) = (yyvsp[(1) - (1)]); } | |
927 | break; | |
928 | ||
929 | case 117: | |
930 | ||
931 | -/* Line 1806 of yacc.c */ | |
932 | +/* Line 1821 of yacc.c */ | |
933 | #line 1292 "awkgram.y" | |
934 | { | |
935 | (yyvsp[(2) - (2)])->opcode = Op_assign_quotient; | |
936 | @@ -3520,49 +3520,49 @@ regular_loop: | |
937 | ||
938 | case 118: | |
939 | ||
940 | -/* Line 1806 of yacc.c */ | |
941 | +/* Line 1821 of yacc.c */ | |
942 | #line 1300 "awkgram.y" | |
943 | { (yyval) = (yyvsp[(1) - (1)]); } | |
944 | break; | |
945 | ||
946 | case 119: | |
947 | ||
948 | -/* Line 1806 of yacc.c */ | |
949 | +/* Line 1821 of yacc.c */ | |
950 | #line 1302 "awkgram.y" | |
951 | { (yyval) = (yyvsp[(1) - (1)]); } | |
952 | break; | |
953 | ||
954 | case 120: | |
955 | ||
956 | -/* Line 1806 of yacc.c */ | |
957 | +/* Line 1821 of yacc.c */ | |
958 | #line 1307 "awkgram.y" | |
959 | { (yyval) = (yyvsp[(1) - (1)]); } | |
960 | break; | |
961 | ||
962 | case 121: | |
963 | ||
964 | -/* Line 1806 of yacc.c */ | |
965 | +/* Line 1821 of yacc.c */ | |
966 | #line 1309 "awkgram.y" | |
967 | { (yyval) = (yyvsp[(1) - (1)]); } | |
968 | break; | |
969 | ||
970 | case 122: | |
971 | ||
972 | -/* Line 1806 of yacc.c */ | |
973 | +/* Line 1821 of yacc.c */ | |
974 | #line 1314 "awkgram.y" | |
975 | { (yyval) = (yyvsp[(1) - (1)]); } | |
976 | break; | |
977 | ||
978 | case 123: | |
979 | ||
980 | -/* Line 1806 of yacc.c */ | |
981 | +/* Line 1821 of yacc.c */ | |
982 | #line 1316 "awkgram.y" | |
983 | { (yyval) = (yyvsp[(1) - (1)]); } | |
984 | break; | |
985 | ||
986 | case 124: | |
987 | ||
988 | -/* Line 1806 of yacc.c */ | |
989 | +/* Line 1821 of yacc.c */ | |
990 | #line 1318 "awkgram.y" | |
991 | { | |
992 | int count = 2; | |
993 | @@ -3617,49 +3617,49 @@ regular_loop: | |
994 | ||
995 | case 126: | |
996 | ||
997 | -/* Line 1806 of yacc.c */ | |
998 | +/* Line 1821 of yacc.c */ | |
999 | #line 1373 "awkgram.y" | |
1000 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1001 | break; | |
1002 | ||
1003 | case 127: | |
1004 | ||
1005 | -/* Line 1806 of yacc.c */ | |
1006 | +/* Line 1821 of yacc.c */ | |
1007 | #line 1375 "awkgram.y" | |
1008 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1009 | break; | |
1010 | ||
1011 | case 128: | |
1012 | ||
1013 | -/* Line 1806 of yacc.c */ | |
1014 | +/* Line 1821 of yacc.c */ | |
1015 | #line 1377 "awkgram.y" | |
1016 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1017 | break; | |
1018 | ||
1019 | case 129: | |
1020 | ||
1021 | -/* Line 1806 of yacc.c */ | |
1022 | +/* Line 1821 of yacc.c */ | |
1023 | #line 1379 "awkgram.y" | |
1024 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1025 | break; | |
1026 | ||
1027 | case 130: | |
1028 | ||
1029 | -/* Line 1806 of yacc.c */ | |
1030 | +/* Line 1821 of yacc.c */ | |
1031 | #line 1381 "awkgram.y" | |
1032 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1033 | break; | |
1034 | ||
1035 | case 131: | |
1036 | ||
1037 | -/* Line 1806 of yacc.c */ | |
1038 | +/* Line 1821 of yacc.c */ | |
1039 | #line 1383 "awkgram.y" | |
1040 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1041 | break; | |
1042 | ||
1043 | case 132: | |
1044 | ||
1045 | -/* Line 1806 of yacc.c */ | |
1046 | +/* Line 1821 of yacc.c */ | |
1047 | #line 1385 "awkgram.y" | |
1048 | { | |
1049 | /* | |
1050 | @@ -3687,7 +3687,7 @@ regular_loop: | |
1051 | ||
1052 | case 133: | |
1053 | ||
1054 | -/* Line 1806 of yacc.c */ | |
1055 | +/* Line 1821 of yacc.c */ | |
1056 | #line 1408 "awkgram.y" | |
1057 | { | |
1058 | (yyvsp[(2) - (2)])->opcode = Op_postincrement; | |
1059 | @@ -3697,7 +3697,7 @@ regular_loop: | |
1060 | ||
1061 | case 134: | |
1062 | ||
1063 | -/* Line 1806 of yacc.c */ | |
1064 | +/* Line 1821 of yacc.c */ | |
1065 | #line 1413 "awkgram.y" | |
1066 | { | |
1067 | (yyvsp[(2) - (2)])->opcode = Op_postdecrement; | |
1068 | @@ -3707,7 +3707,7 @@ regular_loop: | |
1069 | ||
1070 | case 135: | |
1071 | ||
1072 | -/* Line 1806 of yacc.c */ | |
1073 | +/* Line 1821 of yacc.c */ | |
1074 | #line 1418 "awkgram.y" | |
1075 | { | |
1076 | if (do_lint_old) { | |
1077 | @@ -3732,7 +3732,7 @@ regular_loop: | |
1078 | ||
1079 | case 136: | |
1080 | ||
1081 | -/* Line 1806 of yacc.c */ | |
1082 | +/* Line 1821 of yacc.c */ | |
1083 | #line 1443 "awkgram.y" | |
1084 | { | |
1085 | (yyval) = mk_getline((yyvsp[(3) - (4)]), (yyvsp[(4) - (4)]), (yyvsp[(1) - (4)]), (yyvsp[(2) - (4)])->redir_type); | |
1086 | @@ -3742,49 +3742,49 @@ regular_loop: | |
1087 | ||
1088 | case 137: | |
1089 | ||
1090 | -/* Line 1806 of yacc.c */ | |
1091 | +/* Line 1821 of yacc.c */ | |
1092 | #line 1449 "awkgram.y" | |
1093 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1094 | break; | |
1095 | ||
1096 | case 138: | |
1097 | ||
1098 | -/* Line 1806 of yacc.c */ | |
1099 | +/* Line 1821 of yacc.c */ | |
1100 | #line 1451 "awkgram.y" | |
1101 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1102 | break; | |
1103 | ||
1104 | case 139: | |
1105 | ||
1106 | -/* Line 1806 of yacc.c */ | |
1107 | +/* Line 1821 of yacc.c */ | |
1108 | #line 1453 "awkgram.y" | |
1109 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1110 | break; | |
1111 | ||
1112 | case 140: | |
1113 | ||
1114 | -/* Line 1806 of yacc.c */ | |
1115 | +/* Line 1821 of yacc.c */ | |
1116 | #line 1455 "awkgram.y" | |
1117 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1118 | break; | |
1119 | ||
1120 | case 141: | |
1121 | ||
1122 | -/* Line 1806 of yacc.c */ | |
1123 | +/* Line 1821 of yacc.c */ | |
1124 | #line 1457 "awkgram.y" | |
1125 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1126 | break; | |
1127 | ||
1128 | case 142: | |
1129 | ||
1130 | -/* Line 1806 of yacc.c */ | |
1131 | +/* Line 1821 of yacc.c */ | |
1132 | #line 1459 "awkgram.y" | |
1133 | { (yyval) = mk_binary((yyvsp[(1) - (3)]), (yyvsp[(3) - (3)]), (yyvsp[(2) - (3)])); } | |
1134 | break; | |
1135 | ||
1136 | case 143: | |
1137 | ||
1138 | -/* Line 1806 of yacc.c */ | |
1139 | +/* Line 1821 of yacc.c */ | |
1140 | #line 1464 "awkgram.y" | |
1141 | { | |
1142 | (yyval) = list_create((yyvsp[(1) - (1)])); | |
1143 | @@ -3793,7 +3793,7 @@ regular_loop: | |
1144 | ||
1145 | case 144: | |
1146 | ||
1147 | -/* Line 1806 of yacc.c */ | |
1148 | +/* Line 1821 of yacc.c */ | |
1149 | #line 1468 "awkgram.y" | |
1150 | { | |
1151 | if ((yyvsp[(2) - (2)])->opcode == Op_match_rec) { | |
1152 | @@ -3829,14 +3829,14 @@ regular_loop: | |
1153 | ||
1154 | case 145: | |
1155 | ||
1156 | -/* Line 1806 of yacc.c */ | |
1157 | +/* Line 1821 of yacc.c */ | |
1158 | #line 1499 "awkgram.y" | |
1159 | { (yyval) = (yyvsp[(2) - (3)]); } | |
1160 | break; | |
1161 | ||
1162 | case 146: | |
1163 | ||
1164 | -/* Line 1806 of yacc.c */ | |
1165 | +/* Line 1821 of yacc.c */ | |
1166 | #line 1501 "awkgram.y" | |
1167 | { | |
1168 | (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); | |
1169 | @@ -3847,7 +3847,7 @@ regular_loop: | |
1170 | ||
1171 | case 147: | |
1172 | ||
1173 | -/* Line 1806 of yacc.c */ | |
1174 | +/* Line 1821 of yacc.c */ | |
1175 | #line 1507 "awkgram.y" | |
1176 | { | |
1177 | (yyval) = snode((yyvsp[(3) - (4)]), (yyvsp[(1) - (4)])); | |
1178 | @@ -3858,7 +3858,7 @@ regular_loop: | |
1179 | ||
1180 | case 148: | |
1181 | ||
1182 | -/* Line 1806 of yacc.c */ | |
1183 | +/* Line 1821 of yacc.c */ | |
1184 | #line 1513 "awkgram.y" | |
1185 | { | |
1186 | static short warned1 = FALSE; | |
1187 | @@ -3876,7 +3876,7 @@ regular_loop: | |
1188 | ||
1189 | case 151: | |
1190 | ||
1191 | -/* Line 1806 of yacc.c */ | |
1192 | +/* Line 1821 of yacc.c */ | |
1193 | #line 1528 "awkgram.y" | |
1194 | { | |
1195 | (yyvsp[(1) - (2)])->opcode = Op_preincrement; | |
1196 | @@ -3886,7 +3886,7 @@ regular_loop: | |
1197 | ||
1198 | case 152: | |
1199 | ||
1200 | -/* Line 1806 of yacc.c */ | |
1201 | +/* Line 1821 of yacc.c */ | |
1202 | #line 1533 "awkgram.y" | |
1203 | { | |
1204 | (yyvsp[(1) - (2)])->opcode = Op_predecrement; | |
1205 | @@ -3896,7 +3896,7 @@ regular_loop: | |
1206 | ||
1207 | case 153: | |
1208 | ||
1209 | -/* Line 1806 of yacc.c */ | |
1210 | +/* Line 1821 of yacc.c */ | |
1211 | #line 1538 "awkgram.y" | |
1212 | { | |
1213 | (yyval) = list_create((yyvsp[(1) - (1)])); | |
1214 | @@ -3905,7 +3905,7 @@ regular_loop: | |
1215 | ||
1216 | case 154: | |
1217 | ||
1218 | -/* Line 1806 of yacc.c */ | |
1219 | +/* Line 1821 of yacc.c */ | |
1220 | #line 1542 "awkgram.y" | |
1221 | { | |
1222 | (yyval) = list_create((yyvsp[(1) - (1)])); | |
1223 | @@ -3914,7 +3914,7 @@ regular_loop: | |
1224 | ||
1225 | case 155: | |
1226 | ||
1227 | -/* Line 1806 of yacc.c */ | |
1228 | +/* Line 1821 of yacc.c */ | |
1229 | #line 1546 "awkgram.y" | |
1230 | { | |
1231 | if ((yyvsp[(2) - (2)])->lasti->opcode == Op_push_i | |
1232 | @@ -3931,7 +3931,7 @@ regular_loop: | |
1233 | ||
1234 | case 156: | |
1235 | ||
1236 | -/* Line 1806 of yacc.c */ | |
1237 | +/* Line 1821 of yacc.c */ | |
1238 | #line 1558 "awkgram.y" | |
1239 | { | |
1240 | /* | |
1241 | @@ -3946,7 +3946,7 @@ regular_loop: | |
1242 | ||
1243 | case 157: | |
1244 | ||
1245 | -/* Line 1806 of yacc.c */ | |
1246 | +/* Line 1821 of yacc.c */ | |
1247 | #line 1571 "awkgram.y" | |
1248 | { | |
1249 | func_use((yyvsp[(1) - (1)])->lasti->func_name, FUNC_USE); | |
1250 | @@ -3956,7 +3956,7 @@ regular_loop: | |
1251 | ||
1252 | case 158: | |
1253 | ||
1254 | -/* Line 1806 of yacc.c */ | |
1255 | +/* Line 1821 of yacc.c */ | |
1256 | #line 1576 "awkgram.y" | |
1257 | { | |
1258 | /* indirect function call */ | |
1259 | @@ -3994,7 +3994,7 @@ regular_loop: | |
1260 | ||
1261 | case 159: | |
1262 | ||
1263 | -/* Line 1806 of yacc.c */ | |
1264 | +/* Line 1821 of yacc.c */ | |
1265 | #line 1612 "awkgram.y" | |
1266 | { | |
1267 | param_sanity((yyvsp[(3) - (4)])); | |
1268 | @@ -4013,42 +4013,42 @@ regular_loop: | |
1269 | ||
1270 | case 160: | |
1271 | ||
1272 | -/* Line 1806 of yacc.c */ | |
1273 | +/* Line 1821 of yacc.c */ | |
1274 | #line 1629 "awkgram.y" | |
1275 | { (yyval) = NULL; } | |
1276 | break; | |
1277 | ||
1278 | case 161: | |
1279 | ||
1280 | -/* Line 1806 of yacc.c */ | |
1281 | +/* Line 1821 of yacc.c */ | |
1282 | #line 1631 "awkgram.y" | |
1283 | { (yyval) = (yyvsp[(1) - (1)]); } | |
1284 | break; | |
1285 | ||
1286 | case 162: | |
1287 | ||
1288 | -/* Line 1806 of yacc.c */ | |
1289 | +/* Line 1821 of yacc.c */ | |
1290 | #line 1636 "awkgram.y" | |
1291 | { (yyval) = NULL; } | |
1292 | break; | |
1293 | ||
1294 | case 163: | |
1295 | ||
1296 | -/* Line 1806 of yacc.c */ | |
1297 | +/* Line 1821 of yacc.c */ | |
1298 | #line 1638 "awkgram.y" | |
1299 | { (yyval) = (yyvsp[(1) - (2)]); } | |
1300 | break; | |
1301 | ||
1302 | case 164: | |
1303 | ||
1304 | -/* Line 1806 of yacc.c */ | |
1305 | +/* Line 1821 of yacc.c */ | |
1306 | #line 1643 "awkgram.y" | |
1307 | { (yyval) = (yyvsp[(1) - (1)]); } | |
1308 | break; | |
1309 | ||
1310 | case 165: | |
1311 | ||
1312 | -/* Line 1806 of yacc.c */ | |
1313 | +/* Line 1821 of yacc.c */ | |
1314 | #line 1645 "awkgram.y" | |
1315 | { | |
1316 | (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); | |
1317 | @@ -4057,7 +4057,7 @@ regular_loop: | |
1318 | ||
1319 | case 166: | |
1320 | ||
1321 | -/* Line 1806 of yacc.c */ | |
1322 | +/* Line 1821 of yacc.c */ | |
1323 | #line 1652 "awkgram.y" | |
1324 | { | |
1325 | INSTRUCTION *ip = (yyvsp[(1) - (1)])->lasti; | |
1326 | @@ -4076,7 +4076,7 @@ regular_loop: | |
1327 | ||
1328 | case 167: | |
1329 | ||
1330 | -/* Line 1806 of yacc.c */ | |
1331 | +/* Line 1821 of yacc.c */ | |
1332 | #line 1669 "awkgram.y" | |
1333 | { | |
1334 | INSTRUCTION *t = (yyvsp[(2) - (3)]); | |
1335 | @@ -4095,14 +4095,14 @@ regular_loop: | |
1336 | ||
1337 | case 168: | |
1338 | ||
1339 | -/* Line 1806 of yacc.c */ | |
1340 | +/* Line 1821 of yacc.c */ | |
1341 | #line 1686 "awkgram.y" | |
1342 | { (yyval) = (yyvsp[(1) - (1)]); } | |
1343 | break; | |
1344 | ||
1345 | case 169: | |
1346 | ||
1347 | -/* Line 1806 of yacc.c */ | |
1348 | +/* Line 1821 of yacc.c */ | |
1349 | #line 1688 "awkgram.y" | |
1350 | { | |
1351 | (yyval) = list_merge((yyvsp[(1) - (2)]), (yyvsp[(2) - (2)])); | |
1352 | @@ -4111,14 +4111,14 @@ regular_loop: | |
1353 | ||
1354 | case 170: | |
1355 | ||
1356 | -/* Line 1806 of yacc.c */ | |
1357 | +/* Line 1821 of yacc.c */ | |
1358 | #line 1695 "awkgram.y" | |
1359 | { (yyval) = (yyvsp[(1) - (2)]); } | |
1360 | break; | |
1361 | ||
1362 | case 171: | |
1363 | ||
1364 | -/* Line 1806 of yacc.c */ | |
1365 | +/* Line 1821 of yacc.c */ | |
1366 | #line 1700 "awkgram.y" | |
1367 | { | |
1368 | char *var_name = (yyvsp[(1) - (1)])->lextok; | |
1369 | @@ -4131,7 +4131,7 @@ regular_loop: | |
1370 | ||
1371 | case 172: | |
1372 | ||
1373 | -/* Line 1806 of yacc.c */ | |
1374 | +/* Line 1821 of yacc.c */ | |
1375 | #line 1708 "awkgram.y" | |
1376 | { | |
1377 | NODE *n; | |
1378 | @@ -4147,7 +4147,7 @@ regular_loop: | |
1379 | ||
1380 | case 173: | |
1381 | ||
1382 | -/* Line 1806 of yacc.c */ | |
1383 | +/* Line 1821 of yacc.c */ | |
1384 | #line 1722 "awkgram.y" | |
1385 | { | |
1386 | INSTRUCTION *ip = (yyvsp[(1) - (1)])->nexti; | |
1387 | @@ -4165,7 +4165,7 @@ regular_loop: | |
1388 | ||
1389 | case 174: | |
1390 | ||
1391 | -/* Line 1806 of yacc.c */ | |
1392 | +/* Line 1821 of yacc.c */ | |
1393 | #line 1735 "awkgram.y" | |
1394 | { | |
1395 | (yyval) = list_append((yyvsp[(2) - (3)]), (yyvsp[(1) - (3)])); | |
1396 | @@ -4176,7 +4176,7 @@ regular_loop: | |
1397 | ||
1398 | case 175: | |
1399 | ||
1400 | -/* Line 1806 of yacc.c */ | |
1401 | +/* Line 1821 of yacc.c */ | |
1402 | #line 1744 "awkgram.y" | |
1403 | { | |
1404 | (yyvsp[(1) - (1)])->opcode = Op_postincrement; | |
1405 | @@ -4185,7 +4185,7 @@ regular_loop: | |
1406 | ||
1407 | case 176: | |
1408 | ||
1409 | -/* Line 1806 of yacc.c */ | |
1410 | +/* Line 1821 of yacc.c */ | |
1411 | #line 1748 "awkgram.y" | |
1412 | { | |
1413 | (yyvsp[(1) - (1)])->opcode = Op_postdecrement; | |
1414 | @@ -4194,49 +4194,49 @@ regular_loop: | |
1415 | ||
1416 | case 177: | |
1417 | ||
1418 | -/* Line 1806 of yacc.c */ | |
1419 | +/* Line 1821 of yacc.c */ | |
1420 | #line 1751 "awkgram.y" | |
1421 | { (yyval) = NULL; } | |
1422 | break; | |
1423 | ||
1424 | case 179: | |
1425 | ||
1426 | -/* Line 1806 of yacc.c */ | |
1427 | +/* Line 1821 of yacc.c */ | |
1428 | #line 1759 "awkgram.y" | |
1429 | { yyerrok; } | |
1430 | break; | |
1431 | ||
1432 | case 180: | |
1433 | ||
1434 | -/* Line 1806 of yacc.c */ | |
1435 | +/* Line 1821 of yacc.c */ | |
1436 | #line 1763 "awkgram.y" | |
1437 | { yyerrok; } | |
1438 | break; | |
1439 | ||
1440 | case 183: | |
1441 | ||
1442 | -/* Line 1806 of yacc.c */ | |
1443 | +/* Line 1821 of yacc.c */ | |
1444 | #line 1772 "awkgram.y" | |
1445 | { yyerrok; } | |
1446 | break; | |
1447 | ||
1448 | case 184: | |
1449 | ||
1450 | -/* Line 1806 of yacc.c */ | |
1451 | +/* Line 1821 of yacc.c */ | |
1452 | #line 1776 "awkgram.y" | |
1453 | { (yyval) = (yyvsp[(1) - (1)]); yyerrok; } | |
1454 | break; | |
1455 | ||
1456 | case 185: | |
1457 | ||
1458 | -/* Line 1806 of yacc.c */ | |
1459 | +/* Line 1821 of yacc.c */ | |
1460 | #line 1780 "awkgram.y" | |
1461 | { yyerrok; } | |
1462 | break; | |
1463 | ||
1464 | ||
1465 | ||
1466 | -/* Line 1806 of yacc.c */ | |
1467 | +/* Line 1821 of yacc.c */ | |
1468 | #line 4253 "awkgram.c" | |
1469 | default: break; | |
1470 | } | |
1471 | @@ -4485,6 +4485,7 @@ struct token { | |
1472 | # define RESX 0x0800 /* Bell Labs Research extension */ | |
1473 | # define BREAK 0x1000 /* break allowed inside */ | |
1474 | # define CONTINUE 0x2000 /* continue allowed inside */ | |
1475 | + | |
1476 | NODE *(*ptr)(int); /* function that implements this keyword */ | |
1477 | }; | |
1478 | ||
1479 | @@ -4542,9 +4543,9 @@ static const struct token tokentab[] = { | |
1480 | {"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0}, | |
1481 | {"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, | |
1482 | {"function",Op_func, LEX_FUNCTION, NOT_OLD, 0}, | |
1483 | -{"gensub", Op_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, | |
1484 | +{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0}, | |
1485 | {"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0}, | |
1486 | -{"gsub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, | |
1487 | +{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0}, | |
1488 | {"if", Op_K_if, LEX_IF, 0, 0}, | |
1489 | {"in", Op_symbol, LEX_IN, 0, 0}, | |
1490 | {"include", Op_symbol, LEX_INCLUDE, GAWKX, 0}, | |
1491 | @@ -4575,7 +4576,7 @@ static const struct token tokentab[] = { | |
1492 | #endif | |
1493 | {"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime}, | |
1494 | {"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, | |
1495 | -{"sub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, | |
1496 | +{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0}, | |
1497 | {"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, | |
1498 | {"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0}, | |
1499 | {"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, | |
1500 | @@ -6286,8 +6287,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1501 | assert(nexp > 0); | |
1502 | } | |
1503 | ||
1504 | - r->builtin = tokentab[idx].ptr; | |
1505 | - | |
1506 | /* check against how many args. are allowed for this builtin */ | |
1507 | args_allowed = tokentab[idx].flags & ARGS; | |
1508 | if (args_allowed && (args_allowed & A(nexp)) == 0) { | |
1509 | @@ -6296,7 +6295,85 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1510 | return NULL; | |
1511 | } | |
1512 | ||
1513 | + /* special processing for sub, gsub and gensub */ | |
1514 | + | |
1515 | + if (tokentab[idx].value == Op_sub_builtin) { | |
1516 | + const char *operator = tokentab[idx].operator; | |
1517 | + | |
1518 | + r->sub_flags = 0; | |
1519 | + | |
1520 | + arg = subn->nexti; /* first arg list */ | |
1521 | + (void) mk_rexp(arg); | |
1522 | + | |
1523 | + if (strcmp(operator, "gensub") != 0) { | |
1524 | + /* sun and gsub */ | |
1525 | + | |
1526 | + if (strcmp(operator, "gsub") == 0) | |
1527 | + r->sub_flags |= GSUB; | |
1528 | + | |
1529 | + arg = arg->lasti->nexti; /* 2nd arg list */ | |
1530 | + if (nexp == 2) { | |
1531 | + INSTRUCTION *expr; | |
1532 | + expr = list_create(instruction(Op_push_i)); | |
1533 | + expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1534 | + (void) mk_expression_list(subn, | |
1535 | + list_append(expr, instruction(Op_field_spec))); | |
1536 | + } | |
1537 | + | |
1538 | + arg = arg->lasti->nexti; /* third arg list */ | |
1539 | + ip = arg->lasti; | |
1540 | + if (ip->opcode == Op_push_i) { | |
1541 | + if (do_lint) | |
1542 | + lintwarn(_("%s: string literal as last arg of substitute has no effect"), | |
1543 | + operator); | |
1544 | + r->sub_flags |= LITERAL; | |
1545 | + } else { | |
1546 | + if (make_assignable(ip) == NULL) | |
1547 | + yyerror(_("%s third parameter is not a changeable object"), | |
1548 | + operator); | |
1549 | + else | |
1550 | + ip->do_reference = TRUE; | |
1551 | + } | |
1552 | + | |
1553 | + r->expr_count = count_expressions(&subn, FALSE); | |
1554 | + ip = subn->lasti; | |
1555 | + | |
1556 | + (void) list_append(subn, r); | |
1557 | + | |
1558 | + /* add after_assign code */ | |
1559 | + if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) { | |
1560 | + (void) list_append(subn, instruction(Op_var_assign)); | |
1561 | + subn->lasti->memory = ip->memory; | |
1562 | + subn->lasti->assign_var = ip->memory->var_assign; | |
1563 | + r->sub_flags |= AFTER_ASSIGN; | |
1564 | + } else if (ip->opcode == Op_field_spec_lhs) { | |
1565 | + (void) list_append(subn, instruction(Op_field_assign)); | |
1566 | + subn->lasti->field_assign = (Func_ptr) 0; | |
1567 | + ip->target_assign = subn->lasti; | |
1568 | + r->sub_flags |= AFTER_ASSIGN; | |
1569 | + } | |
1570 | + return subn; | |
1571 | + | |
1572 | + } else { | |
1573 | + /* gensub */ | |
1574 | + | |
1575 | + r->sub_flags |= GENSUB; | |
1576 | + if (nexp == 3) { | |
1577 | + ip = instruction(Op_push_i); | |
1578 | + ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1579 | + (void) mk_expression_list(subn, | |
1580 | + list_append(list_create(ip), instruction(Op_field_spec))); | |
1581 | + } | |
1582 | + | |
1583 | + r->expr_count = count_expressions(&subn, FALSE); | |
1584 | + return list_append(subn, r); | |
1585 | + } | |
1586 | + } | |
1587 | + | |
1588 | + r->builtin = tokentab[idx].ptr; | |
1589 | + | |
1590 | /* special case processing for a few builtins */ | |
1591 | + | |
1592 | if (r->builtin == do_length) { | |
1593 | if (nexp == 0) { | |
1594 | /* no args. Use $0 */ | |
1595 | @@ -6338,71 +6415,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1596 | if (/*ip == arg->nexti && */ ip->opcode == Op_push) | |
1597 | ip->opcode = Op_push_array; | |
1598 | } | |
1599 | - } else if (r->builtin == do_sub || r->builtin == do_gsub) { | |
1600 | - int literal = FALSE; | |
1601 | - | |
1602 | - arg = subn->nexti; /* first arg list */ | |
1603 | - (void) mk_rexp(arg); | |
1604 | - | |
1605 | - arg = arg->lasti->nexti; /* 2nd arg list */ | |
1606 | - if (nexp == 2) { | |
1607 | - INSTRUCTION *expr; | |
1608 | - expr = list_create(instruction(Op_push_i)); | |
1609 | - expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1610 | - (void) mk_expression_list(subn, | |
1611 | - list_append(expr, instruction(Op_field_spec))); | |
1612 | - } | |
1613 | - | |
1614 | - arg = arg->lasti->nexti; /* third arg list */ | |
1615 | - ip = arg->lasti; | |
1616 | - if (ip->opcode == Op_push_i) { | |
1617 | - if (do_lint) | |
1618 | - lintwarn(_("%s: string literal as last arg of substitute has no effect"), | |
1619 | - (r->builtin == do_sub) ? "sub" : "gsub"); | |
1620 | - literal = TRUE; | |
1621 | - } else { | |
1622 | - if (make_assignable(ip) == NULL) | |
1623 | - yyerror(_("%s third parameter is not a changeable object"), | |
1624 | - (r->builtin == do_sub) ? "sub" : "gsub"); | |
1625 | - else | |
1626 | - ip->do_reference = TRUE; | |
1627 | - } | |
1628 | - | |
1629 | - /* kludge: This is one of the few cases | |
1630 | - * when we need to know the type of item on stack. | |
1631 | - * In case of string literal as the last argument, | |
1632 | - * pass 4 as # of args (See sub_common code in builtin.c). | |
1633 | - * Other cases like length(array or scalar) seem | |
1634 | - * to work out ok. | |
1635 | - */ | |
1636 | - | |
1637 | - r->expr_count = count_expressions(&subn, FALSE) + !!literal; | |
1638 | - ip = subn->lasti; | |
1639 | - | |
1640 | - (void) list_append(subn, r); | |
1641 | - | |
1642 | - /* add after_assign bytecode(s) */ | |
1643 | - if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) { | |
1644 | - (void) list_append(subn, instruction(Op_var_assign)); | |
1645 | - subn->lasti->memory = ip->memory; | |
1646 | - subn->lasti->assign_var = ip->memory->var_assign; | |
1647 | - } else if (ip->opcode == Op_field_spec_lhs) { | |
1648 | - (void) list_append(subn, instruction(Op_field_assign)); | |
1649 | - subn->lasti->field_assign = (Func_ptr) 0; | |
1650 | - ip->target_assign = subn->lasti; | |
1651 | - } | |
1652 | - return subn; | |
1653 | - } else if (r->builtin == do_gensub) { | |
1654 | - if (nexp == 3) { | |
1655 | - arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd arg list */ | |
1656 | - ip = instruction(Op_push_i); | |
1657 | - ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1658 | - (void) mk_expression_list(subn, | |
1659 | - list_append(list_create(ip), | |
1660 | - instruction(Op_field_spec))); | |
1661 | - } | |
1662 | - arg = subn->nexti; /* first arg list */ | |
1663 | - (void) mk_rexp(arg); | |
1664 | } else if (r->builtin == do_split) { | |
1665 | arg = subn->nexti->lasti->nexti; /* 2nd arg list */ | |
1666 | ip = arg->lasti; | |
1667 | diff --git a/awkgram.y b/awkgram.y | |
1668 | index 6b28b52..4553d09 100644 | |
1669 | --- a/awkgram.y | |
1670 | +++ b/awkgram.y | |
1671 | @@ -1795,6 +1795,7 @@ struct token { | |
1672 | # define RESX 0x0800 /* Bell Labs Research extension */ | |
1673 | # define BREAK 0x1000 /* break allowed inside */ | |
1674 | # define CONTINUE 0x2000 /* continue allowed inside */ | |
1675 | + | |
1676 | NODE *(*ptr)(int); /* function that implements this keyword */ | |
1677 | }; | |
1678 | ||
1679 | @@ -1852,9 +1853,9 @@ static const struct token tokentab[] = { | |
1680 | {"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0}, | |
1681 | {"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, | |
1682 | {"function",Op_func, LEX_FUNCTION, NOT_OLD, 0}, | |
1683 | -{"gensub", Op_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, | |
1684 | +{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0}, | |
1685 | {"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0}, | |
1686 | -{"gsub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, | |
1687 | +{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0}, | |
1688 | {"if", Op_K_if, LEX_IF, 0, 0}, | |
1689 | {"in", Op_symbol, LEX_IN, 0, 0}, | |
1690 | {"include", Op_symbol, LEX_INCLUDE, GAWKX, 0}, | |
1691 | @@ -1885,7 +1886,7 @@ static const struct token tokentab[] = { | |
1692 | #endif | |
1693 | {"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime}, | |
1694 | {"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, | |
1695 | -{"sub", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, | |
1696 | +{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0}, | |
1697 | {"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, | |
1698 | {"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0}, | |
1699 | {"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, | |
1700 | @@ -3596,8 +3597,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1701 | assert(nexp > 0); | |
1702 | } | |
1703 | ||
1704 | - r->builtin = tokentab[idx].ptr; | |
1705 | - | |
1706 | /* check against how many args. are allowed for this builtin */ | |
1707 | args_allowed = tokentab[idx].flags & ARGS; | |
1708 | if (args_allowed && (args_allowed & A(nexp)) == 0) { | |
1709 | @@ -3606,7 +3605,85 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1710 | return NULL; | |
1711 | } | |
1712 | ||
1713 | + /* special processing for sub, gsub and gensub */ | |
1714 | + | |
1715 | + if (tokentab[idx].value == Op_sub_builtin) { | |
1716 | + const char *operator = tokentab[idx].operator; | |
1717 | + | |
1718 | + r->sub_flags = 0; | |
1719 | + | |
1720 | + arg = subn->nexti; /* first arg list */ | |
1721 | + (void) mk_rexp(arg); | |
1722 | + | |
1723 | + if (strcmp(operator, "gensub") != 0) { | |
1724 | + /* sun and gsub */ | |
1725 | + | |
1726 | + if (strcmp(operator, "gsub") == 0) | |
1727 | + r->sub_flags |= GSUB; | |
1728 | + | |
1729 | + arg = arg->lasti->nexti; /* 2nd arg list */ | |
1730 | + if (nexp == 2) { | |
1731 | + INSTRUCTION *expr; | |
1732 | + expr = list_create(instruction(Op_push_i)); | |
1733 | + expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1734 | + (void) mk_expression_list(subn, | |
1735 | + list_append(expr, instruction(Op_field_spec))); | |
1736 | + } | |
1737 | + | |
1738 | + arg = arg->lasti->nexti; /* third arg list */ | |
1739 | + ip = arg->lasti; | |
1740 | + if (ip->opcode == Op_push_i) { | |
1741 | + if (do_lint) | |
1742 | + lintwarn(_("%s: string literal as last arg of substitute has no effect"), | |
1743 | + operator); | |
1744 | + r->sub_flags |= LITERAL; | |
1745 | + } else { | |
1746 | + if (make_assignable(ip) == NULL) | |
1747 | + yyerror(_("%s third parameter is not a changeable object"), | |
1748 | + operator); | |
1749 | + else | |
1750 | + ip->do_reference = TRUE; | |
1751 | + } | |
1752 | + | |
1753 | + r->expr_count = count_expressions(&subn, FALSE); | |
1754 | + ip = subn->lasti; | |
1755 | + | |
1756 | + (void) list_append(subn, r); | |
1757 | + | |
1758 | + /* add after_assign code */ | |
1759 | + if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) { | |
1760 | + (void) list_append(subn, instruction(Op_var_assign)); | |
1761 | + subn->lasti->memory = ip->memory; | |
1762 | + subn->lasti->assign_var = ip->memory->var_assign; | |
1763 | + r->sub_flags |= AFTER_ASSIGN; | |
1764 | + } else if (ip->opcode == Op_field_spec_lhs) { | |
1765 | + (void) list_append(subn, instruction(Op_field_assign)); | |
1766 | + subn->lasti->field_assign = (Func_ptr) 0; | |
1767 | + ip->target_assign = subn->lasti; | |
1768 | + r->sub_flags |= AFTER_ASSIGN; | |
1769 | + } | |
1770 | + return subn; | |
1771 | + | |
1772 | + } else { | |
1773 | + /* gensub */ | |
1774 | + | |
1775 | + r->sub_flags |= GENSUB; | |
1776 | + if (nexp == 3) { | |
1777 | + ip = instruction(Op_push_i); | |
1778 | + ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1779 | + (void) mk_expression_list(subn, | |
1780 | + list_append(list_create(ip), instruction(Op_field_spec))); | |
1781 | + } | |
1782 | + | |
1783 | + r->expr_count = count_expressions(&subn, FALSE); | |
1784 | + return list_append(subn, r); | |
1785 | + } | |
1786 | + } | |
1787 | + | |
1788 | + r->builtin = tokentab[idx].ptr; | |
1789 | + | |
1790 | /* special case processing for a few builtins */ | |
1791 | + | |
1792 | if (r->builtin == do_length) { | |
1793 | if (nexp == 0) { | |
1794 | /* no args. Use $0 */ | |
1795 | @@ -3648,71 +3725,6 @@ snode(INSTRUCTION *subn, INSTRUCTION *r) | |
1796 | if (/*ip == arg->nexti && */ ip->opcode == Op_push) | |
1797 | ip->opcode = Op_push_array; | |
1798 | } | |
1799 | - } else if (r->builtin == do_sub || r->builtin == do_gsub) { | |
1800 | - int literal = FALSE; | |
1801 | - | |
1802 | - arg = subn->nexti; /* first arg list */ | |
1803 | - (void) mk_rexp(arg); | |
1804 | - | |
1805 | - arg = arg->lasti->nexti; /* 2nd arg list */ | |
1806 | - if (nexp == 2) { | |
1807 | - INSTRUCTION *expr; | |
1808 | - expr = list_create(instruction(Op_push_i)); | |
1809 | - expr->nexti->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1810 | - (void) mk_expression_list(subn, | |
1811 | - list_append(expr, instruction(Op_field_spec))); | |
1812 | - } | |
1813 | - | |
1814 | - arg = arg->lasti->nexti; /* third arg list */ | |
1815 | - ip = arg->lasti; | |
1816 | - if (ip->opcode == Op_push_i) { | |
1817 | - if (do_lint) | |
1818 | - lintwarn(_("%s: string literal as last arg of substitute has no effect"), | |
1819 | - (r->builtin == do_sub) ? "sub" : "gsub"); | |
1820 | - literal = TRUE; | |
1821 | - } else { | |
1822 | - if (make_assignable(ip) == NULL) | |
1823 | - yyerror(_("%s third parameter is not a changeable object"), | |
1824 | - (r->builtin == do_sub) ? "sub" : "gsub"); | |
1825 | - else | |
1826 | - ip->do_reference = TRUE; | |
1827 | - } | |
1828 | - | |
1829 | - /* kludge: This is one of the few cases | |
1830 | - * when we need to know the type of item on stack. | |
1831 | - * In case of string literal as the last argument, | |
1832 | - * pass 4 as # of args (See sub_common code in builtin.c). | |
1833 | - * Other cases like length(array or scalar) seem | |
1834 | - * to work out ok. | |
1835 | - */ | |
1836 | - | |
1837 | - r->expr_count = count_expressions(&subn, FALSE) + !!literal; | |
1838 | - ip = subn->lasti; | |
1839 | - | |
1840 | - (void) list_append(subn, r); | |
1841 | - | |
1842 | - /* add after_assign bytecode(s) */ | |
1843 | - if (ip->opcode == Op_push_lhs && ip->memory->type == Node_var && ip->memory->var_assign) { | |
1844 | - (void) list_append(subn, instruction(Op_var_assign)); | |
1845 | - subn->lasti->memory = ip->memory; | |
1846 | - subn->lasti->assign_var = ip->memory->var_assign; | |
1847 | - } else if (ip->opcode == Op_field_spec_lhs) { | |
1848 | - (void) list_append(subn, instruction(Op_field_assign)); | |
1849 | - subn->lasti->field_assign = (Func_ptr) 0; | |
1850 | - ip->target_assign = subn->lasti; | |
1851 | - } | |
1852 | - return subn; | |
1853 | - } else if (r->builtin == do_gensub) { | |
1854 | - if (nexp == 3) { | |
1855 | - arg = subn->nexti->lasti->nexti->lasti->nexti; /* 3rd arg list */ | |
1856 | - ip = instruction(Op_push_i); | |
1857 | - ip->memory = mk_number((AWKNUM) 0.0, (PERM|NUMCUR|NUMBER)); | |
1858 | - (void) mk_expression_list(subn, | |
1859 | - list_append(list_create(ip), | |
1860 | - instruction(Op_field_spec))); | |
1861 | - } | |
1862 | - arg = subn->nexti; /* first arg list */ | |
1863 | - (void) mk_rexp(arg); | |
1864 | } else if (r->builtin == do_split) { | |
1865 | arg = subn->nexti->lasti->nexti; /* 2nd arg list */ | |
1866 | ip = arg->lasti; | |
1867 | diff --git a/builtin.c b/builtin.c | |
1868 | index 724ea6d..d554930 100644 | |
1869 | --- a/builtin.c | |
1870 | +++ b/builtin.c | |
1871 | @@ -72,7 +72,6 @@ extern NODE **fields_arr; | |
1872 | extern int output_is_tty; | |
1873 | extern FILE *output_fp; | |
1874 | ||
1875 | -static NODE *sub_common(int nargs, long how_many, int backdigs); | |
1876 | ||
1877 | #define POP_TWO_SCALARS(s1, s2) \ | |
1878 | s2 = POP_SCALAR(); \ | |
1879 | @@ -2319,7 +2318,7 @@ do_match(int nargs) | |
1880 | return make_number((AWKNUM) rstart); | |
1881 | } | |
1882 | ||
1883 | -/* sub_common --- the common code (does the work) for sub, gsub, and gensub */ | |
1884 | +/* do_sub --- do the work for sub, gsub, and gensub */ | |
1885 | ||
1886 | /* | |
1887 | * Gsub can be tricksy; particularly when handling the case of null strings. | |
1888 | @@ -2412,12 +2411,12 @@ do_match(int nargs) | |
1889 | * NB: `howmany' conflicts with a SunOS 4.x macro in <sys/param.h>. | |
1890 | */ | |
1891 | ||
1892 | -static NODE * | |
1893 | -sub_common(int nargs, long how_many, int backdigs) | |
1894 | +NODE * | |
1895 | +do_sub(int nargs, unsigned int flags, int *num_matches) | |
1896 | { | |
1897 | char *scan; | |
1898 | char *bp, *cp; | |
1899 | - char *buf; | |
1900 | + char *buf = NULL; | |
1901 | size_t buflen; | |
1902 | char *matchend; | |
1903 | size_t len; | |
1904 | @@ -2434,38 +2433,77 @@ sub_common(int nargs, long how_many, int backdigs) | |
1905 | NODE *s; /* subst. pattern */ | |
1906 | NODE *t; /* string to make sub. in; $0 if none given */ | |
1907 | NODE *tmp; | |
1908 | - NODE **lhs; | |
1909 | - int global = (how_many == -1); | |
1910 | + NODE **lhs = NULL; | |
1911 | + long how_many = 1; /* one substitution for sub, also gensub default */ | |
1912 | + int global; | |
1913 | long current; | |
1914 | int lastmatchnonzero; | |
1915 | char *mb_indices = NULL; | |
1916 | - | |
1917 | - tmp = PEEK(2); /* take care of regexp early, in case re_update is fatal */ | |
1918 | - rp = re_update(tmp); | |
1919 | ||
1920 | - /* original string */ | |
1921 | - if (nargs == 4) { /* kludge: no of items on stack is really 3, | |
1922 | - * See snode(..) in awkgram.y | |
1923 | - */ | |
1924 | - lhs = NULL; | |
1925 | - t = POP_STRING(); | |
1926 | + if ((flags & GENSUB) != 0) { | |
1927 | + double d; | |
1928 | + NODE *t1; | |
1929 | + | |
1930 | + tmp = PEEK(3); | |
1931 | + rp = re_update(tmp); | |
1932 | + | |
1933 | + t = POP_STRING(); /* original string */ | |
1934 | + | |
1935 | + t1 = POP_SCALAR(); /* value of global flag */ | |
1936 | + if ((t1->flags & (STRCUR|STRING)) != 0) { | |
1937 | + if (t1->stlen > 0 && (t1->stptr[0] == 'g' || t1->stptr[0] == 'G')) | |
1938 | + how_many = -1; | |
1939 | + else { | |
1940 | + d = force_number(t1); | |
1941 | + | |
1942 | + if ((t1->flags & NUMCUR) != 0) | |
1943 | + goto set_how_many; | |
1944 | + | |
1945 | + how_many = 1; | |
1946 | + } | |
1947 | + } else { | |
1948 | + d = force_number(t1); | |
1949 | +set_how_many: | |
1950 | + if (d < 1) | |
1951 | + how_many = 1; | |
1952 | + else if (d < LONG_MAX) | |
1953 | + how_many = d; | |
1954 | + else | |
1955 | + how_many = LONG_MAX; | |
1956 | + if (d == 0) | |
1957 | + warning(_("gensub: third argument of 0 treated as 1")); | |
1958 | + } | |
1959 | + DEREF(t1); | |
1960 | + | |
1961 | } else { | |
1962 | - lhs = POP_ADDRESS(); | |
1963 | - t = force_string(*lhs); | |
1964 | + | |
1965 | + /* take care of regexp early, in case re_update is fatal */ | |
1966 | + | |
1967 | + tmp = PEEK(2); | |
1968 | + rp = re_update(tmp); | |
1969 | + | |
1970 | + if ((flags & GSUB) != 0) | |
1971 | + how_many = -1; | |
1972 | + | |
1973 | + /* original string */ | |
1974 | + | |
1975 | + if ((flags & LITERAL) != 0) | |
1976 | + t = POP_STRING(); | |
1977 | + else { | |
1978 | + lhs = POP_ADDRESS(); | |
1979 | + t = force_string(*lhs); | |
1980 | + } | |
1981 | } | |
1982 | ||
1983 | + global = (how_many == -1); | |
1984 | ||
1985 | - s = POP_STRING(); /* replacement text */ | |
1986 | + s = POP_STRING(); /* replacement text */ | |
1987 | decr_sp(); /* regexp, already updated above */ | |
1988 | ||
1989 | /* do the search early to avoid work on non-match */ | |
1990 | if (research(rp, t->stptr, 0, t->stlen, RE_NEED_START) == -1 || | |
1991 | - RESTART(rp, t->stptr) > t->stlen) { | |
1992 | - if (lhs == NULL) | |
1993 | - DEREF(t); | |
1994 | - DEREF(s); | |
1995 | - return make_number((AWKNUM) 0.0); | |
1996 | - } | |
1997 | + RESTART(rp, t->stptr) > t->stlen) | |
1998 | + goto done; | |
1999 | ||
2000 | t->flags |= STRING; | |
2001 | ||
2002 | @@ -2476,7 +2514,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2003 | repl = s->stptr; | |
2004 | replend = repl + s->stlen; | |
2005 | repllen = replend - repl; | |
2006 | - emalloc(buf, char *, buflen + 2, "sub_common"); | |
2007 | + emalloc(buf, char *, buflen + 2, "do_sub"); | |
2008 | buf[buflen] = '\0'; | |
2009 | buf[buflen + 1] = '\0'; | |
2010 | ampersands = 0; | |
2011 | @@ -2490,7 +2528,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2012 | * for example. | |
2013 | */ | |
2014 | if (gawk_mb_cur_max > 1 && repllen > 0) { | |
2015 | - emalloc(mb_indices, char *, repllen * sizeof(char), "sub_common"); | |
2016 | + emalloc(mb_indices, char *, repllen * sizeof(char), "do_sub"); | |
2017 | index_multibyte_buffer(repl, mb_indices, repllen); | |
2018 | } | |
2019 | ||
2020 | @@ -2500,7 +2538,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2021 | repllen--; | |
2022 | ampersands++; | |
2023 | } else if (*scan == '\\') { | |
2024 | - if (backdigs) { /* gensub, behave sanely */ | |
2025 | + if (flags & GENSUB) { /* gensub, behave sanely */ | |
2026 | if (isdigit((unsigned char) scan[1])) { | |
2027 | ampersands++; | |
2028 | scan++; | |
2029 | @@ -2575,7 +2613,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2030 | && (gawk_mb_cur_max == 1 | |
2031 | || (repllen > 0 && mb_indices[scan - repl] == 1)) | |
2032 | ) { | |
2033 | - if (backdigs) { /* gensub, behave sanely */ | |
2034 | + if (flags & GENSUB) { /* gensub, behave sanely */ | |
2035 | if (isdigit((unsigned char) scan[1])) { | |
2036 | int dig = scan[1] - '0'; | |
2037 | if (dig < NUMSUBPATS(rp, t->stptr) && SUBPATSTART(rp, tp->stptr, dig) != -1) { | |
2038 | @@ -2619,7 +2657,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2039 | textlen = text + textlen - matchend; | |
2040 | text = matchend; | |
2041 | ||
2042 | - if ((current >= how_many && !global) | |
2043 | + if ((current >= how_many && ! global) | |
2044 | || ((long) textlen <= 0 && matchstart == matchend) | |
2045 | || research(rp, t->stptr, text - t->stptr, textlen, RE_NEED_START) == -1) | |
2046 | break; | |
2047 | @@ -2628,7 +2666,7 @@ sub_common(int nargs, long how_many, int backdigs) | |
2048 | sofar = bp - buf; | |
2049 | if (buflen - sofar - textlen - 1) { | |
2050 | buflen = sofar + textlen + 2; | |
2051 | - erealloc(buf, char *, buflen, "sub_common"); | |
2052 | + erealloc(buf, char *, buflen, "do_sub"); | |
2053 | bp = buf + sofar; | |
2054 | } | |
2055 | for (scan = matchend; scan < text + textlen; scan++) | |
2056 | @@ -2636,102 +2674,39 @@ sub_common(int nargs, long how_many, int backdigs) | |
2057 | *bp = '\0'; | |
2058 | textlen = bp - buf; | |
2059 | ||
2060 | - DEREF(s); | |
2061 | - | |
2062 | - if (lhs != NULL) { | |
2063 | - if (matches > 0) { | |
2064 | - unref(*lhs); | |
2065 | - *lhs = make_str_node(buf, textlen, ALREADY_MALLOCED); | |
2066 | - } else | |
2067 | - efree(buf); | |
2068 | - } else { | |
2069 | - efree(buf); | |
2070 | - DEREF(t); | |
2071 | - } | |
2072 | - | |
2073 | if (mb_indices != NULL) | |
2074 | efree(mb_indices); | |
2075 | ||
2076 | - return make_number((AWKNUM) matches); | |
2077 | -} | |
2078 | - | |
2079 | -/* do_gsub --- global substitution */ | |
2080 | - | |
2081 | -NODE * | |
2082 | -do_gsub(int nargs) | |
2083 | -{ | |
2084 | - return sub_common(nargs, -1, FALSE); | |
2085 | -} | |
2086 | - | |
2087 | -/* do_sub --- single substitution */ | |
2088 | - | |
2089 | -NODE * | |
2090 | -do_sub(int nargs) | |
2091 | -{ | |
2092 | - return sub_common(nargs, 1, FALSE); | |
2093 | -} | |
2094 | - | |
2095 | -/* do_gensub --- fix up the tree for sub_common for the gensub function */ | |
2096 | - | |
2097 | -NODE * | |
2098 | -do_gensub(int nargs) | |
2099 | -{ | |
2100 | - NODE *t, *tmp, *target, *ret; | |
2101 | - long how_many = 1; /* default is one substitution */ | |
2102 | - double d; | |
2103 | - | |
2104 | - tmp = POP_STRING(); /* target */ | |
2105 | - t = POP_SCALAR(); /* value of global flag */ | |
2106 | - | |
2107 | - /* | |
2108 | - * We make copy of the original target string, and pass that | |
2109 | - * in to sub_common() as the target to make the substitution in. | |
2110 | - * We will then return the result string as the return value of | |
2111 | - * this function. | |
2112 | - */ | |
2113 | - | |
2114 | - target = make_string(tmp->stptr, tmp->stlen); | |
2115 | - DEREF(tmp); | |
2116 | - PUSH_ADDRESS(& target); | |
2117 | - | |
2118 | - if ((t->flags & (STRCUR|STRING)) != 0) { | |
2119 | - if (t->stlen > 0 && (t->stptr[0] == 'g' || t->stptr[0] == 'G')) | |
2120 | - how_many = -1; | |
2121 | - else { | |
2122 | - d = force_number(t); | |
2123 | +done: | |
2124 | + DEREF(s); | |
2125 | ||
2126 | - if ((t->flags & NUMCUR) != 0) | |
2127 | - goto set_how_many; | |
2128 | + *num_matches = matches; | |
2129 | + if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL) | |
2130 | + efree(buf); | |
2131 | ||
2132 | - how_many = 1; | |
2133 | + if (flags & GENSUB) { | |
2134 | + if (matches > 0) { | |
2135 | + /* return the result string */ | |
2136 | + DEREF(t); | |
2137 | + return make_str_node(buf, textlen, ALREADY_MALLOCED); | |
2138 | } | |
2139 | - } else { | |
2140 | - d = force_number(t); | |
2141 | -set_how_many: | |
2142 | - if (d < 1) | |
2143 | - how_many = 1; | |
2144 | - else if (d < LONG_MAX) | |
2145 | - how_many = d; | |
2146 | - else | |
2147 | - how_many = LONG_MAX; | |
2148 | - if (d == 0) | |
2149 | - warning(_("gensub: third argument of 0 treated as 1")); | |
2150 | - } | |
2151 | - | |
2152 | - DEREF(t); | |
2153 | ||
2154 | - ret = sub_common(3, how_many, TRUE); | |
2155 | - unref(ret); | |
2156 | + /* return the original string */ | |
2157 | + return t; | |
2158 | + } | |
2159 | ||
2160 | - /* | |
2161 | - * Note that we don't care what sub_common() returns, since the | |
2162 | - * easiest thing for the programmer is to return the string, even | |
2163 | - * if no substitutions were done. | |
2164 | - */ | |
2165 | + /* For a string literal, must not change the original string. */ | |
2166 | + if (flags & LITERAL) | |
2167 | + DEREF(t); | |
2168 | + else if (matches > 0) { | |
2169 | + unref(*lhs); | |
2170 | + *lhs = make_str_node(buf, textlen, ALREADY_MALLOCED); | |
2171 | + } | |
2172 | ||
2173 | - return target; | |
2174 | + return make_number((AWKNUM) matches); | |
2175 | } | |
2176 | ||
2177 | + | |
2178 | /* make_integer - Convert an integer to a number node. */ | |
2179 | ||
2180 | static NODE * | |
2181 | diff --git a/debug.c b/debug.c | |
2182 | index 9b9db34..404042c 100644 | |
2183 | --- a/debug.c | |
2184 | +++ b/debug.c | |
2185 | @@ -3740,7 +3740,16 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) | |
2186 | break; | |
2187 | ||
2188 | case Op_var_assign: | |
2189 | - print_func(fp, "[set_%s]\n", pc->memory->vname); | |
2190 | + if (pc->assign_var) | |
2191 | + print_func(fp, "[set_%s()]", pc->memory->vname); | |
2192 | + print_func(fp, "\n"); | |
2193 | + break; | |
2194 | + | |
2195 | + case Op_field_assign: | |
2196 | + if (pc->field_assign) | |
2197 | + print_func(fp, "[%s]", pc->field_assign == reset_record ? | |
2198 | + "reset_record()" : "invalidate_field0()"); | |
2199 | + print_func(fp, "\n"); | |
2200 | break; | |
2201 | ||
2202 | case Op_field_spec_lhs: | |
2203 | @@ -3830,6 +3839,27 @@ print_instruction(INSTRUCTION *pc, Func_print print_func, FILE *fp, int in_dump) | |
2204 | pc->line_range, pc->target_jmp); | |
2205 | break; | |
2206 | ||
2207 | + case Op_sub_builtin: | |
2208 | + { | |
2209 | + const char *fname = "sub"; | |
2210 | + static const struct flagtab values[] = { | |
2211 | + { GSUB, "GSUB" }, | |
2212 | + { GENSUB, "GENSUB" }, | |
2213 | + { AFTER_ASSIGN, "AFTER_ASSIGN" }, | |
2214 | + { LITERAL, "LITERAL" }, | |
2215 | + { 0, NULL } | |
2216 | + }; | |
2217 | + | |
2218 | + if (pc->sub_flags & GSUB) | |
2219 | + fname = "gsub"; | |
2220 | + else if (pc->sub_flags & GENSUB) | |
2221 | + fname = "gensub"; | |
2222 | + print_func(fp, "%s [arg_count = %ld] [sub_flags = %s]\n", | |
2223 | + fname, pc->expr_count, | |
2224 | + genflags2str(pc->sub_flags, values)); | |
2225 | + } | |
2226 | + break; | |
2227 | + | |
2228 | case Op_builtin: | |
2229 | { | |
2230 | const char *fname = getfname(pc->builtin); | |
2231 | diff --git a/eval.c b/eval.c | |
2232 | index 4132474..bdbd04b 100644 | |
2233 | --- a/eval.c | |
2234 | +++ b/eval.c | |
2235 | @@ -348,6 +348,7 @@ static struct optypetab { | |
2236 | { "Op_K_getline", "getline" }, | |
2237 | { "Op_K_nextfile", "nextfile" }, | |
2238 | { "Op_builtin", NULL }, | |
2239 | + { "Op_sub_builtin", NULL }, | |
2240 | { "Op_in_array", " in " }, | |
2241 | { "Op_func_call", NULL }, | |
2242 | { "Op_indirect_func_call", NULL }, | |
2243 | @@ -2114,11 +2115,13 @@ post: | |
2244 | break; | |
2245 | ||
2246 | case Op_var_assign: | |
2247 | - pc->assign_var(); | |
2248 | + if (pc->assign_var) | |
2249 | + pc->assign_var(); | |
2250 | break; | |
2251 | ||
2252 | case Op_field_assign: | |
2253 | - pc->field_assign(); | |
2254 | + if (pc->field_assign) | |
2255 | + pc->field_assign(); | |
2256 | break; | |
2257 | ||
2258 | case Op_concat: | |
2259 | @@ -2256,7 +2259,34 @@ arrayfor: | |
2260 | #endif | |
2261 | PUSH(r); | |
2262 | break; | |
2263 | - | |
2264 | + | |
2265 | + case Op_sub_builtin: | |
2266 | + { | |
2267 | + /* sub, gsub and gensub */ | |
2268 | + | |
2269 | + int matches = 0; | |
2270 | + | |
2271 | + r = do_sub(pc->expr_count, pc->sub_flags, & matches); | |
2272 | + PUSH(r); | |
2273 | + | |
2274 | + if (matches == 0 && (pc->sub_flags & AFTER_ASSIGN) != 0) { | |
2275 | + | |
2276 | + /* For sub and gsub, must not execute after_assign code; | |
2277 | + * If the target is a FIELD, this means no field re-splitting or | |
2278 | + * $0 reconstruction. For a special variable as target, | |
2279 | + * set_XX routine is not called. | |
2280 | + */ | |
2281 | + | |
2282 | + ni = pc->nexti; | |
2283 | + assert(ni->opcode == Op_field_assign || ni->opcode == Op_var_assign); | |
2284 | + if (ni->opcode == Op_field_assign) | |
2285 | + ni->field_assign = (Func_ptr) 0; | |
2286 | + else | |
2287 | + ni->assign_var = (Func_ptr) 0; | |
2288 | + } | |
2289 | + } | |
2290 | + break; | |
2291 | + | |
2292 | case Op_K_print: | |
2293 | do_print(pc->expr_count, pc->redir_type); | |
2294 | break; | |
2295 | diff --git a/profile.c b/profile.c | |
2296 | index cba8be9..01d1e42 100644 | |
2297 | --- a/profile.c | |
2298 | +++ b/profile.c | |
2299 | @@ -507,6 +507,20 @@ cleanup: | |
2300 | case Op_after_endfile: | |
2301 | break; | |
2302 | ||
2303 | + case Op_sub_builtin: | |
2304 | + { | |
2305 | + const char *fname = "sub"; | |
2306 | + if (pc->sub_flags & GSUB) | |
2307 | + fname = "gsub"; | |
2308 | + else if (pc->sub_flags & GENSUB) | |
2309 | + fname = "gensub"; | |
2310 | + tmp = pp_list(pc->expr_count, "()", ", "); | |
2311 | + str = pp_concat(fname, tmp, ""); | |
2312 | + efree(tmp); | |
2313 | + pp_push(Op_sub_builtin, str, CAN_FREE); | |
2314 | + } | |
2315 | + break; | |
2316 | + | |
2317 | case Op_builtin: | |
2318 | { | |
2319 | static char *ext_func = "extension_function()"; |