📄 futility.cpp
字号:
// ******************************************************************** //
// //
// FUTILITY.CPP //
// Copyright (c) 1993, Michael Holmes and Bob Flanders //
// C++ Communication Utilities //
// //
// This file contains the following miscellaneous routines. //
// quit_with() give an error message, then return to DOS //
// status_line() display status line //
// malloc_chk() allocate memory with error checks //
// clear_memory() clear a large block of memory //
// wait() wait for a give number timer ticks //
// wait_ms() wait in milliseconds //
// first_nonblank() find first non-blank character //
// field_edit() edit a field in a window //
// set_bits() set on a string of bits //
// get_bit() get a bit from a string of bits //
// get_bits() get a bunch of bits from a string of bits //
// reverse_scan() scan a area backwards //
// trim() trim trailing blanks //
// control_break() control break intercept routine //
// critical_rtn() DOS critical error handler //
// //
// ******************************************************************** //
/* ******************************************************************** *
*
* 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
}
_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
}
/* ******************************************************************** *
*
* status_line() -- update the status line
*
* ******************************************************************** */
void status_line(char *msg, ...) // message to format/display
{
char buf[100]; // string buffer
va_list list; // variable list
window(1, 25, 80, 25); // set up status window
_wrapon(_GWRAPOFF); // disable scrolling
textcolor(FG(stat_cn)); // set up foreground
textbackground(BG(stat_cn)); // ..and background colors
va_start(list, msg); // set up variable list
vsprintf(buf, msg, list); // ..format buffer
cprintf(buf); // ..then display message
last_window = 0; // clear last window accessed
window(1, 1, 80, 25); // ..and reset for full screen
}
/* ******************************************************************** *
*
* malloc_chk() -- allocate memory with error processing
*
* ******************************************************************** */
void *malloc_chk(long n) // size of block
{
void *p; // temporary pointer
if (n > 65535L) // q. big area?
p = (void *) _halloc((n + 1) / 2, 2); // a. yes .. get big memory
else
p = (void *) _fmalloc(n); // else .. get regular memory
if (NOT p) // q. enough memory?
quit_with(no_memory); // a. no .. give error msg
return(p); // else .. return w/address
}
/* ******************************************************************** *
*
* clear_memory() -- clear a big block of memory
*
* ******************************************************************** */
void clear_memory(char *s, // area to clear
char c, // character to clear to
long size) // length to clear
{
char huge *p; // huge work pointer
UINT clr_size = 0; // working size
for (p = s; size; size -= clr_size) // clear in big chunks
{
if (size > (65536L - 16)) // q. more than 64k to do?
clr_size = (UINT) 65536L - 16; // a. yes .. just do some
else
clr_size = (UINT) size; // else .. do what's left
memset((char *) p, c, (UINT) clr_size); // clear to block to null
p += clr_size; // point to next block
}
}
/* ******************************************************************** *
*
* wait() -- wait for a given number of timer ticks
*
* ******************************************************************** */
void wait(long n) // time to wait in ticks
{
long far *timer = (long far *) // BIOS timer tick counter
MK_FP(0x40, 0x6c), // ..down in low memory
start, work; // start tick count
start = *timer; // get current time
while (n > 0) // loop 'til n ticks past
{
if ((work = *timer) != start) // q. time pass?
{ // a. yes .. see how much
if (work < start) // q. clock go past midnite?
n--; // a. yes .. count as 1 tick
else
n -= (UINT)(work - start); // else .. count everything
start = work; // start again w/curr time
}
else
kbhit(); // else .. check keyboard
}
}
/* ******************************************************************** *
*
* wait_ms() -- wait in milliseconds
*
* ******************************************************************** */
void wait_ms(long ms) // milliseconds to wait
{
wait((ms + 54) / 55); // convert then wait in ticks
}
/* ******************************************************************** *
*
* 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
}
/* ******************************************************************** *
*
* field_edit() -- edit a string field in a window
*
* ******************************************************************** */
int field_edit(Window *win, // window to work in
int c, int r, // initial column and row
char **s, // initial field data
int m) // maximum field length
{
int i, // string index
k, // keyboard input
x, // current column
ins; // insert flag
char *org, // original string pointer
*w, // work string pointer
b[80]; // work buffer
org = *s; // get initial field data
w = (char *) malloc_chk(m + 1); // allocate work string
memset(w, ' ', m); // clear to blanks
w[m] = 0; // ..and make a string
ins = 0; // clear insert flag
if (org) // q. orig data available?
strncpy(w, org, strlen(org)); // a. yes .. copy to work
CURSOR(); // turn cursor on
win->AtSayReverse(c, r, w); // ..display field
win->GotoXY(x = c, r); // locate start of field
while (1) // loop till user quits
{
while (NOT (k = get_key(NO_ALT))) // wait for a key
; // ..before continuing
switch (k) // handle user's input
{
case LEFT: // left key
if (--x < c) // q. past left margin?
x = c; // a. yes .. reset
break; // ..then get next key
case RIGHT: // right key
if (++x >= (m + c - 1)) // q. past right margin?
x = m + c - 1; // a. yes .. reset
break; // ..then get next key
case BACKSPACE: // backspace
if (x == c) // q. at top of window?
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -