Annotation of researchv9/libc/gen/doprint.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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