xref: /inferno-os/appl/cmd/unicode.b (revision 5139a0a1c6f3b5a03c2e3eeb56e20a81cda5619a)
1implement Unicode;
2
3include "sys.m";
4sys: Sys;
5
6include "draw.m";
7
8include "string.m";
9	str: String;
10
11include "bufio.m";
12	bufio: Bufio;
13	Iobuf: import bufio;
14
15
16Unicode: module
17{
18	init: fn(c: ref Draw->Context, v: list of string);
19};
20
21usage: con "unicode { [-t] hex hex ... | hexmin-hexmax ... | [-n] char ... }";
22hex: con "0123456789abcdefABCDEF";
23numout:= 0;
24text:= 0;
25out: ref Bufio->Iobuf;
26stderr: ref sys->FD;
27
28init(nil: ref Draw->Context, argv: list of string)
29{
30	sys = load Sys Sys->PATH;
31	str = load String String->PATH;
32	bufio = load Bufio Bufio->PATH;
33
34	stderr = sys->fildes(2);
35
36	if(str==nil || bufio==nil){
37		sys->fprint(stderr, "unicode: can't load String or Bufio module: %r\n");
38		return;
39	}
40
41	if(argv == nil){
42		sys->fprint(stderr, "usage: %s\n", usage);
43		return;
44	}
45	argv = tl argv;
46	while(argv != nil) {
47		s := hd argv;
48		if(s != nil && s[0] != '-')
49			break;
50		case s{
51		"-n" =>
52			numout = 1;
53		"-t" =>
54			text = 1;
55		}
56		argv = tl argv;
57	}
58	if(argv == nil){
59		sys->fprint(stderr, "usage: %s\n", usage);
60		return;
61	}
62
63	out = bufio->fopen(sys->fildes(1), Bufio->OWRITE);
64
65	if(!numout && oneof(hd argv, '-'))
66		range(argv);
67	else if(numout || oneof(hex, (hd argv)[0]) == 0)
68		nums(argv);
69	else
70		chars(argv);
71	out.flush();
72}
73
74oneof(s: string, c: int): int
75{
76	for(i:=0; i<len s; i++)
77		if(s[i] == c)
78			return 1;
79	return 0;
80}
81
82badrange(q: string)
83{
84	sys->fprint(stderr, "unicode: bad range %s\n", q);
85}
86
87range(argv: list of string)
88{
89	min, max: int;
90
91	while(argv != nil){
92		q := hd argv;
93		if(oneof(hex, q[0]) == 0){
94			badrange(q);
95			return;
96		}
97		(min, q) = str->toint(q,16);
98		if(min<0 || min>Sys->Runemax || len q==0 || q[0]!='-'){
99			badrange(hd argv);
100			return;
101		}
102		q = q[1:];
103		if(oneof(hex, q[0]) == 0){
104			badrange(hd argv);
105			return;
106		}
107		(max, q) = str->toint(q,16);
108		if(max<0 || max>Sys->Runemax || max<min || len q>0){
109			badrange(hd argv);
110			return;
111		}
112		i := 0;
113		do{
114			out.puts(sys->sprint("%.4x %c", min, min));
115			i++;
116			if(min==max || (i&7)==0)
117				out.puts("\n");
118			else
119				out.puts("\t");
120			min++;
121		}while(min<=max);
122		argv = tl argv;
123	}
124}
125
126
127nums(argv: list of string)
128{
129	while(argv != nil){
130		q := hd argv;
131		for(i:=0; i<len q; i++)
132			out.puts(sys->sprint("%.4x\n", q[i]));
133		argv = tl argv;
134	}
135}
136
137badvalue(s: string)
138{
139	sys->fprint(stderr, "unicode: bad unicode value %s\n", s);
140}
141
142chars(argv: list of string)
143{
144	m: int;
145
146	while(argv != nil){
147		q := hd argv;
148		if(oneof(hex, q[0]) == 0){
149			badvalue(hd argv);
150			return;
151		}
152		(m, q) = str->toint(q, 16);
153		if(m<0 || m>Sys->Runemax || len q>0){
154			badvalue(hd argv);
155			return;
156		}
157		out.puts(sys->sprint("%c", m));
158		if(!text)
159			out.puts("\n");
160		argv = tl argv;
161	}
162}
163