xref: /plan9/sys/src/cmd/unicode.c (revision b9e364c446c00cfa6b1164b4648b126624c464b2)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier char	usage[] = "unicode { [-t] hex hex ... | hexmin-hexmax ... | [-n] char ... }";
63e12c5d1SDavid du Colombier char	hex[] = "0123456789abcdefABCDEF";
73e12c5d1SDavid du Colombier int	numout = 0;
83e12c5d1SDavid du Colombier int	text = 0;
93e12c5d1SDavid du Colombier char	*err;
103e12c5d1SDavid du Colombier Biobuf	bout;
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier char	*range(char*[]);
133e12c5d1SDavid du Colombier char	*nums(char*[]);
143e12c5d1SDavid du Colombier char	*chars(char*[]);
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier void
main(int argc,char * argv[])173e12c5d1SDavid du Colombier main(int argc, char *argv[])
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	ARGBEGIN{
203e12c5d1SDavid du Colombier 	case 'n':
213e12c5d1SDavid du Colombier 		numout = 1;
223e12c5d1SDavid du Colombier 		break;
233e12c5d1SDavid du Colombier 	case 't':
243e12c5d1SDavid du Colombier 		text = 1;
253e12c5d1SDavid du Colombier 		break;
263e12c5d1SDavid du Colombier 	}ARGEND
273e12c5d1SDavid du Colombier 	Binit(&bout, 1, OWRITE);
283e12c5d1SDavid du Colombier 	if(argc == 0){
293e12c5d1SDavid du Colombier 		fprint(2, "usage: %s\n", usage);
303e12c5d1SDavid du Colombier 		exits("usage");
313e12c5d1SDavid du Colombier 	}
323e12c5d1SDavid du Colombier 	if(!numout && utfrune(argv[0], '-'))
333e12c5d1SDavid du Colombier 		exits(range(argv));
343e12c5d1SDavid du Colombier 	if(numout || strchr(hex, argv[0][0])==0)
353e12c5d1SDavid du Colombier 		exits(nums(argv));
363e12c5d1SDavid du Colombier 	exits(chars(argv));
373e12c5d1SDavid du Colombier }
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier char*
range(char * argv[])403e12c5d1SDavid du Colombier range(char *argv[])
413e12c5d1SDavid du Colombier {
423e12c5d1SDavid du Colombier 	char *q;
437dd7cddfSDavid du Colombier 	int min, max;
443e12c5d1SDavid du Colombier 	int i;
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	while(*argv){
473e12c5d1SDavid du Colombier 		q = *argv;
483e12c5d1SDavid du Colombier 		if(strchr(hex, q[0]) == 0){
493e12c5d1SDavid du Colombier     err:
503e12c5d1SDavid du Colombier 			fprint(2, "unicode: bad range %s\n", *argv);
513e12c5d1SDavid du Colombier 			return "bad range";
523e12c5d1SDavid du Colombier 		}
533e12c5d1SDavid du Colombier 		min = strtoul(q, &q, 16);
5482726826SDavid du Colombier 		if(min<0 || min>Runemax || *q!='-')
553e12c5d1SDavid du Colombier 			goto err;
563e12c5d1SDavid du Colombier 		q++;
573e12c5d1SDavid du Colombier 		if(strchr(hex, *q) == 0)
583e12c5d1SDavid du Colombier 			goto err;
593e12c5d1SDavid du Colombier 		max = strtoul(q, &q, 16);
6082726826SDavid du Colombier 		if(max<0 || max>Runemax || max<min || *q!=0)
613e12c5d1SDavid du Colombier 			goto err;
623e12c5d1SDavid du Colombier 		i = 0;
633e12c5d1SDavid du Colombier 		do{
64*b9e364c4SDavid du Colombier 			Bprint(&bout, "%.6x %C", min, min);
653e12c5d1SDavid du Colombier 			i++;
663e12c5d1SDavid du Colombier 			if(min==max || (i&7)==0)
673e12c5d1SDavid du Colombier 				Bprint(&bout, "\n");
683e12c5d1SDavid du Colombier 			else
693e12c5d1SDavid du Colombier 				Bprint(&bout, "\t");
703e12c5d1SDavid du Colombier 			min++;
713e12c5d1SDavid du Colombier 		}while(min<=max);
723e12c5d1SDavid du Colombier 		argv++;
733e12c5d1SDavid du Colombier 	}
743e12c5d1SDavid du Colombier 	return 0;
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier char*
nums(char * argv[])783e12c5d1SDavid du Colombier nums(char *argv[])
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier 	char *q;
813e12c5d1SDavid du Colombier 	Rune r;
8282726826SDavid du Colombier 	int w, rsz;
8382726826SDavid du Colombier 	char utferr[UTFmax];
843e12c5d1SDavid du Colombier 
8582726826SDavid du Colombier 	r = Runeerror;
8682726826SDavid du Colombier 	rsz = runetochar(utferr, &r);
873e12c5d1SDavid du Colombier 	while(*argv){
883e12c5d1SDavid du Colombier 		q = *argv;
893e12c5d1SDavid du Colombier 		while(*q){
903e12c5d1SDavid du Colombier 			w = chartorune(&r, q);
9182726826SDavid du Colombier 			if(r==Runeerror){
9282726826SDavid du Colombier 				if(strlen(q) != rsz || memcmp(q, utferr, rsz) != 0){
933e12c5d1SDavid du Colombier 					fprint(2, "unicode: invalid utf string %s\n", *argv);
943e12c5d1SDavid du Colombier 					return "bad utf";
953e12c5d1SDavid du Colombier 				}
9682726826SDavid du Colombier 			}
9782726826SDavid du Colombier 			Bprint(&bout, "%.6x\n", r);
983e12c5d1SDavid du Colombier 			q += w;
993e12c5d1SDavid du Colombier 		}
1003e12c5d1SDavid du Colombier 		argv++;
1013e12c5d1SDavid du Colombier 	}
1023e12c5d1SDavid du Colombier 	return 0;
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier char*
chars(char * argv[])1063e12c5d1SDavid du Colombier chars(char *argv[])
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier 	char *q;
1097dd7cddfSDavid du Colombier 	int m;
1103e12c5d1SDavid du Colombier 
1113e12c5d1SDavid du Colombier 	while(*argv){
1123e12c5d1SDavid du Colombier 		q = *argv;
1133e12c5d1SDavid du Colombier 		if(strchr(hex, q[0]) == 0){
1143e12c5d1SDavid du Colombier     err:
1153e12c5d1SDavid du Colombier 			fprint(2, "unicode: bad unicode value %s\n", *argv);
1163e12c5d1SDavid du Colombier 			return "bad char";
1173e12c5d1SDavid du Colombier 		}
1183e12c5d1SDavid du Colombier 		m = strtoul(q, &q, 16);
11982726826SDavid du Colombier 		if(m<0 || m>Runemax || *q!=0)
1203e12c5d1SDavid du Colombier 			goto err;
1213e12c5d1SDavid du Colombier 		Bprint(&bout, "%C", m);
1223e12c5d1SDavid du Colombier 		if(!text)
1233e12c5d1SDavid du Colombier 			Bprint(&bout, "\n");
1243e12c5d1SDavid du Colombier 		argv++;
1253e12c5d1SDavid du Colombier 	}
1263e12c5d1SDavid du Colombier 	return 0;
1273e12c5d1SDavid du Colombier }
128