1 /*------------------------------------------------------------*
2 | preprocess.c |
3 | copyright 1999, Andrew Sumner (andrewsumner@yahoo.com) |
4 | |
5 | This is a source file for the awka package, a translator |
6 | of the AWK programming language to ANSI C. |
7 | |
8 | This program is free software; you can redistribute it |
9 | and/or modify it under the terms of the GNU General Public |
10 | License as published by the Free Software Foundation; |
11 | either version 2 of the License, or any later version. |
12 | |
13 | This program is distributed in the hope that it will be |
14 | useful, but WITHOUT ANY WARRANTY; without even the implied |
15 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
16 | PURPOSE. See the GNU General Public License for more |
17 | details. |
18 | |
19 | You should have received a copy of the GNU General Public |
20 | License along with this program; if not, write to the |
21 | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, |
22 | MA 02139, USA. |
23 *------------------------------------------------------------*/
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <limits.h>
30
31 #include <stdarg.h>
32 #include "awka.h"
33 #include "msg.h"
34 #include "../config.h"
35 #include "mem.h"
36 #include "memory.h"
37 #include "awka_exe.h"
38
39 extern struct ivar_idx ivar[];
40 extern int indent;
41 extern int split_req, split_max, mode, dol0_used;
42 extern int var_allc, var_used;
43 extern int lvar_allc, lvar_used;
44 extern int litr_allc, litr_used;
45 extern int lits_allc, lits_used;
46 extern int litd_allc, litd_used;
47 extern awka_varname *varname;
48 extern char **litrname, **litsname, **litdname;
49 extern char **litr_val, **lits_val, **litd_val;
50 extern FILE *outfp;
51 extern int awka_main;
52 extern char *awka_main_func;
53 extern int cur_func;
54 extern int al_count;
55 extern int array_sort;
56 extern int range_no;
57 extern int max_call_args;
58 extern char **vardeclare;
59 extern int vdec_no;
60 extern char **functions;
61 extern int func_no;
62 char *lvar_type = NULL;
63
64 void awka_warning(char *, ...);
65 int findivar(char *);
66
67 int
is_ext_builtin(name)68 is_ext_builtin(name)
69 char *name;
70 {
71 struct a_sc *fp;
72
73 fp = ext_funcs;
74 while (fp->name)
75 {
76 if (!strcmp(fp->name, name))
77 return 1;
78 fp++;
79 }
80
81 return 0;
82 }
83
84 void
moveprog(int k,int i)85 moveprog(int k, int i)
86 {
87 progcode[i].op = progcode[k].op;
88 progcode[i].pop = progcode[k].pop;
89 progcode[i].func = progcode[k].func;
90 progcode[i].val = progcode[k].val;
91 progcode[i].arg = progcode[k].arg;
92 progcode[i].minst = progcode[k].minst;
93 progcode[i].inst = progcode[k].inst;
94 progcode[i].line = progcode[k].line;
95 progcode[i].jumpfrom = progcode[k].jumpfrom;
96 progcode[i].jumpto = progcode[k].jumpto;
97 progcode[i].earliest = progcode[k].earliest;
98 progcode[i].done = progcode[k].done;
99 progcode[i].endloop = progcode[k].endloop;
100 progcode[i].doloop = progcode[k].doloop;
101 progcode[i].context = progcode[k].context;
102 progcode[i].label = progcode[k].label;
103 progcode[i].varidx = progcode[k].varidx;
104 progcode[i].ftype = progcode[k].ftype;
105 progcode[i].file = progcode[k].file;
106 }
107
108 int
findvarname(awka_varname * vname,char * name,int used)109 findvarname(awka_varname *vname, char *name, int used)
110 {
111 int i;
112
113 if (!vname) return -1;
114 for (i=0; i<used; i++)
115 if (!strcmp(vname[i].name, name))
116 return i;
117 return -1;
118 }
119
120 void
initlvartypes()121 initlvartypes()
122 {
123 int i;
124
125 if (!lvar_type)
126 lvar_type = (char *) malloc(128);
127 memset(lvar_type, _VALTYPE_UNK, 128);
128 }
129
130 void
setlvartype(int idx,char flag)131 setlvartype(int idx, char flag)
132 {
133 if (idx > 127) return;
134
135 lvar_type[idx] = flag;
136 }
137
138 int
getlvartype(int idx)139 getlvartype(int idx)
140 {
141 if (idx > 127) return _VALTYPE_UNK;
142 return (int) lvar_type[idx];
143 }
144
145 int
findvaltype(char * name)146 findvaltype(char *name)
147 {
148 int i;
149
150 if (!strncmp(name, "_litd", 5))
151 return _VALTYPE_NUM;
152
153 if (!strncmp(name, "_lits", 5))
154 return _VALTYPE_STR;
155
156 if (!strncmp(name, "_lvar[", 6))
157 return getlvartype(atoi(name+6));
158
159 if (!strcmp(name, "a_bivar[a_NF]") ||
160 !strcmp(name, "a_bivar[a_NR]") ||
161 !strcmp(name, "awka_NFget()"))
162 return _VALTYPE_NUM;
163
164 if ((i = findvarname(varname, name, var_used)) == -1)
165 return _VALTYPE_UNK;
166
167 if (varname[i].valtype == _VALTYPE_UNK ||
168 varname[i].valtype >= _VALTYPE_NUM + _VALTYPE_STR)
169 return _VALTYPE_UNK;
170
171 return varname[i].valtype;
172 }
173
174 char *
getstringvalue(char * name)175 getstringvalue(char *name)
176 {
177 int i;
178 char *p = name, *buf;
179 static char *buf1 = NULL, *buf2 = NULL;
180 static int alloc = 0;
181 static char last = 0;
182
183 if (!strncmp(name, "_lits", 5))
184 {
185 i = atoi(name+5);
186 p = lits_val[i];
187 }
188
189 i = strlen(p);
190 if (alloc == 0)
191 {
192 alloc = i + 6;
193 alloc += 16 - (alloc % 16);
194 buf1 = (char *) malloc(alloc);
195 buf2 = (char *) malloc(alloc);
196 }
197 else if ((i+6) >= alloc)
198 {
199 alloc = i + 6;
200 alloc += 16 - (alloc % 16);
201 buf1 = (char *) realloc(buf1, alloc);
202 buf2 = (char *) realloc(buf2, alloc);
203 }
204
205 if (last == 0)
206 {
207 buf = buf1;
208 last = 1;
209 }
210 else
211 {
212 buf = buf2;
213 last = 0;
214 }
215
216 if (p == name)
217 sprintf(buf, "%s->ptr", p);
218 else
219 sprintf(buf, "\"%s\"", p);
220 return buf;
221 }
222
223 char *
getdoublevalue(char * name)224 getdoublevalue(char *name)
225 {
226 int i;
227 char *p, *buf;
228 static char *buf1 = NULL, *buf2 = NULL;
229 static int alloc = 0;
230 static char last = 0;
231
232 if (!strncmp(name, "_litd", 5))
233 {
234 i = atoi(name+5);
235 if (i < litd_used && i >= 0)
236 return litd_val[i];
237 }
238
239 i = strlen(name);
240 if (alloc == 0)
241 {
242 alloc = i + 7;
243 alloc += 16 - (alloc % 16);
244 buf1 = (char *) malloc(alloc);
245 buf2 = (char *) malloc(alloc);
246 }
247 else if ((i+7) >= alloc)
248 {
249 alloc = i + 7;
250 alloc += 16 - (alloc % 16);
251 buf1 = (char *) realloc(buf1, alloc);
252 buf2 = (char *) realloc(buf2, alloc);
253 }
254
255 if (last == 0)
256 {
257 buf = buf1;
258 last = 1;
259 }
260 else
261 {
262 buf = buf2;
263 last = 0;
264 }
265
266 sprintf(buf, "%s->dval", name);
267 return buf;
268 }
269
270 void
setvaltype(char * name,char flag)271 setvaltype(char *name, char flag)
272 {
273 int i;
274
275 if (*name == '(' || !strncmp(name, "_lit", 4))
276 return;
277
278 if (!strncmp(name, "_lvar[", 6))
279 {
280 setlvartype(atoi(name+6), flag);
281 return;
282 }
283
284 if ((i = findvarname(varname, name, var_used)) == -1)
285 return;
286
287 varname[i].valtype |= flag;
288 }
289
290 void
setvaltype2(char * n1,char * n2)291 setvaltype2(char *n1, char *n2)
292 {
293 int i, j, type, local = -1;
294
295 if (*n2 == '(') return;
296 if (*n1 == '(' || !strncmp(n1, "_lit", 4))
297 return;
298
299 if (!strncmp(n1, "_lvar[", 6))
300 {
301 local = atoi(n1+6);
302 if (local > 127) return;
303 }
304 else if ((i = findvarname(varname, n1, var_used)) == -1)
305 return;
306 if (!strncmp(n2, "_lvar[", 6))
307 {
308 if ((type = atoi(n2+6)) > 127)
309 return;
310 type = lvar_type[type];
311 }
312 else if ((j = findvarname(varname, n2, var_used)) != -1)
313 type = varname[j].valtype;
314 else
315 return;
316
317 if (local != -1)
318 lvar_type[local] = type;
319 else
320 varname[i].valtype |= type;
321 }
322
323 void
addvarname(awka_varname ** vname,char * name,char type)324 addvarname(awka_varname **vname, char *name, char type)
325 {
326 int i = var_used;
327 awka_varname *pvname = *vname;
328
329 if (!pvname)
330 {
331 var_allc = 10;
332 pvname = (awka_varname *) malloc(var_allc * sizeof(awka_varname));
333 }
334 else if (++var_used == var_allc)
335 {
336 var_allc += 10;
337 pvname = (awka_varname *) realloc(pvname, var_allc * sizeof(awka_varname));
338 }
339 pvname[i].name = (char *) malloc(strlen(name)+1);
340 strcpy(pvname[i].name, name);
341 pvname[i].usage = (unsigned int *) malloc( 16 * sizeof(int) );
342 pvname[i].lines = (unsigned int *) malloc( 16 * sizeof(int) );
343 pvname[i].files = (char **) malloc( 16 * sizeof(char *) );
344 pvname[i].line_no = 0;
345 pvname[i].line_allc = 16;
346 pvname[i].type = _VARTYPE_G_SCALAR;
347 pvname[i].valtype = _VALTYPE_UNK;
348 fprintf(outfp, "a_VAR *%s = NULL;\n",pvname[i].name);
349 *vname = pvname;
350 }
351
352 void
laddvarname(awka_varname ** vname,char * name,char type)353 laddvarname(awka_varname **vname, char *name, char type)
354 {
355 int i = lvar_used;
356 awka_varname *pvname = *vname;
357
358 if (!pvname)
359 {
360 lvar_allc = 10;
361 pvname = (awka_varname *) malloc(lvar_allc * sizeof(awka_varname));
362 }
363 else if (++lvar_used == var_allc)
364 {
365 lvar_allc += 10;
366 pvname = (awka_varname *) realloc(pvname, lvar_allc * sizeof(awka_varname));
367 }
368 pvname[i].name = (char *) malloc(strlen(name)+1);
369 strcpy(pvname[i].name, name);
370 pvname[i].usage = (unsigned int *) malloc( 16 * sizeof(int) );
371 pvname[i].lines = (unsigned int *) malloc( 16 * sizeof(int) );
372 pvname[i].files = (char **) malloc( 16 * sizeof(char *) );
373 pvname[i].line_no = 0;
374 pvname[i].line_allc = 16;
375 pvname[i].type = _VARTYPE_G_SCALAR;
376 /*fprintf(outfp, "a_VAR *%s = NULL;\n",pvname[i].name); */
377 *vname = pvname;
378 }
379
380 void
addvarname_ref(awka_varname * vname,int i,char op,char * file,unsigned int line)381 addvarname_ref(awka_varname *vname, int i, char op, char *file, unsigned int line)
382 {
383 int j;
384 j = vname[i].line_no++;
385 if (vname[i].line_no >= vname[i].line_allc)
386 {
387 vname[i].line_allc *= 2;
388 vname[i].lines = (unsigned int *) realloc(vname[i].lines, vname[i].line_allc * sizeof(int));
389 vname[i].usage = (unsigned int *) realloc(vname[i].usage, vname[i].line_allc * sizeof(int));
390 vname[i].files = (char **) realloc(vname[i].files, vname[i].line_allc * sizeof(char *));
391 }
392 vname[i].lines[j] = line;
393 vname[i].usage[j] = op;
394 vname[i].files[j] = file;
395 }
396
397 char *
fix_litsval(char * str)398 fix_litsval( char *str )
399 {
400 static char *output = NULL;
401 char *p, *q;
402 int len;
403 static int alloc = 0;
404
405 if (!str) return "";
406 len = strlen(str);
407
408 if (!alloc)
409 {
410 output = (char *) malloc( len * 2 + 1 );
411 alloc = len * 2 + 1;
412 }
413 else if (alloc < (len * 2 + 1))
414 {
415 alloc = len * 2 + 1;
416 output = (char *) realloc( output, alloc );
417 }
418
419 p = output;
420 q = str;
421
422 while (*q) {
423 if (*q == '\r')
424 {
425 *p = '\\'; ++p;
426 *p = 'r'; ++p; ++q;
427 }
428 else
429 {
430 *p = *q;
431 p++; q++;
432 }
433 }
434 *p = '\0';
435
436 return output;
437 }
438
439 void
preprocess()440 preprocess()
441 {
442 int cur = 0;
443 int i, j, j2, j3, k, p;
444 char *x, *q;
445 int func_allc = 10;
446 struct a_sc *ebp;
447
448 functions = (char **) malloc( 10 * sizeof(char *) );
449 varname = (awka_varname *) malloc( 10 * sizeof(awka_varname) );
450 var_allc = 10;
451
452 /* PREPROCESSING - identify variables & code jumps */
453 for (cur=0; cur<prog_no; cur++)
454 {
455 switch (progcode[cur].op)
456 {
457 case _END:
458 end_used = TRUE;
459 break;
460
461 case _BEGIN:
462 begin_used = TRUE;
463 break;
464
465 case _MAIN:
466 main_used = TRUE;
467 break;
468
469 case _PUSHI:
470 if (!strcmp(progcode[cur].val, "@fs_shadow")) break;
471 if (progcode[cur].val[0] == '$')
472 {
473 progcode[cur].op = F_PUSHI;
474 progcode[cur].func = code[F_PUSHI-1].func;
475 break;
476 }
477 case A_PUSHA:
478 case AE_PUSHA:
479 case AE_PUSHI:
480 if (progcode[cur].op != _PUSHI)
481 add2arraylist(progcode[cur].val);
482 case _PUSHA:
483 if ((i = findivar(progcode[cur].val)) != -1)
484 {
485 if (!strcmp(ivar[i].vname, "a_bivar[a_ARGV]") && progcode[cur].op != AE_PUSHI)
486 {
487 progcode[cur].val = (char *) malloc(15);
488 strcpy(progcode[cur].val, "awka_argv()");
489 }
490 else
491 {
492 progcode[cur].val = (char *) malloc(strlen(ivar[i].vname)+1);
493 strcpy(progcode[cur].val, ivar[i].vname);
494 }
495 break;
496 }
497 /* adding _awk on end avoids conflicts with system defined names */
498 x = (char *) malloc(strlen(progcode[cur].val) + 6);
499 sprintf(x, "%s_awk", progcode[cur].val);
500 free(progcode[cur].val);
501 progcode[cur].val = x;
502
503 for (i=0; i<var_used; i++)
504 if (!strcmp(varname[i].name, progcode[cur].val))
505 break;
506
507 if (i == var_used)
508 addvarname(&varname, progcode[cur].val, _VARTYPE_G_SCALAR);
509 break;
510
511 case _MATCH0:
512 case _MATCH1:
513 case _PUSHC:
514 if (progcode[cur].val[0] != '0')
515 break;
516
517 for (i=0; i<litr_used; i++)
518 if (!strcmp(litr_val[i], progcode[cur].arg))
519 break;
520
521 if (i == litr_used)
522 {
523 if (litr_allc == 0)
524 {
525 litr_allc = 20;
526 litrname = (char **) malloc(20 * sizeof(char *));
527 litr_val = (char **) malloc(20 * sizeof(char *));
528 }
529 else if (litr_used == litr_allc)
530 {
531 litr_allc += 20;
532 litrname = (char **) realloc(litrname, litr_allc * sizeof(char *));
533 litr_val = (char **) realloc(litr_val, litr_allc * sizeof(char *));
534 }
535
536 litrname[i] = (char *) malloc(20);
537 sprintf(litrname[i], "_litr%d_awka", i);
538 /* litr_val[i] = progcode[cur].arg; */
539 litr_val[i] = (char *) malloc(strlen(progcode[cur].arg)*2);
540 strcpy(litr_val[i], fix_litsval(progcode[cur].arg));
541 litr_used++;
542 }
543 progcode[cur].arg = (char *) malloc(20);
544 strcpy(progcode[cur].arg, litrname[i]);
545 break;
546
547
548 case _PUSHD:
549 for (i=0; i<litd_used; i++)
550 if (!strcmp(litd_val[i], progcode[cur].val))
551 break;
552
553 if (i == litd_used)
554 {
555 if (litd_allc == 0)
556 {
557 litd_allc = 20;
558 litdname = (char **) malloc(20 * sizeof(char *));
559 litd_val = (char **) malloc(20 * sizeof(char *));
560 }
561 else if (litd_used == litd_allc)
562 {
563 litd_allc += 20;
564 litdname = (char **) realloc(litdname, litd_allc * sizeof(char *));
565 litd_val = (char **) realloc(litd_val, litd_allc * sizeof(char *));
566 }
567
568 litdname[i] = (char *) malloc(20);
569 sprintf(litdname[i], "_litd%d_awka", i);
570 litd_val[i] = (char *) malloc(strlen(progcode[cur].val)+1);
571 strcpy(litd_val[i], progcode[cur].val);
572 litd_used++;
573 }
574
575 progcode[cur].val = (char *) malloc(20);
576 strcpy(progcode[cur].val, litdname[i]);
577 break;
578
579 case _PUSHS:
580 for (i=0; i<lits_used; i++)
581 if (!strcmp(lits_val[i], progcode[cur].val))
582 break;
583
584 if (i == lits_used)
585 {
586 if (lits_allc == 0)
587 {
588 lits_allc = 20;
589 litsname = (char **) malloc(20 * sizeof(char *));
590 lits_val = (char **) malloc(20 * sizeof(char *));
591 }
592 else if (lits_used == lits_allc)
593 {
594 lits_allc += 20;
595 litsname = (char **) realloc(litsname, lits_allc * sizeof(char *));
596 lits_val = (char **) realloc(lits_val, lits_allc * sizeof(char *));
597 }
598
599 litsname[i] = (char *) malloc(20);
600 sprintf(litsname[i], "_lits%d_awka", i);
601 lits_val[i] = (char *) malloc((strlen(progcode[cur].val)*2)+1);
602 strcpy(lits_val[i], fix_litsval(progcode[cur].val));
603 lits_used++;
604 }
605
606 progcode[cur].val = (char *) malloc(20);
607 strcpy(progcode[cur].val, litsname[i]);
608 break;
609
610 case _LJNZ:
611 case _LJZ:
612 j = atoi(progcode[cur].val);
613 progcode[cur].jumpto = -1;
614 if (j > progcode[cur].minst)
615 {
616 for (i=cur+1; i<prog_no; i++)
617 {
618 if (progcode[i].minst > j ||
619 progcode[i].minst < progcode[cur].minst)
620 break;
621 if (progcode[i].minst == j)
622 {
623 progcode[i].ljumpfrom = cur;
624 progcode[cur].jumpto = i;
625 break;
626 }
627 }
628 }
629 else
630 {
631 for (i=cur-1; i>=0; i--)
632 {
633 if (progcode[i].minst < j ||
634 progcode[i].minst > progcode[cur].minst)
635 break;
636 if (progcode[i].minst == j)
637 {
638 progcode[i].ljumpfrom = cur;
639 progcode[cur].jumpto = i;
640 break;
641 }
642 }
643 }
644 if (progcode[cur].jumpto == -1)
645 awka_error("parse error: lj[n]z target not found, line %d.\n",progcode[cur].line);
646 break;
647
648 case _JMP:
649 j = atoi(progcode[cur].val);
650 progcode[cur].jumpto = -1;
651 if (j > progcode[cur].minst)
652 {
653 for (i=cur+1; i<prog_no; i++)
654 {
655 if (progcode[i].minst < progcode[cur].minst)
656 break;
657 if (progcode[i].minst >= j && progcode[i].op == _JNZ)
658 {
659 progcode[i].jumpfrom = cur;
660 progcode[i].jumpto = cur+1;
661 progcode[cur].jumpto = i;
662 break;
663 }
664 }
665 }
666 else
667 {
668 for (i=cur; i>=0; i--)
669 {
670 if (progcode[i].minst > progcode[cur].minst)
671 break;
672 if (progcode[i].minst == j)
673 {
674 progcode[i].jumpfrom = cur;
675 progcode[i].jumpto = cur+1;
676 progcode[cur].jumpto = i;
677 if (i == cur)
678 progcode[i].foreverloop = 2;
679 else
680 {
681 progcode[i].foreverloop = 1;
682 progcode[cur].endloop++;
683 }
684 break;
685 }
686 }
687 }
688 if (progcode[cur].jumpto == -1 && progcode[cur].op == _JMP)
689 awka_error("parse error: jmp target not found, line %d.\n",progcode[cur].line);
690 break;
691
692 case SET_ALOOP:
693 case _JZ:
694 case _QMARK:
695 j = atoi(progcode[cur].val);
696 progcode[cur].jumpto = -1;
697 if (j > progcode[cur].minst)
698 {
699 for (i=cur+1; i<prog_no; i++)
700 {
701 if (progcode[i].minst > j ||
702 progcode[i].minst < progcode[cur].minst)
703 break;
704 if (progcode[i].minst == j)
705 {
706 progcode[cur].jumpto = i;
707 if (progcode[cur].op != _QMARK)
708 progcode[i].endloop++;
709 break;
710 }
711 }
712 }
713 else
714 {
715 for (i=cur-1; i>=0; i--)
716 {
717 if (progcode[i].minst < j ||
718 progcode[i].minst > progcode[cur].minst)
719 break;
720 if (progcode[i].minst == j)
721 {
722 progcode[cur].jumpto = i;
723 if (progcode[cur].op != _QMARK)
724 progcode[i].endloop++;
725 break;
726 }
727 }
728 }
729 if (progcode[cur].jumpto == -1)
730 awka_error("parse error: set_al/jz/qmark target not found, line %d.\n",progcode[cur].line);
731 if (progcode[cur].op != SET_ALOOP)
732 {
733 if (progcode[cur].op == _QMARK)
734 {
735 j = atoi(progcode[i-1].val);
736 k = progcode[i-1].minst;
737 for (p=i; p<prog_no; p++)
738 {
739 if (progcode[p].minst > j ||
740 progcode[p].minst < k)
741 break;
742 if (progcode[p].minst == j)
743 {
744 for (k=i; k<p; k++)
745 moveprog(k, k-1);
746 k--;
747 progcode[k].op = _COLON;
748 progcode[k].func = code[_COLON-1].func;
749 break;
750 }
751 }
752 }
753 else if (progcode[i-1].op == _ELSE)
754 {
755 /* wimping out of a proper method */
756 progcode[i-1].op = _GOTO;
757 progcode[i-1].func = code[_GOTO-1].func;
758 }
759 progcode[cur].jumpto = -1;
760 }
761 break;
762
763 case _JNZ:
764 /* a while or a do/while statement */
765 j = atoi(progcode[cur].val);
766 if (progcode[cur].jumpto == -1 || progcode[cur].jumpfrom == -1)
767 {
768 progcode[cur].jumpto = -1;
769 if (j > progcode[cur].minst)
770 {
771 for (i=cur+1; i<prog_no; i++)
772 {
773 if (progcode[i].minst > j ||
774 progcode[i].minst < progcode[cur].minst)
775 break;
776 if (progcode[i].minst == j)
777 {
778 progcode[cur].jumpto = i;
779 break;
780 }
781 }
782 }
783 else
784 {
785 for (i=cur-1; i>=0; i--)
786 {
787 if (progcode[i].minst < j ||
788 progcode[i].minst > progcode[cur].minst)
789 break;
790 if (progcode[i].minst == j)
791 {
792 progcode[cur].jumpto = i;
793 break;
794 }
795 }
796 }
797 if (progcode[cur].jumpto == -1)
798 awka_error("parse error: jnz target not found, line %d.\n",progcode[cur].line);
799 /* progcode[cur].jumpto = -1; */
800 if (cur > 0)
801 if (progcode[cur-1].op == _JMP)
802 break; /* while loop */
803 progcode[i].doloop = TRUE;
804 }
805 break;
806
807 case _GOTO:
808 j = atoi(progcode[cur].val);
809 if (j > progcode[cur].minst)
810 {
811 for (i=cur+1; i<prog_no; i++)
812 {
813 if (progcode[i].minst > j ||
814 progcode[i].minst < progcode[cur].minst)
815 break;
816 if (progcode[i].minst == j)
817 {
818 progcode[i].label = TRUE;
819 break;
820 }
821 }
822 }
823 else
824 {
825 for (i=cur-1; i>=0; i--)
826 {
827 if (progcode[i].minst < j ||
828 progcode[i].minst > progcode[cur].minst)
829 break;
830 if (progcode[i].minst == j)
831 {
832 progcode[i].label = TRUE;
833 break;
834 }
835 }
836 }
837 break;
838
839 case _CALL:
840 i = strlen(progcode[cur].val);
841 if (progcode[cur].val[i-1] == '(')
842 progcode[cur].val[i-1] = '\0';
843 j = atoi(progcode[cur].arg);
844 max_call_args = (max_call_args > j ? max_call_args : j);
845 break;
846
847 case _FUNCTION:
848 i = strlen(progcode[cur].val);
849 if (progcode[cur].val[i-1] == '(')
850 progcode[cur].val[i-1] = '\0';
851 for (i=0; i<func_no; i++)
852 if (!strcmp(functions[i], progcode[cur].val))
853 break;
854
855 if (i == func_no)
856 {
857 if (func_no == func_allc)
858 {
859 func_allc *= 2;
860 functions = (char **) realloc(functions, func_allc * sizeof(char *));
861 }
862 functions[i] = (char *) malloc(strlen(progcode[cur].val)+1);
863 strcpy(functions[i], progcode[cur].val);
864 func_no++;
865 }
866 break;
867 }
868
869 }
870
871 /* another pass to decide whether calls are to functions or to
872 extended builtins. */
873 for (cur=0; cur<prog_no; cur++)
874 {
875 /* find extended builtins & see if the're locals */
876 for (ebp = ext_funcs; ebp->name != NULL; ebp++)
877 if (ebp->op == progcode[cur].op)
878 break;
879
880 if (ebp->name)
881 {
882 for (i=0; i<func_no; i++)
883 if (!strcmp(functions[i], ebp->name))
884 break;
885
886 if (i < func_no)
887 {
888 progcode[cur].func = awka_call;
889 progcode[cur].op = _CALL;
890 progcode[cur].pop = FALSE;
891 progcode[cur].val = functions[i];
892 if (cur == 0 || progcode[cur-1].inst != _PUSHINT)
893 {
894 progcode[cur].arg = (char *) malloc(20);
895 sprintf(progcode[cur].arg, "%d", _a_bi_vararg[progcode[cur].varidx].min_args);
896 }
897 progcode[cur].varidx = -1;
898 }
899 continue;
900 }
901
902 /* find locals & see if the're extended builtins */
903 if (progcode[cur].op == _CALL)
904 {
905 for (i=0; i<func_no; i++)
906 if (!strcmp(functions[i], progcode[cur].val))
907 break;
908
909 if (i == func_no)
910 {
911 /* local definition don't exist - is it an extended func? */
912 for (ebp = ext_funcs; ebp->name != NULL; ebp++)
913 if (!strcmp(progcode[cur].val, ebp->name))
914 {
915 progcode[cur].op = ebp->op;
916 progcode[cur].varidx = code[ebp->op-1].varidx;
917 progcode[cur].pop = code[ebp->op-1].pop;
918 progcode[cur].func = code[ebp->op-1].func;
919 break;
920 }
921 }
922 }
923
924 }
925
926 /* set up range patterns */
927 for (cur=prog_no-1; cur>=0; cur--)
928 {
929 if (progcode[cur].op == _RANGE)
930 {
931 j = atoi(progcode[cur].val);
932 k = progcode[cur].endloop;
933 q = progcode[cur].val;
934 while (*q && *q != ' ') q++;
935 if (!(*q))
936 awka_error("parse error: range value not set correctly, line %d.\n",progcode[cur].line);
937 j2 = atoi(++q);
938 while (*q && *q != ' ') q++;
939 if (!(*q))
940 awka_error("parse error: range value not set correctly, line %d.\n",progcode[cur].line);
941 j3 = atoi(q);
942
943 /* find end of patterns */
944 for (i=cur+1; i<prog_no; i++)
945 {
946 if (progcode[i].minst > j2)
947 awka_error("parse error: can't find range target (1), line %d.\n", progcode[cur].line);
948 if (progcode[i].minst == j2)
949 break;
950 }
951 if (i == prog_no)
952 awka_error("parse error: can't find range target (2), line %d.\n", progcode[cur].line);
953 j2 = i-1;
954
955 /* find jumpto opcode */
956 for (i=j2+1; i<prog_no; i++)
957 {
958 if (progcode[i].minst > j3)
959 awka_error("parse error: can't find range target (3), line %d.\n", progcode[cur].line);
960 if (progcode[i].minst == j3)
961 break;
962 }
963 if (i == prog_no)
964 awka_error("parse error: can't find range target (4), line %d.\n", progcode[cur].line);
965 j3 = i;
966 progcode[i].label = TRUE;
967 progcode[cur+1].label = progcode[cur].label;
968 progcode[cur+1].minst = progcode[cur].minst;
969
970 /* move range opcode to end of patterns */
971 for (i=cur+1; i<=j2; i++)
972 moveprog(i, i-1);
973 progcode[--i].op = _RANGE;
974 progcode[i].val = (char *) malloc(20);
975 sprintf(progcode[i].val, "%d", progcode[j3].minst);
976 progcode[i].arg = NULL;
977 progcode[i].func = awka_range;
978 progcode[i].jumpto = j3;
979 progcode[i].endloop = k;
980 }
981 }
982
983 if (warning_msg & MSG_VARDECLARE)
984 {
985 for (i=0; i<var_used; i++)
986 {
987 for (j=0; j<vdec_no; j++)
988 if (!strcmp(varname[i].name, vardeclare[j]))
989 break;
990 if (j == vdec_no)
991 awka_warning("global variable '%s' not declared in VDECL comment.\n",varname[i].name);
992 }
993 }
994
995 fprintf(outfp, "\nstruct gvar_struct *_gvar;\n");
996 fprintf(outfp, "\na_VAR **_lvar;\n");
997
998 if (litd_used)
999 {
1000 fprintf(outfp, "a_VAR *_litd0_awka=NULL");
1001 for (i=1; i<litd_used; i++)
1002 fprintf(outfp, ", *_litd%d_awka=NULL",i);
1003 fprintf(outfp, ";\n");
1004 }
1005
1006 if (lits_used)
1007 {
1008 fprintf(outfp, "a_VAR *_lits0_awka=NULL");
1009 for (i=1; i<lits_used; i++)
1010 fprintf(outfp, ", *_lits%d_awka=NULL",i);
1011 fprintf(outfp, ";\n");
1012 }
1013
1014 if (litr_used)
1015 {
1016 fprintf(outfp, "a_VAR *_litr0_awka=NULL");
1017 for (i=1; i<litr_used; i++)
1018 fprintf(outfp, ", *_litr%d_awka=NULL",i);
1019 fprintf(outfp, ";\n");
1020 }
1021
1022 for (i=0; i<func_no; i++)
1023 fprintf(outfp, "a_VAR * %s_fn(a_VARARG *);\n",functions[i]);
1024 if (begin_used)
1025 fprintf(outfp, "void BEGIN();\n");
1026 if (main_used)
1027 fprintf(outfp, "void MAIN();\n");
1028 if (end_used)
1029 fprintf(outfp, "void END();\n");
1030 }
1031
1032