home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
busi
/
nojcb.zip
/
CBMAIN.INC
< prev
Wrap
Text File
|
1989-09-09
|
29KB
|
620 lines
/*----------------------------------------------------------------------------
* File: CBMAIN.INC (in Turbo C 1.5)
*
* Purpose: Provides functions and structures for CB.
*
* Author: Steven "Noji" Ratzlaff
*
* Date: 09 Sep 1989
*--------------------------------------------------------------------------*/
struct EntryPrompt
{
char msg[MSG_LEN];
char var[LINE_LIM];
} input[] =
{
{ "Check or Item:", 0 },
{ "Date:", 0 },
{ "Amount:", 0 },
{ "Purpose:", 0 },
0
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct Record /* record of each transaction */
{
int ind; /* index number of the record */
char check[INPUT_SP]; /* check number / xaction type */
char date[INPUT_SP]; /* date of transaction */
char amt[INPUT_SP]; /* amount */
char pur[MSG_LEN]; /* purpose of transaction */
char bal[INPUT_SP]; /* balance after transaction */
struct Record
*next; /* pointer to the next record */
} *head,
*tail,
*cur;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
char *func_key[] =
{
"WordPerfect", /* F1 */
"DEP", /* F2 */
"VIS", /* F3 */
"UCC", /* F4 */
"Loan Payment", /* F5 */
"Food-4-Less", /* F6 */
"Albertsons", /* F7 */
"Dr. Myers", /* F8 */
"Visa Credit Payment", /* F9 */
"Tithing", /* F10 */
0
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int nmonth[] =
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char *month[] =
{
"XXX", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
/*--------------------------------------------------------------------------*/
main(argc, argv) /* CB */
int argc;
char **argv;
{
struct ffblk
block; /* structure of file attributes */
int yn = 0; /* yes or no? */
char *acct = *++argv, /* account file name */
filepath[MAX_PATH]; /* " " pathname */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
strcpy(filepath, CB_DIR); /* specify the directory of the path */
if (argc == 2)
{
beg_bal[0] = last_check[0] = '\0'; /* initialize all global variables */
for (yn = 0; yn < ELEMENTS; yn++)
input[yn].var[0] = '\0';
yn = 0;
head = tail = cur = NULL;
prompt = getenv("PROMPT");
strcat(filepath, strupr(acct));
strcat(filepath, ".CB");
if (findfirst(filepath, &block, 0) == 0) /* if the file exists */
transact(filepath, yn); /* transact business */
else
{
printf(" *** Account '%s' not found\n%s", acct,
" Create a new account? ");
while (yn != 'y' && yn != 'n')
yn = tolower(getch());
if (yn == 'y')
{
printf("\n Enter the beginning balance: ");
gets(beg_bal);
transact(filepath, yn);
}
}
} /* end of if (argc == 2) ... */
else
{
printf("%s\n\n", Version);
directory(FALSE); /* display the account directory */
}
return 0; /* successful completion */
} /* end of main() */
/*----------------------------------------------------------------------------
* before_date(): Determines whether date1 is chronologically before date2.
* Both dates must be properly formatted beforehand.
*--------------------------------------------------------------------------*/
int
before_date(date1, date2)
char *date1, /* the date to test */
*date2; /* the date in question */
{
char c_day1[INPUT_SP], /* the day string */
c_day2[INPUT_SP], /* " " " */
c_month1[INPUT_SP], /* " month " */
c_month2[INPUT_SP], /* " " " */
c_year1[INPUT_SP], /* " year " */
c_year2[INPUT_SP]; /* " " " */
long total1, /* the composite of date1 */
total2; /* " " " date2 */
int i_day1, /* the day number */
i_day2, /* " " " */
i_month1, /* " month " */
i_month2, /* " " " */
i_year1, /* " year " */
i_year2, /* " " " */
i; /* arbitrary counter */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
strncpy(c_day1, date1, 2); /* get the days */
strncpy(c_day2, date2, 2);
c_day1[2] = c_day2[2] = '\0';
i_day1 = atoi(c_day1);
i_day2 = atoi(c_day2);
strcpy(c_month1, date1); /* get the months */
strcpy(c_month2, date2);
for (i = 0; i < 3; i++)
{
c_month1[i] = c_month1[i + 3];
c_month2[i] = c_month2[i + 3];
}
c_month1[3] = c_month2[3] = '\0';
for (i = 1; i < 13; i++)
{
if (stricmp(c_month1, month[i]) == 0)
i_month1 = i;
if (stricmp(c_month2, month[i]) == 0)
i_month2 = i;
}
strcpy(c_year1, date1); /* get the years */
strcpy(c_year2, date2);
for (i = 0; i < 2; i++)
{
c_year1[i] = c_year1[i + 7];
c_year2[i] = c_year2[i + 7];
}
c_year1[2] = c_year2[2] = '\0';
i_year1 = atoi(c_year1);
i_year2 = atoi(c_year2);
total1 = (long) i_day1 + (long) i_month1 * 100L + (long) i_year1 * 10000L;
total2 = (long) i_day2 + (long) i_month2 * 100L + (long) i_year2 * 10000L;
return (total1 < total2);
} /* end of before_date() */
/*----------------------------------------------------------------------------
* clear_line(): Clears the line from the current cursor pos to the end.
*--------------------------------------------------------------------------*/
void
clear_line(xpos)
int xpos;
{
while (++xpos < 70)
printf(" ");
} /* end of clear_line() */
/*----------------------------------------------------------------------------
* directory(): Displays a directory listing by account names.
*--------------------------------------------------------------------------*/
void
directory(menucall)
int menucall; /* called from the main menu ? */
{
struct ffblk
block; /* structure of file sttributes */
int done, /* is the directory search done? */
cols = 0; /* columns of display shown */
char drive[MAXDRIVE], /* space for the drive name */
dir[MAXDIR], /* " " " directory name */
fname[MAXFILE], /* " " " file name */
ext[MAXEXT]; /* " " " extension name */
char filepath[MAX_PATH]; /* " " pathname */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
strcpy(filepath, CB_DIR); /* specify the directory of the path */
printf(" Accounts available:\n\n");
strcat(filepath, "*.CB");
done = findfirst(filepath, &block, 0); /* grab the 1st file */
if (!done)
{
while (!done) /* as long as there are files here */
{
fnsplit(block.ff_name, drive, dir, fname, ext);
printf(" %-8s", fname);
if (++cols == 3)
cols = printf("\n") - 1;
done = findnext(&block); /* grab the next filename */
if (done && cols)
printf("\n");
} /* end of while (!done) */
} /* end of if (!done) */
else
printf(" <None available>\n");
if (menucall)
pause();
} /* end of directory() */
/*----------------------------------------------------------------------------
* get_char(): Grabs a keyboard character. This function was made to catch
* function keys on MS-DOS machines.
*--------------------------------------------------------------------------*/
int
get_char()
{
int c; /* the character to return */
static union REGS
rg;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
while (TRUE) /* infinite loop */
{
rg.h.ah = 1;
int86(0x16, &rg, &rg); /* ah = 1, int 16H : keyboard status */
if (rg.x.flags & 0x40) /* if zero flag (key stroke) is set */
{
int86(0x28, &rg, &rg); /* DOSOK interrupt */
continue; /* jump to beginning of loop */
}
rg.h.ah = 0;
int86(0x16, &rg, &rg); /* ah = 0, int 16H : read character */
if (rg.h.al == 0) /* if a function key is detected */
c = rg.h.ah | 128; /* give it an ASCII value */
else
c = rg.h.al;
break;
}
return c; /* return the character */
} /* end of get_char() */
/*----------------------------------------------------------------------------
* get_cursor(): Retrieves the current cursor position.
*--------------------------------------------------------------------------*/
void
get_cursor(x, y)
int *x,
*y;
{
static union REGS
rg;
rg.x.ax = 0x0300;
rg.x.bx = 0;
int86(0x10, &rg, &rg); /* ah = 3, int 10H : get cursor pos */
*x = rg.h.dl; /* x points to the x position */
*y = rg.h.dh; /* y " " " y " */
} /* end of get_cursor() */
/*----------------------------------------------------------------------------
* get_todays_date(): Retrieves today's date from DOS and formats it into a
* string for use in data entry.
*--------------------------------------------------------------------------*/
void
get_todays_date(str)
char *str;
{
struct date today; /* current DOS date structure */
char daynum[INPUT_SP], /* today's date in a string */
year[INPUT_SP]; /* this year in string form */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
getdate(&today); /* grab the current date */
itoa(today.da_day, daynum, DEC); /* convert days to string */
itoa(today.da_year, year, DEC); /* " years " " */
if (today.da_day < DEC) /* leading zeroes in day */
{
daynum[1] = daynum[0];
daynum[0] = '0';
daynum[2] = '\0';
}
year[0] = year[2];
year[1] = year[3];
year[2] = '\0';
strcpy(str, daynum); /* concat the day string */
strcat(str, "-"); /* tack on a dash */
strcat(str, month[today.da_mon]); /* attach the month name */
strcat(str, "-"); /* put on another dash */
strcat(str, year); /* finally stick the year */
} /* end of get_todays_date() */
/*----------------------------------------------------------------------------
* increment_date(): Increments the month or day. The day string must have
* been properly formatted.
*--------------------------------------------------------------------------*/
void
increment_date(date, inc)
char *date; /* date string to increment */
int inc; /* increment type */
{
int i, /* arbitrary counter */
n_day, /* day number */
n_month, /* month number */
n_year; /* year number */
char date_copy1[INPUT_SP], /* a copy of the date string */
date_copy2[INPUT_SP], /* another one */
date_copy3[INPUT_SP]; /* and yet another */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
strcpy(date_copy1, date);
strcpy(date_copy2, date);
strcpy(date_copy3, date);
date_copy1[2] = '\0';
n_day = atoi(date_copy1);
for (i = 0; i < 3; i++)
date_copy2[i] = date_copy2[i + 3];
date_copy2[3] = '\0';
for (i = 1; i < 13; i++)
if (stricmp(date_copy2, month[i]) == 0)
n_month = i;
for (i = 0; i < 2; i++)
date_copy3[i] = date_copy3[i + 7];
date_copy3[2] = '\0';
n_year = atoi(date_copy3);
switch (inc)
{
case UP : if (++n_day > nmonth[n_month])
{
n_day = 1;
if (++n_month > 12)
{
n_month = 1;
n_year++;
}
}
break;
case DN : if (--n_day == 0)
{
if (n_month > 1)
n_month--;
else
{
n_month = 12;
n_year--;
}
n_day = nmonth[n_month];
}
break;
case PGUP : if (++n_month > 12)
{
n_month = 1;
n_year++;
}
break;
case PGDN : if (--n_month < 1)
{
n_month = 12;
n_year--;
}
default : break;
} /* end of switch (inc) */
itoa(n_day, date_copy1, DEC);
if (n_day < DEC) /* leading zeroes in day */
{
date_copy1[1] = date_copy1[0];
date_copy1[0] = '0';
date_copy1[2] = '\0';
}
strcat(date_copy1, "-");
strcat(date_copy1, month[n_month]);
strcat(date_copy1, "-");
itoa(n_year, date_copy3, 10);
strcat(date_copy1, date_copy3);
strcpy(date, date_copy1);
} /* end of increment_date() */
/*----------------------------------------------------------------------------
* instructions(): Displays the set of instructions required to run this
* program.
*--------------------------------------------------------------------------*/
void
instructions()
{
clrscr();
printf(" CB: The Ratzlaff Checkbook Program\n\n"
" Access to all functions in For the 'Date' prompt:\n"
"CB is through the main menu. The Up Arrow / Down Arrow: Increments\n"
"functions are self-explanatory and decrements the day number.\n"
"except for the E>nter option. PgUp / PgDn: Increments and\n"
" After calling the E>nter decrements the month.\n"
"function, the most recent trans- End: Toggles between the most\n"
"action will be displayed. Then recent date and today's date.\n"
"CB will prompt the user for each For all prompts:\n"
"of the four information elements, Home: Clears the line and restarts\n"
"displaying the next expected check from beginning.\n"
"number and the most recently Backspace / Left Arrow: Moves\n"
"entered date. cursor to the left, erasing.\n"
" While being prompted, the Space / Right Arrow: Spaces.\n"
"user may enter and edit characters Delete: Cancels the line and moves\n"
"and numbers as needed. A few to the next prompt.\n"
"special features are included to Function Keys: Places predefined\n"
"aid the user in editing and they strings at the prompt.\n"
"are explained here. Enter: Accepts the input line.\n\n"
" The keyword 'DEP' in the 'Check' section indicates a credit to the\n"
"account; any other string is assumed to be a debit.\n");
pause();
} /* end of instructions() */
/*----------------------------------------------------------------------------
* num_format(): Formats a string that has been converted from a floating
* point value into one compatible with this program.
*--------------------------------------------------------------------------*/
void
num_format(str)
char *str;
{
int ind, /* index into the array */
point = 0; /* index to the decimal point */
char new[INPUT_SP]; /* new array for floating pt number */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
for (ind = 0; str[ind]; ind++) /* ind == string length */
if (str[ind] == '.')
point = ind;
if (point == 0)
if (str[0] == '.') /* decimal point is at the beginning */
{
strcpy(new, "0");
strcat(new, str);
if (ind == 2)
strcat(new , "0");
strcpy(str, new);
}
else /* no decimal point present */
strcat(str, ".00");
else /* decimal point next to last */
if (point == ind - 2)
strcat(str, "0");
} /* end of num_format() */
/*----------------------------------------------------------------------------
* pause(): Pauses until <Space> is pressed.
*--------------------------------------------------------------------------*/
void
pause()
{
printf("\nPress <Space> to continue ");
while (getch() != SP)
;
} /* end of pause() */
/*----------------------------------------------------------------------------
* read_string(): Reads a string from the keyboard into a buffer. This
* replaces scanf() and gets() for this specific application.
*--------------------------------------------------------------------------*/
int
read_string(buff)
char *buff; /* the input buffer */
{
int c = 0, /* the retrieved character */
ind; /* array indexd */
int xcur, /* original x position */
ycur, /* " y " */
xpos, /* current x position */
ypos; /* " y " */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ind = strlen(buff); /* use old string length as offset */
get_cursor(&xcur, &ycur); /* get original cursor position */
xcur -= ind;
xpos = xcur + ind;
ypos = ycur;
while (c != ESC && c != RET && c != DEL && c != END &&
c != UP && c != DN && c != PGUP && c != PGDN)
{
set_cursor(xpos, ypos); /* place the cursor at the curr pos */
c = get_char(); /* grab a character from the kbd */
switch (c)
{
case BS :
case LEFT : if (ind > 0)
{
buff[--ind] = '\0'; /* erase one char */
set_cursor(--xpos, ycur); /* reset cursor one back */
printf(" "); /* display the space */
}
else
ind = 0;
break;
case HOME : buff[ind=0] = '\0'; /* clear the string */
case END :
case UP :
case DN :
case PGUP :
case PGDN : set_cursor(xpos=xcur, ycur); /* reset cursor */
clear_line(xcur); /* clear to end of line */
break;
case RGT : c = SP; /* right arrow == space */
break;
case F1 : case F2 : /* function keys */
case F3 : case F4 :
case F5 : case F6 :
case F7 : case F8 :
case F9 : case F10 : if (ind == 0)
strcpy(buff, func_key[c - F1]);
else
strcat(buff, func_key[c - F1]);
clear_line(xpos);
xpos += strlen(func_key[c - F1]);
ind += strlen(func_key[c - F1]);
break;
default : break;
} /* end of switch (c) */
if (isprint(c) && c != DELIM) /* if c is a printable character */
{
if (ind == LINE_LIM) /* prevent strings being too long */
printf("\a");
else
{
buff[ind++] = c; /* add the character here */
buff[ind] = '\0'; /* and terminate the string */
xpos++; /* update the cursor */
if (ind == 1)
clear_line(xpos); /* clear other characters */
}
}
set_cursor(xcur, ycur); /* move the cursor back to the start */
printf(buff); /* print the string out */
} /* end of while (c != )... */
if (c == RET && strlen(buff) == 0)
c = DEL;
if (c == DEL)
{
strcpy(buff, "***");
clear_line(xcur);
}
set_cursor(xcur, ycur); /* move the cursor back to the start */
return c; /* return the delimiter */
} /* end of read_string() */
/*----------------------------------------------------------------------------
* repeat_entry(): Prompts the user for input until only a carriage return
* is entered, after which the string is converted to a double.
*--------------------------------------------------------------------------*/
void
repeat_entry(str, val)
char *str; /* buffer for string input */
double *val; /* total of the double values */
{
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
*val = 0.0; /* initialize the double total */
do {
printf(" --> "); /* prompt */
gets(str); /* entry */
if (str[0]) /* if an entry was made */
*val += atof(str); /* add it to the total */
} while (str[0]);
} /* end of repeat_entry() */
/*----------------------------------------------------------------------------
* save(): Writes the entire list to the account file.
*--------------------------------------------------------------------------*/
void
save(fname)
char *fname; /* file to save the list to */
{
FILE *fp; /* pointer to the file */
int wrong = TRUE; /* error condition present */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
gotoxy(1, CURSOR);
if (head != NULL)
if (fp = fopen(fname, "w"))
{
printf(" Saving the account to the disk\n");
wrong = FALSE;
for (cur = head; cur != NULL; cur = cur->next)
fprintf(fp, "%s:%s:%s:%s:%s:\n",
cur->check, cur->date, cur->amt, cur->pur, cur->bal);
fclose(fp);
}
else
printf(" *** File '%s' could not be written to\n", fname);
else
printf(" *** No data present to save\n");
if (wrong)
pause();
} /* end of save() */
/*----------------------------------------------------------------------------
* set_cursor(): Sets the current cursor position.
*--------------------------------------------------------------------------*/
void
set_cursor(x, y)
int x,
y;
{
static union REGS
rg;
rg.x.ax = 0x0200;
rg.x.bx = 0;
rg.x.dx = ((y << 8) & 0xff00) + x; /* calculate the position by dx */
int86(0x10, &rg, &rg); /* ah = 2, int 10H : set cursor pos */
} /* end of set_cursor() */
/*----------------------------------------------------------------------------
* shell_out(): Creates a temporary shell out to DOS.
*--------------------------------------------------------------------------*/
void
shell_out()
{
char prompt_add[MAX_PATH], /* addition to the prompt */
path[MAX_PATH]; /* path of the current working dir */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
getcwd(path, MAX_PATH);
strcpy(prompt_add, "PROMPT=");
strcat(prompt_add, "(CB Shell) ");
strcat(prompt_add, prompt);
putenv(prompt_add);
printf("Enter 'Exit' to return to CB");
spawnl(P_WAIT, "c:\\command.com", "c:\\command.com", NULL);
strcpy(prompt_add, "PROMPT=");
strcat(prompt_add, prompt);
putenv(prompt_add);
chdir(path);
} /* end of shell_out() */
/*----------------------------------------------------------------------------
* End of CBMAIN.INC
*--------------------------------------------------------------------------*/