|
|
1.1 ! root 1: /* ! 2: * Standard output printf using putchar. ! 3: * Non-portable things: ! 4: * 1) alignment of arguments is assumed to be completely contiguous. ! 5: * 2) the smallest number is assumed to negate to itself. ! 6: * 3) All of long, int, char*, and double are assumed to ! 7: * be held in an exact number of ints. ! 8: */ ! 9: #include "fsck.h" ! 10: #include <sys/mdata.h> ! 11: ! 12: union alltypes { ! 13: char c; ! 14: int i; ! 15: unsigned u; ! 16: long l; ! 17: double d; ! 18: char *s; ! 19: }; ! 20: ! 21: #define bump(p,s) (p+=sizeof(s)/sizeof(int)) ! 22: ! 23: char *printi(); ! 24: char *printl(); ! 25: ! 26: static char null[] = "{NULL}"; ! 27: ! 28: printf(args) ! 29: union alltypes args; ! 30: { ! 31: xprintf(&args); ! 32: } ! 33: xprintf(argp) ! 34: union alltypes *argp; ! 35: { ! 36: register char *cbp; ! 37: int *iap; ! 38: register c; ! 39: char *s; ! 40: char *cbs; ! 41: char adj, pad; ! 42: int prec; ! 43: int fwidth; ! 44: int pwidth; ! 45: register char *fmt; ! 46: union alltypes elem; ! 47: char cbuf[64]; ! 48: ! 49: iap = (int *)argp; ! 50: fmt = *(char **)iap; ! 51: bump(iap, char*); ! 52: for (;;) { ! 53: while((c = *fmt++) != '%') { ! 54: if(c == '\0') { ! 55: return; ! 56: } ! 57: putchar(c); ! 58: } ! 59: pad = ' '; ! 60: fwidth = -1; ! 61: prec = -1; ! 62: c = *fmt++; ! 63: if (c == '-') { ! 64: adj = 1; ! 65: c = *fmt++; ! 66: } else ! 67: adj = 0; ! 68: if (c == '0') { ! 69: pad = '0'; ! 70: c = *fmt++; ! 71: } ! 72: if (c == '*') { ! 73: fwidth = *iap++; ! 74: c = *fmt++; ! 75: } else ! 76: for (fwidth = 0; c>='0' && c<='9'; c = *fmt++) ! 77: fwidth = fwidth*10 + c-'0'; ! 78: if (c == '.') { ! 79: c = *fmt++; ! 80: if (c == '*') { ! 81: prec = *iap++; ! 82: c = *fmt++; ! 83: } else ! 84: for (prec=0; c>='0' && c<='9'; c=*fmt++) ! 85: prec = prec*10 + c-'0'; ! 86: } ! 87: if (c == 'l') { ! 88: c = *fmt++; ! 89: if (c=='d' || c=='o' || c=='u' || c=='x') ! 90: c += 'A' - 'a'; ! 91: } ! 92: cbp = cbs = cbuf; ! 93: switch (c) { ! 94: ! 95: case 'd': ! 96: elem.i = *iap++; ! 97: if (elem.i < 0) { ! 98: elem.i = -elem.i; ! 99: *cbp++ = '-'; ! 100: } ! 101: cbp = printi(cbp, elem.i, 10); ! 102: break; ! 103: ! 104: case 'u': ! 105: cbp = printi(cbp, *iap++, 10); ! 106: break; ! 107: ! 108: case 'o': ! 109: cbp = printi(cbp, *iap++, 8); ! 110: break; ! 111: ! 112: case 'x': ! 113: cbp = printi(cbp, *iap++, 16); ! 114: break; ! 115: ! 116: case 'D': ! 117: elem.l = *(long *)iap; ! 118: bump(iap, long); ! 119: if (elem.l < 0) { ! 120: elem.l = -elem.l; ! 121: *cbp++ = '-'; ! 122: } ! 123: cbp = printl(cbp, elem.l, 10); ! 124: break; ! 125: ! 126: case 'U': ! 127: cbp = printl(cbp, *(long *)iap, 10); ! 128: bump(iap, long); ! 129: break; ! 130: ! 131: case 'O': ! 132: cbp = printl(cbp, *(long *)iap, 8); ! 133: bump(iap, long); ! 134: break; ! 135: ! 136: case 'X': ! 137: cbp = printl(cbp, *(long *)iap, 16); ! 138: bump(iap, long); ! 139: break; ! 140: ! 141: ! 142: case 's': ! 143: if ((s = *(char **)iap) == NULL) ! 144: s = null; ! 145: bump(iap, char*); ! 146: /* ! 147: * Do %s specially so it can be longer. ! 148: */ ! 149: cbp = cbs = s; ! 150: while (*cbp++ != '\0') ! 151: if (prec>=0 && cbp-s>prec) ! 152: break; ! 153: cbp--; ! 154: break; ! 155: ! 156: case 'c': ! 157: elem.c = *iap++; ! 158: *cbp++ = elem.c; ! 159: break; ! 160: ! 161: case 'r': ! 162: xprintf(*(char ***)iap); ! 163: bump(iap, char**); ! 164: break; ! 165: ! 166: default: ! 167: putchar(c); ! 168: continue; ! 169: } ! 170: if ((pwidth = fwidth + cbs-cbp) < 0) ! 171: pwidth = 0; ! 172: if (!adj) ! 173: while (pwidth-- != 0) ! 174: putchar(pad); ! 175: while (cbs < cbp) ! 176: putchar(*cbs++); ! 177: if (adj) ! 178: while (pwidth-- != 0) ! 179: putchar(pad); ! 180: } ! 181: } ! 182: ! 183: static char digits[] = { ! 184: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ! 185: 'A', 'B', 'C', 'D', 'E', 'F' ! 186: }; ! 187: ! 188: /* ! 189: * Print an unsigned integer in base b. ! 190: */ ! 191: static ! 192: char * ! 193: printi(cp, n, b) ! 194: char *cp; ! 195: register unsigned n; ! 196: { ! 197: register a; ! 198: register char *ep; ! 199: char pbuf[10]; ! 200: ! 201: ep = &pbuf[10]; ! 202: *--ep = 0; ! 203: for ( ; a = n/b; n=a) ! 204: *--ep = digits[n%b]; ! 205: *--ep = digits[n]; ! 206: while (*ep) ! 207: *cp++ = *ep++; ! 208: return (cp); ! 209: } ! 210: ! 211: /* ! 212: * Print an unsigned long in base b. ! 213: */ ! 214: static ! 215: char * ! 216: printl(cp, n, b) ! 217: register char *cp; ! 218: unsigned long n; ! 219: register b; ! 220: { ! 221: char pbuf[13]; ! 222: unsigned long a; ! 223: register char *ep; ! 224: ! 225: ep = &pbuf[13]; ! 226: *--ep = '\0'; ! 227: for ( ; (a = n/b) != 0; n = a) ! 228: *--ep = digits[n%b]; ! 229: *--ep = digits[n]; ! 230: while (*ep) ! 231: *cp++ = *ep++; ! 232: return (cp); ! 233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.