Annotation of lucent/sys/src/boot/pc/donprint.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "lib.h"
                      3: 
                      4: #define        PTR     sizeof(char*)
                      5: #define        SHORT   sizeof(int)
                      6: #define        INT     sizeof(int)
                      7: #define        LONG    sizeof(long)
                      8: #define        IDIGIT  30
                      9: #define        MAXCON  30
                     10: 
                     11: static int     convcount  = { 10 };
                     12: 
                     13: #define        FLONG   (1<<0)
                     14: #define        FSHORT  (1<<1)
                     15: #define        FUNSIGN (1<<2)
                     16: 
                     17: typedef struct Op      Op;
                     18: struct Op
                     19: {
                     20:        char    *p;
                     21:        char    *ep;
                     22:        void    *argp;
                     23:        int     f1;
                     24:        int     f2;
                     25:        int     f3;
                     26: };
                     27: 
                     28: static int     noconv(Op*);
                     29: static int     cconv(Op*);
                     30: static int     dconv(Op*);
                     31: static int     hconv(Op*);
                     32: static int     lconv(Op*);
                     33: static int     oconv(Op*);
                     34: static int     sconv(Op*);
                     35: static int     uconv(Op*);
                     36: static int     xconv(Op*);
                     37: static int     percent(Op*);
                     38: 
                     39: static
                     40: int    (*fmtconv[MAXCON])(Op*) =
                     41: {
                     42:        noconv,
                     43:        cconv, dconv, hconv, lconv,
                     44:        oconv, sconv, uconv, xconv,
                     45:        percent,
                     46: };
                     47: static
                     48: char   fmtindex[128] =
                     49: {
                     50:        ['c'] 1,
                     51:        ['d'] 2,
                     52:        ['h'] 3,
                     53:        ['l'] 4,
                     54:        ['o'] 5,
                     55:        ['s'] 6,
                     56:        ['u'] 7,
                     57:        ['x'] 8,
                     58:        ['%'] 9,
                     59: };
                     60: 
                     61: static void
                     62: PUT(Op *o, int c)
                     63: {
                     64:        static int pos;
                     65:        int opos;
                     66: 
                     67:        if(c == '\t'){
                     68:                opos = pos;
                     69:                pos = (opos+8) & ~7;
                     70:                while(opos++ < pos && o->p < o->ep)
                     71:                        *o->p++ = ' ';
                     72:                return;
                     73:        }
                     74:        if(o->p < o->ep){
                     75:                *o->p++ = c;
                     76:                pos++;
                     77:        }
                     78:        if(c == '\n')
                     79:                pos = 0;
                     80: }
                     81: 
                     82: int
                     83: fmtinstall(char c, int (*f)(Op*))
                     84: {
                     85: 
                     86:        c &= 0177;
                     87:        if(fmtindex[c] == 0) {
                     88:                if(convcount >= MAXCON)
                     89:                        return 1;
                     90:                fmtindex[c] = convcount++;
                     91:        }
                     92:        fmtconv[fmtindex[c]] = f;
                     93:        return 0;
                     94: }
                     95: 
                     96: char*
                     97: donprint(char *p, char *ep, char *fmt, void *argp)
                     98: {
                     99:        int sf1, c;
                    100:        Op o;
                    101: 
                    102:        o.p = p;
                    103:        o.ep = ep;
                    104:        o.argp = argp;
                    105: 
                    106: loop:
                    107:        c = *fmt++;
                    108:        if(c != '%') {
                    109:                if(c == 0) {
                    110:                        if(o.p < o.ep)
                    111:                                *o.p = 0;
                    112:                        return o.p;
                    113:                }
                    114:                PUT(&o, c);
                    115:                goto loop;
                    116:        }
                    117:        o.f1 = 0;
                    118:        o.f2 = -1;
                    119:        o.f3 = 0;
                    120:        c = *fmt++;
                    121:        sf1 = 0;
                    122:        if(c == '-') {
                    123:                sf1 = 1;
                    124:                c = *fmt++;
                    125:        }
                    126:        while(c >= '0' && c <= '9') {
                    127:                o.f1 = o.f1*10 + c-'0';
                    128:                c = *fmt++;
                    129:        }
                    130:        if(sf1)
                    131:                o.f1 = -o.f1;
                    132:        if(c != '.')
                    133:                goto l1;
                    134:        c = *fmt++;
                    135:        while(c >= '0' && c <= '9') {
                    136:                if(o.f2 < 0)
                    137:                        o.f2 = 0;
                    138:                o.f2 = o.f2*10 + c-'0';
                    139:                c = *fmt++;
                    140:        }
                    141: l1:
                    142:        if(c == 0)
                    143:                fmt--;
                    144:        c = (*fmtconv[fmtindex[c&0177]])(&o);
                    145:        if(c < 0) {
                    146:                o.f3 |= -c;
                    147:                c = *fmt++;
                    148:                goto l1;
                    149:        }
                    150:        o.argp = (char*)o.argp + c;
                    151:        goto loop;
                    152: }
                    153: 
                    154: void
                    155: strconv(char *o, Op *op, int f1, int f2)
                    156: {
                    157:        int n, c;
                    158:        char *p;
                    159: 
                    160:        n = strlen(o);
                    161:        if(f1 >= 0)
                    162:                while(n < f1) {
                    163:                        PUT(op, ' ');
                    164:                        n++;
                    165:                }
                    166:        for(p=o; c = *p++;)
                    167:                if(f2 != 0) {
                    168:                        PUT(op, c);
                    169:                        f2--;
                    170:                }
                    171:        if(f1 < 0) {
                    172:                f1 = -f1;
                    173:                while(n < f1) {
                    174:                        PUT(op, ' ');
                    175:                        n++;
                    176:                }
                    177:        }
                    178: }
                    179: 
                    180: int
                    181: numbconv(Op *op, int base)
                    182: {
                    183:        char b[IDIGIT];
                    184:        int i, f, n, r;
                    185:        long v;
                    186:        short h;
                    187: 
                    188:        f = 0;
                    189:        switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
                    190:        case FLONG:
                    191:                v = *(long*)op->argp;
                    192:                r = LONG;
                    193:                break;
                    194: 
                    195:        case FUNSIGN|FLONG:
                    196:                v = *(ulong*)op->argp;
                    197:                r = LONG;
                    198:                break;
                    199: 
                    200:        case FSHORT:
                    201:                h = *(int*)op->argp;
                    202:                v = h;
                    203:                r = SHORT;
                    204:                break;
                    205: 
                    206:        case FUNSIGN|FSHORT:
                    207:                h = *(int*)op->argp;
                    208:                v = (ushort)h;
                    209:                r = SHORT;
                    210:                break;
                    211: 
                    212:        default:
                    213:                v = *(int*)op->argp;
                    214:                r = INT;
                    215:                break;
                    216: 
                    217:        case FUNSIGN:
                    218:                v = *(unsigned*)op->argp;
                    219:                r = INT;
                    220:                break;
                    221:        }
                    222:        if(!(op->f3 & FUNSIGN) && v < 0) {
                    223:                v = -v;
                    224:                f = 1;
                    225:        }
                    226:        b[IDIGIT-1] = 0;
                    227:        for(i = IDIGIT-2;; i--) {
                    228:                n = (ulong)v % base;
                    229:                n += '0';
                    230:                if(n > '9')
                    231:                        n += 'a' - ('9'+1);
                    232:                b[i] = n;
                    233:                if(i < 2)
                    234:                        break;
                    235:                v = (ulong)v / base;
                    236:                if(op->f2 >= 0 && i >= IDIGIT-op->f2)
                    237:                        continue;
                    238:                if(v <= 0)
                    239:                        break;
                    240:        }
                    241: sout:
                    242:        if(f)
                    243:                b[--i] = '-';
                    244:        strconv(b+i, op, op->f1, -1);
                    245:        return r;
                    246: }
                    247: 
                    248: static int
                    249: noconv(Op *op)
                    250: {
                    251: 
                    252:        strconv("***", op, 0, -1);
                    253:        return 0;
                    254: }
                    255: 
                    256: static int
                    257: cconv(Op *op)
                    258: {
                    259:        char b[2];
                    260: 
                    261:        b[0] = *(int*)op->argp;
                    262:        b[1] = 0;
                    263:        strconv(b, op, op->f1, -1);
                    264:        return INT;
                    265: }
                    266: 
                    267: static int
                    268: dconv(Op *op)
                    269: {
                    270:        return numbconv(op, 10);
                    271: }
                    272: 
                    273: static int
                    274: hconv(Op*)
                    275: {
                    276:        return -FSHORT;
                    277: }
                    278: 
                    279: static int
                    280: lconv(Op*)
                    281: {
                    282:        return -FLONG;
                    283: }
                    284: 
                    285: static int
                    286: oconv(Op *op)
                    287: {
                    288:        return numbconv(op, 8);
                    289: }
                    290: 
                    291: static int
                    292: sconv(Op *op)
                    293: {
                    294:        strconv(*(char**)op->argp, op, op->f1, op->f2);
                    295:        return PTR;
                    296: }
                    297: 
                    298: static int
                    299: uconv(Op*)
                    300: {
                    301:        return -FUNSIGN;
                    302: }
                    303: 
                    304: static int
                    305: xconv(Op *op)
                    306: {
                    307:        return numbconv(op, 16);
                    308: }
                    309: 
                    310: static int
                    311: percent(Op *op)
                    312: {
                    313: 
                    314:        PUT(op, '%');
                    315:        return 0;
                    316: }

unix.superglobalmegacorp.com

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