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