Mercurial > hg > index.cgi
comparison lwlib/lw_expr.c @ 249:1f1a28b797e1
Add trap for divide by zero in expression library
Added a trap for division by zero in the expression library and adjusted
lwasm to use it and report division by zero errors instead of crashing with
a cryptic "arithmetic exception" or even more mysterious "floating point
exception".
author | William Astle <lost@l-w.ca> |
---|---|
date | Fri, 25 Jan 2013 21:48:01 -0700 |
parents | 348e2816ce32 |
children | 644f8abf87dc |
comparison
equal
deleted
inserted
replaced
248:891bab942b5a | 249:1f1a28b797e1 |
---|---|
35 static lw_expr_fn3_t *parse_term = NULL; | 35 static lw_expr_fn3_t *parse_term = NULL; |
36 | 36 |
37 /* Q&D to break out of infinite recursion */ | 37 /* Q&D to break out of infinite recursion */ |
38 static int level = 0; | 38 static int level = 0; |
39 static int bailing = 0; | 39 static int bailing = 0; |
40 | |
41 static void (*divzero)(void *priv) = NULL; | |
42 | |
43 void lw_expr_setdivzero(void (*fn)(void *priv)) | |
44 { | |
45 divzero = fn; | |
46 } | |
47 | |
48 static void lw_expr_divzero(void *priv) | |
49 { | |
50 if (divzero) | |
51 (*divzero)(priv); | |
52 else | |
53 fprintf(stderr, "Divide by zero in lw_expr!\n"); | |
54 } | |
40 | 55 |
41 int lw_expr_istype(lw_expr_t e, int t) | 56 int lw_expr_istype(lw_expr_t e, int t) |
42 { | 57 { |
43 /* NULL expression is never of any type */ | 58 /* NULL expression is never of any type */ |
44 if (!e) | 59 if (!e) |
717 for (o = E -> operands -> next; o; o = o -> next) | 732 for (o = E -> operands -> next; o; o = o -> next) |
718 tr *= o -> p -> value; | 733 tr *= o -> p -> value; |
719 break; | 734 break; |
720 | 735 |
721 case lw_expr_oper_divide: | 736 case lw_expr_oper_divide: |
737 if (E -> operands -> next -> p -> value == 0) | |
738 { | |
739 tr = 0; | |
740 lw_expr_divzero(priv); | |
741 break; | |
742 } | |
722 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; | 743 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; |
723 break; | 744 break; |
724 | 745 |
725 case lw_expr_oper_mod: | 746 case lw_expr_oper_mod: |
726 tr = E -> operands -> p -> value % E -> operands -> next -> p -> value; | 747 tr = E -> operands -> p -> value % E -> operands -> next -> p -> value; |
727 break; | 748 break; |
728 | 749 |
729 case lw_expr_oper_intdiv: | 750 case lw_expr_oper_intdiv: |
751 if (E -> operands -> next -> p -> value == 0) | |
752 { | |
753 tr = 0; | |
754 lw_expr_divzero(priv); | |
755 break; | |
756 } | |
730 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; | 757 tr = E -> operands -> p -> value / E -> operands -> next -> p -> value; |
731 break; | 758 break; |
732 | 759 |
733 case lw_expr_oper_bwand: | 760 case lw_expr_oper_bwand: |
734 tr = E -> operands -> p -> value & E -> operands -> next -> p -> value; | 761 tr = E -> operands -> p -> value & E -> operands -> next -> p -> value; |