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, "%.4x %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;
83 
84 	while(*argv){
85 		q = *argv;
86 		while(*q){
87 			w = chartorune(&r, q);
88 			if(r==0x80 && (q[0]&0xFF)!=0x80){
89 				fprint(2, "unicode: invalid utf string %s\n", *argv);
90 				return "bad utf";
91 			}
92 			Bprint(&bout, "%.4x\n", r);
93 			q += w;
94 		}
95 		argv++;
96 	}
97 	return 0;
98 }
99 
100 char*
chars(char * argv[])101 chars(char *argv[])
102 {
103 	char *q;
104 	int m;
105 
106 	while(*argv){
107 		q = *argv;
108 		if(strchr(hex, q[0]) == 0){
109     err:
110 			fprint(2, "unicode: bad unicode value %s\n", *argv);
111 			return "bad char";
112 		}
113 		m = strtoul(q, &q, 16);
114 		if(m<0 || m>Runemax || *q!=0)
115 			goto err;
116 		Bprint(&bout, "%C", m);
117 		if(!text)
118 			Bprint(&bout, "\n");
119 		argv++;
120 	}
121 	return 0;
122 }
123