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