DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T f

⟦16c444fd2⟧ TextFile

    Length: 8741 (0x2225)
    Types: TextFile
    Names: »functions.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/calctool/functions.c« 

TextFile


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