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