FUTILITY.CPP
上传用户:xr_qian
上传日期:2007-01-05
资源大小:443k
文件大小:20k
源码类别:

通讯/手机编程

开发平台:

DOS

  1. // ******************************************************************** //
  2. //                                                                      //
  3. //      FUTILITY.CPP                                                    //
  4. //      Copyright (c) 1993, Michael Holmes and Bob Flanders             //
  5. //      C++ Communication Utilities                                     //
  6. //                                                                      //
  7. //      This file contains the following miscellaneous routines.        //
  8. //          quit_with()      give an error message, then return to DOS  //
  9. //          status_line()    display status line                        //
  10. //          malloc_chk()     allocate memory with error checks          //
  11. //          clear_memory()   clear a large block of memory              //
  12. //          wait()           wait for a give number timer ticks         //
  13. //          wait_ms()        wait in milliseconds                       //
  14. //          first_nonblank() find first non-blank character             //
  15. //          field_edit()     edit a field in a window                   //
  16. //          set_bits()       set on a string of bits                    //
  17. //          get_bit()        get a bit from a string of bits            //
  18. //          get_bits()       get a bunch of bits from a string of bits  //
  19. //          reverse_scan()   scan a area backwards                      //
  20. //          trim()           trim trailing blanks                       //
  21. //          control_break()  control break intercept routine            //
  22. //          critical_rtn()   DOS critical error handler                 //
  23. //                                                                      //
  24. // ******************************************************************** //
  25. /* ******************************************************************** *
  26.  *
  27.  *  quit_with() -- give an error message, then return to DOS
  28.  *
  29.  * ******************************************************************** */
  30. void    quit_with(char *msg, ...)           // quit with an error message
  31. {
  32. va_list list;                               // variable list
  33. if (full_screen)                            // q. in full screen mode?
  34.     {
  35.     term->Close();                          // a. yes .. close term window
  36.     window(1, 1, 80, max_lines);            // set up termination screen
  37.     textcolor(FG(mono_1));                  // ..with foreground
  38.     textbackground(BG(mono_1));             // ..and background colors
  39.     clrscr();                               // ..and clear screen
  40.     CURSOR();                               // ..and set cursor to normal
  41.     printf(copyright);                      // display program banner
  42.     }
  43. _dos_setvect(0x1b, old_break);              // restore old ^break handler
  44. va_start(list, msg);                        // set up variable list
  45. vprintf(msg, list);                         // give error message ..
  46. exit(rc);                                   // ..and then quit
  47. }
  48. /* ******************************************************************** *
  49.  *
  50.  *  status_line() -- update the status line
  51.  *
  52.  * ******************************************************************** */
  53. void    status_line(char *msg, ...)         // message to format/display
  54. {
  55. char    buf[100];                           // string buffer
  56. va_list list;                               // variable list
  57. window(1, 25, 80, 25);                      // set up status window
  58. _wrapon(_GWRAPOFF);                         // disable scrolling
  59. textcolor(FG(stat_cn));                     // set up foreground
  60. textbackground(BG(stat_cn));                // ..and background colors
  61. va_start(list, msg);                        // set up variable list
  62. vsprintf(buf, msg, list);                   // ..format buffer
  63. cprintf(buf);                               // ..then display message
  64. last_window = 0;                            // clear last window accessed
  65. window(1, 1, 80, 25);                       // ..and reset for full screen
  66. }
  67. /* ******************************************************************** *
  68.  *
  69.  *  malloc_chk() -- allocate memory with error processing
  70.  *
  71.  * ******************************************************************** */
  72. void   *malloc_chk(long n)                  // size of block
  73. {
  74. void   *p;                                  // temporary pointer
  75. if (n > 65535L)                             // q. big area?
  76.     p = (void *) _halloc((n + 1) / 2, 2);   // a. yes .. get big memory
  77.  else
  78.     p = (void *) _fmalloc(n);               // else .. get regular memory
  79. if (NOT p)                                  // q. enough memory?
  80.     quit_with(no_memory);                   // a. no .. give error msg
  81. return(p);                                  // else .. return w/address
  82. }
  83. /* ******************************************************************** *
  84.  *
  85.  *  clear_memory() -- clear a big block of memory
  86.  *
  87.  * ******************************************************************** */
  88. void    clear_memory(char *s,               // area to clear
  89.                      char c,                // character to clear to
  90.                      long size)             // length to clear
  91. {
  92. char    huge *p;                            // huge work pointer
  93. UINT    clr_size = 0;                       // working size
  94. for (p = s; size; size -= clr_size)         // clear in big chunks
  95.     {
  96.     if (size > (65536L - 16))               // q. more than 64k to do?
  97.         clr_size = (UINT) 65536L - 16;      // a. yes .. just do some
  98.      else
  99.         clr_size = (UINT) size;             // else .. do what's left
  100.     memset((char *) p, c, (UINT) clr_size); // clear to block to null
  101.     p += clr_size;                          // point to next block
  102.     }
  103. }
  104. /* ******************************************************************** *
  105.  *
  106.  *  wait() -- wait for a given number of timer ticks
  107.  *
  108.  * ******************************************************************** */
  109. void    wait(long n)                        // time to wait in ticks
  110. {
  111. long    far *timer = (long far *)           // BIOS timer tick counter
  112.                         MK_FP(0x40, 0x6c),  // ..down in low memory
  113.         start, work;                        // start tick count
  114. start = *timer;                             // get current time
  115. while (n > 0)                               // loop 'til n ticks past
  116.     {
  117.     if ((work = *timer) != start)           // q. time pass?
  118.         {                                   // a. yes .. see how much
  119.         if (work < start)                   // q. clock go past midnite?
  120.             n--;                            // a. yes .. count as 1 tick
  121.          else
  122.             n -= (UINT)(work - start);      // else .. count everything
  123.         start = work;                       // start again w/curr time
  124.         }
  125.      else
  126.         kbhit();                            // else .. check keyboard
  127.     }
  128. }
  129. /* ******************************************************************** *
  130.  *
  131.  *  wait_ms() -- wait in milliseconds
  132.  *
  133.  * ******************************************************************** */
  134. void    wait_ms(long ms)                    // milliseconds to wait
  135. {
  136. wait((ms + 54) / 55);                       // convert then wait in ticks
  137. }
  138. /* ******************************************************************** *
  139.  *
  140.  *  first_nonblank() -- find first non-blank character
  141.  *
  142.  * ******************************************************************** */
  143. char    *first_nonblank(char *s)            // string to look through
  144. {
  145. for (; *s; s++)                             // loop thru string
  146.     if (NOT isspace(*s))                    // q. find a non-blank char?
  147.         return(s);                          // a. yes .. return w/address
  148. return(0);                                  // else .. string is blank
  149. }
  150. /* ******************************************************************** *
  151.  *
  152.  *  field_edit() -- edit a string field in a window
  153.  *
  154.  * ******************************************************************** */
  155. int     field_edit(Window *win,             // window to work in
  156.                    int  c, int r,           // initial column and row
  157.                    char **s,                // initial field data
  158.                    int  m)                  // maximum field length
  159. {
  160. int     i,                                  // string index
  161.         k,                                  // keyboard input
  162.         x,                                  // current column
  163.         ins;                                // insert flag
  164. char   *org,                                // original string pointer
  165.        *w,                                  // work string pointer
  166.         b[80];                              // work buffer
  167. org = *s;                                   // get initial field data
  168. w = (char *) malloc_chk(m + 1);             // allocate work string
  169. memset(w, ' ', m);                          // clear to blanks
  170. w[m] = 0;                                   // ..and make a string
  171. ins = 0;                                    // clear insert flag
  172. if (org)                                    // q. orig data available?
  173.     strncpy(w, org, strlen(org));           // a. yes .. copy to work
  174. CURSOR();                                   // turn cursor on
  175. win->AtSayReverse(c, r, w);                 // ..display field
  176. win->GotoXY(x = c, r);                      // locate start of field
  177. while (1)                                   // loop till user quits
  178.     {
  179.     while (NOT (k = get_key(NO_ALT)))       // wait for a key
  180.         ;                                   // ..before continuing
  181.     switch (k)                              // handle user's input
  182.         {
  183.         case LEFT:                          // left key
  184.             if (--x < c)                    // q. past left margin?
  185.                 x = c;                      // a. yes .. reset
  186.             break;                          // ..then get next key
  187.         case RIGHT:                         // right key
  188.             if (++x >= (m + c - 1))         // q. past right margin?
  189.                 x = m + c - 1;              // a. yes .. reset
  190.             break;                          // ..then get next key
  191.         case BACKSPACE:                     // backspace
  192.             if (x == c)                     // q. at top of window?
  193.                 {
  194.                 printf(BELL);               // a. yes .. give warning
  195.                 break;                      // ..and wait for another..
  196.                 }
  197.             x--;                            // move left one character
  198.                                             // ..and fall into delete key
  199.         case DELETE:                        // delete key
  200.             i = x - c;                      // set up string index
  201.             strcpy(&w[i], &w[i + 1]);       // simulate delete
  202.             w[m - 1] = ' ';                 // ..and put a blank at end
  203.             sprintf(b, "%s", &w[i]);        // make into string
  204.             win->AtSayReverse(x, r, b);     // ..display remainder
  205.             break;                          // ..and wait for next key
  206.         case HOME:                          // home key
  207.             x = c;                          // reset pointer to start
  208.             break;                          // ..and wait for next key
  209.         case END:                           // end key
  210.             x = c + m - 1;                  // reset pointer to end
  211.             break;                          // ..and wait for next key
  212.         case CR:                            // carriage return
  213.         case UP:                            // up arrow key
  214.         case DOWN:                          // down arrow key
  215.             NOCURSOR();                     // turn cursor off
  216.             free(org);                      // release original data
  217.             *s = w;                         // store addr of new data
  218.             win->AtSay(c, r, w);            // ..display field normally
  219.             return(DOWN);                   // ..then return to caller
  220.         case ESC:                           // escape key
  221.             NOCURSOR();                     // turn cursor off
  222.             win->AtSay(c, r, w);            // ..display field normally
  223.             free(w);                        // release work copy
  224.             return(0);                      // ..then return to caller
  225.         case INSERT:                        // insert toggle
  226.             if (ins)                        // q. insert mode active?
  227.                 {
  228.                 ins = 0;                    // a. yes .. turn it off
  229.                 CURSOR();                   // ..and use proper cursor
  230.                 }
  231.              else
  232.                 {
  233.                 ins = 1;                    // else .. set on insert
  234.                 BIGCURSOR();                // ..and show insert cursor
  235.                 }
  236.             break;                          // then wait for next key
  237.         default:                            // error case
  238.             if (k & 0xff00 ||               // q. function key..
  239.                         k < ' ')            // ..or less than a blank?
  240.                 {
  241.                 printf(BELL);               // a. yes .. ring the bell
  242.                 break;                      // ..and wait for next key
  243.                 }
  244.             i = x - c;                      // get string index
  245.             if (ins)                        // q. insert mode active?
  246.                 {
  247.                 memmove(&w[i + 1], &w[i],   // a. yes .. move everything
  248.                         m - i);             // ..for the remainder over
  249.                 w[m] = 0;                   // ..and overlay the overflow
  250.                 w[i] = (char) k;            // put new char its place
  251.                 sprintf(b, "%s", &w[i]);    // make into a displayable
  252.                 }
  253.              else
  254.                 {
  255.                 w[i] = (char) k;            // save character in string
  256.                 sprintf(b, "%c", k);        // make into a string
  257.                 }
  258.             win->AtSayReverse(x, r, b);     // display new char/string
  259.             if (i < (m - 1))                // q. upto right margin?
  260.                 x++;                        // a. no .. advance one
  261.             break;                          // ..then get next key
  262.         }
  263.     win->GotoXY(x, r);                      // ..then go there
  264.     }
  265. return(0);                                  // keep MSC C/C++ happy
  266. }
  267. /* ******************************************************************** *
  268.  *
  269.  *  set_bits() -- set on a string of bits
  270.  *
  271.  * ******************************************************************** */
  272. void    set_bits(char huge *s,              // target string
  273.                  int   n,                   // starting bit nbr (0 based)
  274.                  int   l)                   // length of bits
  275. {
  276. char    mask;                               // work mask
  277. int     f;                                  // first bit number
  278. if (NOT l)                                  // q. zero length?
  279.     return;                                 // a. yes .. then just return
  280. s += n / 8;                                 // get to 1st target byte
  281. f = n % 8;                                  // bit within byte
  282. mask = 0xff >> f;                           // initial mask
  283. f = 8 - f;                                  // remaining bits after 1st
  284. if (f >= l)                                 // q. too many already?
  285.     {
  286.     mask &= (0xff00 >> ((n % 8) + l));      // a. yes .. clear off extras
  287.     *s |= mask;                             // ..set the bits on
  288.     return;                                 // ..and return to caller
  289.     }
  290.  else
  291.     *s++ |= mask;                           // else .. set on first group
  292. for (l -= f; l >= 8; l -= 8)                // for each group of 8 bits
  293.     *s++ = 0xff;                            // ..mark all of them on
  294. if (l)                                      // q. any straglers?
  295.     *s |= 0xff00 >> l;                      // a. yes .. turn them on too
  296. }
  297. /* ******************************************************************** *
  298.  *
  299.  *  get_bit() -- get a bit from a string of bits
  300.  *
  301.  * ******************************************************************** */
  302. UINT    get_bit(unsigned char huge *s,      // target string
  303.                 int   n)                    // starting bit nbr (0 based)
  304. {
  305. return((s[n / 8] >> (7 - (n % 8))) & 1);    // return with requested bit
  306. }
  307. /* ******************************************************************** *
  308.  *
  309.  *  get_bits() -- get a string of bits
  310.  *
  311.  * ******************************************************************** */
  312. UINT    get_bits(unsigned char huge *s,     // target string
  313.                  int   n,                   // starting bit nbr (0 based)
  314.                  int   l)                   // length of bits
  315. {
  316. UINT    x;                                  // bits from bit string
  317. if (NOT l || l > 16)                        // q. too much or too little?
  318.     return(0);                              // a. yes .. then just return
  319. for (x = 0; l--; n++)                       // while there is work to do
  320.     x = (x << 1) | get_bit(s, n);           // ..get another bit
  321. return(x);                                  // finally, return to caller
  322. }
  323. /* ******************************************************************** *
  324.  *
  325.  *  reverse_scan() -- backscan for dissimilar character
  326.  *
  327.  * ******************************************************************** */
  328. char   *reverse_scan(char *p,               // starting point
  329.                      char c,                // character to scan against
  330.                      int  len)              // length of search
  331. {
  332. for (p += len - 1; len--; p--)              // loop thru memory
  333.     if (*p != c)                            // q. find last one?
  334.         return(p);                          // a. yes .. return w/address
  335. return(0);                                  // else .. return empty handed
  336. }
  337. /* ******************************************************************** *
  338.  *
  339.  *  trim() -- trim trailing blanks
  340.  *
  341.  * ******************************************************************** */
  342. char   *trim(char *s)                       // source and target string
  343. {
  344. char   *p;                                  // work pointer
  345. for (p = s + strlen(s) - 1;                 // starting at the end..
  346.             *p == ' ' && p > s; p--)        // ..work backwards
  347.     ;
  348. *(++p) = 0;                                 // set in new terminator
  349. return(s);                                  // ..and return w/source
  350. }
  351. /* ******************************************************************** *
  352.  *
  353.  *  control_break() -- control break intercept routine
  354.  *
  355.  * ******************************************************************** */
  356. void    interrupt far control_break(void)
  357. {
  358. _asm    mov al, 20                          // al = end of interrupt cmd
  359. _asm    out 20, al                          // clear kb interrupt on 8259
  360. }
  361. /* ******************************************************************** *
  362.  *
  363.  *  critical_rtn() -- DOS critical error handler
  364.  *
  365.  * ******************************************************************** */
  366. void    interrupt far critical_routine(void)
  367. {
  368. _asm
  369.     {
  370.     mov     al, 0x03                        // al = fail request rtn code
  371.     test    ah, 0x80                        // q. fail allowed?
  372.     jnz     Done                            // a. yes .. just return
  373.     mov     al, 0x02                        // al = abort request rtn code
  374.     Done:
  375.     }
  376. }