4 * Copyright (c) 1987-2007 Sun Microsystems, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include "functions.h"
35 #include "ce_parser.h"
36 #include "lr_parser.h"
52 memset(dup
, 0, len
+1);
53 strncpy(dup
, str
, len
);
60 make_exp(char *number
, int t
[MP_SIZE
])
70 a
= gc_strdup(number
);
73 for (i
= 0; !((a
[i
] == 'e') || (a
[i
] == 'E')); i
++) {
80 MPstr_to_num(a
, v
->base
, MP_a
);
81 MPstr_to_num(b
, v
->base
, MP_b
);
85 calc_xtimestenpowx(MP_a
, MP_c
, t
);
87 calc_xtimestenpowx(MP_a
, MP_b
, t
);
95 update_undo_redo_button_sensitivity(void)
100 if (v
->h
.current
!= v
->h
.end
) {
104 if (v
->h
.current
!= v
->h
.begin
) {
108 ui_set_undo_enabled(undo
, redo
);
113 clear_undo_history(void)
116 while (i
!= v
->h
.end
) {
117 if (i
!= v
->h
.current
) {
118 free(v
->h
.e
[i
].expression
);
119 v
->h
.e
[i
].expression
= NULL
;
121 i
= ((i
+ 1) % UNDO_HISTORY_LENGTH
);
123 v
->h
.begin
= v
->h
.end
= v
->h
.current
;
124 update_undo_redo_button_sensitivity();
131 return &(v
->h
.e
[v
->h
.current
]);
136 copy_state(struct exprm_state
*dst
, struct exprm_state
*src
)
138 MEMCPY(dst
, src
, sizeof(struct exprm_state
));
139 dst
->expression
= gc_strdup(src
->expression
);
144 purge_redo_history(void)
146 if (v
->h
.current
!= v
->h
.end
) {
147 int i
= v
->h
.current
;
150 i
= ((i
+ 1) % UNDO_HISTORY_LENGTH
);
151 free(v
->h
.e
[i
].expression
);
152 v
->h
.e
[i
].expression
= NULL
;
153 } while (i
!= v
->h
.end
);
156 v
->h
.end
= v
->h
.current
;
165 purge_redo_history();
168 v
->h
.end
= v
->h
.current
= ((v
->h
.current
+ 1) % UNDO_HISTORY_LENGTH
);
169 if (v
->h
.current
== v
->h
.begin
) {
170 free(v
->h
.e
[v
->h
.begin
].expression
);
171 v
->h
.e
[v
->h
.begin
].expression
= NULL
;
172 v
->h
.begin
= ((v
->h
.begin
+ 1) % UNDO_HISTORY_LENGTH
);
175 copy_state(&(v
->h
.e
[v
->h
.current
]), &(v
->h
.e
[c
]));
176 update_undo_redo_button_sensitivity();
183 if (v
->h
.current
!= v
->h
.begin
) {
184 v
->h
.current
= ((v
->h
.current
- 1) % UNDO_HISTORY_LENGTH
);
185 ui_set_statusbar("", "");
187 ui_set_statusbar(_("No undo history"), "gtk-dialog-warning");
189 update_undo_redo_button_sensitivity();
196 return(v
->h
.current
!= v
->h
.begin
);
203 if (v
->h
.current
!= v
->h
.end
) {
204 v
->h
.current
= ((v
->h
.current
+ 1) % UNDO_HISTORY_LENGTH
);
205 ui_set_statusbar("", "");
207 ui_set_statusbar(_("No redo steps"), "gtk-dialog-warning");
209 update_undo_redo_button_sensitivity();
214 do_accuracy(int value
) /* Set display accuracy. */
217 set_int_resource(R_ACCURACY
, v
->accuracy
);
218 ui_set_accuracy(v
->accuracy
);
220 clear_undo_history();
221 syntaxdep_show_display();
226 do_business() /* Perform special business mode calculations. */
228 if (v
->current
== KEY_FINC_CTRM
) {
229 calc_ctrm(v
->MPdisp_val
);
230 } else if (v
->current
== KEY_FINC_DDB
) {
231 calc_ddb(v
->MPdisp_val
);
232 } else if (v
->current
== KEY_FINC_FV
) {
233 calc_fv(v
->MPdisp_val
);
234 } else if (v
->current
== KEY_FINC_PMT
) {
235 calc_pmt(v
->MPdisp_val
);
236 } else if (v
->current
== KEY_FINC_PV
) {
237 calc_pv(v
->MPdisp_val
);
238 } else if (v
->current
== KEY_FINC_RATE
) {
239 calc_rate(v
->MPdisp_val
);
240 } else if (v
->current
== KEY_FINC_SLN
) {
241 calc_sln(v
->MPdisp_val
);
242 } else if (v
->current
== KEY_FINC_SYD
) {
243 calc_syd(v
->MPdisp_val
);
244 } else if (v
->current
== KEY_FINC_TERM
) {
245 calc_term(v
->MPdisp_val
);
247 show_display(v
->MPdisp_val
);
252 exp_append(char *text
)
255 int orig_len
, dest_len
;
256 struct exprm_state
*e
;
264 orig_len
= (e
->expression
) ? strlen(e
->expression
) : 0;
265 dest_len
= orig_len
+ strlen(text
) +1;
266 buf
= malloc(dest_len
);
269 if (snprintf(buf
, dest_len
, "%s%s", e
->expression
, text
) < 0) {
283 struct exprm_state
*e
= get_state();
285 e
->expression
= NULL
;
290 usable_num(int MPnum
[MP_SIZE
])
294 struct exprm_state
*e
= get_state();
297 ret
= ce_parse(e
->expression
, MPnum
);
307 exp_del_char(char **expr
, int amount
)
323 SNPRINTF(e
, len
+1, "%s", *expr
);
332 exp_replace(char *text
)
334 struct exprm_state
*e
= get_state();
336 e
->expression
= NULL
;
344 struct exprm_state
*e
= get_state();
347 /* Ending zero + parenthesis + minus */
348 int len
= strlen(e
->expression
) + 4;
349 char *exp
= malloc(len
);
352 if (snprintf(exp
, len
, "-(%s)", e
->expression
) < 0) {
364 struct exprm_state
*e
= get_state();
367 /* Ending zero + 1/ + parenthesis */
368 int len
= strlen(e
->expression
) + 5;
369 char *exp
= malloc(len
);
372 if (snprintf(exp
, len
, "1/(%s)", e
->expression
) < 0) {
382 exp_has_postfix(char *str
, char *postfix
)
393 plen
= strlen(postfix
);
399 if (!strcasecmp(str
+ len
- plen
, postfix
)) {
408 str_replace(char **str
, char *from
, char *to
)
424 for (i
= 0; len
-i
>= flen
; i
++) {
425 if (!strncasecmp(from
, *str
+i
, flen
)) {
428 char *prefix
= malloc(i
+1);
429 char *postfix
= malloc(len
-j
+1);
431 assert(prefix
&& postfix
);
432 memset(prefix
, 0, i
+1);
433 memset(postfix
, 0, len
-j
+1);
434 MEMCPY(prefix
, *str
, i
);
435 MEMCPY(postfix
, *str
+i
+flen
, len
-j
);
437 print
= malloc(strlen(to
)+i
+len
-j
+1);
438 SPRINTF(print
, "%s%s%s", prefix
, to
, postfix
);
453 struct exprm_state
*e
;
457 ui_set_statusbar("", "");
459 if (e
->expression
!= NULL
&& strlen(e
->expression
) > 0) {
460 if (!strcmp(e
->expression
, "Ans")) {
461 if (e
->button
.flags
& NUMBER
) {
466 if (e
->button
.flags
& POSTFIXOP
) {
470 zero
= make_number(MP1
, v
->base
, FALSE
);
475 if ((e
->button
.flags
& (PREFIXOP
| FUNC
))
477 && !strcmp(e
->expression
, "Ans")) {
478 SNPRINTF(buf
, MAXLINE
, "%s(Ans)", e
->button
.symname
);
481 switch (e
->button
.id
) {
483 case KEY_CLEAR_ENTRY
:
485 ui_set_error_state(FALSE
);
486 MPstr_to_num("0", DEC
, e
->ans
);
493 case KEY_SET_ACCURACY
:
494 do_accuracy(e
->value
);
498 do_function(e
->value
);
506 do_exchange(e
->value
);
510 SNPRINTF(buf
, MAXLINE
, "R%d", e
->value
);
515 exp_append(make_number(v
->MPcon_vals
[e
->value
], v
->base
, FALSE
));
519 if (exp_has_postfix(e
->expression
, "Ans")) {
520 char *ans
= make_number(e
->ans
, v
->base
, FALSE
);
521 str_replace(&e
->expression
, "Ans", ans
);
523 for (i
= 0; i
< 10; i
++) {
524 SNPRINTF(buf
, MAXLINE
, "R%d", i
);
525 if (exp_has_postfix(e
->expression
, buf
)) {
529 do_rcl_reg(i
, MP_reg
);
530 reg_val
= make_number(MP_reg
, v
->base
, FALSE
);
531 /* Remove "Rx" postfix. */
532 exp_del_char(&e
->expression
, 2);
537 exp_del_char(&e
->expression
, 1);
540 case KEY_CHANGE_SIGN
:
550 if (strcmp(e
->expression
, "Ans")) {
552 int ret
= ce_parse(e
->expression
, MPval
);
555 mpstr(MPval
, e
->ans
);
558 char *message
= NULL
;
561 case -PARSER_ERR_INVALID_BASE
:
562 message
= _("Invalid number for the current base");
565 case -PARSER_ERR_TOO_LONG_NUMBER
:
566 message
= _("Too long number");
569 case -PARSER_ERR_BITWISEOP
:
570 message
= _("Invalid bitwise operation parameter(s)");
573 case -PARSER_ERR_MODULUSOP
:
574 message
= _("Invalid modulus operation parameter(s)");
578 message
= _("Math operation error");
582 message
= _("Malformed expression");
584 ui_set_statusbar(message
, "gtk-dialog-error");
588 if (is_undo_step()) {
595 case KEY_NUMERIC_POINT
:
596 exp_append(ui_get_localized_numeric_point());
600 exp_append(e
->button
.symname
);
601 if (e
->button
.flags
& FUNC
) {
613 do_calc() /* Perform arithmetic calculation and display result. */
616 int MP1
[MP_SIZE
], MP2
[MP_SIZE
];
618 if (v
->current
== KEY_CALCULATE
&&
619 v
->old_cal_value
== KEY_CALCULATE
) {
621 mpstr(v
->MPlast_input
, v
->MPresult
);
623 mpstr(v
->MPlast_input
, v
->MPdisp_val
);
627 if (v
->current
!= KEY_CALCULATE
&&
628 v
->old_cal_value
== KEY_CALCULATE
) {
646 mpstr(v
->MPdisp_val
, v
->MPresult
);
650 mpadd(v
->MPresult
, v
->MPdisp_val
, v
->MPresult
);
654 mpsub(v
->MPresult
, v
->MPdisp_val
, v
->MPresult
);
658 mpmul(v
->MPresult
, v
->MPdisp_val
, v
->MPresult
);
662 mpdiv(v
->MPresult
, v
->MPdisp_val
, v
->MPresult
);
665 case KEY_MODULUS_DIVIDE
:
666 mpcmim(v
->MPresult
, MP1
);
667 mpcmim(v
->MPdisp_val
, MP2
);
668 if (!mpeq(v
->MPresult
, MP1
) || !mpeq(v
->MPdisp_val
, MP2
)) {
669 doerr(_("Error, operands must be integers"));
672 mpdiv(v
->MPresult
, v
->MPdisp_val
, MP1
);
674 mpmul(MP1
, v
->MPdisp_val
, MP2
);
675 mpsub(v
->MPresult
, MP2
, v
->MPresult
);
679 calc_xpowy(v
->MPresult
, v
->MPdisp_val
, v
->MPresult
);
683 mpcmd(v
->MPresult
, &dres
);
684 mpcmd(v
->MPdisp_val
, &dval
);
685 dres
= setbool(ibool(dres
) & ibool(dval
));
686 mpcdm(&dres
, v
->MPresult
);
690 mpcmd(v
->MPresult
, &dres
);
691 mpcmd(v
->MPdisp_val
, &dval
);
692 dres
= setbool(ibool(dres
) | ibool(dval
));
693 mpcdm(&dres
, v
->MPresult
);
697 mpcmd(v
->MPresult
, &dres
);
698 mpcmd(v
->MPdisp_val
, &dval
);
699 dres
= setbool(ibool(dres
) ^ ibool(dval
));
700 mpcdm(&dres
, v
->MPresult
);
704 mpcmd(v
->MPresult
, &dres
);
705 mpcmd(v
->MPdisp_val
, &dval
);
706 dres
= setbool(~ibool(dres
) ^ ibool(dval
));
707 mpcdm(&dres
, v
->MPresult
);
713 show_display(v
->MPresult
);
715 if (!(v
->current
== KEY_CALCULATE
&&
716 v
->old_cal_value
== KEY_CALCULATE
)) {
717 mpstr(v
->MPdisp_val
, v
->MPlast_input
);
720 mpstr(v
->MPresult
, v
->MPdisp_val
);
721 if (v
->current
!= KEY_CALCULATE
) {
722 v
->cur_op
= v
->current
;
724 v
->old_cal_value
= v
->current
;
725 v
->new_input
= v
->key_exp
= 0;
732 calc_trigfunc(sin_t
, v
->MPdisp_val
, v
->MPresult
);
733 show_display(v
->MPresult
);
734 mpstr(v
->MPresult
, v
->MPdisp_val
);
741 calc_trigfunc(sinh_t
, v
->MPdisp_val
, v
->MPresult
);
742 show_display(v
->MPresult
);
743 mpstr(v
->MPresult
, v
->MPdisp_val
);
750 calc_trigfunc(asin_t
, v
->MPdisp_val
, v
->MPresult
);
751 show_display(v
->MPresult
);
752 mpstr(v
->MPresult
, v
->MPdisp_val
);
759 calc_trigfunc(asinh_t
, v
->MPdisp_val
, v
->MPresult
);
760 show_display(v
->MPresult
);
761 mpstr(v
->MPresult
, v
->MPdisp_val
);
768 calc_trigfunc(cos_t
, v
->MPdisp_val
, v
->MPresult
);
769 show_display(v
->MPresult
);
770 mpstr(v
->MPresult
, v
->MPdisp_val
);
777 calc_trigfunc(cosh_t
, v
->MPdisp_val
, v
->MPresult
);
778 show_display(v
->MPresult
);
779 mpstr(v
->MPresult
, v
->MPdisp_val
);
786 calc_trigfunc(acos_t
, v
->MPdisp_val
, v
->MPresult
);
787 show_display(v
->MPresult
);
788 mpstr(v
->MPresult
, v
->MPdisp_val
);
795 calc_trigfunc(acosh_t
, v
->MPdisp_val
, v
->MPresult
);
796 show_display(v
->MPresult
);
797 mpstr(v
->MPresult
, v
->MPdisp_val
);
804 calc_trigfunc(tan_t
, v
->MPdisp_val
, v
->MPresult
);
805 show_display(v
->MPresult
);
806 mpstr(v
->MPresult
, v
->MPdisp_val
);
813 calc_trigfunc(tanh_t
, v
->MPdisp_val
, v
->MPresult
);
814 show_display(v
->MPresult
);
815 mpstr(v
->MPresult
, v
->MPdisp_val
);
822 calc_trigfunc(atan_t
, v
->MPdisp_val
, v
->MPresult
);
823 show_display(v
->MPresult
);
824 mpstr(v
->MPresult
, v
->MPdisp_val
);
831 calc_trigfunc(atanh_t
, v
->MPdisp_val
, v
->MPresult
);
832 show_display(v
->MPresult
);
833 mpstr(v
->MPresult
, v
->MPdisp_val
);
840 calc_percent(v
->MPdisp_val
, v
->MPresult
);
841 show_display(v
->MPresult
);
842 mpstr(v
->MPresult
, v
->MPdisp_val
);
847 do_clear() /* Clear the calculator display and re-initialise. */
858 do_clear_entry() /* Clear the calculator display. */
860 clear_display(FALSE
);
864 do_base(enum base_type b
) /* Change the current base setting. */
866 struct exprm_state
*e
;
867 int ret
, MP
[MP_SIZE
];
872 set_resource(R_BASE
, Rbstr
[(int) v
->base
]);
873 ui_set_base(v
->base
);
879 ret
= usable_num(MP
);
882 ui_set_statusbar(_("No sane value to convert"),
884 } else if (!v
->ghost_zero
) {
889 set_resource(R_BASE
, Rbstr
[(int) v
->base
]);
890 ui_set_base(v
->base
);
892 clear_undo_history();
904 do_constant(int index
)
907 struct exprm_state
*e
;
914 MPval
= v
->MPcon_vals
[index
];
915 mpstr(MPval
, v
->MPdisp_val
);
928 syntaxdep_show_display();
933 do_delete() /* Remove the last numeric character typed. */
937 len
= strlen(v
->display
);
939 v
->display
[len
-1] = '\0';
942 /* If we were entering a scientific number, and we have backspaced over
943 * the exponent sign, then this reverts to entering a fixed point number.
946 if (v
->key_exp
&& !(strchr(v
->display
, '+'))) {
948 v
->display
[strlen(v
->display
)-1] = '\0';
951 /* If we've backspaced over the numeric point, clear the pointed flag. */
953 if (v
->pointed
&& !(strchr(v
->display
, '.'))) {
957 ui_set_display(v
->display
);
958 MPstr_to_num(v
->display
, v
->base
, v
->MPdisp_val
);
960 if (v
->dtype
== FIX
) {
961 STRCPY(v
->fnum
, v
->display
);
962 ui_set_display(v
->fnum
);
968 do_exchange(int index
) /* Exchange display with memory register. */
972 struct exprm_state
*e
;
978 mpstr(v
->MPdisp_val
, MPtemp
);
979 mpstr(v
->MPmvals
[index
], v
->MPdisp_val
);
980 mpstr(MPtemp
, v
->MPmvals
[index
]);
986 ret
= usable_num(MPexpr
);
990 ui_set_statusbar(_("No sane value to store"),
993 mpstr(v
->MPmvals
[n
], MPtemp
);
994 mpstr(MPexpr
, v
->MPmvals
[n
]);
995 mpstr(MPtemp
, e
->ans
);
1007 syntaxdep_show_display();
1013 do_expno() /* Get exponential number. */
1015 v
->pointed
= (strchr(v
->display
, '.') != NULL
);
1016 if (!v
->new_input
) {
1017 STRCPY(v
->display
, "1.0 +");
1018 v
->new_input
= v
->pointed
= 1;
1019 } else if (!v
->pointed
) {
1020 STRNCAT(v
->display
, ". +", 3);
1022 } else if (!v
->key_exp
) {
1023 STRNCAT(v
->display
, " +", 2);
1027 v
->exp_posn
= strchr(v
->display
, '+');
1028 ui_set_display(v
->display
);
1029 MPstr_to_num(v
->display
, v
->base
, v
->MPdisp_val
);
1033 /* Calculate the factorial of MPval. */
1036 do_factorial(int *MPval
, int *MPres
)
1039 int i
, MPa
[MP_SIZE
], MP1
[MP_SIZE
], MP2
[MP_SIZE
];
1041 /* NOTE: do_factorial, on each iteration of the loop, will attempt to
1042 * convert the current result to a double. If v->error is set,
1043 * then we've overflowed. This is to provide the same look&feel
1046 * XXX: Needs to be improved. Shouldn't need to convert to a double in
1047 * order to check this.
1054 if (mpeq(MPval
, MP1
) && mpge(MPval
, MP2
)) { /* Only positive integers. */
1056 if (mpeq(MP1
, MP2
)) { /* Special case for 0! */
1063 matherr((struct exception
*) NULL
);
1066 mpmuli(MPa
, &i
, MPa
);
1076 matherr((struct exception
*) NULL
);
1083 do_function(int index
) /* Perform a user defined function. */
1091 switch (v
->syntax
) {
1093 str
= v
->fun_vals
[index
];
1095 ret
= lr_udf_parse(str
);
1099 str
= v
->fun_vals
[index
];
1101 ret
= ce_udf_parse(str
);
1109 ui_set_statusbar("", "");
1111 ui_set_statusbar(_("Malformed function"), "gtk-dialog-error");
1118 do_immedfunc(int s
[MP_SIZE
], int t
[MP_SIZE
])
1122 if (v
->current
== KEY_MASK_32
) { /* &32 */
1124 } else if (v
->current
== KEY_MASK_16
) { /* &16 */
1126 } else if (v
->current
== KEY_E_POW_X
) { /* e^x */
1129 } else if (v
->current
== KEY_10_POW_X
) { /* 10^x */
1131 } else if (v
->current
== KEY_NATURAL_LOGARITHM
) { /* Ln */
1134 } else if (v
->current
== KEY_LOGARITHM
) { /* Log */
1136 } else if (v
->current
== KEY_RANDOM
) { /* Rand */
1138 } else if (v
->current
== KEY_SQUARE_ROOT
) { /* Sqrt */
1141 } else if (v
->current
== KEY_NOT
) { /* NOT */
1143 } else if (v
->current
== KEY_RECIPROCAL
) { /* 1/x */
1145 } else if (v
->current
== KEY_FACTORIAL
) { /* x! */
1146 do_factorial(s
, MP1
);
1148 } else if (v
->current
== KEY_SQUARE
) { /* x^2 */
1151 } else if (v
->current
== KEY_CHANGE_SIGN
) { /* +/- */
1153 if (*v
->exp_posn
== '+') {
1158 ui_set_display(v
->display
);
1159 MPstr_to_num(v
->display
, v
->base
, s
);
1171 do_immedfunc(v
->MPdisp_val
, v
->MPdisp_val
);
1172 show_display(v
->MPdisp_val
);
1177 do_mode(int toclear
) /* Set special calculator mode. */
1179 set_resource(R_MODE
, Rmstr
[(int) v
->modetype
]);
1180 ui_set_mode(v
->modetype
);
1196 offset
= strlen(v
->display
);
1198 if (offset
< MAXLINE
) {
1199 SNPRINTF(v
->display
+offset
, MAXLINE
-offset
, "%s", buttons
[v
->current
].symname
);
1202 ui_set_display(v
->display
);
1203 MPstr_to_num(v
->display
, v
->base
, v
->MPdisp_val
);
1209 do_numtype(enum num_type n
) /* Set number display type. */
1211 struct exprm_state
*e
;
1212 int ret
, MP
[MP_SIZE
];
1215 set_resource(R_DISPLAY
, Rdstr
[(int) v
->dtype
]);
1217 switch (v
->syntax
) {
1219 ui_make_registers();
1224 ret
= usable_num(MP
);
1226 ui_set_statusbar(_("No sane value to convert"),
1227 "gtk-dialog-error");
1228 } else if (!v
->ghost_zero
) {
1231 ui_make_registers();
1233 clear_undo_history();
1247 ui_set_statusbar("", "");
1249 switch (v
->current
) {
1250 case KEY_START_BLOCK
:
1251 if (v
->noparens
== 0) {
1252 if (v
->cur_op
== -1) {
1254 ui_set_statusbar(_("Cleared display, prefix without an operator is not allowed"), "");
1256 paren_disp(v
->cur_op
);
1266 while (v
->display
[i
++] != '(') {
1270 ret
= lr_parse(&v
->display
[i
], v
->MPdisp_val
);
1272 show_display(v
->MPdisp_val
);
1275 ui_set_statusbar(_("Malformed parenthesis expression"),
1276 "gtk-dialog-error");
1285 paren_disp(v
->current
);
1294 switch (v
->syntax
) {
1296 mpstr(v
->MPdisp_val
, v
->MPmvals
[index
]);
1300 ret
= usable_num(v
->MPmvals
[index
]);
1302 ui_set_statusbar(_("No sane value to store"),
1303 "gtk-dialog-error");
1311 ui_make_registers();
1315 /* Return: 0 = success, otherwise failed.
1317 * TODO: remove hardcoding from reg ranges.
1321 do_sto_reg(int reg
, int value
[MP_SIZE
])
1323 if ((reg
>= 0) && (reg
<= 10)) {
1324 mpstr(value
, v
->MPmvals
[reg
]);
1335 switch (v
->syntax
) {
1337 mpstr(v
->MPmvals
[index
], v
->MPdisp_val
);
1349 syntaxdep_show_display();
1353 /* Return: 0 = success, otherwise failed.
1355 * TODO: remove hardcoding from reg ranges.
1359 do_rcl_reg(int reg
, int value
[MP_SIZE
])
1361 if ((reg
>= 0) && (reg
<= 10)) {
1362 mpstr(v
->MPmvals
[reg
], value
);
1371 syntaxdep_show_display()
1373 switch (v
->syntax
) {
1375 show_display(v
->MPdisp_val
);
1389 do_point() /* Handle numeric point. */
1393 STRCPY(v
->display
, ".");
1396 STRCAT(v
->display
, ".");
1400 ui_set_display(v
->display
);
1401 MPstr_to_num(v
->display
, v
->base
, v
->MPdisp_val
);
1406 do_portionfunc(int num
[MP_SIZE
])
1410 if (v
->current
== KEY_ABSOLUTE_VALUE
) { /* Abs */
1414 } else if (v
->current
== KEY_FRACTION
) { /* Frac */
1418 } else if (v
->current
== KEY_INTEGER
) { /* Int */
1428 do_portionfunc(v
->MPdisp_val
);
1429 show_display(v
->MPdisp_val
);
1434 do_shift(int count
) /* Perform bitwise shift on display value. */
1439 struct exprm_state
*e
;
1440 int MPtemp
[MP_SIZE
], MPval
[MP_SIZE
];
1442 switch (v
->syntax
) {
1444 MPstr_to_num(v
->display
, v
->base
, MPtemp
);
1445 mpcmd(MPtemp
, &dval
);
1449 temp
= temp
>> -count
;
1451 temp
= temp
<< count
;
1454 dval
= setbool(temp
);
1455 mpcdm(&dval
, v
->MPdisp_val
);
1456 show_display(v
->MPdisp_val
);
1457 mpstr(v
->MPdisp_val
, v
->MPlast_input
);
1463 ret
= usable_num(MPval
);
1464 if (ret
|| !is_integer(MPval
)) {
1465 ui_set_statusbar(_("No sane value to do bitwise shift"),
1466 "gtk-dialog-error");
1470 calc_shift(MPval
, e
->ans
, n
);
1480 syntaxdep_show_display();
1485 do_trigtype(enum trig_type t
) /* Change the current trigonometric type. */
1488 set_resource(R_TRIG
, Rtstr
[(int) v
->ttype
]);
1489 switch (v
->cur_op
) {
1502 mpstr(v
->MPtresults
[(int) v
->ttype
], v
->MPdisp_val
);
1503 show_display(v
->MPtresults
[(int) v
->ttype
]);
1512 show_error(char *message
)
1514 ui_set_statusbar(message
, "gtk-dialog-error");