Annotation of coherent/d/lib/libc/stdio/printf.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Standard I/O library printf/fprint/sprintf.
                      3:  * Non-portable things:
                      4:  * 1) alignment of arguments is assumed to be completely contiguous.
                      5:  * 2) the smallest number is assumed to negate to itself.
                      6:  * 3) All of long, int, char*, and double are assumed to
                      7:  *    be held in an exact number of ints.
                      8:  */
                      9: 
                     10: #include <stdio.h>
                     11: #include <sys/mdata.h>
                     12: #include <ctype.h>
                     13: 
                     14: /* Avoid calling the new style toupper() function on MSDOS and GEMDOS */
                     15: #ifdef _toupper
                     16: #define toupper(c) _toupper(c)
                     17: #endif
                     18: 
                     19: union  alltypes {
                     20:        char    c;
                     21:        int     i;
                     22:        unsigned u;
                     23:        long    l;
                     24:        double  d;
                     25:        char    *s;
                     26: };
                     27: 
                     28: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
                     29: 
                     30: char   *printi();
                     31: char   *printl();
                     32: char   *_dtefg();
                     33: 
                     34: static readonly char null[] = "{NULL}";
                     35: 
                     36: /*
                     37:  * Formatted print to standard output.
                     38:  */
                     39: printf(args)
                     40: union alltypes args;
                     41: {
                     42:        xprintf(stdout, &args);
                     43: }
                     44: 
                     45: /*
                     46:  * Formatted print to a specific file.
                     47:  */
                     48: fprintf(fp, args)
                     49: FILE *fp;
                     50: union alltypes args;
                     51: {
                     52:        xprintf(fp, &args);
                     53: }
                     54: 
                     55: /*
                     56:  * Formatted print into given string.
                     57:  * Handcrafted file structure created for putc.
                     58:  */
                     59: sprintf(sp, args)
                     60: char *sp;
                     61: union alltypes args;
                     62: {
                     63:        FILE    file;
                     64: 
                     65:        _stropen(sp, -MAXINT-1, &file);
                     66:        xprintf(&file, &args);
                     67:        putc('\0', &file);
                     68: }
                     69: 
                     70: static
                     71: xprintf(fp, argp)
                     72: FILE *fp;
                     73: union alltypes *argp;
                     74: {
                     75:        register char *cbp;
                     76:        int *iap;
                     77:        register c;
                     78:        char *s;
                     79:        char *cbs;
                     80:        int adj, pad;
                     81:        int prec;
                     82:        int fwidth;
                     83:        int pwidth;
                     84:        int isnumeric;
                     85:        register char *fmt;
                     86:        union alltypes elem;
                     87:        char cbuf[64];
                     88: 
                     89:        iap = (int *)argp;
                     90:        fmt = *(char **)iap;
                     91:        bump(iap, char*);
                     92:        for (;;) {
                     93:                while((c = *fmt++) != '%') {
                     94:                        if(c == '\0') {
                     95:                                return;
                     96:                        }
                     97:                        putc(c, fp);
                     98:                }
                     99:                pad = ' ';
                    100:                fwidth = -1;
                    101:                prec = -1;
                    102:                c = *fmt++;
                    103:                if (c == '-') {
                    104:                        adj = 1;
                    105:                        c = *fmt++;
                    106:                } else
                    107:                        adj = 0;
                    108:                if (c == '0') {
                    109:                        pad = '0';
                    110:                        c = *fmt++;
                    111:                }
                    112:                if (c == '*') {
                    113:                        if ((fwidth = *iap++) < 0) {
                    114:                                adj = 1;
                    115:                                fwidth = -fwidth;
                    116:                        }
                    117:                        c = *fmt++;
                    118:                } else
                    119:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
                    120:                                fwidth = fwidth*10 + c-'0';
                    121:                if (c == '.') {
                    122:                        c = *fmt++;
                    123:                        if (c == '*') {
                    124:                                prec = *iap++;
                    125:                                c = *fmt++;
                    126:                        } else
                    127:                                for (prec=0; c>='0' && c<='9'; c=*fmt++)
                    128:                                        prec = prec*10 + c-'0';
                    129:                }
                    130:                if (c == 'l') {
                    131:                        c = *fmt++;
                    132:                        if (c=='d' || c=='o' || c=='u' || c=='x')
                    133:                                c = toupper(c);
                    134:                }
                    135:                cbp = cbs = cbuf;
                    136:                isnumeric = 1;
                    137:                switch (c) {
                    138: 
                    139:                case 'd':
                    140:                        elem.i = *iap++;
                    141:                        if (elem.i < 0) {
                    142:                                elem.i = -elem.i;
                    143:                                *cbp++ = '-';
                    144:                        }
                    145:                        cbp = printi(cbp, elem.i, 10);
                    146:                        break;
                    147: 
                    148:                case 'u':
                    149:                        cbp = printi(cbp, *iap++, 10);
                    150:                        break;
                    151:        
                    152:                case 'o':
                    153:                        cbp = printi(cbp, *iap++, 8);
                    154:                        break;
                    155: 
                    156:                case 'x':
                    157:                        cbp = printi(cbp, *iap++, 16);
                    158:                        break;
                    159: 
                    160:                case 'D':
                    161:                        elem.l = *(long *)iap;
                    162:                        bump(iap, long);
                    163:                        if (elem.l < 0) {
                    164:                                elem.l = -elem.l;
                    165:                                *cbp++ = '-';
                    166:                        }
                    167:                        cbp = printl(cbp, elem.l, 10);
                    168:                        break;
                    169: 
                    170:                case 'U':
                    171:                        cbp = printl(cbp, *(long *)iap, 10);
                    172:                        bump(iap, long);
                    173:                        break;
                    174: 
                    175:                case 'O':
                    176:                        cbp = printl(cbp, *(long *)iap, 8);
                    177:                        bump(iap, long);
                    178:                        break;
                    179: 
                    180:                case 'X':
                    181:                        cbp = printl(cbp, *(long *)iap, 16);
                    182:                        bump(iap, long);
                    183:                        break;
                    184: 
                    185:                case 'e':
                    186:                case 'f':
                    187:                case 'g':
                    188:                        cbp = _dtefg(c, iap, prec, cbp);
                    189:                        bump(iap, double);
                    190:                        break;
                    191: 
                    192:                case 's':
                    193:                        isnumeric = 0;
                    194:                        if ((s = *(char **)iap) == NULL)
                    195:                                s = null;
                    196:                        bump(iap, char*);
                    197:                        cbp = cbs = s;
                    198:                        while (*cbp++ != '\0')
                    199:                                if (prec>=0 && cbp-s>prec)
                    200:                                        break;
                    201:                        cbp--;
                    202:                        break;
                    203:        
                    204:                case 'c':
                    205:                        isnumeric = 0;
                    206:                        *cbp++ = *iap++;
                    207:                        break;
                    208:        
                    209:                case 'r':
                    210:                        xprintf(fp, *(char ***)iap);
                    211:                        bump(iap, char**);
                    212:                        break;
                    213:        
                    214:                default:
                    215:                        putc(c, fp);
                    216:                        continue;
                    217:                }
                    218:                if ((pwidth = fwidth + cbs-cbp) < 0)
                    219:                        pwidth = 0;
                    220:                if (!adj) {
                    221:                        if (isnumeric && pad == '0' && *cbs == '-')
                    222:                                putc(*cbs++, fp);
                    223:                        while (pwidth-- != 0)
                    224:                                putc(pad, fp);
                    225:                }
                    226:                while (cbs < cbp)
                    227:                        putc(*cbs++, fp);
                    228:                if (adj)
                    229:                        while (pwidth-- != 0)
                    230:                                putc(pad, fp);
                    231:        }
                    232: }
                    233: 
                    234: static readonly char digits[] = {
                    235:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    236:        'A', 'B', 'C', 'D', 'E', 'F'
                    237: };
                    238: 
                    239: /*
                    240:  * Print an unsigned integer in base b.
                    241:  */
                    242: static
                    243: char *
                    244: printi(cp, n, b)
                    245: char *cp;
                    246: register unsigned n;
                    247: {
                    248:        register a;
                    249:        register char *ep;
                    250:        char pbuf[10];
                    251: 
                    252:        ep = &pbuf[10];
                    253:        *--ep = 0;
                    254:        for ( ; a = n/b; n=a)
                    255:                *--ep = digits[n%b];
                    256:        *--ep = digits[n];
                    257:        while (*ep)
                    258:                *cp++ = *ep++;
                    259:        return (cp);
                    260: }
                    261: 
                    262: /*
                    263:  * Print an unsigned long in base b.
                    264:  */
                    265: static
                    266: char *
                    267: printl(cp, n, b)
                    268: register char *cp;
                    269: unsigned long n;
                    270: register b;
                    271: {
                    272:        char pbuf[13];
                    273:        unsigned long a;
                    274:        register char *ep;
                    275: 
                    276:        ep = &pbuf[13];
                    277:        *--ep = '\0';
                    278:        for ( ; (a = n/b) != 0; n = a)
                    279:                *--ep = digits[n%b];
                    280:        *--ep = digits[n];
                    281:        while (*ep)
                    282:                *cp++ = *ep++;
                    283:        return (cp);
                    284: }

unix.superglobalmegacorp.com

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