home *** CD-ROM | disk | FTP | other *** search
- /* VC.C VC.C VC.C VC.C VC.C VC.C VC.C
-
- VISUAL CALCULATOR X X XXX
- MAIN PROGRAM X X X X
- X X X
- July 1, 1987 X X X
- X X X
- X X X
- X XXX
-
- This program will evaluate single value expressions in a
- manner similar to those evaluated by a hand-held calculator,
- hence its name, the Visual Calculator. It was never intended
- to be programmable, so no loop constructs are included in
- its design. It is possible to write a series of statements,
- store them in a file, and recall them while using them to
- calculate with new values of input variables in the six
- variable storage registers. The input variables can be
- changed, and the entire series recalculated.
-
- Although this is a potentially useful program in its own
- right, it was originally written as an illustration of a
- rather large C program. It is especially useful because
- the student of C can run the program to determine its
- operating characteristics, then study the code needed to
- perform the various operations. For that reason, the entire
- program is heavily commented. An actual production program
- would probably not have as many comments as this example
- but it would not be bad practice to comment all of your
- programs to this extent.
- */
- #include "ctype.h"
- #include "stdio.h"
- #include "string.h"
- #include "conio.h"
- #include "process.h"
- #include "struct.def"
- #include "defin.h"
-
- struct vars allvars[12]; /* this is the main variable storage */
- int varinuse = 0; /* which variable is being used now */
- char inline[200]; /* input line area */
- int col; /* used for searching across the input */
- int errcode; /* error code number */
- int colerr; /* column where error occurred */
- int printit = 0; /* 1 = print a transcript */
- int ignore; /* 1 = ignore calculations for line */
- extern char strngout[]; /* output message area */
- extern int valattr; /* value and variable attribute */
- extern int helpattr; /* help box attribute */
- FILE *prtfile; /* file pointers */
-
- struct lines *top, *bot, *q, *p, *arrow, *trnsend;
-
- /* *********************************************************** main */
- /* This is the main control loop for the program. It initializes */
- /* everything and reads statements until no errors are found. It */
- /* continues reading until an F10 is detected in a subordinate */
- /* function where control is returned to DOS */
- main()
- {
- top = bot = q = p = arrow = trnsend = NULL;
- monitor(); /* initialize video attributes */
- initdata(&allvars[0]); /* initialize all data */
- bkgndvid(); /* display video background - double lines */
- valusvid(); /* display starting values of all variables */
- strtrans("Welcome to the Visual Calculator - Version 1.10",0);
- transout();
- do{
- poscurs(23,7);
- printf(" input > ");
- printf(" ");
- do { /* repeat input until no errors */
- readline(); /* get an input line */
- errdis(" "); /* clear error msg */
- parse(); /* parse the line */
- if (errcode) errout();/* output error message */
- } while (errcode);
- if (ignore == 1)
- strtrans(inline,0); /* store comment in transcript */
- else
- strtrans(inline,1); /* store "inline" in transcript */
- transout();
- } while (1); /* continuous loop */
- }
- /* ******************************************************* readline */
- /* This function reads a line by inputting one character at a time */
- /* and deciding what to do with it if it is a special character, or */
- /* adding it to the input line if it is a special character. The */
- /* routine takes care of such things as backspace, cursor movement */
- /* and delete keys. The final result is a single line of text stored*/
- /* in the buffer "inline" and the line displayed on the monitor. */
- void readline(void)
- {
- int index;
- int c,temp;
- int row = 23,col = 17;
- int attr;
-
- if (errcode) { /* error recovery allow reenter */
- index = colerr;
- errcode = 0;
- }
- else { /* normal input routine */
- index = 0;
- for (temp = 0;temp < 80;temp++)
- inline[temp] = 0; /* clear input buffer */
- }
-
- poscurs(row,col+index); /* starting location of cursor */
-
- do { /* repeat this do loop until a return is hit */
- while ((c = getch()) == EOF); /* get a keystroke */
-
- if (c == 0) { /* a zero here says a special key was hit */
- /* get the key and act on it as needed */
- int spec;
- spec = getch(); /* this is the special code found */
- switch (spec) {
- case 59 : helpm(); /* F1 - Help math */
- transout();
- break;
- case 60 : helps(); /* F2 - Help system */
- transout();
- break;
- case 61 : if (printit) { /* F3 - Print on/off */
- printit = 0; /* print off */
- fprintf(prtfile,"%s\n\n","Print off");
- fclose(prtfile);
- strcpy(strngout,"-----");
- attr = helpattr;
- } else {
- prtfile = fopen("PRN","w"); /* print on */
- if (prtprblm()) {
- errcode = 12; /* printer is not ready */
- errout();
- break;
- }
- printit = 1;
- fprintf(prtfile,"%s\n","Print On");
- strcpy(strngout,"Print");
- attr = valattr;
- }
- strngdis(1,73,attr);
- break;
- case 62 : /* F4 - Mark transcript */
- arrow->marked = (arrow->marked?0:1);
- transout();
- break;
- case 63 : fileout(); /* F5 - Store transcript */
- break;
- case 64 : filein(); /* F6 - Retrieve trans */
- errcode = 0;
- break;
- case 65 : /* F7 - */
- break;
- case 66 : /* F8 - */
- break;
- case 67 : /* F9 - Edit a line */
- strcpy(inline,arrow->lineloc);
- poscurs(23,17);
- printf("%s",inline);
- break;
- case 68 : poscurs(23,17); /* F10 - Quit to DOS */
- printf("Quit? (Y/N) ");
- c = getch();
- if ((c == 'Y') || (c == 'y')){
- clrscrn();
- exit(0);
- }
- poscurs(23,17);
- printf(" ");
- break;
- case 75 : if (index) { /* left arrow */
- index = index -1; /* back up cursor */
- }
- break;
-
- case 77 : if (index < 65) { /* right arrow */
- if (inline[index] == 0) /* zero found */
- inline[index] = ' '; /* blank over 0 */
- index = index + 1; /* cursor forward */
- }
- break;
-
- case 72 : movarrow(-1); /* up arrow */
- break;
-
- case 80 : movarrow(1); /* down arrow */
- break;
-
- case 73 : movarrow(-8); /* page up */
- break;
-
- case 81 : movarrow(8); /* page down */
- break;
-
- case 71 : movarrow(-1000); /* home */
- break;
-
- case 79 : movarrow(1000); /* end */
- break;
-
- case 83 : temp = index; /* delete key */
- /* move all characters left one space */
- while (inline[temp]) {
- inline[temp] = inline[temp+1];
- putchar(inline[temp++]);
- }
- putchar(0); /* zero in last place */
- break;
-
- default : poscurs(15,5);
- printf(" S%3d",spec);
- }
- poscurs(row,col+index); /* actually put cursor in position */
- }
-
- else { /* normal letter or char hit */
- int curr,next;
- if (islower(c)) c = toupper(c); /* convert to upper case */
- if ((c >= '\40') && (c <= '\176')) { /* printable char */
- poscurs(row,col+index);
- putchar(c);
- next = inline[index];
- inline[index++] = c;
- curr = index;
- while((next != 0) && (curr <= 65)) { /* move remainder */
- temp = next; /* line right */
- next = inline[curr];
- inline[curr++] = temp;
- putchar(temp);
- }
- }
- else {
- if ((c == 8) && index){ /* backspace */
- index--;
- poscurs(row,col+index); /* back up cursor */
- temp = index;
- while (inline[temp]) {
- inline[temp] = inline[temp+1];
- putchar(inline[temp++]);
- }
- putchar(0);
- }
- }
- poscurs(row,col+index);
- }
- if (c == 3) exit(0); /* ctrl-break, out to DOS */
- } while (c != 13); /* newline found, line input is complete */
- }
-
- /* ********************************************************** parse */
- /* This function does a lot of checking of the input line for */
- /* logical errors in construction, then turns control over to the */
- /* function "calcdata" for the actual calculations. */
- void parse(void)
- {
- int index,parcol;
- double newval;
- char name[7];
-
- varinuse = -1;
- errcode = 0;
- col = 0;
- ignore = 1; /* ignore this line */
-
- if (inline[0] == '#') { /* get list of variable names */
- getnames();
- return;
- }
-
- while (inline[col] == ' ') col++; /* ignore leading blanks */
- if (inline[col] == '$') return; /* ignore a comment line */
- if (inline[col] == 0) return; /* ignore a blank line */
- ignore = 0; /* don't ignore this line */
-
- name[0] = inline[col++]; /* find variable name */
- index = 1;
- while ((((inline[col] >= 'A') && (inline[col] <= 'Z')) ||
- ((inline[col] >= '0') && (inline[col] <= '9'))) &&
- (index <= 5)) { /* continue var or function name */
- name[index++] = inline[col++];
- }
- name[index] = 0; /* name found */
-
- for (index = 0;index < 12;index++) {
- if ((strcmp(name,allvars[index].varname)) == 0)
- varinuse = index; /* variable name found */
- }
- if (varinuse < 0) errchk(3); /* unknown variable name */
-
- while (inline[col] == ' ') col++; /* ignore leading blanks */
- if (inline[col] == '=') col++;
- else errchk(8); /* missing equal sign */
-
- parcol = 0; /* now check for correct parenthesis matchup */
- index = col;
- do {
- if (inline[col] == '(') parcol++;
- if (inline[col++] == ')') parcol--;
- if (parcol < 0) errchk(1); /* paren count went negative */
- } while (inline[col]);
- if (parcol) errchk(2); /* left over parentheses */
- col = index;
-
- calcdata(&newval); /* now go evaluate the full expression */
- if (errcode == 0) { /* don't update value if error found */
- allvars[varinuse].value = newval;
- disnew(varinuse); /* display the changed value */
- }
- }
-
- /* ********************************************************* errout */
- /* This is the function that displays the blinking error message on */
- /* the monitor. Note the extra errors for expansion of the table. */
- void errout(void)
- {
- switch (errcode) {
- case 1 : errdis("extra right parentheses ");
- break;
- case 2 : errdis("missing right parentheses");
- break;
- case 3 : errdis("unknown variable name ");
- break;
- case 4 : errdis("invalid math operator ");
- break;
- case 5 : errdis("negative value for SQRT ");
- break;
- case 6 : errdis("function not found ");
- break;
- case 7 : errdis("negative value for LOG ");
- break;
- case 8 : errdis("equal sign missing ");
- break;
- case 9 : errdis("invalid data field ");
- break;
- case 10 : errdis("division by zero ");
- break;
- case 11 : errdis("File doesn't exist ");
- break;
- case 12 : errdis("Printer not ready ");
- break;
- case 13 : errdis("Out of memory ");
- break;
- case 14 : errdis("Dash expected ");
- break;
- case 15 : errdis("Invalid format code ");
- break;
- case 16 : errdis("Neg value for FACTORIAL ");
- break;
- case 17 : errdis("Err 17 ");
- break;
-
- default : errdis("unknown error ");
- poscurs(21,70);
- printf("%d",errcode);
- }
- poscurs(23,12+colerr);
- }
-