diff options
Diffstat (limited to 'appl/cmd/unicode.b')
| -rw-r--r-- | appl/cmd/unicode.b | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/appl/cmd/unicode.b b/appl/cmd/unicode.b new file mode 100644 index 00000000..9f1ae3d1 --- /dev/null +++ b/appl/cmd/unicode.b @@ -0,0 +1,162 @@ +implement Unicode; + +include "sys.m"; +sys: Sys; + +include "draw.m"; + +include "string.m"; + str: String; + +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; + + +Unicode: module +{ + init: fn(c: ref Draw->Context, v: list of string); +}; + +usage: con "unicode { [-t] hex hex ... | hexmin-hexmax ... | [-n] char ... }"; +hex: con "0123456789abcdefABCDEF"; +numout:= 0; +text:= 0; +out: ref Bufio->Iobuf; +stderr: ref sys->FD; + +init(nil: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + str = load String String->PATH; + bufio = load Bufio Bufio->PATH; + + stderr = sys->fildes(2); + + if(str==nil || bufio==nil){ + sys->fprint(stderr, "unicode: can't load String or Bufio module: %r\n"); + return; + } + + if(argv == nil){ + sys->fprint(stderr, "usage: %s\n", usage); + return; + } + argv = tl argv; + while(argv != nil) { + s := hd argv; + if(s != nil && s[0] != '-') + break; + case s{ + "-n" => + numout = 1; + "-t" => + text = 1; + } + argv = tl argv; + } + if(argv == nil){ + sys->fprint(stderr, "usage: %s\n", usage); + return; + } + + out = bufio->fopen(sys->fildes(1), Bufio->OWRITE); + + if(!numout && oneof(hd argv, '-')) + range(argv); + else if(numout || oneof(hex, (hd argv)[0]) == 0) + nums(argv); + else + chars(argv); + out.flush(); +} + +oneof(s: string, c: int): int +{ + for(i:=0; i<len s; i++) + if(s[i] == c) + return 1; + return 0; +} + +badrange(q: string) +{ + sys->fprint(stderr, "unicode: bad range %s\n", q); +} + +range(argv: list of string) +{ + min, max: int; + + while(argv != nil){ + q := hd argv; + if(oneof(hex, q[0]) == 0){ + badrange(q); + return; + } + (min, q) = str->toint(q,16); + if(min<0 || min>16rFFFF || len q==0 || q[0]!='-'){ + badrange(hd argv); + return; + } + q = q[1:]; + if(oneof(hex, q[0]) == 0){ + badrange(hd argv); + return; + } + (max, q) = str->toint(q,16); + if(max<0 || max>16rFFFF || max<min || len q>0){ + badrange(hd argv); + return; + } + i := 0; + do{ + out.puts(sys->sprint("%.4x %c", min, min)); + i++; + if(min==max || (i&7)==0) + out.puts("\n"); + else + out.puts("\t"); + min++; + }while(min<=max); + argv = tl argv; + } +} + + +nums(argv: list of string) +{ + while(argv != nil){ + q := hd argv; + for(i:=0; i<len q; i++) + out.puts(sys->sprint("%.4x\n", q[i])); + argv = tl argv; + } +} + +badvalue(s: string) +{ + sys->fprint(stderr, "unicode: bad unicode value %s\n", s); +} + +chars(argv: list of string) +{ + m: int; + + while(argv != nil){ + q := hd argv; + if(oneof(hex, q[0]) == 0){ + badvalue(hd argv); + return; + } + (m, q) = str->toint(q, 16); + if(m<0 || m>16rFFFF || len q>0){ + badvalue(hd argv); + return; + } + out.puts(sys->sprint("%c", m)); + if(!text) + out.puts("\n"); + argv = tl argv; + } +} |
