|
|
1.1 root 1: #define NEXT(p) (*(p) ? *(p)++ : 0)
2:
3: char fmtbuf[128];
4:
5: double fnum; long lnum;
6:
7: main(argc, argv)
8: char **argv;
9: {
10: char *format = *++argv, **Argv;
11: register char *fmt, *p;
12: register c, i;
13: ++argv;
14: if (argc >= 2) do {
15: Argv = argv;
16: fmt = format;
17: while (c = NEXT(fmt)) switch (c) {
18: case '\\':
19: switch (c = NEXT(fmt)) {
20: case 'n':
21: putchar('\n'); break;
22: case 'r':
23: putchar('\r'); break;
24: case 't':
25: putchar('\t'); break;
26: case 'b':
27: putchar('\b'); break;
28: case '0': case '1': case '2': case '3':
29: case '4': case '5': case '6': case '7':
30: c -= '0';
31: for (i=0; i<2; i++)
32: if (*fmt >= '0' && *fmt <= '7')
33: c = (c << 3) + *fmt++ - '0';
34: default:
35: putchar(c); break;
36: }
37: break;
38: case '%':
39: p = fmtbuf;
40: *p++ = c;
41: while (c && (c = NEXT(fmt))) switch (c) {
42: case '*':
43: atonum(NEXT(argv));
44: p += sprintf(p, "%d", lnum);
45: break;
46: case 'h': case 'l':
47: break;
48: case 'd': case 'o': case 'x':
49: case 'D': case 'O': case 'X':
50: case 'f': case 'e': case 'g':
51: case 'c': case 'u': case 'U':
52: *p++ = c; *p = 0;
53: if (atonum(NEXT(argv)))
54: printf(fmtbuf, fnum);
55: else
56: printf(fmtbuf, lnum);
57: c = 0; break;
58: case 's':
59: *p++ = c; *p = 0;
60: printf(fmtbuf, NEXT(argv));
61: c = 0; break;
62: case '%':
63: *p++ = c; *p = 0;
64: printf(fmtbuf);
65: c = 0; break;
66: default:
67: *p++ = c;
68: }
69: break;
70: default:
71: putchar(c);
72: break;
73: }
74: } while (*argv && argv > Argv);
75: exit(0);
76: }
77:
78: double
79: pwrten(exp)
80: register exp;
81: {
82: register double d;
83: if (exp < 0) return 1.0/pwrten(-exp);
84: if (exp == 0) return 1.0;
85: if (exp == 1) return 10.0;
86: d = pwrten(exp/2), d *= d;
87: if (exp & 1) d *= 10.0;
88: return d;
89: }
90:
91: lexconst(n, ftype, exp)
92: register n, ftype, exp;
93: {
94: if (ftype)
95: fnum = (double)n * pwrten(exp);
96: else
97: lnum = n;
98: return ftype;
99: }
100:
101: enum States { start, intscan, hexscan, fracscan, expstart, expscan};
102:
103: atonum(p)
104: register char *p;
105: {
106: register state = (int)start, c;
107: unsigned int i = 0, ioct = 0;
108: unsigned int sign = 1, octal = 0, fexp = 0, sexp = 1, exp = 0;
109: switch (c = *p++) {
110: case '+':
111: c = *p++; break;
112: case '-':
113: sign = -1, c = *p++; break;
114: case '0':
115: ++octal, c = *p++; break;
116: case '1': case '2': case '3': case '4': case '5': case '6':
117: case '7': case '8': case '9': case '.': case 'e': case 'E':
118: break;
119: case '\'': case '"':
120: return lexconst(*p++, 0, 0);
121: default:
122: return lexconst(c, 0, 0);
123: }
124: for (;; c = *p++) switch (state) {
125: case start:
126: if (octal && (c == 'x' || c == 'X')) {
127: state = (int)hexscan;
128: break;
129: }
130: state = (int)intscan; /* fall through */
131: case intscan:
132: if (c >= '0' && c <= '9') {
133: i = 10*i + (c -= '0');
134: if (octal) ioct = 8*ioct + c;
135: } else if (c == 'e' || c == 'E') {
136: state = (int)expstart;
137: } else if (c == '.') {
138: state = (int)fracscan;
139: } else {
140: return lexconst(sign*(octal ? ioct : i), 0, 0);
141: }
142: break;
143: case hexscan:
144: if (c >= '0' && c <= '9') {
145: i = 16*i + (c -= '0');
146: } else if (c >= 'a' && c <= 'f') {
147: i = 16*i + (c -= 'a' - 10);
148: } else if (c >= 'A' && c <= 'F') {
149: i = 16*i + (c -= 'A' - 10);
150: } else {
151: return lexconst(sign*i, 0, 0);
152: }
153: break;
154: case fracscan:
155: if (c >= '0' && c <= '9') {
156: i = 10*i + (c -= '0');
157: --fexp;
158: } else if (c == 'e' || c == 'E') {
159: state = (int)expstart;
160: } else {
161: return lexconst(sign*i, 1, fexp);
162: }
163: break;
164: case expstart:
165: state = (int)expscan;
166: if (c == '+') {
167: break;
168: } else if (c == '-') {
169: sexp = -1;
170: break;
171: }
172: case expscan:
173: if (c >= '0' && c <= '9') {
174: exp = 10*exp + (c -= '0');
175: } else {
176: return lexconst(sign*i, 1, fexp + sexp*exp);
177: }
178: break;
179: }
180: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.