1 /*
2 * $Id: decompile.c,v 1.15 2000/08/10 21:02:50 danny Exp $
3 *
4 * Copyright � 1990, 1992, 1993, 1999 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 #include <stdarg.h>
32 #include <ctype.h>
33 #include "global.h"
34 #include "decompile.h"
35 #include "eval.h"
36 #include "cell.h"
37 #include "io-utils.h"
38 #include "cmd.h"
39
40 struct pr_node
41 {
42 int tightness;
43 int len;
44 char string[1];
45 };
46
47
48 static VOIDSTAR save_decomp;
49 static CELLREF decomp_row;
50 static CELLREF decomp_col;
51
52 /* These #defines are so that we don't have to duplicate code below */
53 /* JF: now obsolete, and should be trashed. */
54
55 #define F0 Global->a0?"@%s()":"%s()"
56 #define F1 Global->a0?"@%s(%s)":"%s(%s)"
57 #define F2 Global->a0?"@%s(%s, %s)":"%s(%s, %s)"
58 #define F3 Global->a0?"@%s(%s, %s, %s)":"%s(%s, %s, %s)"
59 #define F4 Global->a0?"@%s(%s, %s, %s, %s)":"%s(%s, %s, %s, %s)"
60 #define FN1 Global->a0?"@%s(%s":"%s(%s"
61
62 /* We decompile things with these wierd node-things. It's ugly, but it works.
63 */
64 static struct pr_node *
n_alloc(int size,int tightness,char * fmt,...)65 n_alloc (int size, int tightness, char *fmt, ...)
66 {
67 struct pr_node *ret;
68 va_list args;
69
70 ret = ck_malloc (sizeof (struct pr_node) + size + 1);
71 ret->len = size;
72 ret->tightness = tightness;
73 va_start (args, fmt);
74 vsprintf (ret->string, fmt, args);
75 va_end (args);
76 return ret;
77 }
78
79 #define n_free(x) ck_free(x)
80
81 extern struct pr_node *
82 byte_decompile (expr)
83 unsigned char *expr;
84 {
85 unsigned char byte;
86 double tmp_flt;
87 long tmp_lng;
88 char *tmp_str;
89 struct var *v;
90 unsigned long_skp;
91 unsigned char save_val;
92 unsigned jumpto;
93
94 struct pr_node *new = 0;
95 int pri;
96 int aso;
97 char *chr;
98
99 static struct pr_node **the_line;
100 static int line_alloc;
101
102 static struct pr_node **c_node;
103 struct function *f;
104
105 if (!the_line)
106 {
107 the_line = (struct pr_node **) ck_malloc (20 * sizeof (struct pr_node *));
108 line_alloc = 20;
109 c_node = the_line;
110 }
111
112 #ifdef TEST
113 if (!expr)
114 panic ("No expression to decompile");
115 #endif
116 next_byte:
117 byte = *expr++;
118 if (byte < USR1)
119 f = &the_funs[byte];
120 else if (byte < SKIP)
121 {
122 tmp_lng = *expr++;
123 f = &usr_funs[byte - USR1][tmp_lng];
124 }
125 else
126 f = &skip_funs[byte - SKIP];
127
128 if (f->fn_argn & X_J)
129 jumpto = *expr++;
130 else if (f->fn_argn & X_JL)
131 {
132 jumpto = expr[0] + ((unsigned) (expr[1]) << 8);
133 expr += 2;
134 }
135 else
136 jumpto = 0;
137
138 switch (GET_COMP (f->fn_comptype))
139 {
140 case C_IF:
141 if (expr[jumpto - 2] != SKIP)
142 {
143 long_skp = 1;
144 save_val = expr[jumpto - 3];
145 expr[jumpto - 3] = 0;
146 }
147 else
148 {
149 long_skp = 0;
150 save_val = expr[jumpto - 2];
151 expr[jumpto - 2] = 0;
152 }
153 c_node[0] = byte_decompile (expr);
154 c_node++;
155
156 if (long_skp)
157 {
158 expr[jumpto - 3] = save_val;
159 expr += jumpto;
160 jumpto = expr[-2] + ((unsigned) (expr[-1]) << 8);
161 }
162 else
163 {
164 expr[jumpto - 2] = save_val;
165 expr += jumpto;
166 jumpto = expr[-1];
167 }
168 save_val = expr[jumpto];
169 expr[jumpto] = 0;
170 c_node[0] = byte_decompile (expr);
171 c_node -= 2;
172 expr[jumpto] = save_val;
173 expr += jumpto;
174 if (byte == IF || byte == IF_L)
175 {
176 if (c_node[0]->tightness <= 1)
177 new = n_alloc (8 + c_node[0]->len + c_node[1]->len + c_node[2]->len,
178 1,
179 "(%s) ? %s : %s", c_node[0]->string, c_node[1]->string, c_node[2]->string);
180 else
181 new = n_alloc (6 + c_node[0]->len + c_node[1]->len + c_node[2]->len,
182 1,
183 "%s ? %s : %s", c_node[0]->string, c_node[1]->string, c_node[2]->string);
184 }
185 else
186 new = n_alloc (6 + c_node[0]->len + c_node[1]->len + c_node[2]->len + strlen (f->fn_str),
187 1000,
188 F3, f->fn_str, c_node[0]->string, c_node[1]->string, c_node[2]->string);
189 n_free (c_node[0]);
190 n_free (c_node[1]);
191 n_free (c_node[2]);
192 break;
193
194 case C_ANDOR:
195 save_val = expr[jumpto];
196 expr[jumpto] = 0;
197 c_node[0] = byte_decompile (expr);
198 expr[jumpto] = save_val;
199 expr += jumpto;
200 c_node++;
201 if (ISINFIX (f->fn_comptype))
202 {
203 pri = GET_IN (f->fn_comptype);
204 aso = GET_ASO (f->fn_comptype);
205 chr = f->fn_str;
206 goto do_infix;
207 }
208 else
209 goto do_fn2;
210
211 case C_STR:
212 tmp_str = backslash_a_string ((char *) expr + jumpto, 2);
213 new = n_alloc (strlen (tmp_str) + 1,
214 1000,
215 "%s", tmp_str);
216 break;
217
218 case C_CELL:
219 {
220 int num1, num2;
221 char *str;
222 CELLREF row, col;
223
224 row = GET_ROW (expr);
225 col = GET_COL (expr);
226 expr += EXP_ADD;
227
228 if (Global->a0)
229 {
230 new = n_alloc (30, 1000, f->fn_str, col_to_str (col), row);
231 }
232 else
233 {
234 if (byte & ROWREL)
235 {
236 num1 = row - decomp_row;
237 if (byte & COLREL)
238 {
239 num2 = col - decomp_col;
240 if (row == decomp_row && col == decomp_col)
241 str = "rc";
242 else if (row == decomp_row)
243 {
244 str = "rc[%+d]";
245 num1 = num2;
246 }
247 else if (col == decomp_col)
248 str = "r[%+d]c";
249 else
250 str = "r[%+d]c[%+d]";
251 }
252 else if (row == decomp_row)
253 {
254 str = "rc%u";
255 num1 = num2 = col;
256 }
257 else
258 {
259 str = "r[%+d]c%u";
260 num2 = col;
261 }
262 }
263 else if (byte & COLREL)
264 {
265 num1 = row;
266 num2 = col - decomp_col;
267 if (col == decomp_col)
268 str = "r%uc";
269 else
270 str = "r%uc[%+d]";
271 }
272 else
273 {
274 str = "r%uc%u";
275 num1 = row;
276 num2 = col;
277 }
278 new = n_alloc (30, 1000, str, num1, num2);
279 }
280 new->len = strlen (new->string);
281 }
282 break;
283
284 case C_RANGE:
285 {
286 char tmprbuf[40];
287 char tmpcbuf[40];
288 struct rng rng;
289
290 GET_RNG (expr, &rng);
291 expr += EXP_ADD_RNG;
292
293 if (Global->a0)
294 new = n_alloc (40, 1000, f->fn_str, col_to_str (rng.lc), rng.lr, col_to_str (rng.hc), rng.hr);
295 else
296 {
297 /* Check for special cases */
298 if (rng.lr == rng.hr && ((byte & LRREL) ? 1 : 0) == ((byte & HRREL) ? 1 : 0))
299 {
300 if (byte & LRREL)
301 {
302 if (rng.lr == decomp_row)
303 {
304 tmprbuf[0] = 'r';
305 tmprbuf[1] = '\0';
306 }
307 else
308 (void) sprintf (tmprbuf, "r[%+d]", rng.lr - decomp_row);
309 }
310 else
311 sprintf (tmprbuf, "r%u", rng.lr);
312 }
313 else if ((byte & LRREL) && (byte & HRREL))
314 {
315 int r1, r2, rtmp;
316
317 r1 = rng.lr - decomp_row;
318 r2 = rng.hr - decomp_row;
319 if (r1 < r2)
320 rtmp = r1, r1 = r2, r2 = rtmp;
321 (void) sprintf (tmprbuf, "r[%+d:%+d]", r1, r2);
322 }
323 else if ((byte & LRREL))
324 (void) sprintf (tmprbuf, "r[%+d]:%u", rng.lr - decomp_row, rng.hr);
325 else if (byte & HRREL)
326 (void) sprintf (tmprbuf, "r%u:[%+d]", rng.lr, rng.hr - decomp_row);
327 else if (rng.lr < rng.hr)
328 (void) sprintf (tmprbuf, "r%u:%u", rng.lr, rng.hr);
329 else
330 (void) sprintf (tmprbuf, "r%u:%u", rng.hr, rng.lr);
331
332 if (rng.lc == rng.hc && ((byte & LCREL) ? 1 : 0) == ((byte & HCREL) ? 1 : 0))
333 {
334 if (byte & LCREL)
335 {
336 if (rng.lc == decomp_col)
337 {
338 tmpcbuf[0] = 'c';
339 tmpcbuf[1] = '\0';
340 }
341 else
342 sprintf (tmpcbuf, "c[%+d]", rng.lc - decomp_col);
343 }
344 else
345 sprintf (tmpcbuf, "c%u", rng.lc);
346 }
347 else if ((byte & LCREL) && (byte & HCREL))
348 {
349 int c1, c2, ctmp;
350
351 c1 = rng.lc - decomp_col;
352 c2 = rng.hc - decomp_col;
353 if (c1 < c2)
354 ctmp = c1, c1 = c2, c2 = ctmp;
355 (void) sprintf (tmpcbuf, "c[%+d:%+d]", c1, c2);
356 }
357 else if ((byte & LCREL))
358 (void) sprintf (tmpcbuf, "c[%+d]:%u", rng.lc - decomp_col, rng.hc);
359 else if (byte & HCREL)
360 (void) sprintf (tmpcbuf, "c%u:[%+d]", rng.lc, rng.hc - decomp_col);
361 else if (rng.lc < rng.hc)
362 (void) sprintf (tmpcbuf, "c%u:%u", rng.lc, rng.hc);
363 else
364 (void) sprintf (tmpcbuf, "c%u:%u", rng.hc, rng.lc);
365
366 new = n_alloc (40, 1000, "%s%s", tmprbuf, tmpcbuf);
367 }
368 new->len = strlen (new->string);
369 }
370 break;
371
372 case C_CONST:
373 new = n_alloc (strlen (f->fn_str) + 1, 1000, f->fn_str);
374 break;
375
376 case C_FN0:
377 case C_FN0X:
378 case C_FN0 | C_T:
379 new = n_alloc (strlen (f->fn_str) + 3,
380 1000,
381 F0,
382 f->fn_str);
383 break;
384
385 case C_FN1:
386 --c_node;
387 new = n_alloc (c_node[0]->len + strlen (f->fn_str) + 3,
388 1000,
389 F1, f->fn_str, c_node[0]->string);
390 n_free (*c_node);
391 break;
392
393 case C_UNA:
394 --c_node;
395 if (c_node[0]->tightness < 9)
396 {
397 new = n_alloc (3 + c_node[0]->len,
398 9,
399 "%s(%s)", f->fn_str, c_node[0]->string);
400 }
401 else
402 {
403 new = n_alloc (1 + c_node[0]->len,
404 9,
405 "%s%s", f->fn_str, c_node[0]->string);
406 }
407 n_free (*c_node);
408 break;
409
410 case C_INF:
411 pri = GET_IN (f->fn_comptype);
412 aso = GET_ASO (f->fn_comptype);
413 chr = f->fn_str;
414
415 do_infix:
416 c_node -= 2;
417 if (c_node[0]->tightness < pri || (c_node[0]->tightness == pri && aso != 1))
418 {
419 if (c_node[1]->tightness < pri || (c_node[1]->tightness == pri && aso != -1))
420 new = n_alloc (7 + c_node[0]->len + c_node[1]->len,
421 pri,
422 "(%s) %s (%s)", c_node[0]->string, chr, c_node[1]->string);
423 else
424 new = n_alloc (5 + c_node[0]->len + c_node[1]->len,
425 pri,
426 "(%s) %s %s", c_node[0]->string, chr, c_node[1]->string);
427 }
428 else if (c_node[1]->tightness < pri || (c_node[1]->tightness == pri && aso != -1))
429 new = n_alloc (5 + c_node[0]->len + c_node[1]->len,
430 pri,
431 "%s %s (%s)", c_node[0]->string, chr, c_node[1]->string);
432 else
433 new = n_alloc (3 + c_node[0]->len + c_node[1]->len,
434 pri,
435 "%s %s %s", c_node[0]->string, chr, c_node[1]->string);
436
437 n_free (c_node[0]);
438 n_free (c_node[1]);
439 break;
440
441 case C_FN2:
442 do_fn2:
443 c_node -= 2;
444 new = n_alloc (c_node[0]->len + c_node[1]->len + strlen (f->fn_str) + 5,
445 1000,
446 F2, f->fn_str, c_node[0]->string, c_node[1]->string);
447 n_free (c_node[0]);
448 n_free (c_node[1]);
449 break;
450
451 case C_FN3:
452 c_node -= 3;
453 new = n_alloc (c_node[0]->len + c_node[1]->len + c_node[2]->len + strlen (f->fn_str) + 7,
454 1000,
455 F3,
456 f->fn_str,
457 c_node[0]->string,
458 c_node[1]->string,
459 c_node[2]->string);
460 n_free (c_node[0]);
461 n_free (c_node[1]);
462 n_free (c_node[2]);
463 break;
464
465 case C_FNN:
466 aso = *expr++;
467 c_node -= aso;
468
469 if (aso == 1)
470 new = n_alloc (3 + c_node[0]->len + strlen (f->fn_str),
471 1000,
472 F1, f->fn_str, c_node[0]->string);
473 else
474 {
475 new = n_alloc (2 + c_node[0]->len + strlen (f->fn_str),
476 1000,
477 FN1, f->fn_str, c_node[0]->string);
478 --aso;
479 for (pri = 1; pri < aso; pri++)
480 {
481 n_free (c_node[0]);
482 c_node[0] = new;
483 new = n_alloc (2 + new->len + c_node[pri]->len,
484 1000,
485 "%s, %s", new->string, c_node[pri]->string);
486 }
487 n_free (c_node[0]);
488 c_node[0] = new;
489 new = n_alloc (3 + new->len + c_node[aso]->len,
490 1000,
491 "%s, %s)", new->string, c_node[aso]->string);
492 }
493 n_free (c_node[0]);
494 break;
495
496 case C_FN4:
497 c_node -= 4;
498 new = n_alloc (c_node[0]->len + c_node[1]->len + c_node[2]->len + c_node[3]->len + strlen (f->fn_str) + 6,
499 1000,
500 F4,
501 f->fn_str,
502 c_node[0]->string,
503 c_node[1]->string,
504 c_node[2]->string,
505 c_node[3]->string);
506 n_free (c_node[0]);
507 n_free (c_node[1]);
508 n_free (c_node[2]);
509 n_free (c_node[3]);
510 break;
511
512 case C_ERR:
513 tmp_str = (char *) expr + jumpto;
514 expr++;
515 new = n_alloc (strlen (tmp_str) + 1, 1000, "%s", tmp_str);
516 /* bcopy((VOIDSTAR)expr,(VOIDSTAR)&tmp_str,sizeof(char *));
517 expr+=sizeof(char *);
518 new=n_alloc(strlen(tmp_str)+1,1000,f->fn_str,tmp_str); */
519 break;
520
521 case C_FLT:
522 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & tmp_flt, sizeof (double));
523 expr += sizeof (double);
524 new = n_alloc (20, 1000, f->fn_str, tmp_flt);
525 new->len = strlen (new->string);
526 break;
527
528 case C_INT:
529 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & tmp_lng, sizeof (long));
530 expr += sizeof (long);
531 new = n_alloc (20, 1000, f->fn_str, tmp_lng);
532 new->len = strlen (new->string);
533 break;
534
535 case C_VAR:
536 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & v, sizeof (struct var *));
537 expr += sizeof (struct var *);
538 new = n_alloc (strlen (v->var_name) + 1,
539 1000,
540 f->fn_str, v->var_name);
541 break;
542
543
544 default:
545 panic ("Bad decompile %d", f->fn_comptype);
546 }
547 *c_node++ = new;
548 if (c_node == &the_line[line_alloc])
549 {
550 line_alloc *= 2;
551 the_line = ck_realloc (the_line, line_alloc * sizeof (struct pr_node *));
552 c_node = &the_line[line_alloc / 2];
553 }
554
555 if (*expr)
556 goto next_byte;
557
558 /* if(c_node != &the_line[1]) {
559 io_error_msg("%d values on decompile stack!",c_node - the_line);
560 return the_line[0];
561 } */
562 new = *--c_node;
563 /* free(the_line); */
564 return new;
565 }
566
567 /* Actual entry points to this file */
568 /* decomp(row, col, cell) returns a string that can be byte_compiled to create
569 cell->formula decomp_free() frees up the allocated string */
570 /* Have moved decomp(row, col, cell) to decomp_formula(row, col, cell, tog).
571 * Alias decomp(row, col, cell) behaves exactly as command described
572 * in the comment aboce. the new int tog argument, if true, can be
573 * used to turn on formatted editing.
574 */
575 char *
decomp(CELLREF r,CELLREF c,CELL * cell)576 decomp (CELLREF r, CELLREF c, CELL *cell)
577 {
578 char *tmp;
579
580 tmp = decomp_formula (r, c, cell, 0);
581
582 return (tmp);
583 }
584 char *
decomp_formula(CELLREF r,CELLREF c,CELL * cell,int tog)585 decomp_formula (CELLREF r, CELLREF c, CELL *cell, int tog)
586 {
587 struct pr_node *ret;
588 char *str;
589 extern char *bname[];
590
591 if (!cell)
592 {
593 str = ck_malloc (1);
594 str[0] = '\0';
595 save_decomp = (VOIDSTAR) str;
596 return str;
597 }
598 decomp_row = r;
599 decomp_col = c;
600 if (cell->cell_formula == 0)
601 {
602 switch (GET_TYP (cell))
603 {
604 case 0:
605 str = ck_malloc (1);
606 str[0] = '\0';
607 break;
608 case TYP_FLT:
609 if (tog)
610 {
611 str = strdup (flt_to_str_fmt(cell));
612 }
613 else
614 {
615 str = strdup (flt_to_str (cell->cell_flt));
616 }
617 break;
618 case TYP_INT:
619 str = ck_malloc (20);
620 sprintf (str, "%ld", cell->cell_int);
621 break;
622 case TYP_STR:
623 str = strdup (backslash_a_string (cell->cell_str, 1));
624 break;
625 case TYP_BOL:
626 str = strdup (bname[cell->cell_bol]);
627 break;
628 case TYP_ERR:
629 str = strdup (ename[cell->cell_bol]);
630 break;
631 default:
632 str = 0;
633 #ifdef TEST
634 panic ("Unknown type %d in decomp", GET_TYP (cell));
635 #endif
636 }
637 save_decomp = (VOIDSTAR) str;
638 return str;
639 }
640 else
641 ret = byte_decompile (cell->cell_formula);
642 save_decomp = (VOIDSTAR) ret;
643 return &(ret->string[0]);
644 }
645
646 void
decomp_free(void)647 decomp_free (void)
648 {
649 #ifdef TEST
650 if (!save_decomp)
651 panic ("No save decomp");
652 n_free (save_decomp);
653 save_decomp = (VOIDSTAR) 0;
654 #else
655 n_free (save_decomp);
656 #endif
657 }
658
659 /*
660 * This takes a string and returns a backslashed form suitable for printing.
661 * Iff add_quote is true, it'll add "s at the beginning and end.
662 * Note that this returns a pointer to a static area that is overwritten with
663 * each call. . .
664 *
665 * If add_quote is 1, escape normal quotes, if it is 2, also escape %.
666 */
667 char *
backslash_a_string(char * string,int add_quote)668 backslash_a_string (char *string, int add_quote)
669 {
670 char *pf, *pt;
671 unsigned char ch;
672 int size, len;
673 static char *cbuf;
674 static int s_cbuf;
675
676 #define ALLOC_PT() \
677 len=strlen(pf); \
678 size=pf-string; \
679 if(s_cbuf<3+size+4*len) { \
680 s_cbuf=3+size+4*len; \
681 cbuf= (cbuf) ? ck_realloc(cbuf,s_cbuf) : ck_malloc(s_cbuf); \
682 } \
683 if(size) \
684 bcopy(string,cbuf,size); \
685 pt=cbuf+size; \
686
687
688 pt = 0;
689 pf = string;
690 if (add_quote) {
691 ALLOC_PT ()
692 *pt++ = '"';
693 }
694 for (; *pf; pf++) {
695 ch = *pf;
696 if (isprint(ch) && ch != '\\'
697 && (ch != '%' || !(add_quote == 2))
698 && (ch != '"' || !add_quote)) {
699 if (pt)
700 *pt++ = ch;
701 continue;
702 }
703
704 if (!pt) {
705 ALLOC_PT ()
706 }
707 if (ch == '\\') {
708 *pt++ = '\\';
709 *pt++ = '\\';
710 } else if (ch == '"') {
711 *pt++ = '\\';
712 *pt++ = ch;
713 } else if (ch == '%') {
714 *pt++ = '%';
715 *pt++ = '%';
716 } else {
717 *pt++ = '\\';
718 *pt++ = ((ch >> 6) & 0x3) + '0';
719 *pt++ = ((ch >> 3) & 0x7) + '0';
720 *pt++ = (ch & 0x7) + '0';
721 }
722 }
723 if (add_quote)
724 *pt++ = '"';
725 if (pt) {
726 *pt++ = '\0';
727 return cbuf;
728 }
729 return string;
730 }
731
732 void
dbg_print_formula(expr)733 dbg_print_formula (expr)
734 unsigned char *expr;
735 {
736 unsigned char byte;
737 struct function *f;
738 double tmp_flt;
739 char *tmp_str;
740 long tmp_int;
741 struct var *v;
742 struct rng rng;
743 char *buf;
744 unsigned jumpto;
745 extern char print_buf[];
746
747 if (!expr)
748 return;
749 strcpy (print_buf, "Formula: ");
750 buf = print_buf + 9;
751 while (*expr)
752 {
753 byte = *expr++;
754
755 if (byte < USR1)
756 f = &the_funs[byte];
757 else if (byte < SKIP)
758 {
759 tmp_int = *expr++;
760 f = &usr_funs[byte - USR1][tmp_int];
761 }
762 else
763 f = &skip_funs[byte - SKIP];
764
765 if (f->fn_argn & X_J)
766 jumpto = *expr++;
767 else if (f->fn_argn & X_JL)
768 {
769 jumpto = expr[0] + ((unsigned) (expr[1]) << 8);
770 expr += 2;
771 }
772 else
773 jumpto = 0;
774
775 switch (GET_COMP (f->fn_comptype))
776 {
777 case C_IF:
778 sprintf (buf, " if%d.%u", byte, jumpto);
779 break;
780 case C_ANDOR:
781 sprintf (buf, " andor%d.%u", byte, jumpto);
782 break;
783 case C_ERR:
784 tmp_str = (char *) (expr + jumpto);
785 byte = *expr++;
786 sprintf (buf, " err%d.%p(%s)", byte, tmp_str, tmp_str);
787 break;
788 case C_FLT:
789 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & tmp_flt, sizeof (double));
790 expr += sizeof (double);
791 sprintf (buf, " flt.%.15g", tmp_flt);
792 break;
793 case C_INT:
794 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & tmp_int, sizeof (long));
795 expr += sizeof (long);
796 sprintf (buf, " int.%ld", tmp_int);
797 break;
798 case C_STR:
799 tmp_str = (char *) (expr + jumpto);
800 sprintf (buf, " str.%p.%s", tmp_str, tmp_str);
801 break;
802 case C_VAR:
803 bcopy ((VOIDSTAR) expr, (VOIDSTAR) & v, sizeof (struct var *));
804 expr += sizeof (struct var *);
805 sprintf (buf, " var.%p.%s", v, v->var_name);
806 break;
807 case C_CELL:
808 sprintf (buf, " ref%d.%u.%u", byte, GET_ROW (expr), GET_COL (expr));
809 expr += EXP_ADD;
810 break;
811 case C_RANGE:
812 GET_RNG (expr, &rng);
813 sprintf (buf, " rng%d.%u-%u,%u-%u", byte, rng.lr, rng.hr, rng.lc, rng.hc);
814 expr += EXP_ADD_RNG;
815 break;
816 case C_FN0:
817 case C_FN0X:
818 case C_FN1:
819 case C_FN2:
820 case C_FN3:
821 case C_FN4:
822 case C_UNA:
823 case C_INF:
824 sprintf (buf, " fun%d.%s.%p", byte, f->fn_str, f->fn_fun);
825 break;
826
827 case C_FNN:
828 sprintf (buf, " funn%d.%s.%p.%d", byte, f->fn_str, f->fn_fun, *expr++);
829 break;
830 case C_CONST:
831 sprintf (buf, " const%s", f->fn_str);
832 break;
833 case C_SKIP:
834 sprintf (buf, " skip.%d", jumpto);
835 break;
836 case 0:
837 sprintf (buf, " ???%d", byte);
838 break;
839 default:
840 io_error_msg ("Unknown decompile type %d", f->fn_comptype);
841 }
842 buf += strlen (buf);
843 }
844 io_text_line (print_buf);
845 }
846