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

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

unix.superglobalmegacorp.com

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