UTILITY.CPP
资源名称:commutil.zip [点击查看]
上传用户:xr_qian
上传日期:2007-01-05
资源大小:443k
文件大小:26k
源码类别:
通讯/手机编程
开发平台:
DOS
- // ******************************************************************** //
- // //
- // 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 = ' '; // 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
- }
- /* ******************************************************************** *
- *
- * elapsed_time() -- return elapsed time in ticks
- *
- * ******************************************************************** */
- ULONG elapsed_time(ULONG st) // start time in ticks
- {
- static
- ULONG far *timer = (unsigned long far *) // BIOS timer tick counter
- MK_FP(0x40, 0x6c); // ..down in low memory
- if (st > *timer) // q. start time greater?
- return((TICKS_DAY - st) + *timer); // a. yes .. add in rollover;
- else
- return(*timer - st); // return elapsed ticks
- }
- /* ******************************************************************** *
- *
- * 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
- }
- /* ******************************************************************** *
- *
- * malloc_chk() -- allocate memory with error processing
- *
- * ******************************************************************** */
- void *malloc_chk(int s) // size to allocate
- {
- void *p; // work pointer
- if ((p = malloc(s)) == 0) // q. out of memory?
- quit_with(no_memory, s); // a. yes .. give error msg
- return(p); // finally rtn with pointer
- }
- /* ******************************************************************** *
- *
- * 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
- for(;;) // 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. up to right margin?
- x++; // a. no .. advance one
- break; // ..then get next key
- }
- win->GotoXY(x, r); // ..then go there
- }
- }
- /* ******************************************************************** *
- *
- * delete_file() -- delete file any way necessary
- *
- * ******************************************************************** */
- int delete_file(char *s) // filename to delete
- {
- int rc; // return code, 0=ok
- if ((rc = unlink(s)) != 0) // q. regular unlink work?
- { // a. no .. change attributes
- if (NOT (rc = chmod(s, S_IWRITE))) // q. change work?
- rc = unlink(s); // a. yes .. try delete again
- }
- return(rc); // return with final status
- }
- /* ******************************************************************** *
- *
- * pad() -- pad a string to a length
- *
- * ******************************************************************** */
- void pad(char *s, // target string
- int len) // final length
- {
- int i; // calculated pad length
- i = strlen(s); // get current length
- if (i < len) // q. need padding?
- {
- len -= i; // a. yes .. get pad length
- memset(&s[i], ' ', len); // ..blank out rest
- }
- s[len] = 0; // ..and terminate string
- }
- /* ******************************************************************** *
- *
- * touppers() -- translate all characters to uppercase
- *
- * ******************************************************************** */
- void touppers(char *s) // string to translate
- {
- while (*s) // for each char in string
- {
- *s = toupper(*s); // .. translate to uppercase
- s++; // .. and go to next char
- }
- }
- /* ******************************************************************** *
- *
- * 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
- }