Annotation of coherent/d/lib/libc/stdio/printf.c, revision 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.