|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.