#include <u.h>
#include <libc.h>
#include <utffold.h>
#include <utfunfold.h>
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 <bio.h>
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("");
}
|