home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / OS2 / BEAV132X.ZIP / ECHO.C < prev    next >
C/C++ Source or Header  |  1992-01-06  |  8KB  |  449 lines

  1. /*
  2. *       Echo line reading and writing.
  3. * Common routines for reading
  4. * and writing characters in the echo line area
  5. * of the display screen. Used by the entire
  6. * known universe.
  7. */
  8. #include    "def.h"
  9.  
  10. void    eerase ();
  11. char    ereply ();
  12. char    eread ();
  13. void    eformat ();
  14. void    eputi ();
  15. void    eputs ();
  16. void    eputc ();
  17.  
  18.  
  19. extern    char    MSG_null[];
  20. extern    char    MSG_y_n[];
  21. extern    char    MSG_hex_dig[];
  22. extern    char    MSG_hit_key[];
  23.  
  24. int     epresf = FALSE;         /* Stuff in echo line flag. */
  25.  
  26. /*
  27. * Erase the echo line.
  28. */
  29. void eerase ()
  30. {
  31.     writ_echo (MSG_null);  /* clear the echo line */
  32.     epresf = FALSE;
  33. }
  34.  
  35.  
  36. /*
  37. * Ask "yes" or "no" question.
  38. * Return ABORT if the user answers the question
  39. * with the abort ("^G") character. Return FALSE
  40. * for "no" and TRUE for "yes". No formatting
  41. * services are available.
  42. */
  43. char    eyesno (sp)
  44. char   *sp;
  45. {
  46.  
  47.     register char   s;
  48.     char    buf[NCOL];
  49.  
  50.     for (;;)
  51.     {
  52.  
  53.         s = ereply (MSG_y_n, buf, sizeof (buf), sp);
  54.         if (s == ABORT)
  55.             return (ABORT);
  56.         if (s != FALSE)
  57.         {
  58.  
  59.             if (buf[0] == 'y' || buf[0] == 'Y')
  60.                 return (TRUE);
  61.             if (buf[0] == 'n' || buf[0] == 'N')
  62.                 return (FALSE);
  63.         }
  64.  
  65.     }
  66.  
  67. }
  68.  
  69.  
  70. /*
  71. * Write out a prompt, and read back a
  72. * reply. The prompt is now written out with full "eprintf"
  73. * formatting, although the arguments are in a rather strange
  74. * place. This is always a new message, there is no auto
  75. * completion, and the return is echoed as such.
  76. */
  77. /* VARARGS3 */
  78. char    ereply (fp, buf, nbuf, arg)
  79. char   *fp;
  80. char   *buf;
  81. int     nbuf;
  82. char   *arg;
  83. {
  84.     return (eread (fp, buf, nbuf, EFNEW | EFCR, arg));
  85. }
  86.  
  87.  
  88. /*
  89. * This is the general "read input from the
  90. * echo line" routine. The basic idea is that the prompt
  91. * string "prompt" is written to the echo line, and a one
  92. * line reply is read back into the supplied "buf" (with
  93. * maximum length "len"). The "flag" contains EFNEW (a
  94. * new prompt), an EFAUTO (autocomplete), or EFCR (echo
  95. * the carriage return as CR).
  96. */
  97. char    eread (fp, buf, nbuf, flag, ap)
  98. char   *fp;
  99. char   *buf;
  100. int    nbuf, flag;
  101. char   *ap;
  102. {
  103.  
  104.     register int    cpos;
  105.     register    SYMBOL * sp1;
  106.     register    SYMBOL * sp2;
  107.     register int    i;
  108.     register int    c;
  109.     register int    h;
  110.     register int    nhits;
  111.     register int    nxtra;
  112.     register int    bxtra;
  113.  
  114.     int     quote_flag;
  115.  
  116.     quote_flag = 0;
  117.     cpos = 0;
  118.     if (kbdmop != NULL)
  119.     {
  120.         /* In a macro.      */
  121.         while ((c = *kbdmop++) != '\0')
  122.             buf[cpos++] = c;
  123.         buf[cpos] = '\0';
  124.         goto done;
  125.     }
  126.  
  127.     if ((flag & EFNEW) != 0 || ttrow != nrow - 1)
  128.     {
  129.  
  130.         ttcolor (CTEXT);
  131.         ttmove (nrow - 1, 0);
  132.         epresf = TRUE;
  133.     }
  134.     else
  135.         eputc (' ');
  136.     eformat (fp, ap);
  137.     tteeol ();
  138.     ttflush ();
  139.     for (;;)
  140.     {
  141.         c = getkey ();
  142.         if (c == ' ' && (flag & EFAUTO) != 0)
  143.         {
  144.             nhits = 0;
  145.             nxtra = HUGE;
  146.             for (h = 0; h < NSHASH; ++h)
  147.             {
  148.                 sp1 = symbol[h];
  149.                 while (sp1 != NULL)
  150.                 {
  151.                     for (i = 0; i < cpos; ++i)
  152.                     {
  153.                         if (buf[i] != sp1 -> s_name[i])
  154.                             break;
  155.                     }
  156.  
  157.                     if (i == cpos)
  158.                     {
  159.                         if (nhits == 0)
  160.                             sp2 = sp1;
  161.                         ++nhits;
  162.                         bxtra = getxtra (sp1, sp2, cpos);
  163.                         if (bxtra < nxtra)
  164.                             nxtra = bxtra;
  165.                     }
  166.  
  167.                     sp1 = sp1 -> s_symp;
  168.                 }
  169.             }
  170.  
  171.             if (nhits == 0)     /* No completion.   */
  172.                 continue;
  173.             for (i = 0; i < nxtra && cpos < nbuf - 1; ++i)
  174.             {
  175.                 c = sp2 -> s_name[cpos];
  176.                 buf[cpos++] = c;
  177.                 eputc (c);
  178.             }
  179.  
  180.             ttflush ();
  181.             if (nhits != 1)     /* Fake a CR if there   */
  182.                 continue;       /* is 1 choice.     */
  183.             c = (KCTRL | 'M');
  184.         }
  185.         if (quote_flag)
  186.         {
  187.             c = c & 0x1f;
  188.             quote_flag = 0;
  189.         }
  190.  
  191.  
  192.         switch (c)
  193.         {
  194.         case (KCTRL | 'Q'):
  195.             quote_flag = 1;
  196.             break;
  197.         case (KCTRL | 'M'): /* Return, done.    */
  198.                 case (KCTRL | 'J'): /* Linefeed, done.    */
  199.             buf[cpos] = '\0';
  200.             if (kbdmip != NULL)
  201.             {
  202.                 if (kbdmip + cpos + 1 > &kbdm[NKBDM - 3])
  203.                 {
  204.                     (void) ctrlg (FALSE, 0, KRANDOM);
  205.                     ttflush ();
  206.                     return (ABORT);
  207.                 }
  208.  
  209.                 for (i = 0; i < cpos; ++i)
  210.                     *kbdmip++ = buf[i];
  211.                 *kbdmip++ = '\0';
  212.             }
  213.  
  214.             if ((flag & EFCR) != 0)
  215.             {
  216.                 ttputc (0x0D);
  217.                 ttflush ();
  218.             }
  219.  
  220.             goto done;
  221.  
  222.         case (KCTRL | 'G'): /* Bell, abort.     */
  223.             eputc (0x07);
  224.             (void) ctrlg (FALSE, 0, KRANDOM);
  225.             ttflush ();
  226.             return (ABORT);
  227.  
  228.         case 0x7F:          /* Rubout, erase.   */
  229.         case (KCTRL | 'H'): /* Backspace, erase.    */
  230.             if (cpos != 0)
  231.             {
  232.                 ttputc ('\b');
  233.                 ttputc (' ');
  234.                 ttputc ('\b');
  235.                 --ttcol;
  236.                 if (ISCTRL (buf[--cpos]) != FALSE)
  237.                 {
  238.                     ttputc ('\b');
  239.                     ttputc (' ');
  240.                     ttputc ('\b');
  241.                     --ttcol;
  242.                 }
  243.  
  244.                 ttflush ();
  245.             }
  246.             break;
  247.  
  248.         case (KCTRL | 'U'): /* C-U, kill line.  */
  249.             while (cpos != 0)
  250.             {
  251.                 ttputc ('\b');
  252.                 ttputc (' ');
  253.                 ttputc ('\b');
  254.                 --ttcol;
  255.                 if (ISCTRL (buf[--cpos]) != FALSE)
  256.                 {
  257.                     ttputc ('\b');
  258.                     ttputc (' ');
  259.                     ttputc ('\b');
  260.                     --ttcol;
  261.                 }
  262.  
  263.             }
  264.  
  265.             ttflush ();
  266.             break;
  267.  
  268.         default:            /* All the rest.    */
  269.             if ((cpos < nbuf - 1) && ((c & ~KCHAR) == 0))
  270.             {
  271.                 buf[cpos++] = c;
  272.                 eputc (c);
  273.                 ttflush ();
  274.             }
  275.         }                   /* End switch */
  276.  
  277.     }
  278.  
  279. done:
  280.     if (buf[0] == '\0')
  281.         return (FALSE);
  282.     return (TRUE);
  283. }
  284.  
  285.  
  286. /*
  287. * The "sp1" and "sp2" point to extended command
  288. * symbol table entries. The "cpos" is a horizontal position
  289. * in the name. Return the longest block of characters that can
  290. * be autocompleted at this point. Sometimes the two symbols
  291. * are the same, but this is normal.
  292. */
  293. int     getxtra (sp1, sp2, cpos)
  294. SYMBOL * sp1;
  295. SYMBOL * sp2;
  296. int cpos;
  297. {
  298.  
  299.     register int    i;
  300.  
  301.     i = cpos;
  302.     for (;;)
  303.     {
  304.  
  305.         if (sp1 -> s_name[i] != sp2 -> s_name[i])
  306.             break;
  307.         if (sp1 -> s_name[i] == '\0')
  308.             break;
  309.         ++i;
  310.     }
  311.  
  312.     return (i - cpos);
  313. }
  314.  
  315. /*
  316. * Printf style formatting. This is
  317. * called by both "eprintf" and "ereply", to provide
  318. * formatting services to their clients. The move to the
  319. * start of the echo line, and the erase to the end of
  320. * the echo line, is done by the caller.
  321. */
  322. void eformat (fp, ap)
  323. char  *fp;
  324. char  *ap;
  325. {
  326.  
  327.     register int    c;
  328.  
  329.     while ((c = *fp++) != '\0')
  330.     {
  331.  
  332.         if (c != '%')
  333.             eputc (c);
  334.         else
  335.         {
  336.  
  337.             c = *fp++;
  338.             switch (c)
  339.             {
  340.  
  341.             case 'd':
  342.                 eputi (*(int *) ap, 10);
  343.                 ap += sizeof (int);
  344.                 break;
  345.  
  346.             case 'x':       /* krw */
  347.                 eputi (*(int *) ap, 16);
  348.                 ap += sizeof (int);
  349.                 break;
  350.  
  351.             case 'o':
  352.                 eputi (*(int *) ap, 8);
  353.                 ap += sizeof (int);
  354.                 break;
  355.  
  356.             case 's':
  357.                 eputs (ap);
  358.                 ap += sizeof (char *);
  359.                 break;
  360.  
  361.             default:
  362.                 eputc (c);
  363.             }
  364.  
  365.         }
  366.  
  367.     }
  368.  
  369. }
  370.  
  371.  
  372. /*
  373. * Put integer, in radix "r".
  374. */
  375. void eputi (i, r)
  376. int    i;
  377. int    r;
  378. {
  379.     static char *convert =
  380.     {
  381.         MSG_hex_dig
  382.     };
  383.  
  384.  
  385.     register int    q;
  386.  
  387.     if ((q = i / r) != 0)
  388.         eputi (q, r);
  389.     eputc (convert[i % r]);
  390.  
  391. }
  392.  
  393.  
  394. /*
  395. * Put string.
  396. */
  397. void eputs (s)
  398. char  *s;
  399. {
  400.     register int    c;
  401.  
  402.     while ((c = *s++) != '\0')
  403.         eputc (c);
  404. }
  405.  
  406.  
  407. /*
  408. * Put character. Watch for
  409. * control characters, and for the line
  410. * getting too long.
  411. */
  412. void eputc (c)
  413. int    c;
  414. {
  415.  
  416.     if (ttcol < ncol)
  417.     {
  418.  
  419.         if (ISCTRL (c) != FALSE)
  420.         {
  421.  
  422.             eputc ('^');
  423.             c ^= 0x40;
  424.         }
  425.  
  426.         ttputc (c);
  427.         ++ttcol;
  428.     }
  429.  
  430. }
  431. /*
  432.  *   Print warning message and wait for the user to hit a key.
  433.  */
  434. void    err_echo (buf)
  435. char    *buf;
  436. {
  437.     char   ch[NCOL * 2];
  438.  
  439.     strcpy (ch, buf);
  440.     strcat (ch, MSG_hit_key);
  441.     writ_echo (ch);
  442.     ttbeep ();
  443.     while (ttgetc () != CTL_G);
  444.     {
  445.         ttbeep ();
  446.         ttflush ();
  447.     }
  448. }
  449.