home *** CD-ROM | disk | FTP | other *** search
- /*
- * Echo line reading and writing.
- * Common routines for reading
- * and writing characters in the echo line area
- * of the display screen. Used by the entire
- * known universe.
- */
- #include "def.h"
-
- void eerase ();
- char ereply ();
- char eread ();
- void eformat ();
- void eputi ();
- void eputs ();
- void eputc ();
-
-
- extern char MSG_null[];
- extern char MSG_y_n[];
- extern char MSG_hex_dig[];
-
- #include "lintfunc.dec"
- int epresf = FALSE; /* Stuff in echo line flag. */
-
- /*
- * Erase the echo line.
- */
- void eerase ()
- {
- writ_echo (MSG_null); /* clear the echo line */
- epresf = FALSE;
- }
-
-
- /*
- * Ask "yes" or "no" question.
- * Return ABORT if the user answers the question
- * with the abort ("^G") character. Return FALSE
- * for "no" and TRUE for "yes". No formatting
- * services are available.
- */
- char eyesno (sp)
- char *sp;
- {
-
- register char s;
- char buf[64];
-
- for (;;)
- {
-
- s = ereply (MSG_y_n, buf, sizeof (buf), sp);
- if (s == ABORT)
- return (ABORT);
- if (s != FALSE)
- {
-
- if (buf[0] == 'y' || buf[0] == 'Y')
- return (TRUE);
- if (buf[0] == 'n' || buf[0] == 'N')
- return (FALSE);
- }
-
- }
-
- }
-
-
- /*
- * Write out a prompt, and read back a
- * reply. The prompt is now written out with full "eprintf"
- * formatting, although the arguments are in a rather strange
- * place. This is always a new message, there is no auto
- * completion, and the return is echoed as such.
- */
- /* VARARGS3 */
- char ereply (fp, buf, nbuf, arg)
- char *fp;
- char *buf;
- int nbuf;
- char *arg;
- {
- return (eread (fp, buf, nbuf, EFNEW | EFCR, arg));
- }
-
-
- /*
- * This is the general "read input from the
- * echo line" routine. The basic idea is that the prompt
- * string "prompt" is written to the echo line, and a one
- * line reply is read back into the supplied "buf" (with
- * maximum length "len"). The "flag" contains EFNEW (a
- * new prompt), an EFAUTO (autocomplete), or EFCR (echo
- * the carriage return as CR).
- */
- char eread (fp, buf, nbuf, flag, ap)
- char *fp;
- char *buf;
- char *ap;
- {
-
- register int cpos;
- register SYMBOL * sp1;
- register SYMBOL * sp2;
- register int i;
- register int c;
- register int h;
- register int nhits;
- register int nxtra;
- register int bxtra;
-
- int quote_flag;
-
- quote_flag = 0;
- cpos = 0;
- if (kbdmop != NULL)
- {
- /* In a macro. */
- while ((c = *kbdmop++) != '\0')
- buf[cpos++] = c;
- buf[cpos] = '\0';
- goto done;
- }
-
- if ((flag & EFNEW) != 0 || ttrow != nrow - 1)
- {
-
- ttcolor (CTEXT);
- ttmove (nrow - 1, 0);
- epresf = TRUE;
- }
- else
- eputc (' ');
- eformat (fp, ap);
- tteeol ();
- ttflush ();
- for (;;)
- {
- c = getkey ();
- if (c == ' ' && (flag & EFAUTO) != 0)
- {
- nhits = 0;
- nxtra = HUGE;
- for (h = 0; h < NSHASH; ++h)
- {
- sp1 = symbol[h];
- while (sp1 != NULL)
- {
- for (i = 0; i < cpos; ++i)
- {
- if (buf[i] != sp1 -> s_name[i])
- break;
- }
-
- if (i == cpos)
- {
- if (nhits == 0)
- sp2 = sp1;
- ++nhits;
- bxtra = getxtra (sp1, sp2, cpos);
- if (bxtra < nxtra)
- nxtra = bxtra;
- }
-
- sp1 = sp1 -> s_symp;
- }
- }
-
- if (nhits == 0) /* No completion. */
- continue;
- for (i = 0; i < nxtra && cpos < nbuf - 1; ++i)
- {
- c = sp2 -> s_name[cpos];
- buf[cpos++] = c;
- eputc (c);
- }
-
- ttflush ();
- if (nhits != 1) /* Fake a CR if there */
- continue; /* is 1 choice. */
- c = (KCTRL | 'M');
- }
- if (quote_flag)
- {
- c = c & 0x1f;
- quote_flag = 0;
- }
-
-
- switch (c)
- {
- case (KCTRL | 'Q'):
- quote_flag = 1;
- break;
- case (KCTRL | 'M'): /* Return, done. */
- buf[cpos] = '\0';
- if (kbdmip != NULL)
- {
- if (kbdmip + cpos + 1 > &kbdm[NKBDM - 3])
- {
- (void) ctrlg (FALSE, 0, KRANDOM);
- ttflush ();
- return (ABORT);
- }
-
- for (i = 0; i < cpos; ++i)
- *kbdmip++ = buf[i];
- *kbdmip++ = '\0';
- }
-
- if ((flag & EFCR) != 0)
- {
- ttputc (0x0D);
- ttflush ();
- }
-
- goto done;
-
- case (KCTRL | 'G'): /* Bell, abort. */
- eputc (0x07);
- (void) ctrlg (FALSE, 0, KRANDOM);
- ttflush ();
- return (ABORT);
-
- case 0x7F: /* Rubout, erase. */
- case (KCTRL | 'H'): /* Backspace, erase. */
- if (cpos != 0)
- {
- ttputc ('\b');
- ttputc (' ');
- ttputc ('\b');
- --ttcol;
- if (ISCTRL (buf[--cpos]) != FALSE)
- {
- ttputc ('\b');
- ttputc (' ');
- ttputc ('\b');
- --ttcol;
- }
-
- ttflush ();
- }
- break;
-
- case (KCTRL | 'U'): /* C-U, kill line. */
- while (cpos != 0)
- {
- ttputc ('\b');
- ttputc (' ');
- ttputc ('\b');
- --ttcol;
- if (ISCTRL (buf[--cpos]) != FALSE)
- {
- ttputc ('\b');
- ttputc (' ');
- ttputc ('\b');
- --ttcol;
- }
-
- }
-
- ttflush ();
- break;
-
- default: /* All the rest. */
- if ((cpos < nbuf - 1) && ((c & ~KCHAR) == 0))
- {
- buf[cpos++] = c;
- eputc (c);
- ttflush ();
- }
- } /* End switch */
-
- }
-
- done:
- if (buf[0] == '\0')
- return (FALSE);
- return (TRUE);
- }
-
-
- /*
- * The "sp1" and "sp2" point to extended command
- * symbol table entries. The "cpos" is a horizontal position
- * in the name. Return the longest block of characters that can
- * be autocompleted at this point. Sometimes the two symbols
- * are the same, but this is normal.
- */
- int getxtra (sp1, sp2, cpos)
- SYMBOL * sp1;
- SYMBOL * sp2;
- {
-
- register int i;
-
- i = cpos;
- for (;;)
- {
-
- if (sp1 -> s_name[i] != sp2 -> s_name[i])
- break;
- if (sp1 -> s_name[i] == '\0')
- break;
- ++i;
- }
-
- return (i - cpos);
- }
-
- /*
- * Printf style formatting. This is
- * called by both "eprintf" and "ereply", to provide
- * formatting services to their clients. The move to the
- * start of the echo line, and the erase to the end of
- * the echo line, is done by the caller.
- */
- void eformat (fp, ap)
- char *fp;
- char *ap;
- {
-
- register int c;
-
- while ((c = *fp++) != '\0')
- {
-
- if (c != '%')
- eputc (c);
- else
- {
-
- c = *fp++;
- switch (c)
- {
-
- case 'd':
- eputi (*(int *) ap, 10);
- ap += sizeof (int);
- break;
-
- case 'x': /* krw */
- eputi (*(int *) ap, 16);
- ap += sizeof (int);
- break;
-
- case 'o':
- eputi (*(int *) ap, 8);
- ap += sizeof (int);
- break;
-
- case 's':
- eputs (ap);
- ap += sizeof (char *);
- break;
-
- default:
- eputc (c);
- }
-
- }
-
- }
-
- }
-
-
- /*
- * Put integer, in radix "r".
- */
- void eputi (i, r)
- int i;
- int r;
- {
- static char *convert =
- {
- MSG_hex_dig
- }
- ;
-
- register int q;
-
- if ((q = i / r) != 0)
- eputi (q, r);
- eputc (convert[i % r]);
-
- }
-
-
- /*
- * Put string.
- */
- void eputs (s)
- char *s;
- {
- register int c;
-
- while ((c = *s++) != '\0')
- eputc (c);
- }
-
-
- /*
- * Put character. Watch for
- * control characters, and for the line
- * getting too long.
- */
- void eputc (c)
- int c;
- {
-
- if (ttcol < ncol)
- {
-
- if (ISCTRL (c) != FALSE)
- {
-
- eputc ('^');
- c ^= 0x40;
- }
-
- ttputc (c);
- ++ttcol;
- }
-
- }
-
-