Annotation of researchv10no/cmd/mk/export/libc/doprint.c, revision 1.1.1.1

1.1       root        1: #include <varargs.h>
                      2: 
                      3: #define        SIZE    1024
                      4: #define        FUNSIGN 4
                      5: #define        FSHORT  2
                      6: #define        FLONG   1
                      7: #define        PTR     sizeof (char *)
                      8: #define        SHORT   sizeof (int)
                      9: #define        INT     sizeof (int)
                     10: #define        LONG    sizeof (long)
                     11: #define        FLOAT   sizeof (double)
                     12: #define        FDIGIT  30
                     13: #define        FDEFLT  8
                     14: #define        IDIGIT  40
                     15: #define        MAXCONV 30
                     16: 
                     17: static char    *out, *eout;
                     18: static         convcount  = { 13 };
                     19: 
                     20: static noconv();
                     21: static cconv(), dconv(), hconv(), lconv();
                     22: static oconv(), sconv(), uconv(), xconv();
                     23: 
                     24: static econv(), fconv(), gconv(), percent();
                     25: int    printcol;
                     26: static
                     27: int    (*fmtconv[MAXCONV])() =
                     28: {
                     29:        noconv,
                     30:        cconv, dconv, hconv, lconv,
                     31:        oconv, sconv, uconv, xconv,
                     32:        econv, fconv, gconv, percent,
                     33: };
                     34: static
                     35: char   fmtindex[128] =
                     36: {
                     37:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     38:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     39:        0, 0, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     40:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     41:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     42:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     43:        0, 0, 0, 1, 2, 9,10,11, 3, 0, 0, 0, 4, 0, 0, 5,
                     44:        0, 0, 0, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
                     45: };
                     46: 
                     47: fmtinstall(c, f)
                     48: char c;
                     49: int (*f)();
                     50: {
                     51: 
                     52:        c &= 0177;
                     53:        if(fmtindex[c] == 0) {
                     54:                if(convcount >= MAXCONV)
                     55:                        return 1;
                     56:                fmtindex[c] = convcount++;
                     57:        }
                     58:        fmtconv[fmtindex[c]] = f;
                     59:        return 0;
                     60: }
                     61: 
                     62: char*
                     63: donprint(s, es, fmt, argpp)
                     64: char *s, *es;
                     65: register char *fmt;
                     66: va_list *argpp;
                     67: {
                     68:        register int f1, f2, f3, sf1, c;
                     69:        char *sout, *seout;
                     70: 
                     71:        sout = out;
                     72:        seout = eout;
                     73:        out = s;
                     74:        eout = es-1;
                     75: loop:
                     76:        c = *fmt++;
                     77:        if(c != '%') {
                     78:                if(c == 0) {
                     79:                        *out = 0;
                     80:                        s = out;
                     81:                        out = sout;
                     82:                        eout = seout;
                     83:                        return s;
                     84:                }
                     85:                if(out < eout)
                     86:                        *out++ = c;
                     87:                printcol++;
                     88:                if(c == '\n')
                     89:                        printcol = 0; else
                     90:                if(c == '\t')
                     91:                        printcol = (printcol+7) & ~7;
                     92:                goto loop;
                     93:        }
                     94:        f1 = 0;
                     95:        f2 = -1;
                     96:        f3 = 0;
                     97:        c = *fmt++;
                     98:        sf1 = 0;
                     99:        if(c == '-') {
                    100:                sf1 = 1;
                    101:                c = *fmt++;
                    102:        }
                    103:        while(c >= '0' && c <= '9') {
                    104:                f1 = f1*10 + c-'0';
                    105:                c = *fmt++;
                    106:        }
                    107:        if(sf1)
                    108:                f1 = -f1;
                    109:        if(c != '.')
                    110:                goto l1;
                    111:        c = *fmt++;
                    112:        while(c >= '0' && c <= '9') {
                    113:                if(f2 < 0)
                    114:                        f2 = 0;
                    115:                f2 = f2*10 + c-'0';
                    116:                c = *fmt++;
                    117:        }
                    118: l1:
                    119:        if(c == 0)
                    120:                fmt--;
                    121:        /* NB: first arg is now a (va_list *) */
                    122:        c = (*fmtconv[fmtindex[c&0177]])(argpp, f1, f2, f3);
                    123:        if(c < 0) {
                    124:                f3 |= -c;
                    125:                c = *fmt++;
                    126:                goto l1;
                    127:        }
                    128: #ifdef notdef
                    129:        argp += c;      /* increment is now done in called routine by va_arg() */
                    130: #endif
                    131:        goto loop;
                    132: }
                    133: 
                    134: numbconv(o, f1, f2, f3, b)
                    135: va_list *o;
                    136: {
                    137:        char s[IDIGIT];
                    138:        register long v;
                    139:        register int i, f, n, r;
                    140: 
                    141:        switch(f3 & (FLONG|FSHORT|FUNSIGN)) {
                    142:        case FLONG:
                    143:                v = va_arg(*o, long);
                    144:                r = LONG;
                    145:                break;
                    146: 
                    147:        case FUNSIGN|FLONG:
                    148:                v = va_arg(*o, unsigned long);
                    149:                r = LONG;
                    150:                break;
                    151: 
                    152:        /* NB: a (unsigned) short argument is promoted to an (unsigned) int arg. */
                    153:        case FSHORT:
                    154:                v = (short)va_arg(*o, int);
                    155:                r = SHORT;
                    156:                break;
                    157: 
                    158:        case FUNSIGN|FSHORT:
                    159:                v = (unsigned short)va_arg(*o, unsigned);
                    160:                r = SHORT;
                    161:                break;
                    162: 
                    163:        default:
                    164:                v = va_arg(*o, int);
                    165:                r = INT;
                    166:                break;
                    167: 
                    168:        case FUNSIGN:
                    169:                v = va_arg(*o, unsigned);
                    170:                r = INT;
                    171:                break;
                    172:        }
                    173:        f = 0;
                    174:        if(!(f3 & FUNSIGN) && v < 0) {
                    175:                v = -v;
                    176:                f = 1;
                    177:        }
                    178:        s[IDIGIT-1] = 0;
                    179:        for(i = IDIGIT-2; i >= 1; i--) {
                    180:                n = (unsigned long)v % b;
                    181:                n += '0';
                    182:                if(n > '9')
                    183:                        n += 'a' - ('9'+1);
                    184:                s[i] = n;
                    185:                v = (unsigned long)v / b;
                    186:                if(f2 >= 0 && i >= IDIGIT-f2)
                    187:                        continue;
                    188:                if(v <= 0)
                    189:                        break;
                    190:        }
                    191:        if(f)
                    192:                s[--i] = '-';
                    193:        strconv(s+i, f1, -1);
                    194:        return r;
                    195: }
                    196: 
                    197: char*
                    198: doprint(s, fmt, argp)
                    199: char *s, *fmt;
                    200: va_list *argp;
                    201: {
                    202: 
                    203:        return donprint(s, s+SIZE, fmt, argp);
                    204: }
                    205: 
                    206: /*
                    207:        if you change this, change chconv
                    208: */
                    209: 
                    210: strconv(o, f1, f2)
                    211: char *o;
                    212: {
                    213:        register int n, c;
                    214:        register char *s;
                    215: 
                    216:        n = 0;
                    217:        for(s = o; *s++;)
                    218:                n++;
                    219:        if(f1 >= 0)
                    220:                while(n < f1) {
                    221:                        if(out < eout)
                    222:                                *out++ = ' ';
                    223:                        printcol++;
                    224:                        n++;
                    225:                }
                    226:        for(s=o; c = *s++;)
                    227:                if(f2 != 0) {
                    228:                        if(out < eout)
                    229:                                *out++ = c;
                    230:                        printcol++;
                    231:                        if(c == '\n')
                    232:                                printcol = 0; else
                    233:                        if(c == '\t')
                    234:                                printcol = (printcol+7) & ~7;
                    235:                        f2--;
                    236:                }
                    237:        if(f1 < 0) {
                    238:                f1 = -f1;
                    239:                while(n < f1) {
                    240:                        if(out < eout)
                    241:                                *out++ = ' ';
                    242:                        printcol++;
                    243:                        n++;
                    244:                }
                    245:        }
                    246: }
                    247: 
                    248: chconv(o, f1)
                    249: char o;
                    250: {
                    251:        register int n;
                    252: 
                    253:        n = 1;
                    254:        if(f1 >= 0)
                    255:                while(n < f1) {
                    256:                        if(out < eout)
                    257:                                *out++ = ' ';
                    258:                        printcol++;
                    259:                        n++;
                    260:                }
                    261:        if(out < eout)
                    262:                *out++ = o;
                    263:        printcol++;
                    264:        if(o == '\n')
                    265:                printcol = 0; else
                    266:        if(o == '\t')
                    267:                printcol = (printcol+7) & ~7;
                    268:        if(f1 < 0) {
                    269:                f1 = -f1;
                    270:                while(n < f1) {
                    271:                        if(out < eout)
                    272:                                *out++ = ' ';
                    273:                        printcol++;
                    274:                        n++;
                    275:                }
                    276:        }
                    277: }
                    278: 
                    279: /* ARGSUSED */
                    280: static
                    281: noconv(o, f1, f2, f3)
                    282: char *o;
                    283: {
                    284: 
                    285:        strconv("***", 0, -1);
                    286:        return 0;
                    287: }
                    288: 
                    289: /* ARGSUSED */
                    290: static
                    291: cconv(o, f1, f2, f3)
                    292: va_list *o;
                    293: {
                    294:        chconv((char)va_arg(*o, int), f1);
                    295:        return INT;
                    296: }
                    297: 
                    298: static
                    299: dconv(o, f1, f2, f3)
                    300: va_list *o;
                    301: {
                    302:        int r;
                    303: 
                    304:        r = numbconv(o, f1, f2, f3, 10);
                    305:        return r;
                    306: }
                    307: 
                    308: /* ARGSUSED */
                    309: static
                    310: hconv(o, f1, f2, f3)
                    311: {
                    312:        return -FSHORT;
                    313: }
                    314: 
                    315: /* ARGSUSED */
                    316: static
                    317: lconv(o, f1, f2, f3)
                    318: {
                    319: 
                    320:        return -FLONG;
                    321: }
                    322: 
                    323: static
                    324: oconv(o, f1, f2, f3)
                    325: va_list *o;
                    326: {
                    327:        int r;
                    328: 
                    329:        r = numbconv(o, f1, f2, f3, 8);
                    330:        return r;
                    331: }
                    332: 
                    333: /* ARGSUSED */
                    334: static
                    335: sconv(o, f1, f2, f3)
                    336: va_list *o;
                    337: {
                    338: 
                    339:        strconv(va_arg(*o, char *), f1, f2);
                    340:        return PTR;
                    341: }
                    342: 
                    343: /* ARGSUSED */
                    344: static
                    345: uconv(o, f1, f2, f3)
                    346: {
                    347:        return -FUNSIGN;
                    348: }
                    349: 
                    350: static
                    351: xconv(o, f1, f2, f3)
                    352: va_list *o;
                    353: {
                    354:        int r;
                    355: 
                    356:        r = numbconv(o, f1, f2, f3, 16);
                    357:        return r;
                    358: }
                    359: 
                    360: double pow10(), frexp();
                    361: /* ARGSUSED */
                    362: fltconv(f, f1, f2, f3, c)
                    363: register double f;
                    364: {
                    365:        char s1[FDIGIT+10], s2[FDIGIT+10];
                    366:        register double g;
                    367:        register int d, i, n, s;
                    368:        double h;
                    369:        int e;
                    370:        int c1, c2, c3;
                    371: 
                    372:        s = 0;
                    373:        if(f < 0) {
                    374:                f = -f;
                    375:                s++;
                    376:        }
                    377: 
                    378: loop:
                    379:        e = 0;
                    380:        g = 0;
                    381:        if(f != 0) {
                    382:                g = frexp(f, &e);
                    383:                e = e * .30103;
                    384:                d = e/2;
                    385:                h = f * pow10(-d);              /* 10**-e in 2 parts */
                    386:                g = h * pow10(d-e);
                    387:                while(g < 1) {
                    388:                        e--;
                    389:                        g = h * pow10(d-e);
                    390:                }
                    391:                while(g >= 10) {
                    392:                        e++;
                    393:                        g = h * pow10(d-e);
                    394:                }
                    395:        }
                    396:        if(f2 < 0)
                    397:                f2 = FDEFLT;
                    398:        if(c == 'g' && f2 > 0)
                    399:                f2--;
                    400:        if(f2 > FDIGIT)
                    401:                f2 = FDIGIT;
                    402:        /*
                    403:         * n is number of digits to convert
                    404:         * 1 before, f2 after, 1 extra for rounding
                    405:         */
                    406:        n = f2 + 2;
                    407:        if(c == 'f') {
                    408:                /*
                    409:                 * e+1 before, f2 after, 1 extra
                    410:                 */
                    411:                n += e;
                    412:                if(n <= 0) {
                    413:                        n = 1;
                    414:                        g = 0;
                    415:                }
                    416:        }
                    417:        if(n >= FDIGIT+2) {
                    418:                if(c == 'e')
                    419:                        f2 = -1;
                    420:                c = 'e';
                    421:                goto loop;
                    422:        }
                    423:        /*
                    424:         * convert n digits
                    425:         */
                    426:        for(i=0; i<n; i++) {
                    427:                d = g;
                    428:                if(d > g)
                    429:                        d--;
                    430:                g -= d;
                    431:                s1[i+1] = d + '0';
                    432:                g *= 10;
                    433:        }
                    434:        /*
                    435:         * round by adding .5 into extra digit
                    436:         */
                    437:        d = 5;
                    438:        for(i=n-1; i>=0; i--) {
                    439:                s1[i+1] += d;
                    440:                d = 0;
                    441:                if(s1[i+1] > '9') {
                    442:                        s1[i+1] -= 10;
                    443:                        d++;
                    444:                }
                    445:        }
                    446:        i = 1;
                    447:        if(d) {
                    448:                s1[0] = '1';
                    449:                e++;
                    450:                i = 0;
                    451:        } 
                    452:        /*
                    453:         * copy into final place
                    454:         * c1 digits of leading '0'
                    455:         * c2 digits from conversion
                    456:         * c3 digits after '.'
                    457:         */
                    458:        d = 0;
                    459:        if(s)
                    460:                s2[d++] = '-';
                    461:        c1 = 0;
                    462:        c2 = f2 + 1;
                    463:        c3 = f2;
                    464:        if(c == 'g')
                    465:        if(e >= -5 && e <= f2) {
                    466:                c1 = -e - 1;
                    467:                c3 = c1;
                    468:                if(c1 < 0)
                    469:                        c1 = 0;
                    470:                c3 = f2 - e;
                    471:                c = 'h';
                    472:        }
                    473:        if(c == 'f') {
                    474:                c1 = -e;
                    475:                if(c1 < 0)
                    476:                        c1 = 0;
                    477:                if(c1 > f2)
                    478:                        c1 = c2;
                    479:                c2 += e;
                    480:                if(c2 < 0)
                    481:                        c2 = 0;
                    482:        }
                    483:        while(c1 > 0) {
                    484:                if(c1+c2 == c3)
                    485:                        s2[d++] = '.';
                    486:                s2[d++] = '0';
                    487:                c1--;
                    488:        }
                    489:        while(c2 > 0) {
                    490:                if(c1+c2 == c3)
                    491:                        s2[d++] = '.';
                    492:                s2[d++] = s1[i++];
                    493:                c2--;
                    494:        }
                    495:        /*
                    496:         * strip trailing '0' on g conv
                    497:         */
                    498:        if(c == 'g' || c == 'h') {
                    499:                for(n=d-1; n>=0; n--)
                    500:                        if(s2[n] != '0')
                    501:                                break;
                    502:                for(i=n; i>=0; i--)
                    503:                        if(s2[i] == '.') {
                    504:                                d = n;
                    505:                                if(i != n)
                    506:                                        d++;
                    507:                                break;
                    508:                        }
                    509:        }
                    510:        if(c == 'e' || c == 'g') {
                    511:                s2[d++] = 'e';
                    512:                s2[d++] = '+';
                    513:                c1 = e;
                    514:                if(c1 < 0) {
                    515:                        s2[d-1] = '-';
                    516:                        c1 = -c1;
                    517:                }
                    518:                if(c1 >= 100) {
                    519:                        s2[d++] = c1/100 + '0';
                    520:                        c1 %= 100;
                    521:                }
                    522:                s2[d++] = c1/10 + '0';
                    523:                s2[d++] = c1%10 + '0';
                    524:        }
                    525:        s2[d] = 0;
                    526:        strconv(s2, f1, -1);
                    527:        return FLOAT;
                    528: }
                    529: 
                    530: static
                    531: econv(o, f1, f2, f3)
                    532: va_list *o;
                    533: {
                    534: 
                    535:        return fltconv(va_arg(*o, double), f1, f2, f3, 'e');
                    536: }
                    537: 
                    538: static
                    539: fconv(o, f1, f2, f3)
                    540: va_list *o;
                    541: {
                    542: 
                    543:        return fltconv(va_arg(*o, double), f1, f2, f3, 'f');
                    544: }
                    545: 
                    546: static
                    547: gconv(o, f1, f2, f3)
                    548: va_list *o;
                    549: {
                    550: 
                    551:        return fltconv(va_arg(*o, double), f1, f2, f3, 'g');
                    552: }
                    553: 
                    554: static
                    555: percent()
                    556: {
                    557: 
                    558:        if(out < eout)
                    559:                *out++ = '%';
                    560:        return 0;
                    561: }

unix.superglobalmegacorp.com

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