|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 8741 (0x2225)
Types: TextFile
Names: »functions.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/calctool/functions.c«
/* functions.c
*
* This file contains the seperate functions used whenever a calculator
* button is pressed.
*
* Copyright (c) Rich Burridge - January 1987.
* Sun Microsystems, Australia - All rights reserved.
*
*
* Version 1.2.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if
* reported to me then an attempt will be made to fix them.
*/
#include "calctool.h"
double setbool() ;
extern double convert_display() ;
#ifdef SUNTOOL
extern Canvas canvas ;
extern Cursor main_cursor ;
extern Event event ;
extern Frame frame ;
extern Pixwin *cpw ;
extern struct cursor help_cursor ;
#else
extern struct sgttyb old ;
#endif SUNTOOL
extern FILE *hfd ; /* File descriptor for help information. */
extern struct button buttons[] ; /* Calculator button values. */
/* Length of display in characters for each base. */
extern int disp_length[] ;
extern double disp_val ; /* Value of the current display. */
extern double last_input ; /* Previous number input by user. */
extern double mem_vals[10] ; /* Memory registers. */
extern double result ; /* Current calculator total value. */
extern int accuracy ; /* Number of digits precision (Max 9). */
extern int base ; /* Current base: BIN, OCT, DEC or HEX. */
extern int new_input ; /* New number input since last op. */
extern int nohelp ; /* Indicates if a help file was found. */
extern int pointed ; /* Whether a decimal point has been given. */
extern int toclear ; /* Indicates if display should be cleared. */
extern char cur_op ; /* Current arithmetic operation. */
extern char cur_value ; /* Current button or character pressed. */
extern char old_cal_value ; /* Previous calculation operator. */
extern char display[MAXLINE] ; /* Current calculator display. */
do_accuracy() /* Get value for number of digits accuracy. */
{
int n,valid ;
valid = 0 ;
while (!valid)
{
n = get_next_value() ;
if (buttons[n].value >= '0' && buttons[n].value <= '9')
{
accuracy = char_val(buttons[n].value) ;
valid = 1 ;
}
}
make_number(disp_val) ;
}
do_base() /* Change the current base setting. */
{
switch (cur_value)
{
case 'B' : base = BIN ;
break ;
case 'O' : base = OCT ;
break ;
case 'D' : base = DEC ;
break ;
case 'H' : base = HEX ;
}
display_base(base) ;
make_number(disp_val) ; /* Convert display value to current base. */
}
do_calculation() /* Perform arithmetic calculation and display result. */
{
int isboolean ;
BOOLEAN temp ;
if (cur_value == '=' && old_cal_value == '=')
if (new_input) result = last_input ;
else disp_val = last_input ;
if (cur_value != '=' && old_cal_value == '=') cur_op = '?' ;
isboolean = 0 ;
switch (cur_op)
{
case '?' : result = disp_val ; /* Undefined. */
break ;
case '+' : result += disp_val ; /* Addition. */
break ;
case '-' : result -= disp_val ; /* Subtraction. */
break ;
case 'x' :
case 'X' : result *= disp_val ; /* Multiplication. */
break ;
case '/' : result /= disp_val ; /* Division. */
break ;
case '&' : temp = (BOOLEAN) result & (BOOLEAN) disp_val ; /* AND. */
isboolean = 1 ;
break ;
case '|' : temp = (BOOLEAN) result | (BOOLEAN) disp_val ; /* OR. */
isboolean = 1 ;
break ;
case '^' : temp = (BOOLEAN) result ^ (BOOLEAN) disp_val ; /* XOR. */
isboolean = 1 ;
break ;
case 'n' :
case 'N' : temp = (BOOLEAN) result ^ (BOOLEAN) disp_val ; /* XNOR. */
temp = ~((BOOLEAN) temp) ;
isboolean = 1 ;
break ;
case '\015' :
case '=' : break ; /* Equals. */
}
if (isboolean) result = setbool(temp) ;
make_number(result) ;
if (!(cur_value == '=' && old_cal_value == '=')) last_input = disp_val ;
disp_val = result ;
if (cur_value != '=') cur_op = cur_value ;
old_cal_value = cur_value ;
new_input = 0 ;
}
do_clear() /* Clear the calculator display and re-initialise. */
{
clear_display() ;
initialise() ;
}
do_close() /* Close the window to its iconic form. */
{
#ifdef SUNTOOL
window_set(frame,FRAME_CLOSED,TRUE,0) ;
#endif SUNTOOL
}
do_delete() /* Remove the last numeric character typed. */
{
if (strlen(display)) display[strlen(display)-1] = '\0' ;
display_result(display) ;
disp_val = convert_display() ; /* Convert input to a number. */
}
do_help()
{
char help_str[MAXLINE],nextline[MAXLINE],*p ;
int n,y ;
n = get_next_value() ;
#ifdef SUNTOOL
window_set(canvas,WIN_CURSOR,&help_cursor,0) ;
pw_writebackground(cpw,0,0,TOTAL_WIDTH,TOTAL_HEIGHT,PIX_CLR) ;
#endif SUNTOOL
if (nohelp) make_text(20,20,"No help file found.") ;
else
{
SPRINTF(help_str,"%%%s%%\n",buttons[n].str) ;
rewind(hfd) ;
while (p = fgets(nextline,BUFSIZ,hfd))
if (*p == '%' && EQUAL(p,help_str)) break ;
y = 15 ;
for (;;)
{
FGETS(nextline,BUFSIZ,hfd) ;
if (EQUAL(nextline,"%%\n")) break ;
nextline[strlen(nextline)-1] = '\0' ;
make_text(5,y,nextline) ;
y += 15 ;
}
}
#ifdef SUNTOOL
make_text(5,y+25,DEF_CONT_MSG) ;
for (;;)
{
window_read_event(canvas,&event) ;
if ((event_is_up(&event) && event_is_button(&event)) ||
(event_is_ascii(&event) && event_id(&event))) break ;
}
make_canvas() ;
window_set(canvas,WIN_CURSOR,main_cursor,0) ;
#endif SUNTOOL
}
do_memory() /* Store or retrieve number from memory location. */
{
int n,valid ;
valid = 0 ;
while (!valid)
{
n = get_next_value() ;
if (buttons[n].value >= '0' && buttons[n].value <= '9')
{
switch (cur_value)
{
case 'r' : disp_val = mem_vals[char_val(buttons[n].value)] ;
break ;
case 's' : mem_vals[char_val(buttons[n].value)] = disp_val ;
}
valid = 1 ;
}
}
make_number(disp_val) ;
}
do_not() /* Do logical NOT operation on current display value. */
{
disp_val = setbool(~((BOOLEAN) disp_val)) ;
make_number(disp_val) ;
}
do_number()
{
int n ;
static int maxvals[4] = {1, 7, 9, 15} ;
n = cur_value - '0' ;
if (base == HEX && cur_value >= 'a' && cur_value <= 'f')
n = cur_value - 'a' + 10 ;
if (n > maxvals[base]) return ;
if (toclear)
{
SPRINTF(display,"%c",cur_value) ;
toclear = 0 ;
}
else if (strlen(display) < disp_length[base])
STRNCAT(display,&cur_value,1) ;
make_display(display) ;
disp_val = convert_display() ; /* Convert input to a number. */
new_input = 1 ;
}
do_point() /* Handle numeric point. */
{
if (!pointed)
{
if (toclear)
{
STRCPY(display,".") ;
toclear = 0 ;
}
else if (strlen(display) < disp_length[base])
STRNCAT(display,".",1) ;
pointed = 1 ;
}
make_display(display) ;
disp_val = convert_display() ; /* Convert input to a number. */
}
do_quit() /* Terminate the program. */
{
#ifdef SUNTOOL
window_destroy(frame) ;
#else
IOCTL(fileno(stdin),TIOCSETP,&old) ;
exit(0) ;
#endif SUNTOOL
}
do_shift() /* Shift the display value to the left or the right. */
{
int n,shift,valid ;
BOOLEAN temp ;
valid = 0 ;
while (!valid)
{
n = get_next_value() ;
if (buttons[n].value >= '0' && buttons[n].value <= '9')
{
shift = char_val(buttons[n].value) ;
valid = 1 ;
}
}
temp = (BOOLEAN) convert_display() ;
switch (cur_value)
{
case '<' : temp = temp << shift ;
break ;
case '>' : temp = temp >> shift ;
}
make_number(setbool(temp)) ;
disp_val = last_input = convert_display() ;
}
do_sqrt() /* Square root. */
{
disp_val = sqrt(disp_val) ;
make_number(disp_val) ;
}
double
setbool(p)
BOOLEAN p ;
{
BOOLEAN q ;
double val ;
q = p & 0x80000000 ;
p &= 0x7fffffff ;
val = (double) p ;
if (q) val += 2147483648.0 ;
return(val) ;
}