|
|
1.1 root 1: #include <ctype.h>
2: #include <string.h>
3:
4: #define CAPS (1<<0)
5: #define ALLCAPS (1<<1)
6: #define RJUST (1<<2)
7: #define LDEL (1<<3)
8: #define RDEL (1<<4)
9:
10: #define SUBST 1
11: #define LMARK 2
12: #define RMARK 3
13:
14: #define FLAGS 0
15: #define WIDTH 1
16: #define PREC 2
17: #define VAR 3
18: #define PSIZE 4
19:
20: fmtcomp(prog, fmt, vars)
21: register char *prog, *fmt;
22: char *vars[];
23: {
24: register char c, b;
25: register char *p;
26: int nl = 1, curly, i;
27:
28: vars[0] = 0;
29: while (c = *fmt++)
30: top: switch (c) {
31: case '%':
32: *prog++ = SUBST;
33: prog[FLAGS] = prog[WIDTH] = prog[PREC] = 0;
34: p = &prog[WIDTH];
35: curly = 0;
36: while (c = *fmt++)
37: switch (c) {
38: case '^': prog[FLAGS] |= CAPS; break;
39: case '+': prog[FLAGS] |= ALLCAPS; break;
40: case '-': prog[FLAGS] |= RJUST; break;
41: case '<': prog[FLAGS] |= LDEL; break;
42: case '>': prog[FLAGS] |= RDEL; break;
43: case '.': p = &prog[PREC]; break;
44: case '{':
45: curly++;
46: c = *fmt++;
47: /* fall thru */
48: default:
49: if (isdigit(c)) {
50: *p = (*p * 10) + (c - '0');
51: break;
52: }
53: p = --fmt;
54: while (isalnum(c))
55: c = *++fmt;
56: if (p == fmt) {
57: prog--;
58: goto brake;
59: }
60: if (c)
61: *fmt++ = 0;
62: for (i = 0; vars[i] &&
63: strcmp(vars[i], p); i++);
64: prog[VAR] = i;
65: prog += PSIZE;
66: if (!vars[i]) {
67: vars[i] = p;
68: vars[++i] = 0;
69: }
70: if (c && !curly)
71: goto top;
72: goto brake;
73: }
74: prog--;
75: fmt--;
76: brake: break;
77: case '\\':
78: switch (c = *fmt++) {
79: case '<': c = LMARK; break;
80: case '>': c = RMARK; break;
81: case 'n': c = '\n'; break;
82: case 'r': c = '\r'; break;
83: case 't': c = '\t'; break;
84: case 'b': c = '\b'; break;
85: case 'f': c = '\f'; break;
86: case 'v': c = '\v'; break;
87: case 0: c = '\\',fmt--; break;
88: case 'c': nl = 0; continue;
89: default:
90: for (i = b = 0; i < 3 && isdigit(c); i++) {
91: b = (b * 010) + (c - '0');
92: c = *fmt++;
93: }
94: if (i > 0) {
95: c = b;
96: fmt--;
97: }
98: }
99: /* fall thru */
100: default:
101: *prog++ = c;
102: }
103: if (nl) {
104: *prog++ = RMARK;
105: *prog++ = '\n';
106: }
107: *prog = 0;
108: }
109:
110: fmtexec(out, prog, vals)
111: register char *out, *prog;
112: char *vals[];
113: {
114: register int len, spaces;
115: register char c, prev;
116: register char *val;
117: char *mark = out;
118:
119: while (c = *prog++)
120: switch (c) {
121: case SUBST:
122: c = prog[FLAGS];
123: val = vals[prog[VAR]];
124: if ((len = strlen(val)) == 0 && c & (LDEL|RDEL)) {
125: prog += PSIZE;
126: if (c & LDEL)
127: out = mark;
128: if (c & RDEL)
129: while (*prog && *prog != RMARK)
130: if (*prog++ == SUBST)
131: prog += PSIZE;
132: break;
133: }
134: if (prog[PREC] > 0 && prog[PREC] < len)
135: len = prog[PREC];
136: spaces = prog[WIDTH] - len;
137: if (spaces > 0 && c & RJUST)
138: while (spaces--)
139: *out++ = ' ';
140: prev = 0;
141: while (len--)
142: *out++ = prev = c & ALLCAPS ||
143: (c & CAPS && !isalnum(prev))
144: ? toupper(*val++) : *val++;
145: if (spaces > 0 && !(c & RJUST))
146: while (spaces--)
147: *out++ = ' ';
148: prog += PSIZE;
149: break;
150: case LMARK:
151: mark = out;
152: break;
153: case RMARK:
154: break;
155: default:
156: *out++ = c;
157: }
158: *out = 0;
159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.