Annotation of 43BSDReno/contrib/jove/fmt.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.