|
|
1.1 root 1: /***************************************************************************
2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
3: * is provided to you without charge, and with no warranty. You may give *
4: * away copies of JOVE, including sources, provided that this notice is *
5: * included in all the files. *
6: ***************************************************************************/
7:
8: #include "jove.h"
9: #include "fp.h"
10: #include "termcap.h"
11: #include "ctype.h"
12: #include "disp.h"
13:
14: #ifdef MAC
15: # include "mac.h"
16: #else
17: # ifdef STDARGS
18: # include <stdarg.h>
19: # else
20: # include <varargs.h>
21: # endif
22: #endif
23:
24: private void
25: doformat proto((File *, char *, va_list)),
26: outld proto((long, int)),
27: pad proto((int, int)),
28: PPchar proto((int, char *)),
29: putld proto((long, int)),
30: puts proto((char *));
31:
32: char mesgbuf[MESG_SIZE];
33:
34: void
35: format(buf, len, fmt, ap)
36: char *buf,
37: *fmt;
38: size_t len;
39: va_list ap;
40: {
41: File strbuf,
42: *sp = &strbuf;
43:
44: sp->f_ptr = sp->f_base = buf;
45: sp->f_fd = -1; /* Not legit for files */
46: sp->f_cnt = len;
47: sp->f_flags = F_STRING;
48: sp->f_bufsize = len;
49:
50: doformat(sp, fmt, ap);
51: jputc('\0', sp);
52: }
53:
54: #ifdef IBMPC
55: int specialmap = 0,
56: specialkey = 0;
57:
58: #define Empty ""
59:
60: const char *const altseq[133] = {
61: Empty, Empty, Empty, "Ctrl-@", Empty, Empty, Empty, Empty,
62: Empty, Empty, Empty, Empty, Empty, Empty, Empty, "Left",
63: "Alt-Q", "Alt-W", "Alt-E", "Alt-R", "Alt-T", "Alt-Y", "Alt-U", "Alt-I",
64: "Alt-O", "Alt-P", Empty, Empty, Empty, Empty, "Alt-A", "Alt-S",
65: "Alt-D", "Alt-F", "Alt-G", "Alt-H", "Alt-J", "Alt-K", "Alt-L", Empty,
66: Empty, Empty, Empty, Empty, "Alt-Z", "Alt-X", "Alt-C", "Alt-V",
67: "Alt-B", "Alt-N", "Alt-M", Empty, Empty, Empty, Empty, Empty,
68: Empty, Empty, Empty, "F1", "F2", "F3", "F4", "F5",
69: "F6", "F7", "F8", "F9", "F10", Empty, Empty, "Home",
70: "Up", "PageUp", Empty, "Left", Empty, "Right", Empty, "End",
71: "Down", "PageDown", "Ins", "Del", "Shift F1", "Shift F2", "Shift F3", "Shift F4",
72: "Shift F5", "Shift F6", "Shift F7", "Shift F8", "Shift F9", "Shift F10", "Ctrl F1", "Ctrl F2",
73: "Ctrl F3", "Ctrl F4", "Ctrl F5", "Ctrl F6", "Ctrl F7", "Ctrl F8", "Ctrl F9", "Ctrl F10",
74: "Alt F1", "Alt F2", "Alt F3", "Alt F4", "Alt F5", "Alt F6", "Alt F7", "Alt F8",
75: "Alt F9", "Alt F10", "Ctrl PrtSc", "Ctrl Left", "Ctrl Right", "Ctrl End", "Ctrl PageDown", "Ctrl Home",
76: "Alt 1", "Alt 2", "Alt 3", "Alt 4", "Alt 5", "Alt 6", "Alt 7", "Alt 8",
77: "Alt 9", "Alt 0", "Alt Minus", "Alt Equals", "Ctrl PageUp"
78: };
79: #endif
80:
81:
82: private void
83: PPchar(c, str)
84: int c;
85: char *str;
86: {
87: char *cp = str;
88:
89: #ifdef IBMPC
90: if (specialmap || specialkey) {
91: if (c < 0 || c > 132)
92: c = 0;
93: strcpy(cp, altseq[c]);
94: } else
95: #endif
96: if (c == '\033')
97: strcpy(cp, "ESC");
98: #ifdef IBMPC /* this character is invisible */
99: else if (c == '\377') {
100: *cp = 0;
101: }
102: #endif /* IBMPC */
103: else if (c < ' ')
104: swritef(cp, "C-%c", c + '@');
105: else if (c == '\177')
106: strcpy(cp, "^?");
107: else
108: swritef(cp, "%c", c);
109: }
110:
111: private struct fmt_state {
112: int precision,
113: width,
114: leftadj;
115: char padc;
116: File *iop;
117: } current_fmt;
118:
119: private void
120: putld(d, base)
121: long d;
122: int base;
123: {
124: int len = 1;
125: long tmpd = d;
126:
127: if (current_fmt.width == 0 && current_fmt.precision) {
128: current_fmt.width = current_fmt.precision;
129: current_fmt.padc = '0';
130: }
131: while ((tmpd = (tmpd / base)) != 0)
132: len += 1;
133: if (d < 0)
134: len += 1;
135: if (!current_fmt.leftadj)
136: pad(current_fmt.padc, current_fmt.width - len);
137: if (d < 0) {
138: jputc('-', current_fmt.iop);
139: d = -d;
140: }
141: outld(d, base);
142: if (current_fmt.leftadj)
143: pad(current_fmt.padc, current_fmt.width - len);
144: }
145:
146: private void
147: outld(d, base)
148: long d;
149: int base;
150: {
151: register long n;
152: static const char chars[] = {'0', '1', '2', '3', '4', '5', '6',
153: '7', '8', '9', 'a', 'b', 'c', 'd',
154: 'e', 'f'};
155:
156: if ((n = (d / base)) != 0)
157: outld(n, base);
158: jputc((int) (chars[(int) (d % base)]), current_fmt.iop);
159: }
160:
161: private void
162: puts(str)
163: char *str;
164: {
165: int len;
166: register char *cp;
167:
168: if (str == 0)
169: #if defined(pyr)
170: str = "";
171: #else
172: str = "(null)";
173: #endif
174: len = strlen(str);
175: if (current_fmt.precision == 0 || len < current_fmt.precision)
176: current_fmt.precision = len;
177: else
178: len = current_fmt.precision;
179: cp = str;
180: if (!current_fmt.leftadj)
181: pad(' ', current_fmt.width - len);
182: while (--current_fmt.precision >= 0)
183: jputc(*cp++, current_fmt.iop);
184: if (current_fmt.leftadj)
185: pad(' ', current_fmt.width - len);
186: }
187:
188: private void
189: pad(c, amount)
190: register int c,
191: amount;
192: {
193: while (--amount >= 0)
194: jputc(c, current_fmt.iop);
195: }
196:
197: private void
198: doformat(sp, fmt, ap)
199: register File *sp;
200: register char *fmt;
201: va_list ap;
202: {
203: register char c;
204: struct fmt_state prev_fmt;
205:
206: prev_fmt = current_fmt;
207: current_fmt.iop = sp;
208:
209: while ((c = *fmt++) != '\0') {
210: if (c != '%') {
211: jputc(c, current_fmt.iop);
212: continue;
213: }
214:
215: current_fmt.padc = ' ';
216: current_fmt.precision = current_fmt.leftadj = current_fmt.width = 0;
217: c = *fmt++;
218: if (c == '-') {
219: current_fmt.leftadj = YES;
220: c = *fmt++;
221: }
222: if (c == '0') {
223: current_fmt.padc = '0';
224: c = *fmt++;
225: }
226: while (c >= '0' && c <= '9') {
227: current_fmt.width = current_fmt.width * 10 + (c - '0');
228: c = *fmt++;
229: }
230: if (c == '*') {
231: current_fmt.width = va_arg(ap, int);
232: c = *fmt++;
233: }
234: if (c == '.') {
235: c = *fmt++;
236: while (c >= '0' && c <= '9') {
237: current_fmt.precision = current_fmt.precision * 10 + (c - '0');
238: c = *fmt++;
239: }
240: if (c == '*') {
241: current_fmt.precision = va_arg(ap, int);
242: c = *fmt++;
243: }
244: }
245: reswitch:
246: /* At this point, fmt points at one past the format letter. */
247: switch (c) {
248: case '%':
249: jputc('%', current_fmt.iop);
250: break;
251:
252: case 'O':
253: case 'D':
254: case 'X':
255: putld(va_arg(ap, long), (c == 'O') ? 8 :
256: (c == 'D') ? 10 : 16);
257: break;
258:
259: case 'b':
260: {
261: Buffer *b = va_arg(ap, Buffer *);
262:
263: puts(b->b_name);
264: break;
265: }
266:
267: case 'c':
268: jputc(va_arg(ap, int), current_fmt.iop);
269: break;
270:
271: case 'o':
272: case 'd':
273: case 'x':
274: putld((long) va_arg(ap, int), (c == 'o') ? 8 :
275: (c == 'd') ? 10 : 16);
276: break;
277:
278: case 'f': /* current command name gets inserted here! */
279: puts(LastCmd->Name);
280: break;
281:
282: case 'l':
283: c = CharUpcase(*++fmt);
284: goto reswitch;
285:
286: case 'n':
287: if (va_arg(ap, int) != 1)
288: puts("s");
289: break;
290:
291: case 'p':
292: {
293: char cbuf[20];
294:
295: PPchar(va_arg(ap, int), cbuf);
296: puts(cbuf);
297: break;
298: }
299:
300: case 's':
301: puts(va_arg(ap, char *));
302: break;
303:
304: default:
305: complain("Unknown format directive: \"%%%c\"", c);
306: }
307: }
308: current_fmt = prev_fmt;
309: }
310:
311: #ifdef STDARGS
312: char *
313: sprint(char *fmt, ...)
314: #else
315: /*VARARGS1*/ char *
316: sprint(fmt, va_alist)
317: char *fmt;
318: va_dcl
319: #endif
320: {
321: va_list ap;
322: static char line[100];
323:
324: va_init(ap, fmt);
325: format(line, sizeof line, fmt, ap);
326: va_end(ap);
327: return line;
328: }
329:
330: #ifdef STDARGS
331: void
332: writef(char *fmt, ...)
333: #else
334: /*VARARGS1*/ void
335: writef(fmt, va_alist)
336: char *fmt;
337: va_dcl
338: #endif
339: {
340: va_list ap;
341:
342: va_init(ap, fmt);
343: #ifndef IBMPC
344: doformat(stdout, fmt, ap);
345: #else /* IBMPC */
346: write_em(sprint(fmt, ap));
347: /* doformat(stdout, fmt, ap); */
348: #endif /* IBMPC */
349: va_end(ap);
350: }
351:
352: #ifdef STDARGS
353: void
354: fwritef(File *fp, char *fmt, ...)
355: #else
356: /*VARARGS2*/ void
357: fwritef(fp, fmt, va_alist)
358: File *fp;
359: char *fmt;
360: va_dcl
361: #endif
362: {
363: va_list ap;
364:
365: va_init(ap, fmt);
366: doformat(fp, fmt, ap);
367: va_end(ap);
368: }
369:
370: #ifdef STDARGS
371: void
372: swritef(char *str, char *fmt, ...)
373: #else
374: /*VARARGS2*/ void
375: swritef(str, fmt, va_alist)
376: char *str,
377: *fmt;
378: va_dcl
379: #endif
380: {
381: va_list ap;
382:
383: va_init(ap, fmt);
384: format(str, (size_t)130, fmt, ap);
385: va_end(ap);
386: }
387:
388: #ifdef STDARGS
389: void
390: s_mess(char *fmt, ...)
391: #else
392: /*VARARGS1*/ void
393: s_mess(fmt, va_alist)
394: char *fmt;
395: va_dcl
396: #endif
397: {
398: va_list ap;
399:
400: if (InJoverc)
401: return;
402: va_init(ap, fmt);
403: format(mesgbuf, sizeof mesgbuf, fmt, ap);
404: va_end(ap);
405: message(mesgbuf);
406: }
407:
408: #ifdef STDARGS
409: void
410: f_mess(char *fmt, ...)
411: #else
412: /*VARARGS1*/ void
413: f_mess(fmt, va_alist)
414: char *fmt;
415: va_dcl
416: #endif
417: {
418: va_list ap;
419:
420: va_init(ap, fmt);
421: format(mesgbuf, sizeof mesgbuf, fmt, ap);
422: va_end(ap);
423: DrawMesg(NO);
424: errormsg = NO;
425: UpdMesg = YES; /* still needs updating (for convenience) */
426: }
427:
428: #ifdef STDARGS
429: void
430: add_mess(char *fmt, ...)
431: #else
432: /*VARARGS1*/ void
433: add_mess(fmt, va_alist)
434: char *fmt;
435: va_dcl
436: #endif
437: {
438: int mesg_len = strlen(mesgbuf);
439: va_list ap;
440:
441: if (InJoverc)
442: return;
443: va_init(ap, fmt);
444: format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
445: va_end(ap);
446: message(mesgbuf);
447: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.