FUTILITY.CPP
资源名称:commutil.zip [点击查看]
上传用户:xr_qian
上传日期:2007-01-05
资源大小:443k
文件大小:20k
源码类别:
通讯/手机编程
开发平台:
DOS
- // ******************************************************************** //
- // //
- // 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
- _wscroll = 0; // 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 (NOT (p = (void *) _fmalloc(n))) // 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?
- {
- printf(BELL); // a. yes .. give warning
- break; // ..and wait for another..
- }
- x--; // move left one character
- // ..and fall into delete key
- case DELETE: // delete key
- i = x - c; // set up string index
- strcpy(&w[i], &w[i + 1]); // simulate delete
- w[m - 1] = ' '; // ..and put a blank at end
- sprintf(b, "%s", &w[i]); // make into string
- win->AtSayReverse(x, r, b); // ..display remainder
- break; // ..and wait for next key
- case HOME: // home key
- x = c; // reset pointer to start
- break; // ..and wait for next key
- case END: // end key
- x = c + m - 1; // reset pointer to end
- break; // ..and wait for next key
- case CR: // carriage return
- case UP: // up arrow key
- case DOWN: // down arrow key
- NOCURSOR(); // turn cursor off
- free(org); // release original data
- *s = w; // store addr of new data
- win->AtSay(c, r, w); // ..display field normally
- return(DOWN); // ..then return to caller
- case ESC: // escape key
- NOCURSOR(); // turn cursor off
- win->AtSay(c, r, w); // ..display field normally
- free(w); // release work copy
- return(0); // ..then return to caller
- case INSERT: // insert toggle
- if (ins) // q. insert mode active?
- {
- ins = 0; // a. yes .. turn it off
- CURSOR(); // ..and use proper cursor
- }
- else
- {
- ins = 1; // else .. set on insert
- BIGCURSOR(); // ..and show insert cursor
- }
- break; // then wait for next key
- default: // error case
- if (k & 0xff00 || // q. function key..
- k < ' ') // ..or less than a blank?
- {
- printf(BELL); // a. yes .. ring the bell
- break; // ..and wait for next key
- }
- i = x - c; // get string index
- if (ins) // q. insert mode active?
- {
- memmove(&w[i + 1], &w[i], // a. yes .. move everything
- m - i); // ..for the remainder over
- w[m] = 0; // ..and overlay the overflow
- w[i] = (char) k; // put new char its place
- sprintf(b, "%s", &w[i]); // make into a displayable
- }
- else
- {
- w[i] = (char) k; // save character in string
- sprintf(b, "%c", k); // make into a string
- }
- win->AtSayReverse(x, r, b); // display new char/string
- if (i < (m - 1)) // q. upto right margin?
- x++; // a. no .. advance one
- break; // ..then get next key
- }
- win->GotoXY(x, r); // ..then go there
- }
- }
- /* ******************************************************************** *
- *
- * set_bits() -- set on a string of bits
- *
- * ******************************************************************** */
- void set_bits(char *s, // target string
- int n, // starting bit nbr (0 based)
- int l) // length of bits
- {
- char mask; // work mask
- int f; // first bit number
- if (NOT l) // q. zero length?
- return; // a. yes .. then just return
- s += n / 8; // get to 1st target byte
- f = n % 8; // bit within byte
- mask = 0xff >> f; // initial mask
- f = 8 - f; // remaining bits after 1st
- if (f >= l) // q. too many already?
- {
- mask &= (0xff00 >> ((n % 8) + l)); // a. yes .. clear off extras
- *s |= mask; // ..set the bits on
- return; // ..and return to caller
- }
- else
- *s++ |= mask; // else .. set on first group
- for (l -= f; l >= 8; l -= 8) // for each group of 8 bits
- *s++ = 0xff; // ..mark all of them on
- if (l) // q. any straglers?
- *s |= 0xff00 >> l; // a. yes .. turn them on too
- }
- /* ******************************************************************** *
- *
- * get_bit() -- get a bit from a string of bits
- *
- * ******************************************************************** */
- UINT get_bit(unsigned char *s, // target string
- int n) // starting bit nbr (0 based)
- {
- return((s[n / 8] >> (7 - (n % 8))) & 1); // return with requested bit
- }
- /* ******************************************************************** *
- *
- * get_bits() -- get a string of bits
- *
- * ******************************************************************** */
- UINT get_bits(unsigned char *s, // target string
- int n, // starting bit nbr (0 based)
- int l) // length of bits
- {
- UINT x; // bits from bit string
- if (NOT l || l > 16) // q. too much or too little?
- return(0); // a. yes .. then just return
- for (x = 0; l--; n++) // while there is work to do
- x = (x << 1) | get_bit(s, n); // ..get another bit
- return(x); // finally, return to caller
- }
- /* ******************************************************************** *
- *
- * reverse_scan() -- backscan for dissimilar character
- *
- * ******************************************************************** */
- char *reverse_scan(char *p, // starting point
- char c, // character to scan against
- int len) // length of search
- {
- for (p += len - 1; len--; p--) // loop thru memory
- if (*p != c) // q. find last one?
- return(p); // a. yes .. return w/address
- return(0); // else .. return empty handed
- }
- /* ******************************************************************** *
- *
- * trim() -- trim trailing blanks
- *
- * ******************************************************************** */
- char *trim(char *s) // source and target string
- {
- char *p; // work pointer
- for (p = s + strlen(s) - 1; // starting at the end..
- *p == ' ' && p > s; p--) // ..work backwards
- ;
- *(++p) = 0; // set in new terminator
- return(s); // ..and return w/source
- }
- /* ******************************************************************** *
- *
- * control_break() -- control break intercept routine
- *
- * ******************************************************************** */
- #pragma option -O2-b-e // no global reg allocation
- // ..or dead code elimination
- void interrupt control_break(...)
- {
- asm mov al, 20 // al = end of interrupt cmd
- asm out 20, al // clear kb interrupt on 8259
- }
- /* ******************************************************************** *
- *
- * critical_rtn() -- DOS critical error handler
- *
- * ******************************************************************** */
- #pragma option -O2-b-e // no global reg allocation
- // ..or dead code elimination
- void interrupt critical_routine(...)
- {
- if (_AX & 0x800) // q. fail allowed?
- _AX = (_AX & 0xff00) | 3; // a. yes .. show failed
- else
- _AX = (_AX & 0xff00) | 2; // else .. abort
- }