#include #include #include #include static Rune* bsearch(Rune c, Rune *t, int n, int ne) { Rune *p; int m; while(n > 1) { m = n/2; p = t + m*ne; if(c >= p[0]) { t = p; n = n-m; } else n = m; } if(n && c >= t[0]) return t; return 0; } static Rune* bsearchs(Rune c, Rune **t, int n, int ne) { Rune **p; int m; while(n > 1) { m = n/2; p = t + m*ne; if(c >= p[0][0]) { t = p; n = n-m; } else n = m; } if(n && c >= t[0][0]) return t[0]; return 0; } Rune tobaserune(Rune c) { Rune *p; p = bsearch(c, __base2, nelem(__base2)/2, 2); if(p && *p == c) c = p[1]; return c; } Rune* equivrune(Rune c) { Rune *p; p = bsearchs(c, __unfoldbase, nelem(__unfoldbase), 1); if(p && *p == c) return p; return nil; } #include void unfold(Biobuf *b, char *re) { Rune r, r0, *s; for(; *re != 0; ){ if(*re == '\\'){ Bputc(b, '\\'); if(re[1] == 0) break; } re += chartorune(&r, re); r0 = tobaserune(r); if(s = equivrune(r0)) Bprint(b, "[%S]", s); else Bputrune(b, r); } } void usage(void) { fprint(2, "usage: unfoldre\n"); exits("usage"); } void main(int argc, char **argv) { int i; Biobuf b; ARGBEGIN{ default: usage(); }ARGEND Binit(&b, 1, OWRITE); for(i = 0; i < argc; i++) unfold(&b, argv[i]); Bterm(&b); exits(""); }