home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- #include "jove.h"
- #include "fp.h"
- #include "termcap.h"
- #include "ctype.h"
- #include "disp.h"
-
- #ifdef MAC
- # include "mac.h"
- #else
- # ifdef STDARGS
- # include <stdarg.h>
- # else
- # include <varargs.h>
- # endif
- #endif
-
- private void
- doformat proto((File *, char *, va_list)),
- outld proto((long, int)),
- pad proto((int, int)),
- PPchar proto((int, char *)),
- putld proto((long, int)),
- puts proto((char *));
-
- char mesgbuf[MESG_SIZE];
-
- void
- format(buf, len, fmt, ap)
- char *buf,
- *fmt;
- size_t len;
- va_list ap;
- {
- File strbuf,
- *sp = &strbuf;
-
- sp->f_ptr = sp->f_base = buf;
- sp->f_fd = -1; /* Not legit for files */
- sp->f_cnt = len;
- sp->f_flags = F_STRING;
- sp->f_bufsize = len;
-
- doformat(sp, fmt, ap);
- jputc('\0', sp);
- }
-
- #ifdef IBMPC
- int specialmap = 0,
- specialkey = 0;
-
- #define Empty ""
-
- const char *const altseq[133] = {
- Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
- Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left",
- "Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
- "Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
- "Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
- Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
- "Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
- Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5",
- "F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
- "Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
- "Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4",
- "Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
- "Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10",
- "Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
- "Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
- "Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
- "Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp"
- };
- #endif
-
-
- private void
- PPchar(c, str)
- int c;
- char *str;
- {
- char *cp = str;
-
- #ifdef IBMPC
- if (specialmap || specialkey) {
- if (c < 0 || c > 132)
- c = 0;
- strcpy(cp, altseq[c]);
- } else
- #endif
- if (c == '\033')
- strcpy(cp, "ESC");
- #ifdef IBMPC /* this character is invisible */
- else if (c == '\377') {
- *cp = 0;
- }
- #endif /* IBMPC */
- else if (c < ' ')
- swritef(cp, "C-%c", c + '@');
- else if (c == '\177')
- strcpy(cp, "^?");
- else
- swritef(cp, "%c", c);
- }
-
- private struct fmt_state {
- int precision,
- width,
- leftadj;
- char padc;
- File *iop;
- } current_fmt;
-
- private void
- putld(d, base)
- long d;
- int base;
- {
- int len = 1;
- long tmpd = d;
-
- if (current_fmt.width == 0 && current_fmt.precision) {
- current_fmt.width = current_fmt.precision;
- current_fmt.padc = '0';
- }
- while ((tmpd = (tmpd / base)) != 0)
- len += 1;
- if (d < 0)
- len += 1;
- if (!current_fmt.leftadj)
- pad(current_fmt.padc, current_fmt.width - len);
- if (d < 0) {
- jputc('-', current_fmt.iop);
- d = -d;
- }
- outld(d, base);
- if (current_fmt.leftadj)
- pad(current_fmt.padc, current_fmt.width - len);
- }
-
- private void
- outld(d, base)
- long d;
- int base;
- {
- register long n;
- static const char chars[] = {'0', '1', '2', '3', '4', '5', '6',
- '7', '8', '9', 'a', 'b', 'c', 'd',
- 'e', 'f'};
-
- if ((n = (d / base)) != 0)
- outld(n, base);
- jputc((int) (chars[(int) (d % base)]), current_fmt.iop);
- }
-
- private void
- puts(str)
- char *str;
- {
- int len;
- register char *cp;
-
- if (str == 0)
- #if defined(pyr)
- str = "";
- #else
- str = "(null)";
- #endif
- len = strlen(str);
- if (current_fmt.precision == 0 || len < current_fmt.precision)
- current_fmt.precision = len;
- else
- len = current_fmt.precision;
- cp = str;
- if (!current_fmt.leftadj)
- pad(' ', current_fmt.width - len);
- while (--current_fmt.precision >= 0)
- jputc(*cp++, current_fmt.iop);
- if (current_fmt.leftadj)
- pad(' ', current_fmt.width - len);
- }
-
- private void
- pad(c, amount)
- register int c,
- amount;
- {
- while (--amount >= 0)
- jputc(c, current_fmt.iop);
- }
-
- private void
- doformat(sp, fmt, ap)
- register File *sp;
- register char *fmt;
- va_list ap;
- {
- register char c;
- struct fmt_state prev_fmt;
-
- prev_fmt = current_fmt;
- current_fmt.iop = sp;
-
- while ((c = *fmt++) != '\0') {
- if (c != '%') {
- jputc(c, current_fmt.iop);
- continue;
- }
-
- current_fmt.padc = ' ';
- current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
- c = *fmt++;
- if (c == '-') {
- current_fmt.leftadj = YES;
- c = *fmt++;
- }
- if (c == '0') {
- current_fmt.padc = '0';
- c = *fmt++;
- }
- while (c >= '0' && c <= '9') {
- current_fmt.width = current_fmt.width * 10 + (c - '0');
- c = *fmt++;
- }
- if (c == '*') {
- current_fmt.width = va_arg(ap, int);
- c = *fmt++;
- }
- if (c == '.') {
- c = *fmt++;
- while (c >= '0' && c <= '9') {
- current_fmt.precision = current_fmt.precision * 10 + (c - '0');
- c = *fmt++;
- }
- if (c == '*') {
- current_fmt.precision = va_arg(ap, int);
- c = *fmt++;
- }
- }
- reswitch:
- /* At this point, fmt points at one past the format letter. */
- switch (c) {
- case '%':
- jputc('%', current_fmt.iop);
- break;
-
- case 'O':
- case 'D':
- case 'X':
- putld(va_arg(ap, long), (c == 'O') ? 8 :
- (c == 'D') ? 10 : 16);
- break;
-
- case 'b':
- {
- Buffer *b = va_arg(ap, Buffer *);
-
- puts(b->b_name);
- break;
- }
-
- case 'c':
- jputc(va_arg(ap, int), current_fmt.iop);
- break;
-
- case 'o':
- case 'd':
- case 'x':
- putld((long) va_arg(ap, int), (c == 'o') ? 8 :
- (c == 'd') ? 10 : 16);
- break;
-
- case 'f': /* current command name gets inserted here! */
- puts(LastCmd->Name);
- break;
-
- case 'l':
- c = CharUpcase(*++fmt);
- goto reswitch;
-
- case 'n':
- if (va_arg(ap, int) != 1)
- puts("s");
- break;
-
- case 'p':
- {
- char cbuf[20];
-
- PPchar(va_arg(ap, int), cbuf);
- puts(cbuf);
- break;
- }
-
- case 's':
- puts(va_arg(ap, char *));
- break;
-
- default:
- complain("Unknown format directive: \"%%%c\"", c);
- }
- }
- current_fmt = prev_fmt;
- }
-
- #ifdef STDARGS
- char *
- sprint(char *fmt, ...)
- #else
- /*VARARGS1*/ char *
- sprint(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
- static char line[100];
-
- va_init(ap, fmt);
- format(line, sizeof line, fmt, ap);
- va_end(ap);
- return line;
- }
-
- #ifdef STDARGS
- void
- writef(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- writef(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- va_init(ap, fmt);
- #ifndef IBMPC
- doformat(stdout, fmt, ap);
- #else /* IBMPC */
- write_em(sprint(fmt, ap));
- /* doformat(stdout, fmt, ap); */
- #endif /* IBMPC */
- va_end(ap);
- }
-
- #ifdef STDARGS
- void
- fwritef(File *fp, char *fmt, ...)
- #else
- /*VARARGS2*/ void
- fwritef(fp, fmt, va_alist)
- File *fp;
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- va_init(ap, fmt);
- doformat(fp, fmt, ap);
- va_end(ap);
- }
-
- #ifdef STDARGS
- void
- swritef(char *str, char *fmt, ...)
- #else
- /*VARARGS2*/ void
- swritef(str, fmt, va_alist)
- char *str,
- *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- va_init(ap, fmt);
- format(str, (size_t)130, fmt, ap);
- va_end(ap);
- }
-
- #ifdef STDARGS
- void
- s_mess(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- s_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- if (InJoverc)
- return;
- va_init(ap, fmt);
- format(mesgbuf, sizeof mesgbuf, fmt, ap);
- va_end(ap);
- message(mesgbuf);
- }
-
- #ifdef STDARGS
- void
- f_mess(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- f_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- va_list ap;
-
- va_init(ap, fmt);
- format(mesgbuf, sizeof mesgbuf, fmt, ap);
- va_end(ap);
- DrawMesg(NO);
- errormsg = NO;
- UpdMesg = YES; /* still needs updating (for convenience) */
- }
-
- #ifdef STDARGS
- void
- add_mess(char *fmt, ...)
- #else
- /*VARARGS1*/ void
- add_mess(fmt, va_alist)
- char *fmt;
- va_dcl
- #endif
- {
- int mesg_len = strlen(mesgbuf);
- va_list ap;
-
- if (InJoverc)
- return;
- va_init(ap, fmt);
- format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
- va_end(ap);
- message(mesgbuf);
- }
-