1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 char usage[] = "unicode { [-t] hex hex ... | hexmin-hexmax ... | [-n] char ... }";
6 char hex[] = "0123456789abcdefABCDEF";
7 int numout = 0;
8 int text = 0;
9 char *err;
10 Biobuf bout;
11
12 char *range(char*[]);
13 char *nums(char*[]);
14 char *chars(char*[]);
15
16 void
main(int argc,char * argv[])17 main(int argc, char *argv[])
18 {
19 ARGBEGIN{
20 case 'n':
21 numout = 1;
22 break;
23 case 't':
24 text = 1;
25 break;
26 }ARGEND
27 Binit(&bout, 1, OWRITE);
28 if(argc == 0){
29 fprint(2, "usage: %s\n", usage);
30 exits("usage");
31 }
32 if(!numout && utfrune(argv[0], '-'))
33 exits(range(argv));
34 if(numout || strchr(hex, argv[0][0])==0)
35 exits(nums(argv));
36 exits(chars(argv));
37 }
38
39 char*
range(char * argv[])40 range(char *argv[])
41 {
42 char *q;
43 int min, max;
44 int i;
45
46 while(*argv){
47 q = *argv;
48 if(strchr(hex, q[0]) == 0){
49 err:
50 fprint(2, "unicode: bad range %s\n", *argv);
51 return "bad range";
52 }
53 min = strtoul(q, &q, 16);
54 if(min<0 || min>Runemax || *q!='-')
55 goto err;
56 q++;
57 if(strchr(hex, *q) == 0)
58 goto err;
59 max = strtoul(q, &q, 16);
60 if(max<0 || max>Runemax || max<min || *q!=0)
61 goto err;
62 i = 0;
63 do{
64 Bprint(&bout, "%.6x %C", min, min);
65 i++;
66 if(min==max || (i&7)==0)
67 Bprint(&bout, "\n");
68 else
69 Bprint(&bout, "\t");
70 min++;
71 }while(min<=max);
72 argv++;
73 }
74 return 0;
75 }
76
77 char*
nums(char * argv[])78 nums(char *argv[])
79 {
80 char *q;
81 Rune r;
82 int w, rsz;
83 char utferr[UTFmax];
84
85 r = Runeerror;
86 rsz = runetochar(utferr, &r);
87 while(*argv){
88 q = *argv;
89 while(*q){
90 w = chartorune(&r, q);
91 if(r==Runeerror){
92 if(strlen(q) != rsz || memcmp(q, utferr, rsz) != 0){
93 fprint(2, "unicode: invalid utf string %s\n", *argv);
94 return "bad utf";
95 }
96 }
97 Bprint(&bout, "%.6x\n", r);
98 q += w;
99 }
100 argv++;
101 }
102 return 0;
103 }
104
105 char*
chars(char * argv[])106 chars(char *argv[])
107 {
108 char *q;
109 int m;
110
111 while(*argv){
112 q = *argv;
113 if(strchr(hex, q[0]) == 0){
114 err:
115 fprint(2, "unicode: bad unicode value %s\n", *argv);
116 return "bad char";
117 }
118 m = strtoul(q, &q, 16);
119 if(m<0 || m>Runemax || *q!=0)
120 goto err;
121 Bprint(&bout, "%C", m);
122 if(!text)
123 Bprint(&bout, "\n");
124 argv++;
125 }
126 return 0;
127 }
128