1: /************************************************************************* 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * 3: * provided to you without charge for use only on a licensed Unix * 4: * system. You may copy JOVE provided that this notice is included with * 5: * the copy. You may not sell copies of this program or versions * 6: * modified for use on microcomputer systems, unless the copies are * 7: * included with a Unix system distribution and the source is provided. * 8: *************************************************************************/ 9: 10: #include "jove.h" 11: #include "io.h" 12: #include "termcap.h" 13: 14: #include <varargs.h> 15: 16: char mesgbuf[MESG_SIZE]; 17: 18: /* VARARGS2 */ 19: 20: format(buf, len, fmt, ap) 21: char *buf, 22: *fmt; 23: va_list ap; 24: { 25: File strbuf, 26: *sp = &strbuf; 27: 28: sp->f_ptr = sp->f_base = buf; 29: sp->f_fd = -1; /* Not legit for files */ 30: sp->f_cnt = len; 31: sp->f_flags = F_STRING; 32: sp->f_bufsize = len; 33: 34: doformat(sp, fmt, ap); 35: putc('\0', sp); 36: } 37: 38: static char padc = ' '; 39: static File *curiop = 0; 40: 41: static 42: PPchar(c, str) 43: int c; 44: char *str; 45: { 46: char *cp = str; 47: 48: if (c == '\033') 49: strcpy(cp, "ESC"); 50: else if (c < ' ') 51: sprintf(cp, "C-%c", c + '@'); 52: else if (c == '\177') 53: strcpy(cp, "^?"); 54: else 55: sprintf(cp, "%c", c); 56: } 57: 58: static 59: putld(leftadj, width, d, base) 60: long d; 61: { 62: int length = 1; 63: long tmpd = d; 64: 65: while (tmpd = (tmpd / base)) 66: length++; 67: if (d < 0) 68: length++; 69: if (!leftadj) 70: pad(padc, width - length); 71: if (d < 0) { 72: putc('-', curiop); 73: d = -d; 74: } 75: outld(d, base); 76: if (leftadj) 77: pad(padc, width - length); 78: } 79: 80: static 81: outld(d, base) 82: long d; 83: { 84: long n; 85: 86: if (n = (d / base)) 87: outld(n, base); 88: putc((int) ('0' + (int) (d % base)), curiop); 89: } 90: 91: static 92: puts(leftadj, width, str) 93: char *str; 94: { 95: int length; 96: register char *cp, 97: c; 98: 99: if (str == 0) 100: #if pyr 101: str = ""; 102: #else 103: str = "(null)"; 104: #endif 105: length = strlen(str); 106: cp = str; 107: if (!leftadj) 108: pad(' ', width - length); 109: while (c = *cp++) 110: putc(c, curiop); 111: if (leftadj) 112: pad(' ', width - length); 113: } 114: 115: static 116: pad(c, amount) 117: register int c, 118: amount; 119: { 120: while (--amount >= 0) 121: putc(c, curiop); 122: } 123: 124: static 125: doformat(sp, fmt, ap) 126: register File *sp; 127: register char *fmt; 128: va_list ap; 129: { 130: register char c; 131: int leftadj, 132: width; 133: File *pushiop = curiop; 134: 135: curiop = sp; 136: 137: while (c = *fmt++) { 138: if (c != '%') { 139: putc(c, sp); 140: continue; 141: } 142: 143: padc = ' '; 144: leftadj = width = 0; 145: c = *fmt++; 146: if (c == '-') { 147: leftadj++; 148: c = *fmt++; 149: } 150: if (c == '0') { 151: padc = '0'; 152: c = *fmt++; 153: } 154: while (c >= '0' && c <= '9') { 155: width = width * 10 + (c - '0'); 156: c = *fmt++; 157: } 158: if (c == '*') { 159: width = va_arg(ap, int); 160: c = *fmt++; 161: } 162: reswitch: 163: /* At this point, fmt points at one past the format letter. */ 164: switch (c) { 165: case 'l': 166: c = Upper(*++fmt); 167: goto reswitch; 168: 169: case '%': 170: putc('%', curiop); 171: break; 172: 173: case 'o': 174: putld(leftadj, width, (long) va_arg(ap, int), 8); 175: break; 176: 177: case 'd': 178: putld(leftadj, width, (long) va_arg(ap, int), 10); 179: break; 180: 181: case 'D': 182: putld(leftadj, width, va_arg(ap, long), 10); 183: break; 184: 185: case 'p': 186: { 187: char cbuf[20]; 188: 189: PPchar(va_arg(ap, int), cbuf); 190: puts(leftadj, width, cbuf); 191: break; 192: } 193: 194: case 'n': 195: if (va_arg(ap, int) != 1) 196: puts(leftadj, width, "s"); 197: break; 198: 199: case 's': 200: puts(leftadj, width, va_arg(ap, char *)); 201: break; 202: 203: case 'c': 204: putc(va_arg(ap, int), curiop); 205: break; 206: 207: case 'f': /* current command name gets inserted here! */ 208: puts(leftadj, width, LastCmd->Name); 209: break; 210: 211: default: 212: complain("%%%c?", c); 213: } 214: } 215: curiop = pushiop; 216: } 217: 218: /* VARARGS1 */ 219: 220: char * 221: sprint(fmt, va_alist) 222: char *fmt; 223: va_dcl 224: { 225: va_list ap; 226: static char line[100]; 227: 228: va_start(ap); 229: format(line, sizeof line, fmt, ap); 230: va_end(ap); 231: return line; 232: } 233: 234: /* VARARGS1 */ 235: 236: printf(fmt, va_alist) 237: char *fmt; 238: va_dcl 239: { 240: va_list ap; 241: 242: va_start(ap); 243: doformat(stdout, fmt, ap); 244: va_end(ap); 245: } 246: 247: /* VARARGS1 */ 248: 249: fprintf(fp, fmt, va_alist) 250: File *fp; 251: char *fmt; 252: va_dcl 253: { 254: va_list ap; 255: 256: va_start(ap); 257: doformat(fp, fmt, ap); 258: va_end(ap); 259: } 260: 261: /* VARARGS2 */ 262: 263: sprintf(str, fmt, va_alist) 264: char *str, 265: *fmt; 266: va_dcl 267: { 268: va_list ap; 269: 270: va_start(ap); 271: format(str, 130, fmt, ap); 272: va_end(ap); 273: } 274: 275: /* VARARGS1 */ 276: 277: s_mess(fmt, va_alist) 278: char *fmt; 279: va_dcl 280: { 281: va_list ap; 282: 283: if (InJoverc) 284: return; 285: va_start(ap); 286: format(mesgbuf, sizeof mesgbuf, fmt, ap); 287: va_end(ap); 288: message(mesgbuf); 289: } 290: 291: /* VARARGS1 */ 292: 293: f_mess(fmt, va_alist) 294: char *fmt; 295: va_dcl 296: { 297: va_list ap; 298: 299: va_start(ap); 300: format(mesgbuf, sizeof mesgbuf, fmt, ap); 301: va_end(ap); 302: DrawMesg(NO); 303: UpdMesg++; /* Still needs updating (for convenience) */ 304: } 305: 306: /* VARARGS1 */ 307: 308: add_mess(fmt, va_alist) 309: char *fmt; 310: va_dcl 311: { 312: int mesg_len = strlen(mesgbuf); 313: va_list ap; 314: 315: if (InJoverc) 316: return; 317: va_start(ap); 318: format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap); 319: va_end(ap); 320: message(mesgbuf); 321: }