4 typedef struct PCB /* Control block controlling specification parse */
6 char *base; /* start of specification */
7 char *current; /* current parse point */
8 long last; /* last Rune returned */
9 long final; /* final Rune in a span */
12 uchar bits[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
14 #define SETBIT(a, c) ((a)[(c)/8] |= bits[(c)&07])
15 #define CLEARBIT(a,c) ((a)[(c)/8] &= ~bits[(c)&07])
16 #define BITSET(a,c) ((a)[(c)/8] & bits[(c)&07])
18 uchar f[(Runemax+1)/8];
19 uchar t[(Runemax+1)/8];
29 void complement(void);
34 char *getrune(char*, Rune*);
35 void Pinit(Pcb*, char*);
37 int readrune(int, long*);
39 void writerune(int, Rune);
44 fprint(2, "usage: %s [-cds] [string1 [string2]]\n", argv0);
49 main(int argc, char **argv)
52 case 's': sflag++; break;
53 case 'd': dflag++; break;
54 case 'c': cflag++; break;
58 Pinit(&pfrom, argv[0]);
64 if ((sflag && argc != 2) || (!sflag && argc != 1))
83 memset((char *) f, 0xff, sizeof f);
84 while ((c = canon(&pfrom)) >= 0)
87 while ((c = canon(&pfrom)) >= 0)
91 while ((c = canon(&pto)) >= 0)
96 while (readrune(0, &c) > 0) {
97 if(!BITSET(f, c) && (c != last || !BITSET(t,c))) {
99 writerune(1, (Rune) c);
110 long from, to, lastc, high;
114 while ((from = canon(&pfrom)) >= 0) {
115 if (from > high) high = from;
118 while ((to = canon(&pto)) > 0) {
119 if (to > high) high = to;
123 if ((p = (Rune *) malloc((high+1)*sizeof(Rune))) == 0)
124 sysfatal("no memory");
125 for (i = 0; i <= high; i++){
127 if ((to = canon(&pto)) < 0)
136 while (readrune(0, &from) > 0) {
141 if (from != lastc || !BITSET(t,from)) {
143 writerune(1, (Rune) from);
148 while (readrune(0, &from) > 0){
153 writerune(1, (Rune) from);
164 long from, to, lastc, high;
168 while ((from = canon(&pfrom)) >= 0)
169 if (from > high) high = from;
171 if ((p = (Rune *) malloc((high+1)*sizeof(Rune))) == 0)
172 sysfatal("no memory");
173 for (i = 0; i <= high; i++)
175 while ((from = canon(&pfrom)) >= 0) {
176 if ((to = canon(&pto)) < 0)
179 if (BITSET(f,from) && p[from] != to)
180 sysfatal("ambiguous translation");
185 while ((to = canon(&pto)) >= 0) {
190 while (readrune(0, &from) > 0) {
193 if (from != lastc || !BITSET(t,from)) {
195 writerune(1, (Rune) from);
200 while (readrune(0, &from) > 0) {
203 writerune(1, (Rune) from);
210 readrune(int fd, long *rp)
215 static char buf[4096];
222 memcpy(buf, buf+j, n-j);
224 n = read(fd, &buf[i], sizeof(buf)-i);
226 sysfatal("read error: %r");
233 if (fullrune(&buf[j], i-j))
236 chartorune(&r, &buf[j]);
242 writerune(int fd, Rune r)
249 n = runetochar(buf, (Rune*)&r);
250 if (wptr+n >= wbuf+sizeof(wbuf))
252 memcpy(wptr, buf, n);
259 if (wptr && wptr > wbuf)
260 if (write(fd, wbuf, wptr-wbuf) != wptr-wbuf)
261 sysfatal("write error: %r");
266 getrune(char *s, Rune *rp)
272 s += chartorune(rp, s);
273 if((r = *rp) == '\\' && *s){
277 for (i = 0; i < 4; i++) {
279 s += chartorune(&r, s);
280 if ('0' <= r && r <= '9')
282 else if ('a' <= r && r <= 'f')
283 n = 16*n + r - 'a' + 10;
284 else if ('A' <= r && r <= 'F')
285 n = 16*n + r - 'A' + 10;
294 for(i = 0; i < 3; i++) {
296 s += chartorune(&r, s);
297 if('0' <= r && r <= '7')
310 sysfatal("character > 0377");
323 if (p->last < p->final)
327 if (*p->current == '\0')
329 if(*p->current == '-' && p->last >= 0 && p->current[1]){
330 p->current = getrune(p->current+1, &r);
332 sysfatal("invalid range specification");
338 p->current = getrune(p->current, &r);
344 Pinit(Pcb *p, char *cp)
346 p->current = p->base = cp;
347 p->last = p->final = -1;
352 p->current = p->base;
353 p->last = p->final = -1;