dos_compilers/Borland Turbo C v1/MCOMMAND.C
2024-07-01 13:08:21 -07:00

844 lines
19 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Turbo C - (C) Copyright 1987 by Borland International */
#include <string.h>
#include <mem.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include "mcalc.h"
char *name = MSGNAME;
void moverowup(void)
/* Moves up 1 row */
{
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (currow > toprow)
currow--;
else if (toprow != 0)
{
scroll(DOWN, 1, LEFTMARGIN, 2, 79, SCREENROWS + 1, WHITE);
displayrow(--toprow, NOUPDATE);
currow--;
setbottomrow();
}
} /* moverowup */
void moverowdown(void)
/* Moves down one row */
{
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (currow < bottomrow)
currow++;
else if (bottomrow < (MAXROWS - 1))
{
scroll(UP, 1, LEFTMARGIN, 2, 79, SCREENROWS + 1, WHITE);
toprow++;
currow++;
setbottomrow();
displayrow(bottomrow, NOUPDATE);
}
} /* moverowdown */
void movecolleft(void)
/* Moves left one column */
{
#if VIDEOWRITE
int col, oldleftcol, start, finish, amt;
unsigned char oldcolstart[SCREENCOLS];
oldleftcol = leftcol;
movmem(colstart, oldcolstart, sizeof(colstart));
#endif
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (curcol > leftcol)
curcol--;
else if (leftcol != 0)
{
curcol--;
leftcol--;
setrightcol();
setleftcol();
#if VIDEOWRITE
start = LEFTMARGIN;
finish = oldcolstart[rightcol - oldleftcol] + colwidth[rightcol] - 1;
amt = colstart[oldleftcol - leftcol] - LEFTMARGIN;
if (oldleftcol <= rightcol)
scroll(RIGHT, amt, start, 2, finish, SCREENROWS + 1, WHITE);
clearlastcol();
for (col = leftcol; col <= oldleftcol - 1; col++)
displaycol(col, NOUPDATE);
#else
clearlastcol();
displayscreen(NOUPDATE);
#endif
}
} /* movecolleft */
void movecolright(void)
/* Moves right one column */
{
#if VIDEOWRITE
int col, oldleftcol, oldrightcol, start, finish, amt;
unsigned char oldcolstart[SCREENCOLS];
movmem(colstart, oldcolstart, sizeof(colstart));
oldleftcol = leftcol;
oldrightcol = rightcol;
#endif
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (curcol < rightcol)
curcol++;
else if (rightcol < (MAXCOLS - 1))
{
curcol++;
rightcol++;
setleftcol();
setrightcol();
#if VIDEOWRITE
start = oldcolstart[leftcol - oldleftcol];
amt = start - LEFTMARGIN;
finish = oldcolstart[oldrightcol - oldleftcol] + colwidth[oldrightcol] - 1;
if (oldrightcol >= leftcol)
scroll(LEFT, amt, start, 2, finish, SCREENROWS + 1, WHITE);
clearlastcol();
for (col = oldrightcol + 1; col <= rightcol; col++)
displaycol(col, NOUPDATE);
#else
clearlastcol();
displayscreen(NOUPDATE);
#endif
}
} /* movecolright */
void recalc(void)
/* Recalculates all of the numbers in the speadsheet */
{
int col, row, dummy;
for (col = 0; col <= lastcol; col++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[col][row] != NULL) && (cell[col][row]->attrib == FORMULA))
cell[col][row]->v.f.fvalue = parse(cell[col][row]->v.f.formula, &dummy);
}
}
displayscreen(UPDATE);
} /* recalc */
void changeautocalc(int newmode)
/* Changes and prints the current AutoCalc value on the screen */
{
char s[15];
if (!autocalc && newmode)
recalc();
autocalc = newmode;
if (autocalc)
strcpy(s, MSGAUTOCALC);
else
s[0] = 0;
writef(72, 0, MSGAUTOCALCCOLOR, strlen(MSGAUTOCALC), s);
} /* autocalc */
void changeformdisplay(int newmode)
/* Changes and prints the current formula display value on the screen */
{
char s[15];
formdisplay = newmode;
if (formdisplay)
strcpy(s, MSGFORMDISPLAY);
else
s[0] = 0;
writef(64, 0, MSGFORMDISPLAYCOLOR, strlen(MSGFORMDISPLAY), s);
} /* autocalc */
void editcell(CELLPTR ecell)
/* Edits a selected cell */
{
char s[MAXINPUT + 1];
if (ecell == NULL)
return;
switch(ecell->attrib)
{
case TEXT :
strcpy(s, ecell->v.text);
break;
case VALUE :
if (ecell->v.value == HUGE_VAL)
strcpy(s, "0");
else
sprintf(s, "%.*f", MAXPLACES, ecell->v.value);
break;
case FORMULA :
strcpy(s, ecell->v.f.formula);
break;
} /* switch */
if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
return;
act(s);
changed = TRUE;
} /* editcell */
void clearsheet(void)
/* Clears the current spreadsheet */
{
int col, row;
for (row = 0; row <= lastrow; row++)
{
for (col = 0; col <= lastcol; col++)
deletecell(col, row, NOUPDATE);
}
initvars();
setrightcol();
setbottomrow();
displayscreen(NOUPDATE);
printfreemem();
changed = FALSE;
} /* clearsheet */
struct CELLREC rec;
void loadsheet(char *filename)
/* Loads a new spreadsheet */
{
int size, allocated, reallastcol = 0, reallastrow = 0, file;
char check[81];
if (filename[0] == 0)
{
writeprompt(MSGFILENAME);
if (!editstring(filename, "", MAXINPUT))
return;
}
if (access(filename, 0))
{
errormsg(MSGNOEXIST);
return;
}
if ((file = open(filename, O_RDWR | O_BINARY)) == -1)
{
errormsg(MSGNOOPEN);
return;
}
read(file, check, strlen(name) + 1);
if (strcmp(check, name) != 0)
{
errormsg(MSGNOMICROCALC);
close(file);
return;
}
writef(0, 24, PROMPTCOLOR, 80, MSGLOADING);
gotoxy(strlen(MSGLOADING), 24);
clearsheet();
read(file, (char *)&size, 1);
read(file, (char *)&lastcol, 2);
read(file, (char *)&lastrow, 2);
read(file, (char *)&size, 2);
read(file, colwidth, sizeof(colwidth));
do
{
if (read(file, (char *)&curcol, 2) <= 0)
break;
read(file, (char *)&currow, 2);
read(file, &format[curcol][currow], 1);
read(file, (char *)&size, 2);
read(file, (char *)&rec, size);
switch (rec.attrib)
{
case TEXT :
if ((allocated = alloctext(curcol, currow, rec.v.text)) == TRUE)
setoflags(curcol, currow, NOUPDATE);
break;
case VALUE :
allocated = allocvalue(curcol, currow, rec.v.value);
break;
case FORMULA :
allocated = allocformula(curcol, currow, rec.v.f.formula, rec.v.f.fvalue);
break;
} /* switch */
if (!allocated)
{
errormsg(MSGFILELOMEM);
lastrow = reallastrow;
lastcol = reallastcol;
format[curcol][currow] = DEFAULTFORMAT;
break;
}
else
{
if (curcol > reallastcol)
reallastcol = curcol;
if (currow > reallastrow)
reallastrow = currow;
}
}
while (TRUE);
writef(0, 24, WHITE, strlen(MSGLOADING), "");
gotoxy(0, 24);
printfreemem();
close(file);
curcol = currow = 0;
setrightcol();
displayscreen(NOUPDATE);
changed = FALSE;
} /* loadsheet */
void savesheet(void)
/* Saves the current spreadsheet */
{
char filename[MAXINPUT+1] = "", eof = 26;
int size, col, row, overwrite, file;
CELLPTR cellptr;
writeprompt(MSGFILENAME);
if (!editstring(filename, "", MAXINPUT))
return;
if (!access(filename, 0))
{
if (!getyesno(&overwrite, MSGOVERWRITE) || (overwrite == 'N'))
return;
}
if ((file = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
S_IREAD | S_IWRITE)) == -1)
{
errormsg(MSGNOOPEN);
return;
}
writef(0, 24, PROMPTCOLOR, 80, MSGSAVING);
gotoxy(strlen(MSGSAVING), 24);
write(file, name, strlen(name) + 1);
write(file, &eof, 1);
write(file, (char *)&lastcol, 2);
write(file, (char *)&lastrow, 2);
size = MAXCOLS;
write(file, (char *)&size, 2);
write(file, colwidth, sizeof(colwidth));
for (row = 0; row <= lastrow; row++)
{
for (col = lastcol; col >= 0; col--)
{
if (cell[col][row] != NULL)
{
cellptr = cell[col][row];
switch(cellptr->attrib)
{
case TEXT :
size = strlen(cellptr->v.text) + 2;
break;
case VALUE :
size = sizeof(double) + 1;
break;
case FORMULA :
size = strlen(cellptr->v.f.formula) + 2 + sizeof(double);
break;
} /* switch */
write(file, (char *)&col, 2);
write(file, (char *)&row, 2);
write(file, (char *)&format[col][row], 1);
write(file, (char *)&size, 2);
write(file, (char *)cellptr, size);
}
}
}
close(file);
writef(0, 24, WHITE, strlen(MSGSAVING), "");
gotoxy(0, 24);
changed = FALSE;
} /* savesheet */
int pagerows(int row, int toppage, int border)
/* Returns the number of rows to print */
{
int rows;
rows = toppage ? 66 - TOPMARGIN : 66;
if (border)
rows--;
if (row + rows - 1 > lastrow)
return(lastrow - row + 1);
else
return(rows);
} /* pagerows */
int pagecols(int col, int border, int columns)
/* Returns the number of columns to print starting at col */
{
int len = ((col == 0) && (border)) ? columns - LEFTMARGIN : columns;
int firstcol = col;
while ((len > 0) && (col <= lastcol))
len -= colwidth[col++];
if (len < 0)
col--;
return(col - firstcol);
} /* pagecols */
void printsheet(void)
/* Prints a copy of the spreadsheet to a file or to the printer */
{
char filename[MAXINPUT + 1] = "", s[133], colstr[MAXCOLWIDTH + 1];
FILE *file;
int columns, counter1, counter2, counter3, col = 0, row, border, toppage,
lcol, lrow, dummy, printed, oldlastcol;
writeprompt(MSGPRINT);
if (!editstring(filename, "", MAXINPUT))
return;
if (filename[0] == 0)
strcpy(filename, "PRN");
if ((file = fopen(filename, "wt")) == NULL)
{
errormsg(MSGNOOPEN);
return;
}
oldlastcol = lastcol;
for (counter1 = 0; counter1 <= lastrow; counter1++)
{
for (counter2 = lastcol; counter2 < MAXCOLS; counter2++)
{
if (format[counter2][counter1] >= OVERWRITE)
lastcol = counter2;
}
}
if (!getyesno(&columns, MSGCOLUMNS))
return;
columns = (columns == 'Y') ? 131 : 79;
if (!getyesno(&border, MSGBORDER))
return;
border = (border == 'Y');
while (col <= lastcol)
{
row = 0;
toppage = TRUE;
lcol = pagecols(col, border, columns) + col;
while (row <= lastrow)
{
lrow = pagerows(row, toppage, border) + row;
printed = 0;
if (toppage)
{
for (counter1 = 0; counter1 < TOPMARGIN; counter1++)
{
fprintf(file, "\n");
printed++;
}
}
for (counter1 = row; counter1 < lrow; counter1++)
{
if ((border) && (counter1 == row) && (toppage))
{
if ((col == 0) && (border))
sprintf(s, "%*s", LEFTMARGIN, "");
else
s[0] = 0;
for (counter3 = col; counter3 < lcol; counter3++)
{
centercolstring(counter3, colstr);
strcat(s, colstr);
}
fprintf(file, "%s\n", s);
printed++;
}
if ((col == 0) && (border))
sprintf(s, "%-*d", LEFTMARGIN, counter1 + 1);
else
s[0] = 0;
for (counter2 = col; counter2 < lcol; counter2++)
strcat(s, cellstring(counter2, counter1, &dummy, FORMAT));
fprintf(file, "%s\n", s);
printed++;
}
row = lrow;
toppage = FALSE;
if (printed < 66)
fprintf(file, "%c", FORMFEED);
}
col = lcol;
}
fclose(file);
lastcol = oldlastcol;
} /* printsheet */
void setcolwidth(int col)
/* Sets the new column width for a selected column */
{
int width, row;
writeprompt(MSGCOLWIDTH);
if (!getint(&width, MINCOLWIDTH, MAXCOLWIDTH))
return;
colwidth[col] = width;
setrightcol();
if (rightcol < col)
{
rightcol = col;
setleftcol();
setrightcol();
}
for (row = 0; row <= lastrow; row++)
{
if ((cell[col][row] != NULL) && (cell[col][row]->attrib == TEXT))
clearoflags(col + 1, row, NOUPDATE);
else
clearoflags(col, row, NOUPDATE);
updateoflags(col, row, NOUPDATE);
}
displayscreen(NOUPDATE);
changed = TRUE;
} /* setcolwidth */
void gotocell()
/* Moves to a selected cell */
{
writeprompt(MSGGOTO);
if (!getcell(&curcol, &currow))
return;
leftcol = curcol;
toprow = currow;
setbottomrow();
setrightcol();
setleftcol();
displayscreen(NOUPDATE);
} /* gotocell */
void formatcells(void)
/* Prompts the user for a selected format and range of cells */
{
int col, row, col1, col2, row1, row2, temp, newformat = 0;
writeprompt(MSGCELL1);
if (!getcell(&col1, &row1))
return;
writeprompt(MSGCELL2);
if (!getcell(&col2, &row2))
return;
if ((col1 != col2) && (row1 != row2))
errormsg(MSGDIFFCOLROW);
else
{
if (col1 > col2)
swap(&col1, &col2);
if (row1 > row2)
swap(&row1, &row2);
if (!getyesno(&temp, MSGRIGHTJUST))
return;
newformat += (temp == 'Y') * RJUSTIFY;
if (!getyesno(&temp, MSGDOLLAR))
return;
newformat += (temp == 'Y') * DOLLAR;
if (!getyesno(&temp, MSGCOMMAS))
return;
newformat += (temp == 'Y') * COMMAS;
if (newformat & DOLLAR)
newformat += 2;
else
{
writeprompt(MSGPLACES);
if (!getint(&temp, 0, MAXPLACES))
return;
newformat += temp;
}
for (col = col1; col <= col2; col++)
{
for (row = row1; row <= row2; row++)
{
format[col][row] = (format[col][row] & OVERWRITE) | newformat;
if ((col >= leftcol) && (col <= rightcol) &&
(row >= toprow) && (row <= bottomrow))
displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
}
}
}
changed = TRUE;
} /* formatcells */
void deletecol(int col)
/* Deletes a column */
{
int counter, row;
for (counter = 0; counter <= lastrow; counter++)
deletecell(col, counter, NOUPDATE);
printfreemem();
if (col != MAXCOLS - 1)
{
movmem(&cell[col + 1][0], &cell[col][0], MAXROWS * sizeof(CELLPTR) *
(MAXCOLS - col - 1));
movmem(&format[col + 1][0], &format[col][0], MAXROWS * (MAXCOLS - col - 1));
movmem(&colwidth[col + 1], &colwidth[col], MAXCOLS - col - 1);
}
setmem(&cell[MAXCOLS - 1][0], MAXROWS * sizeof(CELLPTR), 0);
setmem(&format[MAXCOLS - 1][0], MAXROWS, DEFAULTFORMAT);
colwidth[MAXCOLS - 1] = DEFAULTWIDTH;
if ((lastcol >= col) && (lastcol > 0))
lastcol--;
setrightcol();
if (curcol > rightcol)
{
rightcol++;
setleftcol();
}
clearlastcol();
for (counter = 0; counter <= lastcol; counter++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[counter][row] != NULL) &&
(cell[counter][row]->attrib == FORMULA))
fixformula(counter, row, COLDEL, col);
updateoflags(col, row, NOUPDATE);
}
}
while (col <= rightcol)
displaycol(col++, NOUPDATE);
changed = TRUE;
recalc();
} /* deletecol */
void insertcol(int col)
/* Inserts a column */
{
int counter, row;
if (lastcol == MAXCOLS - 1)
{
for (counter = 0; counter <= lastrow; counter++)
deletecell(lastcol, counter, NOUPDATE);
printfreemem();
}
if (col != MAXCOLS - 1)
{
movmem(&cell[col][0], &cell[col + 1][0], MAXROWS * sizeof(CELLPTR) *
(MAXCOLS - col - 1));
movmem(&format[col][0], &format[col + 1][0], MAXROWS * (MAXCOLS - col - 1));
movmem(&colwidth[col], &colwidth[col + 1], MAXCOLS - col - 1);
}
setmem(&cell[col][0], MAXROWS * sizeof(CELLPTR), 0);
setmem(&format[col][0], MAXROWS, DEFAULTFORMAT);
colwidth[col] = DEFAULTWIDTH;
lastcol = MAXCOLS - 1;
setlastcol();
setrightcol();
if (curcol > rightcol)
{
rightcol++;
setleftcol();
}
for (counter = 0; counter <= lastcol; counter++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[counter][row] != NULL) &&
(cell[counter][row]->attrib == FORMULA))
fixformula(counter, row, COLADD, col);
updateoflags(col, row, NOUPDATE);
}
}
while (col <= rightcol)
displaycol(col++, NOUPDATE);
changed = TRUE;
recalc();
} /* insertcol */
void deleterow(int row)
/* Deletes a row */
{
int counter, rowc;
for (counter = 0; counter <= lastcol; counter++)
deletecell(counter, row, NOUPDATE);
printfreemem();
if (row != MAXROWS - 1)
{
for (counter = 0; counter < MAXCOLS; counter++)
{
movmem(&cell[counter][row + 1], &cell[counter][row],
sizeof(CELLPTR) * (MAXROWS - row - 1));
movmem(&format[counter][row + 1], &format[counter][row], MAXROWS - row - 1);
}
}
else
{
for (counter = 0; counter <= lastcol; counter++)
{
cell[counter][MAXROWS - 1] = NULL;
format[counter][MAXROWS - 1] = DEFAULTFORMAT;
}
}
if ((lastrow >= row) && (lastrow > 0))
lastrow--;
for (counter = 0; counter <= lastcol; counter++)
{
for (rowc = 0; rowc <= lastrow; rowc++)
{
if ((cell[counter][rowc] != NULL) &&
(cell[counter][rowc]->attrib == FORMULA))
fixformula(counter, rowc, ROWDEL, row);
}
}
while (row <= bottomrow)
displayrow(row++, NOUPDATE);
changed = TRUE;
recalc();
} /* deleterow */
void insertrow(int row)
/* Inserts a row */
{
int counter, rowc;
if (lastrow == MAXROWS - 1)
{
for (counter = 0; counter <= lastcol; counter++)
deletecell(counter, lastrow, NOUPDATE);
printfreemem();
}
if (row != MAXROWS - 1)
{
for (counter = 0; counter < MAXCOLS; counter++)
{
movmem(&cell[counter][row], &cell[counter][row + 1],
sizeof(CELLPTR) * (MAXROWS - row - 1));
movmem(&format[counter][row], &format[counter][row + 1], MAXROWS - row - 1);
}
}
for (counter = 0; counter <= lastcol; counter++)
{
cell[counter][row] = NULL;
format[counter][row] = DEFAULTFORMAT;
}
lastrow = MAXROWS - 1;
setlastrow();
for (counter = 0; counter <= lastcol; counter++)
{
for (rowc = 0; rowc <= lastrow; rowc++)
{
if ((cell[counter][rowc] != NULL) &&
(cell[counter][rowc]->attrib == FORMULA))
fixformula(counter, rowc, ROWADD, row);
}
}
while (row <= bottomrow)
displayrow(row++, NOUPDATE);
changed = TRUE;
recalc();
} /* insertrow */
void smenu(void)
/* Executes the commands in the spreadsheet menu */
{
char filename[MAXINPUT + 1] = "";
switch(getcommand(SMENU, SCOMMAND))
{
case 0 :
checkforsave();
loadsheet(filename);
break;
case 1 :
savesheet();
break;
case 2 :
printsheet();
break;
case 3 :
checkforsave();
clearsheet();
break;
} /* switch */
} /* smenu */
void cmenu(void)
/* Executes the commands in the column menu */
{
switch(getcommand(CMENU, CCOMMAND))
{
case 0 :
insertcol(curcol);
break;
case 1 :
deletecol(curcol);
break;
case 2 :
setcolwidth(curcol);
break;
} /* switch */
} /* cmenu */
void rmenu(void)
/* Executes the commands in the row menu */
{
switch(getcommand(RMENU, RCOMMAND))
{
case 0 :
insertrow(currow);
break;
case 1 :
deleterow(currow);
break;
} /* switch */
} /* rmenu */
void umenu(void)
/* Executes the commands in the utility menu */
{
switch(getcommand(UMENU, UCOMMAND))
{
case 0 :
recalc();
break;
case 1 :
changeformdisplay(!formdisplay);
displayscreen(UPDATE);
break;
} /* switch */
} /* umenu */
void mainmenu(void)
/* Executes the commands in the main menu */
{
switch(getcommand(MENU, COMMAND))
{
case 0 :
smenu();
break;
case 1 :
formatcells();
break;
case 2 :
deletecell(curcol, currow, UPDATE);
printfreemem();
if (autocalc)
recalc();
break;
case 3 :
gotocell();
break;
case 4 :
cmenu();
break;
case 5 :
rmenu();
break;
case 6 :
editcell(curcell);
break;
case 7 :
umenu();
break;
case 8 :
changeautocalc(!autocalc);
break;
case 9 :
checkforsave();
stop = TRUE;
break;
} /* switch */
} /* mainmenu */