]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/dc/bcode.c
Update to zlib 1.2.4 and add versioned symbols to the
[FreeBSD/FreeBSD.git] / usr.bin / dc / bcode.c
1 /*      $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $      */
2
3 /*
4  * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <sys/cdefs.h>
20 __FBSDID("$FreeBSD$");
21
22 #include <err.h>
23 #include <limits.h>
24 #include <openssl/ssl.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "extern.h"
31
32 BIGNUM          zero;
33
34 #define __inline        
35
36 #define MAX_ARRAY_INDEX         2048
37 #define READSTACK_SIZE          8
38
39 #define NO_ELSE                 -2      /* -1 is EOF */
40 #define REG_ARRAY_SIZE_SMALL    (UCHAR_MAX + 1)
41 #define REG_ARRAY_SIZE_BIG      (UCHAR_MAX + 1 + USHRT_MAX + 1)
42
43 struct bmachine {
44         struct source           *readstack;
45         struct stack            *reg;
46         struct stack             stack;
47         volatile sig_atomic_t    interrupted;
48         u_int                    scale;
49         u_int                    obase;
50         u_int                    ibase;
51         size_t                   readsp;
52         size_t                   reg_array_size;
53         size_t                   readstack_sz;
54         bool                     extended_regs;
55 };
56
57 static struct bmachine   bmachine;
58 static void              sighandler(int);
59
60 static __inline int      readch(void);
61 static __inline void     unreadch(void);
62 static __inline char    *readline(void);
63 static __inline void     src_free(void);
64
65 static __inline u_int    max(u_int, u_int);
66 static u_long            get_ulong(struct number *);
67
68 static __inline void     push_number(struct number *);
69 static __inline void     push_string(char *);
70 static __inline void     push(struct value *);
71 static __inline struct value *tos(void);
72 static __inline struct number   *pop_number(void);
73 static __inline char    *pop_string(void);
74 static __inline void     clear_stack(void);
75 static __inline void     print_tos(void);
76 static void              pop_print(void);
77 static void              pop_printn(void);
78 static __inline void     print_stack(void);
79 static __inline void     dup(void);
80 static void              swap(void);
81 static void              drop(void);
82
83 static void              get_scale(void);
84 static void              set_scale(void);
85 static void              get_obase(void);
86 static void              set_obase(void);
87 static void              get_ibase(void);
88 static void              set_ibase(void);
89 static void              stackdepth(void);
90 static void              push_scale(void);
91 static u_int             count_digits(const struct number *);
92 static void              num_digits(void);
93 static void              to_ascii(void);
94 static void              push_line(void);
95 static void              comment(void);
96 static void              bexec(char *);
97 static void              badd(void);
98 static void              bsub(void);
99 static void              bmul(void);
100 static void              bdiv(void);
101 static void              bmod(void);
102 static void              bdivmod(void);
103 static void              bexp(void);
104 static bool              bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *);
105 static void              bsqrt(void);
106 static void              not(void);
107 static void              equal_numbers(void);
108 static void              less_numbers(void);
109 static void              lesseq_numbers(void);
110 static void              equal(void);
111 static void              not_equal(void);
112 static void              less(void);
113 static void              not_less(void);
114 static void              greater(void);
115 static void              not_greater(void);
116 static void              not_compare(void);
117 static bool              compare_numbers(enum bcode_compare, struct number *,
118                              struct number *);
119 static void              compare(enum bcode_compare);
120 static int               readreg(void);
121 static void              load(void);
122 static void              store(void);
123 static void              load_stack(void);
124 static void              store_stack(void);
125 static void              load_array(void);
126 static void              store_array(void);
127 static void              nop(void);
128 static void              quit(void);
129 static void              quitN(void);
130 static void              skipN(void);
131 static void              skip_until_mark(void);
132 static void              parse_number(void);
133 static void              unknown(void);
134 static void              eval_string(char *);
135 static void              eval_line(void);
136 static void              eval_tos(void);
137
138
139 typedef void            (*opcode_function)(void);
140
141 struct jump_entry {
142         u_char           ch;
143         opcode_function  f;
144 };
145
146 static opcode_function jump_table[UCHAR_MAX];
147
148 static const struct jump_entry jump_table_data[] = {
149         { ' ',  nop             },
150         { '!',  not_compare     },
151         { '#',  comment         },
152         { '%',  bmod            },
153         { '(',  less_numbers    },
154         { '*',  bmul            },
155         { '+',  badd            },
156         { '-',  bsub            },
157         { '.',  parse_number    },
158         { '/',  bdiv            },
159         { '0',  parse_number    },
160         { '1',  parse_number    },
161         { '2',  parse_number    },
162         { '3',  parse_number    },
163         { '4',  parse_number    },
164         { '5',  parse_number    },
165         { '6',  parse_number    },
166         { '7',  parse_number    },
167         { '8',  parse_number    },
168         { '9',  parse_number    },
169         { ':',  store_array     },
170         { ';',  load_array      },
171         { '<',  less            },
172         { '=',  equal           },
173         { '>',  greater         },
174         { '?',  eval_line       },
175         { 'A',  parse_number    },
176         { 'B',  parse_number    },
177         { 'C',  parse_number    },
178         { 'D',  parse_number    },
179         { 'E',  parse_number    },
180         { 'F',  parse_number    },
181         { 'G',  equal_numbers   },
182         { 'I',  get_ibase       },
183         { 'J',  skipN           },
184         { 'K',  get_scale       },
185         { 'L',  load_stack      },
186         { 'M',  nop             },
187         { 'N',  not             },
188         { 'O',  get_obase       },
189         { 'P',  pop_print       },
190         { 'Q',  quitN           },
191         { 'R',  drop            },
192         { 'S',  store_stack     },
193         { 'X',  push_scale      },
194         { 'Z',  num_digits      },
195         { '[',  push_line       },
196         { '\f', nop             },
197         { '\n', nop             },
198         { '\r', nop             },
199         { '\t', nop             },
200         { '^',  bexp            },
201         { '_',  parse_number    },
202         { 'a',  to_ascii        },
203         { 'c',  clear_stack     },
204         { 'd',  dup             },
205         { 'f',  print_stack     },
206         { 'i',  set_ibase       },
207         { 'k',  set_scale       },
208         { 'l',  load            },
209         { 'n',  pop_printn      },
210         { 'o',  set_obase       },
211         { 'p',  print_tos       },
212         { 'q',  quit            },
213         { 'r',  swap            },
214         { 's',  store           },
215         { 'v',  bsqrt           },
216         { 'x',  eval_tos        },
217         { 'z',  stackdepth      },
218         { '{',  lesseq_numbers  },
219         { '~',  bdivmod         }
220 };
221
222 #define JUMP_TABLE_DATA_SIZE \
223         (sizeof(jump_table_data)/sizeof(jump_table_data[0]))
224
225 static void
226 sighandler(int ignored)
227 {
228
229         switch (ignored)
230         {
231         default:
232                 bmachine.interrupted = true;
233         }
234 }
235
236 void
237 init_bmachine(bool extended_registers)
238 {
239         unsigned int i;
240
241         bmachine.extended_regs = extended_registers;
242         bmachine.reg_array_size = bmachine.extended_regs ?
243             REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
244
245         bmachine.reg = calloc(bmachine.reg_array_size,
246             sizeof(bmachine.reg[0]));
247         if (bmachine.reg == NULL)
248                 err(1, NULL);
249
250         for (i = 0; i < UCHAR_MAX; i++)
251                 jump_table[i] = unknown;
252         for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
253                 jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
254
255         stack_init(&bmachine.stack);
256
257         for (i = 0; i < bmachine.reg_array_size; i++)
258                 stack_init(&bmachine.reg[i]);
259
260         bmachine.readstack_sz = READSTACK_SIZE;
261         bmachine.readstack = calloc(sizeof(struct source),
262             bmachine.readstack_sz);
263         if (bmachine.readstack == NULL)
264                 err(1, NULL);
265         bmachine.obase = bmachine.ibase = 10;
266         BN_init(&zero);
267         bn_check(BN_zero(&zero));
268         signal(SIGINT, sighandler);
269 }
270
271 /* Reset the things needed before processing a (new) file */
272 void
273 reset_bmachine(struct source *src)
274 {
275
276         bmachine.readsp = 0;
277         bmachine.readstack[0] = *src;
278 }
279
280 static __inline int
281 readch(void)
282 {
283         struct source *src = &bmachine.readstack[bmachine.readsp];
284
285         return (src->vtable->readchar(src));
286 }
287
288 static __inline void
289 unreadch(void)
290 {
291         struct source *src = &bmachine.readstack[bmachine.readsp];
292
293         src->vtable->unreadchar(src);
294 }
295
296 static __inline char *
297 readline(void)
298 {
299         struct source *src = &bmachine.readstack[bmachine.readsp];
300
301         return (src->vtable->readline(src));
302 }
303
304 static __inline void
305 src_free(void)
306 {
307         struct source *src = &bmachine.readstack[bmachine.readsp];
308
309         src->vtable->free(src);
310 }
311
312 #ifdef DEBUGGING
313 void
314 pn(const char *str, const struct number *n)
315 {
316         char *p = BN_bn2dec(n->number);
317
318         if (p == NULL)
319                 err(1, "BN_bn2dec failed");
320         fputs(str, stderr);
321         fprintf(stderr, " %s (%u)\n" , p, n->scale);
322         OPENSSL_free(p);
323 }
324
325 void
326 pbn(const char *str, const BIGNUM *n)
327 {
328         char *p = BN_bn2dec(n);
329
330         if (p == NULL)
331                 err(1, "BN_bn2dec failed");
332         fputs(str, stderr);
333         fprintf(stderr, " %s\n", p);
334         OPENSSL_free(p);
335 }
336
337 #endif
338
339 static __inline u_int
340 max(u_int a, u_int b)
341 {
342
343         return (a > b ? a : b);
344 }
345
346 static unsigned long factors[] = {
347         0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
348         100000000, 1000000000
349 };
350
351 void
352 scale_number(BIGNUM *n, int s)
353 {
354         unsigned int abs_scale;
355
356         if (s == 0)
357                 return;
358
359         abs_scale = s > 0 ? s : -s;
360
361         if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
362                 if (s > 0)
363                         bn_check(BN_mul_word(n, factors[abs_scale]));
364                 else
365                         BN_div_word(n, factors[abs_scale]);
366         } else {
367                 BIGNUM *a, *p;
368                 BN_CTX *ctx;
369
370                 a = BN_new();
371                 bn_checkp(a);
372                 p = BN_new();
373                 bn_checkp(p);
374                 ctx = BN_CTX_new();
375                 bn_checkp(ctx);
376
377                 bn_check(BN_set_word(a, 10));
378                 bn_check(BN_set_word(p, abs_scale));
379                 bn_check(BN_exp(a, a, p, ctx));
380                 if (s > 0)
381                         bn_check(BN_mul(n, n, a, ctx));
382                 else
383                         bn_check(BN_div(n, NULL, n, a, ctx));
384                 BN_CTX_free(ctx);
385                 BN_free(a);
386                 BN_free(p);
387         }
388 }
389
390 void
391 split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
392 {
393         u_long rem;
394
395         bn_checkp(BN_copy(i, n->number));
396
397         if (n->scale == 0 && f != NULL)
398                 bn_check(BN_zero(f));
399         else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
400                 rem = BN_div_word(i, factors[n->scale]);
401                 if (f != NULL)
402                         bn_check(BN_set_word(f, rem));
403         } else {
404                 BIGNUM  *a, *p;
405                 BN_CTX  *ctx;
406
407                 a = BN_new();
408                 bn_checkp(a);
409                 p = BN_new();
410                 bn_checkp(p);
411                 ctx = BN_CTX_new();
412                 bn_checkp(ctx);
413
414                 bn_check(BN_set_word(a, 10));
415                 bn_check(BN_set_word(p, n->scale));
416                 bn_check(BN_exp(a, a, p, ctx));
417                 bn_check(BN_div(i, f, n->number, a, ctx));
418                 BN_CTX_free(ctx);
419                 BN_free(a);
420                 BN_free(p);
421         }
422 }
423
424 __inline void
425 normalize(struct number *n, u_int s)
426 {
427
428         scale_number(n->number, s - n->scale);
429         n->scale = s;
430 }
431
432 static u_long
433 get_ulong(struct number *n)
434 {
435
436         normalize(n, 0);
437         return (BN_get_word(n->number));
438 }
439
440 void
441 negate(struct number *n)
442 {
443
444         bn_check(BN_sub(n->number, &zero, n->number));
445 }
446
447 static __inline void
448 push_number(struct number *n)
449 {
450
451         stack_pushnumber(&bmachine.stack, n);
452 }
453
454 static __inline void
455 push_string(char *string)
456 {
457
458         stack_pushstring(&bmachine.stack, string);
459 }
460
461 static __inline void
462 push(struct value *v)
463 {
464
465         stack_push(&bmachine.stack, v);
466 }
467
468 static __inline struct value *
469 tos(void)
470 {
471
472         return (stack_tos(&bmachine.stack));
473 }
474
475 static __inline struct value *
476 pop(void)
477 {
478
479         return (stack_pop(&bmachine.stack));
480 }
481
482 static __inline struct number *
483 pop_number(void)
484 {
485
486         return (stack_popnumber(&bmachine.stack));
487 }
488
489 static __inline char *
490 pop_string(void)
491 {
492
493         return (stack_popstring(&bmachine.stack));
494 }
495
496 static __inline void
497 clear_stack(void)
498 {
499
500         stack_clear(&bmachine.stack);
501 }
502
503 static __inline void
504 print_stack(void)
505 {
506
507         stack_print(stdout, &bmachine.stack, "", bmachine.obase);
508 }
509
510 static __inline void
511 print_tos(void)
512 {
513         struct value *value = tos();
514
515         if (value != NULL) {
516                 print_value(stdout, value, "", bmachine.obase);
517                 putchar('\n');
518         }
519         else
520                 warnx("stack empty");
521 }
522
523 static void
524 pop_print(void)
525 {
526         struct value *value = pop();
527
528         if (value != NULL) {
529                 switch (value->type) {
530                 case BCODE_NONE:
531                         break;
532                 case BCODE_NUMBER:
533                         normalize(value->u.num, 0);
534                         print_ascii(stdout, value->u.num);
535                         fflush(stdout);
536                         break;
537                 case BCODE_STRING:
538                         fputs(value->u.string, stdout);
539                         fflush(stdout);
540                         break;
541                 }
542                 stack_free_value(value);
543         }
544 }
545
546 static void
547 pop_printn(void)
548 {
549         struct value *value = pop();
550
551         if (value != NULL) {
552                 print_value(stdout, value, "", bmachine.obase);
553                 fflush(stdout);
554                 stack_free_value(value);
555         }
556 }
557
558 static __inline void
559 dup(void)
560 {
561
562         stack_dup(&bmachine.stack);
563 }
564
565 static void
566 swap(void)
567 {
568
569         stack_swap(&bmachine.stack);
570 }
571
572 static void
573 drop(void)
574 {
575         struct value *v = pop();
576         if (v != NULL)
577                 stack_free_value(v);
578 }
579
580 static void
581 get_scale(void)
582 {
583         struct number *n;
584
585         n = new_number();
586         bn_check(BN_set_word(n->number, bmachine.scale));
587         push_number(n);
588 }
589
590 static void
591 set_scale(void)
592 {
593         struct number *n;
594         u_long scale;
595
596         n = pop_number();
597         if (n != NULL) {
598                 if (BN_cmp(n->number, &zero) < 0)
599                         warnx("scale must be a nonnegative number");
600                 else {
601                         scale = get_ulong(n);
602                         if (scale != BN_MASK2 && scale <= UINT_MAX)
603                                 bmachine.scale = (u_int)scale;
604                         else
605                                 warnx("scale too large");
606                         }
607                 free_number(n);
608         }
609 }
610
611 static void
612 get_obase(void)
613 {
614         struct number *n;
615
616         n = new_number();
617         bn_check(BN_set_word(n->number, bmachine.obase));
618         push_number(n);
619 }
620
621 static void
622 set_obase(void)
623 {
624         struct number *n;
625         u_long base;
626
627         n = pop_number();
628         if (n != NULL) {
629                 base = get_ulong(n);
630                 if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
631                         bmachine.obase = (u_int)base;
632                 else
633                         warnx("output base must be a number greater than 1");
634                 free_number(n);
635         }
636 }
637
638 static void
639 get_ibase(void)
640 {
641         struct number *n;
642
643         n = new_number();
644         bn_check(BN_set_word(n->number, bmachine.ibase));
645         push_number(n);
646 }
647
648 static void
649 set_ibase(void)
650 {
651         struct number *n;
652         u_long base;
653
654         n = pop_number();
655         if (n != NULL) {
656                 base = get_ulong(n);
657                 if (base != BN_MASK2 && 2 <= base && base <= 16)
658                         bmachine.ibase = (u_int)base;
659                 else
660                         warnx("input base must be a number between 2 and 16 "
661                             "(inclusive)");
662                 free_number(n);
663         }
664 }
665
666 static void
667 stackdepth(void)
668 {
669         struct number *n;
670         size_t i;
671
672         i = stack_size(&bmachine.stack);
673         n = new_number();
674         bn_check(BN_set_word(n->number, i));
675         push_number(n);
676 }
677
678 static void
679 push_scale(void)
680 {
681         struct number *n;
682         struct value *value;
683         u_int scale = 0;
684
685         value = pop();
686         if (value != NULL) {
687                 switch (value->type) {
688                 case BCODE_NONE:
689                         return;
690                 case BCODE_NUMBER:
691                         scale = value->u.num->scale;
692                         break;
693                 case BCODE_STRING:
694                         break;
695                 }
696                 stack_free_value(value);
697                 n = new_number();
698                 bn_check(BN_set_word(n->number, scale));
699                 push_number(n);
700         }
701 }
702
703 static u_int
704 count_digits(const struct number *n)
705 {
706         struct number *int_part, *fract_part;
707         u_int i;
708
709         if (BN_is_zero(n->number))
710                 return (1);
711
712         int_part = new_number();
713         fract_part = new_number();
714         fract_part->scale = n->scale;
715         split_number(n, int_part->number, fract_part->number);
716
717         i = 0;
718         while (!BN_is_zero(int_part->number)) {
719                 BN_div_word(int_part->number, 10);
720                 i++;
721         }
722         free_number(int_part);
723         free_number(fract_part);
724         return (i + n->scale);
725 }
726
727 static void
728 num_digits(void)
729 {
730         struct number *n = NULL;
731         struct value *value;
732         size_t digits;
733
734         value = pop();
735         if (value != NULL) {
736                 switch (value->type) {
737                 case BCODE_NONE:
738                         return;
739                 case BCODE_NUMBER:
740                         digits = count_digits(value->u.num);
741                         n = new_number();
742                         bn_check(BN_set_word(n->number, digits));
743                         break;
744                 case BCODE_STRING:
745                         digits = strlen(value->u.string);
746                         n = new_number();
747                         bn_check(BN_set_word(n->number, digits));
748                         break;
749                 }
750                 stack_free_value(value);
751                 push_number(n);
752         }
753 }
754
755 static void
756 to_ascii(void)
757 {
758         struct number *n;
759         struct value *value;
760         char str[2];
761
762         value = pop();
763         if (value != NULL) {
764                 str[1] = '\0';
765                 switch (value->type) {
766                 case BCODE_NONE:
767                         return;
768                 case BCODE_NUMBER:
769                         n = value->u.num;
770                         normalize(n, 0);
771                         if (BN_num_bits(n->number) > 8)
772                                 bn_check(BN_mask_bits(n->number, 8));
773                         str[0] = (char)BN_get_word(n->number);
774                         break;
775                 case BCODE_STRING:
776                         str[0] = value->u.string[0];
777                         break;
778                 }
779                 stack_free_value(value);
780                 push_string(bstrdup(str));
781         }
782 }
783
784 static int
785 readreg(void)
786 {
787         int ch1, ch2, idx;
788
789         idx = readch();
790         if (idx == 0xff && bmachine.extended_regs) {
791                 ch1 = readch();
792                 ch2 = readch();
793                 if (ch1 == EOF || ch2 == EOF) {
794                         warnx("unexpected eof");
795                         idx = -1;
796                 } else
797                         idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
798         }
799         if (idx < 0 || (unsigned)idx >= bmachine.reg_array_size) {
800                 warnx("internal error: reg num = %d", idx);
801                 idx = -1;
802         }
803         return (idx);
804 }
805
806 static void
807 load(void)
808 {
809         struct number *n;
810         struct value *v;
811         struct value copy;
812         int idx;
813
814         idx = readreg();
815         if (idx >= 0) {
816                 v = stack_tos(&bmachine.reg[idx]);
817                 if (v == NULL) {
818                         n = new_number();
819                         bn_check(BN_zero(n->number));
820                         push_number(n);
821                 } else
822                         push(stack_dup_value(v, &copy));
823         }
824 }
825
826 static void
827 store(void)
828 {
829         struct value *val;
830         int idx;
831
832         idx = readreg();
833         if (idx >= 0) {
834                 val = pop();
835                 if (val == NULL) {
836                         return;
837                 }
838                 stack_set_tos(&bmachine.reg[idx], val);
839         }
840 }
841
842 static void
843 load_stack(void)
844 {
845         struct stack *stack;
846         struct value *value;
847         int idx;
848
849         idx = readreg();
850         if (idx >= 0) {
851                 stack = &bmachine.reg[idx];
852                 value = NULL;
853                 if (stack_size(stack) > 0) {
854                         value = stack_pop(stack);
855                 }
856                 if (value != NULL)
857                         push(value);
858                 else
859                         warnx("stack register '%c' (0%o) is empty",
860                             idx, idx);
861         }
862 }
863
864 static void
865 store_stack(void)
866 {
867         struct value *value;
868         int idx;
869
870         idx = readreg();
871         if (idx >= 0) {
872                 value = pop();
873                 if (value == NULL)
874                         return;
875                 stack_push(&bmachine.reg[idx], value);
876         }
877 }
878
879 static void
880 load_array(void)
881 {
882         struct number *inumber, *n;
883         struct stack *stack;
884         struct value *v;
885         struct value copy;
886         u_long idx;
887         int reg;
888
889         reg = readreg();
890         if (reg >= 0) {
891                 inumber = pop_number();
892                 if (inumber == NULL)
893                         return;
894                 idx = get_ulong(inumber);
895                 if (BN_cmp(inumber->number, &zero) < 0)
896                         warnx("negative idx");
897                 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
898                         warnx("idx too big");
899                 else {
900                         stack = &bmachine.reg[reg];
901                         v = frame_retrieve(stack, idx);
902                         if (v == NULL || v->type == BCODE_NONE) {
903                                 n = new_number();
904                                 bn_check(BN_zero(n->number));
905                                 push_number(n);
906                         }
907                         else
908                                 push(stack_dup_value(v, &copy));
909                 }
910                 free_number(inumber);
911         }
912 }
913
914 static void
915 store_array(void)
916 {
917         struct number *inumber;
918         struct value *value;
919         struct stack *stack;
920         u_long idx;
921         int reg;
922
923         reg = readreg();
924         if (reg >= 0) {
925                 inumber = pop_number();
926                 if (inumber == NULL)
927                         return;
928                 value = pop();
929                 if (value == NULL) {
930                         free_number(inumber);
931                         return;
932                 }
933                 idx = get_ulong(inumber);
934                 if (BN_cmp(inumber->number, &zero) < 0) {
935                         warnx("negative idx");
936                         stack_free_value(value);
937                 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
938                         warnx("idx too big");
939                         stack_free_value(value);
940                 } else {
941                         stack = &bmachine.reg[reg];
942                         frame_assign(stack, idx, value);
943                 }
944                 free_number(inumber);
945         }
946 }
947
948 static void
949 push_line(void)
950 {
951
952         push_string(read_string(&bmachine.readstack[bmachine.readsp]));
953 }
954
955 static void
956 comment(void)
957 {
958
959         free(readline());
960 }
961
962 static void
963 bexec(char *line)
964 {
965
966         system(line);
967         free(line);
968 }
969
970 static void
971 badd(void)
972 {
973         struct number   *a, *b, *r;
974
975         a = pop_number();
976         if (a == NULL) {
977                 return;
978         }
979         b = pop_number();
980         if (b == NULL) {
981                 push_number(a);
982                 return;
983         }
984
985         r = new_number();
986         r->scale = max(a->scale, b->scale);
987         if (r->scale > a->scale)
988                 normalize(a, r->scale);
989         else if (r->scale > b->scale)
990                 normalize(b, r->scale);
991         bn_check(BN_add(r->number, a->number, b->number));
992         push_number(r);
993         free_number(a);
994         free_number(b);
995 }
996
997 static void
998 bsub(void)
999 {
1000         struct number   *a, *b, *r;
1001
1002         a = pop_number();
1003         if (a == NULL) {
1004                 return;
1005         }
1006         b = pop_number();
1007         if (b == NULL) {
1008                 push_number(a);
1009                 return;
1010         }
1011
1012         r = new_number();
1013
1014         r->scale = max(a->scale, b->scale);
1015         if (r->scale > a->scale)
1016                 normalize(a, r->scale);
1017         else if (r->scale > b->scale)
1018                 normalize(b, r->scale);
1019         bn_check(BN_sub(r->number, b->number, a->number));
1020         push_number(r);
1021         free_number(a);
1022         free_number(b);
1023 }
1024
1025 void
1026 bmul_number(struct number *r, struct number *a, struct number *b)
1027 {
1028         BN_CTX *ctx;
1029
1030         /* Create copies of the scales, since r might be equal to a or b */
1031         u_int ascale = a->scale;
1032         u_int bscale = b->scale;
1033         u_int rscale = ascale + bscale;
1034
1035         ctx = BN_CTX_new();
1036         bn_checkp(ctx);
1037         bn_check(BN_mul(r->number, a->number, b->number, ctx));
1038         BN_CTX_free(ctx);
1039
1040         if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) {
1041                 r->scale = rscale;
1042                 normalize(r, max(bmachine.scale, max(ascale, bscale)));
1043         } else
1044                 r->scale = rscale;
1045 }
1046
1047 static void
1048 bmul(void)
1049 {
1050         struct number *a, *b, *r;
1051
1052         a = pop_number();
1053         if (a == NULL) {
1054                 return;
1055         }
1056         b = pop_number();
1057         if (b == NULL) {
1058                 push_number(a);
1059                 return;
1060         }
1061
1062         r = new_number();
1063         bmul_number(r, a, b);
1064
1065         push_number(r);
1066         free_number(a);
1067         free_number(b);
1068 }
1069
1070 static void
1071 bdiv(void)
1072 {
1073         struct number *a, *b, *r;
1074         BN_CTX *ctx;
1075         u_int scale;
1076
1077         a = pop_number();
1078         if (a == NULL) {
1079                 return;
1080         }
1081         b = pop_number();
1082         if (b == NULL) {
1083                 push_number(a);
1084                 return;
1085         }
1086
1087         r = new_number();
1088         r->scale = bmachine.scale;
1089         scale = max(a->scale, b->scale);
1090
1091         if (BN_is_zero(a->number))
1092                 warnx("divide by zero");
1093         else {
1094                 normalize(a, scale);
1095                 normalize(b, scale + r->scale);
1096
1097                 ctx = BN_CTX_new();
1098                 bn_checkp(ctx);
1099                 bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1100                 BN_CTX_free(ctx);
1101         }
1102         push_number(r);
1103         free_number(a);
1104         free_number(b);
1105 }
1106
1107 static void
1108 bmod(void)
1109 {
1110         struct number *a, *b, *r;
1111         BN_CTX *ctx;
1112         u_int scale;
1113
1114         a = pop_number();
1115         if (a == NULL) {
1116                 return;
1117         }
1118         b = pop_number();
1119         if (b == NULL) {
1120                 push_number(a);
1121                 return;
1122         }
1123
1124         r = new_number();
1125         scale = max(a->scale, b->scale);
1126         r->scale = max(b->scale, a->scale + bmachine.scale);
1127
1128         if (BN_is_zero(a->number))
1129                 warnx("remainder by zero");
1130         else {
1131                 normalize(a, scale);
1132                 normalize(b, scale + bmachine.scale);
1133
1134                 ctx = BN_CTX_new();
1135                 bn_checkp(ctx);
1136                 bn_check(BN_mod(r->number, b->number, a->number, ctx));
1137                 BN_CTX_free(ctx);
1138         }
1139         push_number(r);
1140         free_number(a);
1141         free_number(b);
1142 }
1143
1144 static void
1145 bdivmod(void)
1146 {
1147         struct number *a, *b, *rdiv, *rmod;
1148         BN_CTX *ctx;
1149         u_int scale;
1150
1151         a = pop_number();
1152         if (a == NULL) {
1153                 return;
1154         }
1155         b = pop_number();
1156         if (b == NULL) {
1157                 push_number(a);
1158                 return;
1159         }
1160
1161         rdiv = new_number();
1162         rmod = new_number();
1163         rdiv->scale = bmachine.scale;
1164         rmod->scale = max(b->scale, a->scale + bmachine.scale);
1165         scale = max(a->scale, b->scale);
1166
1167         if (BN_is_zero(a->number))
1168                 warnx("divide by zero");
1169         else {
1170                 normalize(a, scale);
1171                 normalize(b, scale + bmachine.scale);
1172
1173                 ctx = BN_CTX_new();
1174                 bn_checkp(ctx);
1175                 bn_check(BN_div(rdiv->number, rmod->number,
1176                     b->number, a->number, ctx));
1177                 BN_CTX_free(ctx);
1178         }
1179         push_number(rdiv);
1180         push_number(rmod);
1181         free_number(a);
1182         free_number(b);
1183 }
1184
1185 static void
1186 bexp(void)
1187 {
1188         struct number *a, *p, *r;
1189         u_int scale;
1190         bool neg;
1191
1192         p = pop_number();
1193         if (p == NULL) {
1194                 return;
1195         }
1196         a = pop_number();
1197         if (a == NULL) {
1198                 push_number(p);
1199                 return;
1200         }
1201
1202         if (p->scale != 0)
1203                 warnx("Runtime warning: non-zero scale in exponent");
1204         normalize(p, 0);
1205
1206         neg = false;
1207         if (BN_cmp(p->number, &zero) < 0) {
1208                 neg = true;
1209                 negate(p);
1210                 scale = bmachine.scale;
1211         } else {
1212                 /* Posix bc says min(a.scale * b, max(a.scale, scale) */
1213                 u_long b;
1214                 u_int m;
1215
1216                 b = BN_get_word(p->number);
1217                 m = max(a->scale, bmachine.scale);
1218                 scale = a->scale * (u_int)b;
1219                 if (scale > m || (a->scale > 0 && (b == BN_MASK2 ||
1220                     b > UINT_MAX)))
1221                         scale = m;
1222         }
1223
1224         if (BN_is_zero(p->number)) {
1225                 r = new_number();
1226                 bn_check(BN_one(r->number));
1227                 normalize(r, scale);
1228         } else {
1229                 while (!BN_is_bit_set(p->number, 0)) {
1230                         bmul_number(a, a, a);
1231                         bn_check(BN_rshift1(p->number, p->number));
1232                 }
1233
1234                 r = dup_number(a);
1235                 normalize(r, scale);
1236                 bn_check(BN_rshift1(p->number, p->number));
1237
1238                 while (!BN_is_zero(p->number)) {
1239                         bmul_number(a, a, a);
1240                         if (BN_is_bit_set(p->number, 0))
1241                                 bmul_number(r, r, a);
1242                         bn_check(BN_rshift1(p->number, p->number));
1243                 }
1244
1245                 if (neg) {
1246                         BN_CTX *ctx;
1247                         BIGNUM *one;
1248
1249                         one = BN_new();
1250                         bn_checkp(one);
1251                         bn_check(BN_one(one));
1252                         ctx = BN_CTX_new();
1253                         bn_checkp(ctx);
1254                         scale_number(one, r->scale + scale);
1255                         normalize(r, scale);
1256                         bn_check(BN_div(r->number, NULL, one, r->number, ctx));
1257                         BN_free(one);
1258                         BN_CTX_free(ctx);
1259                 } else
1260                         normalize(r, scale);
1261         }
1262         push_number(r);
1263         free_number(a);
1264         free_number(p);
1265 }
1266
1267 static bool
1268 bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
1269 {
1270         BIGNUM *r;
1271         bool ret;
1272
1273         r = BN_new();
1274         bn_checkp(r);
1275         bn_check(BN_sub(r, x, y));
1276         if (BN_is_one(r))
1277                 (*onecount)++;
1278         ret = BN_is_zero(r);
1279         BN_free(r);
1280         return (ret || *onecount > 1);
1281 }
1282
1283 static void
1284 bsqrt(void)
1285 {
1286         struct number *n, *r;
1287         BIGNUM *x, *y;
1288         BN_CTX *ctx;
1289         u_int onecount, scale;
1290
1291         onecount = 0;
1292         n = pop_number();
1293         if (n == NULL) {
1294                 return;
1295         }
1296         if (BN_is_zero(n->number)) {
1297                 r = new_number();
1298                 push_number(r);
1299         } else if (BN_cmp(n->number, &zero) < 0)
1300                 warnx("square root of negative number");
1301         else {
1302                 scale = max(bmachine.scale, n->scale);
1303                 normalize(n, 2*scale);
1304                 x = BN_dup(n->number);
1305                 bn_checkp(x);
1306                 bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1307                 y = BN_new();
1308                 bn_checkp(y);
1309                 ctx = BN_CTX_new();
1310                 bn_checkp(ctx);
1311                 for (;;) {
1312                         bn_checkp(BN_copy(y, x));
1313                         bn_check(BN_div(x, NULL, n->number, x, ctx));
1314                         bn_check(BN_add(x, x, y));
1315                         bn_check(BN_rshift1(x, x));
1316                         if (bsqrt_stop(x, y, &onecount))
1317                                 break;
1318                 }
1319                 r = bmalloc(sizeof(*r));
1320                 r->scale = scale;
1321                 r->number = y;
1322                 BN_free(x);
1323                 BN_CTX_free(ctx);
1324                 push_number(r);
1325         }
1326
1327         free_number(n);
1328 }
1329
1330 static void
1331 not(void)
1332 {
1333         struct number *a;
1334
1335         a = pop_number();
1336         if (a == NULL) {
1337                 return;
1338         }
1339         a->scale = 0;
1340         bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1341         push_number(a);
1342 }
1343
1344 static void
1345 equal(void)
1346 {
1347
1348         compare(BCODE_EQUAL);
1349 }
1350
1351 static void
1352 equal_numbers(void)
1353 {
1354         struct number *a, *b, *r;
1355
1356         a = pop_number();
1357         if (a == NULL) {
1358                 return;
1359         }
1360         b = pop_number();
1361         if (b == NULL) {
1362                 push_number(a);
1363                 return;
1364         }
1365         r = new_number();
1366         bn_check(BN_set_word(r->number,
1367             compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1368         push_number(r);
1369 }
1370
1371 static void
1372 less_numbers(void)
1373 {
1374         struct number *a, *b, *r;
1375
1376         a = pop_number();
1377         if (a == NULL) {
1378                 return;
1379         }
1380         b = pop_number();
1381         if (b == NULL) {
1382                 push_number(a);
1383                 return;
1384         }
1385         r = new_number();
1386         bn_check(BN_set_word(r->number,
1387             compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1388         push_number(r);
1389 }
1390
1391 static void
1392 lesseq_numbers(void)
1393 {
1394         struct number *a, *b, *r;
1395
1396         a = pop_number();
1397         if (a == NULL) {
1398                 return;
1399         }
1400         b = pop_number();
1401         if (b == NULL) {
1402                 push_number(a);
1403                 return;
1404         }
1405         r = new_number();
1406         bn_check(BN_set_word(r->number,
1407             compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1408         push_number(r);
1409 }
1410
1411 static void
1412 not_equal(void)
1413 {
1414
1415         compare(BCODE_NOT_EQUAL);
1416 }
1417
1418 static void
1419 less(void)
1420 {
1421
1422         compare(BCODE_LESS);
1423 }
1424
1425 static void
1426 not_compare(void)
1427 {
1428
1429         switch (readch()) {
1430         case '<':
1431                 not_less();
1432                 break;
1433         case '>':
1434                 not_greater();
1435                 break;
1436         case '=':
1437                 not_equal();
1438                 break;
1439         default:
1440                 unreadch();
1441                 bexec(readline());
1442                 break;
1443         }
1444 }
1445
1446 static void
1447 not_less(void)
1448 {
1449
1450         compare(BCODE_NOT_LESS);
1451 }
1452
1453 static void
1454 greater(void)
1455 {
1456
1457         compare(BCODE_GREATER);
1458 }
1459
1460 static void
1461 not_greater(void)
1462 {
1463
1464         compare(BCODE_NOT_GREATER);
1465 }
1466
1467 static bool
1468 compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1469 {
1470         u_int scale;
1471         int cmp;
1472
1473         scale = max(a->scale, b->scale);
1474
1475         if (scale > a->scale)
1476                 normalize(a, scale);
1477         else if (scale > b->scale)
1478                 normalize(b, scale);
1479
1480         cmp = BN_cmp(a->number, b->number);
1481
1482         free_number(a);
1483         free_number(b);
1484
1485         switch (type) {
1486         case BCODE_EQUAL:
1487                 return (cmp == 0);
1488         case BCODE_NOT_EQUAL:
1489                 return (cmp != 0);
1490         case BCODE_LESS:
1491                 return (cmp < 0);
1492         case BCODE_NOT_LESS:
1493                 return (cmp >= 0);
1494         case BCODE_GREATER:
1495                 return (cmp > 0);
1496         case BCODE_NOT_GREATER:
1497                 return (cmp <= 0);
1498         }
1499         return (false);
1500 }
1501
1502 static void
1503 compare(enum bcode_compare type)
1504 {
1505         struct number *a, *b;
1506         struct value *v;
1507         int idx, elseidx;
1508         bool ok;
1509
1510         elseidx = NO_ELSE;
1511         idx = readreg();
1512         if (readch() == 'e')
1513                 elseidx = readreg();
1514         else
1515                 unreadch();
1516
1517         a = pop_number();
1518         if (a == NULL)
1519                 return;
1520         b = pop_number();
1521         if (b == NULL) {
1522                 push_number(a);
1523                 return;
1524         }
1525
1526         ok = compare_numbers(type, a, b);
1527
1528         if (!ok && elseidx != NO_ELSE)
1529                 idx = elseidx;
1530
1531         if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1532                 v = stack_tos(&bmachine.reg[idx]);
1533                 if (v == NULL)
1534                         warnx("register '%c' (0%o) is empty", idx, idx);
1535                 else {
1536                         switch(v->type) {
1537                         case BCODE_NONE:
1538                                 warnx("register '%c' (0%o) is empty", idx, idx);
1539                                 break;
1540                         case BCODE_NUMBER:
1541                                 warn("eval called with non-string argument");
1542                                 break;
1543                         case BCODE_STRING:
1544                                 eval_string(bstrdup(v->u.string));
1545                                 break;
1546                         }
1547                 }
1548         }
1549 }
1550
1551
1552 static void
1553 nop(void)
1554 {
1555
1556 }
1557
1558 static void
1559 quit(void)
1560 {
1561
1562         if (bmachine.readsp < 2)
1563                 exit(0);
1564         src_free();
1565         bmachine.readsp--;
1566         src_free();
1567         bmachine.readsp--;
1568 }
1569
1570 static void
1571 quitN(void)
1572 {
1573         struct number *n;
1574         u_long i;
1575
1576         n = pop_number();
1577         if (n == NULL)
1578                 return;
1579         i = get_ulong(n);
1580         free_number(n);
1581         if (i == BN_MASK2 || i == 0)
1582                 warnx("Q command requires a number >= 1");
1583         else if (bmachine.readsp < i)
1584                 warnx("Q command argument exceeded string execution depth");
1585         else {
1586                 while (i-- > 0) {
1587                         src_free();
1588                         bmachine.readsp--;
1589                 }
1590         }
1591 }
1592
1593 static void
1594 skipN(void)
1595 {
1596         struct number *n;
1597         u_long i;
1598
1599         n = pop_number();
1600         if (n == NULL)
1601                 return;
1602         i = get_ulong(n);
1603         if (i == BN_MASK2)
1604                 warnx("J command requires a number >= 0");
1605         else if (i > 0 && bmachine.readsp < i)
1606                 warnx("J command argument exceeded string execution depth");
1607         else {
1608                 while (i-- > 0) {
1609                         src_free();
1610                         bmachine.readsp--;
1611                 }
1612                 skip_until_mark();
1613         }
1614 }
1615
1616 static void
1617 skip_until_mark(void)
1618 {
1619
1620         for (;;) {
1621                 switch (readch()) {
1622                 case 'M':
1623                         return;
1624                 case EOF:
1625                         errx(1, "mark not found");
1626                         return;
1627                 case 'l':
1628                 case 'L':
1629                 case 's':
1630                 case 'S':
1631                 case ':':
1632                 case ';':
1633                 case '<':
1634                 case '>':
1635                 case '=':
1636                         readreg();
1637                         if (readch() == 'e')
1638                                 readreg();
1639                         else
1640                                 unreadch();
1641                         break;
1642                 case '[':
1643                         free(read_string(&bmachine.readstack[bmachine.readsp]));
1644                         break;
1645                 case '!':
1646                         switch (readch()) {
1647                                 case '<':
1648                                 case '>':
1649                                 case '=':
1650                                         readreg();
1651                                         if (readch() == 'e')
1652                                                 readreg();
1653                                         else
1654                                                 unreadch();
1655                                         break;
1656                                 default:
1657                                         free(readline());
1658                                         break;
1659                         }
1660                         break;
1661                 default:
1662                         break;
1663                 }
1664         }
1665 }
1666
1667 static void
1668 parse_number(void)
1669 {
1670
1671         unreadch();
1672         push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1673             bmachine.ibase));
1674 }
1675
1676 static void
1677 unknown(void)
1678 {
1679         int ch = bmachine.readstack[bmachine.readsp].lastchar;
1680         warnx("%c (0%o) is unimplemented", ch, ch);
1681 }
1682
1683 static void
1684 eval_string(char *p)
1685 {
1686         int ch;
1687
1688         if (bmachine.readsp > 0) {
1689                 /* Check for tail call. Do not recurse in that case. */
1690                 ch = readch();
1691                 if (ch == EOF) {
1692                         src_free();
1693                         src_setstring(&bmachine.readstack[bmachine.readsp], p);
1694                         return;
1695                 } else
1696                         unreadch();
1697         }
1698         if (bmachine.readsp == bmachine.readstack_sz - 1) {
1699                 size_t newsz = bmachine.readstack_sz * 2;
1700                 struct source *stack;
1701                 stack = realloc(bmachine.readstack, newsz *
1702                     sizeof(struct source));
1703                 if (stack == NULL)
1704                         err(1, "recursion too deep");
1705                 bmachine.readstack_sz = newsz;
1706                 bmachine.readstack = stack;
1707         }
1708         src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1709 }
1710
1711 static void
1712 eval_line(void)
1713 {
1714         /* Always read from stdin */
1715         struct source in;
1716         char *p;
1717
1718         clearerr(stdin);
1719         src_setstream(&in, stdin);
1720         p = (*in.vtable->readline)(&in);
1721         eval_string(p);
1722 }
1723
1724 static void
1725 eval_tos(void)
1726 {
1727         char *p;
1728
1729         p = pop_string();
1730         if (p == NULL)
1731                 return;
1732         eval_string(p);
1733 }
1734
1735 void
1736 eval(void)
1737 {
1738         int ch;
1739
1740         for (;;) {
1741                 ch = readch();
1742                 if (ch == EOF) {
1743                         if (bmachine.readsp == 0)
1744                                 return;
1745                         src_free();
1746                         bmachine.readsp--;
1747                         continue;
1748                 }
1749                 if (bmachine.interrupted) {
1750                         if (bmachine.readsp > 0) {
1751                                 src_free();
1752                                 bmachine.readsp--;
1753                                 continue;
1754                         } else
1755                                 bmachine.interrupted = false;
1756                 }
1757 #ifdef DEBUGGING
1758                 fprintf(stderr, "# %c\n", ch);
1759                 stack_print(stderr, &bmachine.stack, "* ",
1760                     bmachine.obase);
1761                 fprintf(stderr, "%zd =>\n", bmachine.readsp);
1762 #endif
1763
1764                 if (0 <= ch && ch < (signed)UCHAR_MAX)
1765                         (*jump_table[ch])();
1766                 else
1767                         warnx("internal error: opcode %d", ch);
1768
1769 #ifdef DEBUGGING
1770                 stack_print(stderr, &bmachine.stack, "* ",
1771                     bmachine.obase);
1772                 fprintf(stderr, "%zd ==\n", bmachine.readsp);
1773 #endif
1774         }
1775 }