/* File: chrutil.c */
/* This file contains various utility functions for processing characters */
#include <stdio.h>
#include "tfdef.h"
#include "chrutil.h"
/* Function converts ch to an integer if it is a digit. Otherwise, it
prints an error message.
*/
int dig_to_int(char ch)
{
if (IS_DIGIT(ch))
return ch - '0';
printf("ERROR:dig_to_int: %c is not a digit\n", ch);
return ERROR;
}
/* Function converts a positive integer less than 10 to a corresponding
digit character.
*/
char int_to_dig(int n)
{
if (n >= 0 && n < 10)
return n + '0';
printf("ERROR:int_to_dig: %d is not in the range 0 to 9\n", n);
return NULL;
}
/* Function reads the next integer from the input */
int getint()
{ int n = 0;
int got_dig = FALSE;
signed char ch;
ch = getchar(); /* read next char */
while (IS_WHITE_SPACE(ch)) /* skip white space */
ch = getchar();
while (IS_DIGIT(ch)) { /* repeat as long as ch is a digit */
n = n * 10 + dig_to_int(ch); /* accumulate value in n */
got_dig = TRUE;
#ifdef DEBUG
printf("debug:getint: ch = %c\n", ch); /* debug statement */
printf("debug:getint: n = %d\n", n); /* debug statement */
#endif
ch = getchar(); /* read next char */
}
if(ch == EOF) return EOF; /* test for end of file */
if(!got_dig) return ERROR; /* test for no digits read */
return n; /* otherwise return the result */
}
/* Function tests if c is an alphabetic letter. */
int letterp(char c)
{
if (IS_LOWER(c) || IS_UPPER(c))
return TRUE;
return FALSE;
}
/* Function returns TRUE if c is a delimiter, i.e., it is a white space
or a punctuation. Otherwise, it returns FALSE.
*/
int delimitp(char c)
{
if (whitep(c) || punctp(c))
return TRUE;
return FALSE;
}
/* Function returns TRUE if c is white space; returns FALSE otherwise. */
int whitep(char c)
{
if (c == '\n' || c == '\t' || c == ' ')
return TRUE;
return FALSE;
}
/* Function returns TRUE if c is a punctuation; returns FALSE otherwise. */
int punctp(char c)
{
if (c == '.' || c == ',' || c == ';' || c == ':'
|| c == '?' || c == '!')
return TRUE;
return FALSE;
}
/* Function checks if c is a vowel. */
int vowelp(char c)
{
switch(c) {
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U': return TRUE;
default: return FALSE;
}
}
/* Function tests if c is printable. */
int illegal(char c)
{
if (IS_PRINT(c) || IS_WHITE_SPACE(c))
return FALSE;
return TRUE;
}
/* File: chrutil.h */
/* This file contains various macros and prototypes for character processing */
#define ERROR -2
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define IS_WHITE_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
#define IS_PRINT(c) ((c) >= 32 && (c) < 127)
#define LOWER 0
#define UPPER 1
#define DIGIT 2
#define PUNCT 3
#define SPACE 4
#define CONTROL 5
#define SPECIAL 6
int dig_to_int(char ch);
char int_to_dig(int n);
char uppercase(char ch);
int getint();
int delimitp(char c);
int whitep(char c);
int punctp(char c);
int vowelp(char c);
int letterp(char c);
int illegal(char c); /* Tests if c is legal. */
/* File: compute.h
by: Tep Dobry
date:
*/
/* This file contains the prototypes for functions in compute.c */
int compute_result(int opnd1,char op,int opnd2);
/* This function is given two integer operands and an character operator.
it performs the indicated operation and returns the integer
result.
*/
/* File: display.h
by: Tep Dobry
login: tep
date:
*/
/* This file contains the prototypes for useful funcitons in display.o
library */
#define MYFLUSH(c) while((((c) = getchar()) != '\n') && ((c) != 13));
void write_char(char);
/* This function is given a character and writes it to the display.
The characters recognized to be written include the digits, '0'..'9',
the operators, '+', '-', 'x', '/', and '=', the period, '.', and
the special characters, 'q', ' ', '\n', and '\b'. The
special characters are explained in the documentation.
*/
void write_exp(char);
/* This function is given a character and writes it as an exponent to
the dispaly. The characters recognized to be written are
the digits '0'..'9', and the minus sign, '-'.
*/
void write_message(char *);
/* This function is given a string which is written in the center
of the top line of the display. It also initializes the
dispaly.
*/
void write_error(char *);
/* This function is given a string which is written to the bottom line
of the display and causes the display to beep.
*/
void write_debug(int);
/* This function is given an integer which is written to the bottom line
of the display to be used as debugging output in the program
*/
/* File: driver1.c
by: Tep Dobry
date:
*/
/* This file contains a test driver for experimenting with
the Display Module functions. It simply writes
input characters to the dispaly until quit. It also tests
for exponent characters (shift-number) and converts
and writes those.
*/
#include <stdio.h>
#include "display.h"
#include "exponent.h"
main()
{ char ch;
/* Initialize the dispaly with a message */
write_message("Display Test");
/* while not quitting */
while((ch = getchar()) != 'q')
{
/* if exponent character */
if( is_exp(ch))
/* write the converted exponent character */
write_exp(exp_value(ch));
/* otherwise write the character */
else write_char(ch);
}
/* write the q character to terminate the dispaly */
write_char(ch);
}
/* File: exponent.h
by: Tep Dobry
date:
*/
/* This file contains the prototypes for the functions in exponent.c */
int is_exp(char ch);
/* This function is given a character and returns true if it
is a legal shifted exponent character, false otherwise.
*/
char exp_value(char ch);
/* This function is given a legal shifted exponent character and converts
it to its unshifted form, returning the cnverted character.
*/
float pos_power(float b, int e);
/* This function is given a float base and integer exponent and
raises the base to the exponent, returning the float result.
*/
CALC = /inst/ee/ee160/ee160/Code.lect/Calc
CHAP4 = /inst/ee/ee160/ee160/Code.text/Chap4
calc: calc.o display.o chrutil.o exponent.o opnd.o presults.o ops.o compute.o
cc calc.o display.o chrutil.o exponent.o opnd.o presults.o ops.o compute.o -o calc -lcurses
driver1: driver1.o display.o exponent.o chrutil.o
cc driver1.o display.o exponent.o chrutil.o -o driver1 -lcurses
driver2: driver2.o display.o exponent.o opnd.o chrutil.o
cc driver2.o display.o exponent.o opnd.o chrutil.o -o driver2 -lcurses
driver3: driver3.o compute.o ops.o
cc driver3.o compute.o ops.o -o driver3
driver4: driver4.o chrutil.o presults.o
cc driver4.o chrutil.o presults.o -o driver4
driver1.o: exponent.h display.h
driver2.o: display.h exponent.h opnd.h chrutil.h
driver3.o: compute.h ops.h
driver4.o: presults.h display.h chrutil.h
exponent.o: tfdef.h exponent.h
opnd.o: opnd.h chrutil.h display.h tfdef.h exponent.h
ops.o: ops.h chrutil.h display.h
compute.o: compute.h
presults.o: presults.h display.h
chrutil.o: tfdef.h chrutil.h
links:
ln -s -f $(CHAP4)/tfdef.h .
ln -s -f $(CHAP4)/chrutil.c .
ln -s -f $(CHAP4)/chrutil.h .
ln -s -f $(CALC)/display.o .
ln -s -f $(CALC)/compute.h .
ln -s -f $(CALC)/display.h .
ln -s -f $(CALC)/exponent.h .
ln -s -f $(CALC)/opnd.h .
ln -s -f $(CALC)/ops.h .
ln -s -f $(CALC)/presults.h .
ln -s -f $(CALC)/driver1.c .
cp -i $(CALC)/presults.c .
clean:
mv display.o display.sav
rm -f *.o
mv display.sav display.o
real_clean: clean
rm -f driver1 driver2 driver3 driver4 calc a.out core
/* File: opnd.h
by: Tep Dobry
date:
*/
/* This file contains the prototypes for funcitons in opnd.c */
int get_opnd(char ch);
/* This function is given the first character of an operand. It
reads the remaining characters of the operand and converts
it to internal integer form. Operands may be a sequence of
digit characters or a sequence of digits (the base) followed
by a sequence of exponent characters, in which case get_opnd()
computes the base to the exponent as its result. All characters
are echoed to the display using Display Module routines.
*/
/* File: ops.h
by: Tep Dobry
date:
*/
/* This file contains the prototypes for funcitons in ops.c */
#define ILLEGAL_OP(c) (((c) != '+')&&((c) != '-')&&((c) != 'x')&&((c) != '/')\
&& ((c) != '='))
char get_op(void);
/* This function reads the operator character from the input
and echos it to dispaly. It checks the validity of the
operator and returns it as a character.
*/
/* File: presults.c
by: Tep Dobry
date:
*/
/* This file contains the code to convert an integer into a
sequence of characters and print them. The code uses
conditonal compilation to determine whether or not to
use the calculator display.
*/
/* define for use without the display
#define DISPLAY
*/
#include "presults.h"
#include "display.h"
#include "chrutil.h"
void put_result(int ans)
/* This function is given an integer and prints it one digit at a time
either to the calc display or the stdout.
*/
{ int wt; /* the weight of the msd */
/* if the integer is 0, print it and return */
if(ans == 0)
{
#ifdef DISPLAY
write_char('0');
#else
putchar('0');
#endif
return;
}
/* if the integer is negative, print the '-' and make it pos. */
if(ans < 0)
{
#ifdef DISPLAY
write_char('-');
#else
putchar('-');
#endif
ans = -ans;
}
/* find the weight of the msd */
wt = weight(ans);
/* while there are more digits */
while(wt >= 1)
{ /* get msd, convert to char, and print it */
#ifdef DISPLAY
write_char(int_to_dig(sig_dig_value(ans,wt)));
#else
putchar(int_to_dig(sig_dig_value(ans,wt)));
#endif
/* strip the msd */
ans = supress_msd(ans,wt);
/* go on to next weight */
wt = weight(ans);
}
}
int sig_dig_value(int n, int wt)
/* This function is given and integer and the current weight. It
returns the integer value of the most significant digit. */
{ return n/wt; }
int supress_msd(int n, int wt)
/* This function is given an integer and the current weight. It
returns an integer with the most significant digit removed. */
{ return n % wt; }
int weight(int n)
/* This function is given an integer. It returns the weight (a power
of 10) of the most significant digit. */
{ int wt = 1;
while((n/wt) != 0)
wt = wt * BASE;
wt = wt / BASE;
return wt;
}
/* File: presults.h
by: Tep Dobry
date:
*/
/* This file contains prototypes for presults.c */
#define BASE 10
void put_result(int ans);
/* This function is given an integer and prints it to the dispaly
one digit at a time.
*/
int sig_dig_value(int n, int wt);
/* This function is given an integer and the current weight. It
returns the integer value of the most significant digit.
*/
int supress_msd(int n, int wt);
/* This function is given an integer and the current weight. It
returns the integer with the most significant digit removed.
*/
int weight(int n);
/* This function is given an integer. It returns the weight (a power
of 10) of the most significant digit.
*/