1 /*
2  * $Id: byte-compile.c,v 1.12 2000/11/22 19:33:00 danny Exp $
3  *
4  * Copyright � 1990, 1992, 1993 Free Software Foundation, Inc.
5  *
6  * This file is part of Oleo, the GNU Spreadsheet.
7  *
8  * Oleo is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * Oleo is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Oleo; see the file COPYING.  If not, write to
20  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #ifdef	WITH_DMALLOC
28 #include <dmalloc.h>
29 #endif
30 
31 /* FIXME #include "funcdef.h" */
32 #include <stdio.h>
33 
34 #include "sysdef.h"
35 
36 #ifdef	HAVE_MALLOC_H
37 #include <malloc.h>
38 #endif
39 
40 #ifdef _DEBUG_MALLOC_INC
41 static void
local_free(p)42 local_free (p)
43      void * p;
44 {
45   free (p);
46 }
47 #define obstack_chunk_free local_free
48 #else /* ndef _DEBUG_MALLOC_INC */
49 #define obstack_chunk_free free
50 #endif /* ndef _DEBUG_MALLOC_INC */
51 
52 #define obstack_chunk_alloc ck_malloc
53 #include "obstack.h"
54 
55 #include "global.h"
56 #include "node.h"
57 #include "eval.h"
58 #include "hash.h"
59 #include "ref.h"
60 
61 extern int yyparse (void);
62 
63 extern struct function date_funs[];
64 extern struct function busi_funs[];
65 extern struct function string_funs[];
66 extern struct function cells_funs[];
67 extern struct function mysql_functions[];
68 extern struct function gsl_functions[];
69 
70 extern char *instr;
71 extern int parse_error;
72 extern struct node *parse_return;
73 extern void sort ();
74 
75 static void add_backpatch (unsigned, unsigned);
76 
77 struct backpatch
78   {
79     unsigned from, to;
80   };
81 
82 static struct backpatch *patches;
83 static int patches_allocated;
84 static int patches_used;
85 static void *fn_stack;
86 static void *str_stack;
87 struct obstack tmp_mem;
88 void *tmp_mem_start;
89 
90 
91 #define V (void(*)())
92 
93 /* These have to go in some file or other, so it is stuck in here (for now).
94  */
95 struct function the_funs[] =
96 {
97   {0, X_A0, "", 0, "<END>"},
98   {0, X_A0, "", 0, "<DUMMY1>"},
99 
100   {C_IF | R | INF (1), X_A1 | X_J, "D", 0, "?"},
101   {C_IF | R | INF (1), X_A1 | X_JL, "D", 0, "?"},
102   {C_IF, X_A1 | X_J, "D", 0, "if"},
103   {C_IF, X_A1 | X_JL, "D", 0, "if"},
104   {C_ANDOR, X_A1 | X_J, "D", 0, "and"},
105 /* { C_ANDOR|L|INF(3), X_A1, "DD", 0,		"&" }, */
106   {C_ANDOR, X_A1 | X_JL, "D", 0, "and"},
107 /* { C_ANDOR|L|INF(3), X_A1, "DD", 0,		"&" }, */
108   {C_ANDOR, X_A1 | X_J, "D", 0, "or"},
109 /* { C_ANDOR|L|INF(2), X_A1, "DD", 0,		"|" }, */
110   {C_ANDOR, X_A1 | X_JL, "D", 0, "or"},
111 /* { C_ANDOR|L|INF(2), X_A1, "DD", 0,		"|" }, */
112   {C_STR, X_A0 | X_J, "", 0, "\"%s\""},
113   {C_STR, X_A0 | X_JL, "", 0, "\"%s\""},
114 
115   {C_CELL, X_A0, "", 0, "$%s$%u"},
116   {C_CELL, X_A0, "", 0, "$%s%u"},
117   {C_CELL, X_A0, "", 0, "%s$%u"},
118   {C_CELL, X_A0, "", 0, "%s%u"},
119   {C_RANGE, X_A0, "", 0, "$%s$%u:$%s$%u"},
120   {C_RANGE, X_A0, "", 0, "$%s%u:$%s$%u"},
121   {C_RANGE, X_A0, "", 0, "$%s$%u:$%s%u"},
122   {C_RANGE, X_A0, "", 0, "$%s%u:$%s%u"},
123   {C_RANGE, X_A0, "", 0, "%s$%u:$%s$%u"},
124   {C_RANGE, X_A0, "", 0, "%s%u:$%s$%u"},
125   {C_RANGE, X_A0, "", 0, "%s$%u:$%s%u"},
126   {C_RANGE, X_A0, "", 0, "%s%u:$%s%u"},
127   {C_RANGE, X_A0, "", 0, "$%s$%u:%s$%u"},
128   {C_RANGE, X_A0, "", 0, "$%s%u:%s$%u"},
129   {C_RANGE, X_A0, "", 0, "$%s$%u:%s%u"},
130   {C_RANGE, X_A0, "", 0, "$%s%u:%s%u"},
131   {C_RANGE, X_A0, "", 0, "%s$%u:%s$%u"},
132   {C_RANGE, X_A0, "", 0, "%s%u:%s$%u"},
133   {C_RANGE, X_A0, "", 0, "%s$%u:%s%u"},
134   {C_RANGE, X_A0, "", 0, "%s%u:%s%u"},
135 
136   {C_CONST, X_A0, "", 0, tname},
137   {C_CONST, X_A0, "", 0, fname},
138 
139   {C_CONST, X_A0, "", 0, iname},
140   {C_CONST, X_A0, "", 0, mname},
141   {C_CONST, X_A0, "", 0, nname},
142   {C_ERR, X_A0 | X_J, "", 0, "%s"},
143   {C_FLT, X_A0, "", 0, "%.15g"},
144   {C_INT, X_A0, "", 0, "%ld"},
145 
146   {C_VAR, X_A0, "", 0, "%s"},
147 
148   {C_UNA, X_A1, "F", 0, "-"},
149   {C_UNA, X_A1, "B", 0, "!"},
150 
151   {C_INF | L | INF (6), X_A2, "NN", 0, "-"},
152   {C_INF | L | INF (7), X_A2, "NN", 0, "/"},
153   {C_INF | L | INF (7), X_A2, "NN", 0, "%"},
154   {C_INF | L | INF (7), X_A2, "NN", 0, "*"},
155   {C_INF | L | INF (6), X_A2, "NN", 0, "+"},
156   {C_INF | L | INF (2), X_A2, "SS", 0, "&"},
157   {C_INF | N | INF (4), X_A2, "AA", 0, "="},
158   {C_INF | N | INF (5), X_A2, "AA", 0, ">="},
159   {C_INF | N | INF (5), X_A2, "AA", 0, ">"},
160   {C_INF | N | INF (5), X_A2, "AA", 0, "<"},
161   {C_INF | N | INF (5), X_A2, "AA", 0, "<="},
162   {C_INF | N | INF (4), X_A2, "AA", 0, "!="},
163   {C_INF | R | INF (8), X_A2, "FF", V pow, "^"},
164 
165   {C_FN0, X_A0, "", 0, "pi"},
166   {C_FN0X, X_A0, "", 0, "row"},
167   {C_FN0X, X_A0, "", 0, "col"},
168   {C_FN0 | C_T, X_A0, "", 0, "now"},
169 
170   {C_FN1, X_A1, "F", V fabs, "abs"},
171   {C_FN1, X_A1, "F", V acos, "acos"},
172   {C_FN1, X_A1, "F", V asin, "asin"},
173   {C_FN1, X_A1, "F", V atan, "atan"},
174   {C_FN1, X_A1, "F", V ceil, "ceil"},
175   {C_FN1, X_A1, "F", V to_int, "int"},
176   {C_FN1, X_A1, "F", V floor, "floor"},
177   {C_FN1, X_A1, "F", V cos, "cos"},
178   {C_FN1, X_A1, "F", V dtr, "dtr"},
179   {C_FN1, X_A1, "F", V exp, "exp"},
180   {C_FN1, X_A1, "F", V log, "log"},
181   {C_FN1, X_A1, "F", V log10, "log10"},
182   {C_FN1, X_A1, "F", V rtd, "rtd"},
183   {C_FN1, X_A1, "F", V sin, "sin"},
184   {C_FN1, X_A1, "F", V sqrt, "sqrt"},
185   {C_FN1, X_A1, "F", V tan, "tan"},
186   {C_FN1, X_A1, "I", 0, "ctime"},
187   {C_FN1, X_A1, "A", 0, "negate"},
188   {C_FN1, X_A1, "A", 0, "not"},
189   {C_FN1, X_A1, "A", 0, "iserr"},
190   {C_FN1, X_A1, "A", 0, "isnum"},
191 
192   {C_FN1 | C_T, X_A1, "I", 0, "rnd"},
193   {C_FN1, X_A1, "R", 0, "rows"},
194   {C_FN1, X_A1, "R", 0, "cols"},
195   {C_FN2, X_A2, "FF", V atan2, "atan2"},
196 #ifdef HAVE_HYPOT
197   {C_FN2, X_A2, "FF", V hypot, "hypot"},
198 #else
199   {C_FN2, X_A2, "FF", 0, "*&%$%*"},
200 #endif
201   {C_FN2, X_A2, "FI", 0, "fixed"},
202   {C_FN2, X_A2, "AA", 0, "iferr"},
203   {C_FN2, X_A2, "RI", 0, "index"},
204   {C_FN3, X_A3, "RII", 0, "index"},
205   {C_FNN, X_AN, "IAAA", 0, "oneof"},
206 
207   {C_FNN, X_AN, "SIIA", 0, "file"},
208   {C_FNN, X_AN, "EEEE", 0, "sum"},
209   {C_FNN, X_AN, "EEEE", 0, "prod"},
210   {C_FNN, X_AN, "EEEE", 0, "avg"},
211   {C_FNN, X_AN, "EEEE", 0, "std"},
212   {C_FNN, X_AN, "EEEE", 0, "max"},
213   {C_FNN, X_AN, "EEEE", 0, "min"},
214   {C_FNN, X_AN, "EEEE", 0, "count"},
215   {C_FNN, X_AN, "EEEE", 0, "var"},
216 
217 };
218 
219 /*
220  * This is the place where you can add extra functions
221  */
222 static struct function *__usr_funs[] =
223 {
224 	date_funs,
225 	busi_funs,
226 	string_funs,
227 	cells_funs,
228 	mysql_functions,
229 	gsl_functions,
230 	/* Add something here */
231 };
232 
233 /*
234  * A small function in each module tells us how many functions
235  * it defines.
236  */
237 extern int init_date_function_count(void);
238 extern int init_busi_function_count(void);
239 extern int init_string_function_count(void);
240 extern int init_cells_function_count(void);
241 extern int init_mysql_function_count(void);
242 extern int init_gsl_function_count(void);
243 /* Add something here */
244 
245 typedef int (*init_function_count)(void);
246 
247 static init_function_count init_function_counts[] = {
248 	&init_date_function_count,
249 	&init_busi_function_count,
250 	&init_string_function_count,
251 	&init_cells_function_count,
252 	&init_mysql_function_count,
253 	&init_gsl_function_count
254 	/* Add something here */
255 };
256 
257 /* Determine how many groups of functions we have */
258 int n_usr_funs = sizeof(init_function_counts) / sizeof(init_function_count);
259 
260 /*
261  * This is an array containing the number of functions in each group.
262  * It is allocated and initialised in init_mem() below.
263  * Previous versions of Oleo required manual maintenance of this.
264  */
265 int *usr_n_funs = NULL;
266 
267 struct function **usr_funs = __usr_funs;
268 
269 /* ... A whole huge empty space, then ... */
270 struct function skip_funs[] =
271 {
272   {C_SKIP, X_A0 | X_J, "", 0, "<Skip %u>"},
273   {C_SKIP, X_A0 | X_JL, "", 0, "<SkipL %u>"},
274 };
275 
276 /* The memory allocated here is used for several things, but byte_compile
277    is a small file, so it might as well be here */
278 void
init_mem()279 init_mem ()
280 {
281   int n, i;
282 
283   /* Initialise counters */
284   usr_n_funs = (int *)calloc(n_usr_funs, sizeof(int));
285   for (i=0; i<n_usr_funs; i++)
286     usr_n_funs[i] = init_function_counts[i]();
287 
288   parse_hash = hash_new ();
289   hash_insert (parse_hash, the_funs[F_IF].fn_str, &the_funs[F_IF]);
290   hash_insert (parse_hash, the_funs[AND].fn_str, &the_funs[AND]);
291   hash_insert (parse_hash, the_funs[OR].fn_str, &the_funs[OR]);
292   for (n = F_PI; n < USR1; n++)
293     hash_insert (parse_hash, the_funs[n].fn_str, &the_funs[n]);
294 
295   for (n = 0; n < n_usr_funs; n++)
296     {
297       int nn;
298 
299       for (nn = 0; usr_funs[n][nn].fn_str; nn++)
300 	hash_insert (parse_hash, usr_funs[n][nn].fn_str, &usr_funs[n][nn]);
301 #ifdef TEST
302       if (usr_n_funs[n] != nn)
303 	{
304 	  fprintf (stderr, "Usr_n_funs[%d]%d!=%d", n, usr_n_funs[n], nn);
305 	  usr_n_funs[n] = nn;
306 
307 	}
308 #endif
309     }
310 
311   fn_stack = init_stack ();
312   str_stack = init_stack ();
313   obstack_begin (&tmp_mem, 400);
314   tmp_mem_start = obstack_alloc (&tmp_mem, 0);
315 }
316 
317 /* Stash away a backpatch for future editing. */
318 static void
add_backpatch(from,to)319 add_backpatch (from, to)
320      unsigned from;
321      unsigned to;
322 {
323   if (!patches)
324     {
325       patches_allocated = 5;
326       patches = (struct backpatch *) ck_malloc (patches_allocated * sizeof (struct backpatch));
327       patches_used = 0;
328     }
329   if (patches_allocated == patches_used)
330     {
331       patches_allocated *= 2;
332       patches = (struct backpatch *) ck_realloc (patches, patches_allocated * sizeof (struct backpatch));
333     }
334   patches[patches_used].from = from;
335   patches[patches_used].to = to;
336   patches_used++;
337 }
338 
339 static int
cmp_patch(n1,n2)340 cmp_patch (n1, n2)
341      int n1;
342      int n2;
343 {
344   int ret;
345 
346   ret = (patches[n1].from == patches[n2].from) ? patches[n1].to - patches[n2].to : patches[n1].from - patches[n2].from;
347   return ret;
348 }
349 
350 static void
swp_patch(n1,n2)351 swp_patch (n1, n2)
352      int n1;
353      int n2;
354 {
355   struct backpatch tmp;
356 
357   tmp = patches[n1];
358   patches[n1] = patches[n2];
359   patches[n2] = tmp;
360 }
361 
362 static void
rot_patch(n1,n2)363 rot_patch (n1, n2)
364      int n1;
365      int n2;
366 {
367   struct backpatch tmp;
368   tmp = patches[n2];
369   while (n2 > n1)
370     {
371       patches[n2] = patches[n2 - 1];
372       --n2;
373     }
374   patches[n2] = tmp;
375 }
376 
377 
378 /* This takes an ascii string and returns a pointer to the byte-compiled
379    result.  It calls yyparse() to do the actual parsing.  This is complicated
380    only because yyparse returns a parse tree which needs to be turned into
381    postfix compiled bytes.  This is further complicated by the presence of
382    forward branches in the byte-compiled code.  That's what the backpatch
383    stuff is for.
384 
385    It'd be nice if oneof() could compile into
386    arg1
387    ONEOF n_possibilities
388    JUMP poss1
389    JUMP poss2
390    JUMP poss3
391    ...
392    JUMP error
393    {poss 1}
394    JUMP end
395    {poss 2}
396    JUMP end
397    ...
398    end: {rest of expression}
399    instead of the simplistic (and slow-to-execute) version currently used
400 
401    It'd also be nice if byte-compiled expressions could have *BIG*
402    subexpressions, instead of silently failing as they do now.  Error checking
403    and a way to encode longer branches would be a *good* idea.
404  */
405 unsigned char *
parse_and_compile(string)406 parse_and_compile (string)
407      char *string;
408 {
409   struct node *new_node;
410   struct node *node;
411   const struct function *f;
412   unsigned char *ret;
413   int n;
414   unsigned buf_siz;
415   int need_relax;
416   int byte;
417 
418   instr = string;
419   parse_error = 0;
420   patches_used = 0;
421   if (yyparse () || parse_error)
422     {
423       ret = ck_malloc (strlen (string) + 5);
424       ret[0] = CONST_ERR;
425       ret[1] = 2;
426       ret[2] = parse_error;
427       ret[3] = ENDCOMP;
428       strcpy ((char *) &ret[4], string);
429       (void) obstack_free (&tmp_mem, tmp_mem_start);
430       return ret;
431     }
432 
433   node = parse_return;
434   if (!node)
435     return 0;
436 
437 loop:
438   if (node->comp_value < USR1)
439     {
440       f = &the_funs[node->comp_value];
441     }
442   else if (node->comp_value < SKIP)
443     {
444       n = node->sub_value;
445       f = &usr_funs[node->comp_value - USR1][n];
446     }
447   else
448     {
449       f = &skip_funs[node->comp_value - SKIP];
450     }
451   byte = node->comp_value;
452 
453 #ifdef TEST
454   if (!f)
455     panic ("f is zero in byte_compile!");
456 #endif
457   switch (GET_COMP (f->fn_comptype))
458     {
459     case C_IF:
460       /* if compiles to
461 		   test-code IF amt-to-skip-on-false true-code SKIP
462  		      amt-to-skip-on-true false-code */
463       if (node->n_x.v_subs[0])
464 	{
465 	  if (node->n_x.v_subs[0]->n_x.v_subs[0])
466 	    {
467 	      /* Put out the test-code */
468 	      push_stack (fn_stack, node);
469 	      new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
470 	      node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
471 	      node = new_node;
472 	      goto loop;
473 	    }
474 	  /* Put out IF, null-byte to backpatch */
475 	  (void) obstack_1grow (&tmp_mem, byte);
476 	  node->add_byte = obstack_object_size (&tmp_mem);
477 	  (void) obstack_1grow (&tmp_mem, 0);
478 
479 	  /* put out true-code */
480 	  push_stack (fn_stack, node);
481 	  new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
482 	  node->n_x.v_subs[0] = 0;
483 	  node = new_node;
484 	  goto loop;
485 	}
486       if (node->n_x.v_subs[1])
487 	{
488 
489 	  (void) obstack_1grow (&tmp_mem, (char)SKIP);
490 	  (void) obstack_1grow (&tmp_mem, 0);
491 	  add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
492 	  node->add_byte = obstack_object_size (&tmp_mem) - 1;
493 
494 	  push_stack (fn_stack, node);
495 	  new_node = node->n_x.v_subs[1];
496 	  node->n_x.v_subs[1] = 0;
497 	  node = new_node;
498 	  goto loop;
499 	}
500       add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
501       break;
502 
503     case C_ANDOR:
504       if (node->n_x.v_subs[0])
505 	{
506 	  push_stack (fn_stack, node);
507 	  new_node = node->n_x.v_subs[0];
508 	  node->n_x.v_subs[0] = 0;
509 	  node = new_node;
510 	  goto loop;
511 	}
512       if (node->n_x.v_subs[1])
513 	{
514 	  (void) obstack_1grow (&tmp_mem, byte);
515 	  node->add_byte = obstack_object_size (&tmp_mem);
516 	  (void) obstack_1grow (&tmp_mem, 0);	/* for backpatching */
517 	  push_stack (fn_stack, node);
518 	  new_node = node->n_x.v_subs[1];
519 	  node->n_x.v_subs[1] = 0;
520 	  node = new_node;
521 	  goto loop;
522 	}
523       add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
524       break;
525 
526     case C_ERR:
527       (void) obstack_1grow (&tmp_mem, byte);
528       node->add_byte = obstack_object_size (&tmp_mem);
529       (void) obstack_1grow (&tmp_mem, 0);
530       (void) obstack_1grow (&tmp_mem, node->n_x.v_int);
531       node->n_x.v_string = ename[node->n_x.v_int];
532       push_stack (str_stack, node);
533       break;
534 
535     case C_FLT:
536       (void) obstack_1grow (&tmp_mem, byte);
537       (void) obstack_grow (&tmp_mem, &(node->n_x.v_float), sizeof (double));
538       break;
539 
540     case C_INT:
541       (void) obstack_1grow (&tmp_mem, byte);
542       (void) obstack_grow (&tmp_mem, &(node->n_x.v_int), sizeof (long));
543       break;
544 
545     case C_STR:
546       (void) obstack_1grow (&tmp_mem, byte);
547       node->add_byte = obstack_object_size (&tmp_mem);
548       (void) obstack_1grow (&tmp_mem, 0);
549       push_stack (str_stack, node);
550       break;
551 
552     case C_VAR:
553       add_ref_to (obstack_object_size (&tmp_mem));
554       add_var_ref (node->n_x.v_var);
555       (void) obstack_1grow (&tmp_mem, byte);
556       (void) obstack_grow (&tmp_mem, &(node->n_x.v_var), sizeof (struct var *));
557       break;
558 
559     case C_CELL:
560       add_ref_to (obstack_object_size (&tmp_mem));
561       add_ref (node->n_x.v_rng.lr, node->n_x.v_rng.lc);
562       (void) obstack_1grow (&tmp_mem, byte);
563 #if BITS_PER_CELLREF==16
564       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr >> 8);
565       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr);
566       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc >> 8);
567       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc);
568 #else
569 #if BITS_PER_CELLREF==8
570       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lr);
571       (void) obstack_1grow (&tmp_mem, node->n_x.v_rng.lc);
572 #else
573       Insert appropriate code here
574 #endif
575 #endif
576         break;
577 
578     case C_RANGE:
579       add_ref_to (obstack_object_size (&tmp_mem));
580       add_range_ref (&(node->n_x.v_rng));
581       (void) obstack_1grow (&tmp_mem, byte);
582       (void) obstack_grow (&tmp_mem, &(node->n_x.v_rng), sizeof (struct rng));
583       break;
584 
585     case C_FN0X:
586       add_ref_to (obstack_object_size (&tmp_mem));
587       /* FALLTHROUGH */
588     case C_FN0:
589     case C_CONST:
590     add_byte:
591       if (f->fn_comptype & C_T)
592 	add_timer_ref (obstack_object_size (&tmp_mem));
593       (void) obstack_1grow (&tmp_mem, byte);
594       if (byte >= USR1 && byte < SKIP)
595 	(void) obstack_1grow (&tmp_mem, (int) node->sub_value);
596       break;
597 
598     case C_FN1:
599     case C_UNA:
600       if (node->n_x.v_subs[0])
601 	{
602 	  push_stack (fn_stack, node);
603 	  new_node = node->n_x.v_subs[0];
604 	  node->n_x.v_subs[0] = 0;
605 	  node = new_node;
606 	  goto loop;
607 	}
608       goto add_byte;
609 
610     case C_FN2:
611     case C_INF:
612       if (node->n_x.v_subs[0])
613 	{
614 	  push_stack (fn_stack, node);
615 	  new_node = node->n_x.v_subs[0];
616 	  node->n_x.v_subs[0] = 0;
617 	  node = new_node;
618 	  goto loop;
619 	}
620       if (node->n_x.v_subs[1])
621 	{
622 	  push_stack (fn_stack, node);
623 	  new_node = node->n_x.v_subs[1];
624 	  node->n_x.v_subs[1] = 0;
625 	  node = new_node;
626 	  goto loop;
627 	}
628       goto add_byte;
629 
630     case C_FN3:
631       if (node->n_x.v_subs[0])
632 	{
633 	  if (node->n_x.v_subs[0]->n_x.v_subs[0])
634 	    {
635 	      push_stack (fn_stack, node);
636 	      new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
637 	      node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
638 	      node = new_node;
639 	      goto loop;
640 	    }
641 	  push_stack (fn_stack, node);
642 	  new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
643 	  node->n_x.v_subs[0] = 0;
644 	  node = new_node;
645 	  goto loop;
646 	}
647       if (node->n_x.v_subs[1])
648 	{
649 	  push_stack (fn_stack, node);
650 	  new_node = node->n_x.v_subs[1];
651 	  node->n_x.v_subs[1] = 0;
652 	  node = new_node;
653 	  goto loop;
654 	}
655       goto add_byte;
656 
657     case C_FN4:
658       if (node->n_x.v_subs[0])
659 	{
660 	  if (node->n_x.v_subs[0]->n_x.v_subs[0])
661 	    {
662 	      push_stack (fn_stack, node);
663 	      new_node = node->n_x.v_subs[0]->n_x.v_subs[0];
664 	      node->n_x.v_subs[0]->n_x.v_subs[0] = 0;
665 	      node = new_node;
666 	      goto loop;
667 	    }
668 	  push_stack (fn_stack, node);
669 	  new_node = node->n_x.v_subs[0]->n_x.v_subs[1];
670 	  node->n_x.v_subs[0] = 0;
671 	  node = new_node;
672 	  goto loop;
673 	}
674       if (node->n_x.v_subs[1])
675 	{
676 	  if (node->n_x.v_subs[1]->n_x.v_subs[0])
677 	    {
678 	      push_stack (fn_stack, node);
679 	      new_node = node->n_x.v_subs[1]->n_x.v_subs[0];
680 	      node->n_x.v_subs[1]->n_x.v_subs[0] = 0;
681 	      node = new_node;
682 	      goto loop;
683 	    }
684 	  push_stack (fn_stack, node);
685 	  new_node = node->n_x.v_subs[1]->n_x.v_subs[1];
686 	  node->n_x.v_subs[1] = 0;
687 	  node = new_node;
688 	  goto loop;
689 	}
690       goto add_byte;
691 
692     case C_FNN:
693       if (node->n_x.v_subs[1])
694 	{
695 	  if (node->add_byte == 0)
696 	    for (new_node = node; new_node->n_x.v_subs[1]; new_node = new_node->n_x.v_subs[1])
697 	      node->add_byte++;
698 	  for (new_node = node; new_node->n_x.v_subs[1]->n_x.v_subs[1]; new_node = new_node->n_x.v_subs[1])
699 	    ;
700 	  push_stack (fn_stack, node);
701 	  node = new_node->n_x.v_subs[1]->n_x.v_subs[0];
702 	  new_node->n_x.v_subs[1] = 0;
703 	  goto loop;
704 	}
705       (void) obstack_1grow (&tmp_mem, byte);
706       if (byte >= USR1 && byte < SKIP)
707 	(void) obstack_1grow (&tmp_mem, (int) node->sub_value);
708       (void) obstack_1grow (&tmp_mem, node->add_byte);
709       break;
710 
711     default:
712       panic ("Bad comptype %d", f->fn_comptype);
713     }
714   node = (struct node *) pop_stack (fn_stack);
715   if (node)
716     goto loop;
717 
718   (void) obstack_1grow (&tmp_mem, 0);
719 
720   while ((node = (pop_stack (str_stack))))
721     {
722       add_backpatch (node->add_byte, obstack_object_size (&tmp_mem));
723       (void) obstack_grow (&tmp_mem, node->n_x.v_string, strlen (node->n_x.v_string) + 1);
724     }
725 
726   buf_siz = obstack_object_size (&tmp_mem);
727   ret = (unsigned char *) ck_malloc (buf_siz);
728   bcopy (obstack_finish (&tmp_mem), ret, buf_siz);
729 
730   need_relax = 0;
731   for (n = 0; n < patches_used; n++)
732     {
733       long offset;
734 
735       offset = (patches[n].to - patches[n].from) - 1;
736       if (offset < 0 || offset > 255)
737 	need_relax++;
738       else
739 	ret[patches[n].from] = offset;
740     }
741   if (need_relax)
742     {
743       int n_lo;
744       long offset;
745       int start;
746 
747       /* ... Sort the patches list ... */
748       sort (patches_used, cmp_patch, swp_patch, rot_patch);
749 
750       while (need_relax)
751 	{
752 	  ret = ck_realloc (ret, buf_siz + need_relax);
753 	  for (n_lo = 0; n_lo < patches_used; n_lo++)
754 	    {
755 	      offset = (patches[n_lo].to - patches[n_lo].from) - 1;
756 	      if (offset < 0 || offset > 255 - need_relax)
757 		break;
758 	    }
759 
760 	  /* n_lo points to the first jump that may need to be relaxed */
761 	  for (n = n_lo; n < patches_used; n++)
762 	    {
763 	      offset = (patches[n].to - patches[n].from) - 1;
764 	      if (offset < 0 || offset > 255)
765 		{
766 		  int nn;
767 
768 		  start = patches[n].from;
769 
770 		  ret[start - 1]++;	/* Translate insn to LONG */
771 		  ret[start] = offset;
772 		  bcopy (&ret[start + 1], &ret[start + 2], buf_siz - start);
773 		  ret[start + 1] = offset >> 8;
774 		  need_relax--;
775 		  buf_siz++;
776 		  for (nn = 0; nn < patches_used; nn++)
777 		    {
778 		      if (patches[nn].from > start)
779 			patches[nn].from++;
780 		      if (patches[nn].to > start)
781 			patches[nn].to++;
782 		      if (patches[nn].from < start && patches[nn].to > start && ret[patches[nn].from]++ == 255)
783 			{
784 			  if (ret[patches[nn].from - 1] & 01)
785 			    ret[patches[nn].from + 1]++;
786 			  else
787 			    need_relax++;
788 			}
789 		    }
790 		}
791 	    }
792 	}
793     }
794 
795   (void) obstack_free (&tmp_mem, tmp_mem_start);
796 
797   patches_used = 0;
798 
799   return ret;
800 }
801 
802 /* Back when strings stored a char*, they needed to be freed when a
803    byte-compiled expression was freed.  Now that they're appended to the end,
804    they don't need to be specially freed anymore.
805  */
806 void
byte_free(form)807 byte_free (form)
808      unsigned char *form;
809 {
810   /* no longer needed
811 	unsigned char *f;
812 
813 	for(f=form;*f;f++) {
814 		switch(*f) {
815 		case IF:
816 		case F_IF:
817 		case SKIP:
818 		case AND:
819 		case OR:
820 		case CONST_STR:
821 			f++;
822 			break;
823 		case CONST_INT:
824 			f+=sizeof(long);
825 			break;
826 		case CONST_FLT:
827 			f+=sizeof(double);
828 			break;
829 		case VAR:
830 			f+=sizeof(struct var *);
831 			break;
832 		case R_CELL:
833 		case R_CELL|ROWREL:
834 		case R_CELL|COLREL:
835 		case R_CELL|ROWREL|COLREL:
836 			f+=EXP_ADD;
837 			break;
838 		case RANGE:
839 		case RANGE|LRREL:
840 		case RANGE|LRREL|LCREL:
841 		case RANGE|LRREL|LCREL|HCREL:
842 		case RANGE|LRREL|HCREL:
843 		case RANGE|LRREL|HRREL:
844 		case RANGE|LRREL|HRREL|LCREL:
845 		case RANGE|LRREL|HRREL|LCREL|HCREL:
846 		case RANGE|LRREL|HRREL|HCREL:
847 		case RANGE|HRREL:
848 		case RANGE|HRREL|LCREL:
849 		case RANGE|HRREL|LCREL|HCREL:
850 		case RANGE|HRREL|HCREL:
851 		case RANGE|LCREL:
852 		case RANGE|LCREL|HCREL:
853 		case RANGE|HCREL:
854 			f+=EXP_ADD_RNG;
855 			break;
856 		case F_PRINTF:
857 		case F_CONCAT:
858 		case F_ONEOF:
859 		case F_STRSTR:
860 		case F_EDIT:
861 		case AREA_SUM:
862 		case AREA_PROD:
863 		case AREA_AVG:
864 		case AREA_STD:
865 		case AREA_MAX:
866 		case AREA_MIN:
867 		case AREA_CNT:
868 		case AREA_VAR:
869 			f++;
870 			break;
871 		default:
872 			break;
873 		}
874 	} */
875   free (form);
876 }
877 
878 /* This tries to tell if a byte-compiled expression is a constant.  If it
879    is a constant, we can free it, and never try to recompute its value.
880    This returns non-zero if the expression is constant.*/
881 int
is_constant(bytes)882 is_constant (bytes)
883      unsigned char *bytes;
884 {
885   /* It's constant, but it's already been dealt with.
886 	   Pretend it isn't. */
887   if (!bytes)
888     return 0;
889 
890   switch (bytes[0])
891     {
892     case CONST_ERR:
893       return (bytes[3] == 0 && !strcmp ((char *) bytes + 4, ename[bytes[2]]));
894     case CONST_INT:
895       return bytes[sizeof (long) + 1] == ENDCOMP;
896     case CONST_FLT:
897       return bytes[sizeof (double) + 1] == ENDCOMP;
898     case CONST_STR:
899       return bytes[2] == ENDCOMP;
900     case F_TRUE:
901     case F_FALSE:
902     case CONST_INF:
903     case CONST_NINF:
904     case CONST_NAN:
905       return bytes[1] == ENDCOMP;
906     default:
907       return 0;
908     }
909 }
910