|
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) ; }