📄 utility.cpp
字号:
// ******************************************************************** //
// //
// UTILITY.CPP //
// Copyright (c) 1993, Michael Holmes and Bob Flanders //
// C++ Communication Utilities //
// //
// Chapter 7: Receiving a FAX //
// Last changed in chapter 7 //
// //
// This file contains the following miscellaneous routines. //
// status_line() update the status line //
// build_comm() build comm instance //
// terminal_handler() handle special terminal keys //
// terminal_display() display comm input stream //
// first_nonblank() find first non-blank character //
// ascii_encode() encode string w/control characters //
// quit_with() give an error message, then rtn to DOS //
// get_time() retrieve time of day in ticks //
// elapsed_time() calculate elapsed time in ticks //
// time_out() check for a timeout situation //
// wait() wait for a given number timer ticks //
// wait_ms() wait in milliseconds //
// malloc_chk() allocate memory with error checks //
// field_edit() edit a field in a window //
// delete_file() delete file any way possible //
// pad() pad a string to a length //
// touppers() translate string to uppercase //
// control_break() control break intercept routine //
// critical_rtn() DOS critical error handler //
// //
// ******************************************************************** //
#define TICKS_DAY 1573040L // number of ticks per day
/* ******************************************************************** *
*
* status_line() -- update the status line
*
* ******************************************************************** */
void status_line(void)
{
char msr; // modem status register
window(1, 25, 80, 25); // set up status window
_wscroll = 0; // disable scrolling
textcolor(FG(stat_cn)); // set up foreground
textbackground(BG(stat_cn)); // ..and background colors
msr = comm->Modem(); // get modem status register
cprintf(stat_format, // write current status line
com_ports[comport].name, // ..including selected port
line[SPEED].lp->parm, // ..selected baud rate
line[DATA].lp->parm, // ..data bits
line[PARITY].lp->parm, // ..parity
line[STOP].lp->parm, // ..and stop bits
msr & MSR_CD ? "CD" : " ", // ..carrier detect
msr & MSR_CTS ? "CTS" : " ", // ..clear to send
comm->IFlow() ? " " : "RTS"); // ..request to send
last_window = 0; // clear last window accessed
window(1, 1, 80, 25); // ..and reset for full screen
}
/* ******************************************************************** *
*
* build_comm() -- build comm instance with current parameters
*
* ******************************************************************** */
void build_comm()
{
if (comm) // q. using a port already?
comm->~Comm(); // a. yes .. close it down
comm = new Comm( // build a Comm instance
com_ports[comport].port, // ..with base port address
com_ports[comport].irq, // ..and interrupt number
line[SPEED].lp->value, // ..baud rate divisor
line[PARITY].lp->value | // ..line control values
line[DATA].lp->value | // ..including parity,
line[STOP].lp->value, // ..data and stop bits
flowctl, 4096, 512); // ..and flow control flag
comm->Write(CMD_EXECUTE); // execute previous command
wait_ms(250); // .. let it execute
comm->Write(CMD_EXECUTE); // .. and.. kill it.
comm->Write(CMD_INIT); // send modem init string
comm->Write(CMD_EXECUTE); // .. execute init command
}
/* ******************************************************************** *
*
* terminal_handler() -- handle terminal input
*
* ******************************************************************** */
void terminal_handler(void)
{
int key; // extended keyboard character
if (comm->ModemChanged()) // q. time to update status?
{
status_line(); // a. yes .. do a status update
term->MakeCurrent(); // ..and reposition cursor
}
if ((key = get_key(ALLOW_ALT)) == 0) // q. get a valid key?
return; // a. no .. just return
if (key >= 0x100) // q. alt or function key?
{ // a. yes .. check validity
if (main_menu.ValidateKey(key)) // q. valid for main menu?
{
main_menu.Display(key); // a. yes .. display menu
term->MakeCurrent(); // reposition cursor
return; // ..then return to caller
}
}
switch (key) // handle special keys
{
case F1: // clear screen request
term->Clear(); // clear terminal window
break; // ..and continue
default:
if (key >= 0x100) // q. special key?
{
printf(BELL); // a. yes .. give error beep
break; // ..and continue
}
comm->Write(key); // else .. send out com port
}
}
/* ******************************************************************** *
*
* terminal_display() -- display comm input stream
*
* ******************************************************************** */
void terminal_display(void)
{
int i; // loop counter
char c, // input character
msr, // modem status register
lsr, // line status register
buf[40]; // work buffer
if ((i = comm->Read(&c, &msr, &lsr)) == -1) // q. get a comm character?
return; // a. no .. just return
if (i) // q. buffer overflow?
{
sprintf(buf, overflow_msg, i); // a. yes .. prepare msg
term->DisplayReverse(buf); // ..and give to user
return; // ..then return to caller
}
if ((lsr &= LSR_ERROR) != 0) // q. any errors?
for (i = 0, lsr >>= 1; lsr; // a. yes .. loop thru and
i++, lsr >>= 1) // ..display error messages
if (lsr & 1) // q. recognize this error?
term->DisplayReverse( // a. yes .. display error msg
line_error[i]); // ..from message table
if (c) // q. null character?
term->Display(c); // a. no .. display character
}
/* ******************************************************************** *
*
* first_nonblank() -- find first non-blank character
*
* ******************************************************************** */
char *first_nonblank(char *s) // string to look through
{
for (; *s; s++) // loop thru string
if (NOT isspace(*s)) // q. find a non-blank char?
return(s); // a. yes .. return w/address
return(0); // else .. string is blank
}
/* ******************************************************************** *
*
* ascii_encode() -- encode string w/control characters
*
* ******************************************************************** */
char *ascii_encode(char *s) // string to encode
{
char *p, *q; // work pointers
for (p = q = s; // work across input string
*s == ' ' || *s == '='; s++) // ..skipping leading blanks
; // ..and delimiting equals
for (; *s; s++) // work across rest of the
{ // ..input string
if (*s == ';') // q. hit start of comment?
break; // a. yes .. exit loop
if (*s != '^') // q. control character?
{
*p++ = *s; // a. no .. just copy
continue; // ..and process next one
}
s++; // move on to next input char
if (*s == '^' || *s == ';') // q. special characters?
{
*p++ = *s; // a. yes .. just copy
continue; // ..and process next one
}
*p++ = *s & 0x1f; // make into control char
}
*p = '\0'; // terminate encoded string
return(q); // ..and return string addr
}
/* ******************************************************************** *
*
* quit_with() -- give an error message, then return to DOS
*
* ******************************************************************** */
void quit_with(char *msg, ...) // quit with an error message
{
va_list list; // variable list
if (full_screen) // q. in full screen mode?
{
term->Close(); // a. yes .. close term window
window(1, 1, 80, max_lines); // set up termination screen
textcolor(FG(mono_1)); // ..with foreground
textbackground(BG(mono_1)); // ..and background colors
clrscr(); // ..and clear screen
CURSOR(); // ..and set cursor to normal
printf(copyright); // display program banner
}
if (comm) // q. comm object created?
comm->~Comm(); // a. yes .. call destructor
_dos_setvect(0x1b, old_break); // restore old ^break handler
va_start(list, msg); // set up variable list
vprintf(msg, list); // give error message ..
exit(rc); // ..and then quit
}
/* ******************************************************************** *
*
* time_out() -- check for a timeout event
*
* ******************************************************************** */
int time_out(long *n) // time to wait in ticks
{
static unsigned
long far *timer = (unsigned long far *) // BIOS timer tick counter
MK_FP(0x40, 0x6c), // ..down in low memory
last, // last accessed time
work; // work variable
work = *timer; // get current time
if (*n > 0) // q. first time call?
{
*n = -*n; // a. yes .. change sign
last = work; // ..and initialize counters
}
if (work != last) // q. time pass?
{ // a. yes .. see how much
if (work <= last) // q. clock go past midnite?
(*n)++; // a. yes .. count as 1 tick
else
*n += (UINT)(work - last); // else .. count everything
last = work; // start again w/curr time
}
return(*n >= 0L); // return TRUE at timeout time
}
/* ******************************************************************** *
*
* get_time() -- retrieve the time in ticks
*
* ******************************************************************** */
ULONG get_time(void) // retrieve time in ticks
{
static
ULONG far *timer = (unsigned long far *) // BIOS timer tick counter
MK_FP(0x40, 0x6c); // ..down in low memory
return(*timer); // return current value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -