jehanne/sys/src/cmd/unicode.c

137 lines
2.4 KiB
C

/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#include <u.h>
#include <lib9.h>
#include <bio.h>
char usage[] = "unicode { [-t] hex hex ... | hexmin-hexmax ... | [-n] char ... }";
char hex[] = "0123456789abcdefABCDEF";
int numout = 0;
int text = 0;
char *err;
Biobuf bout;
char *range(char*[]);
char *nums(char*[]);
char *chars(char*[]);
void
main(int argc, char *argv[])
{
ARGBEGIN{
case 'n':
numout = 1;
break;
case 't':
text = 1;
break;
}ARGEND
Binit(&bout, 1, OWRITE);
if(argc == 0){
fprint(2, "usage: %s\n", usage);
exits("usage");
}
if(!numout && utfrune(argv[0], '-'))
exits(range(argv));
if(numout || strchr(hex, argv[0][0])==0)
exits(nums(argv));
exits(chars(argv));
}
char*
range(char *argv[])
{
char *q;
int min, max;
int i;
while(*argv){
q = *argv;
if(strchr(hex, q[0]) == 0){
err:
fprint(2, "unicode: bad range %s\n", *argv);
return "bad range";
}
min = strtoul(q, &q, 16);
if(min<0 || min>Runemax || *q!='-')
goto err;
q++;
if(strchr(hex, *q) == 0)
goto err;
max = strtoul(q, &q, 16);
if(max<0 || max>Runemax || max<min || *q!=0)
goto err;
i = 0;
do{
Bprint(&bout, "%.6x %C", min, min);
i++;
if(min==max || (i&7)==0)
Bprint(&bout, "\n");
else
Bprint(&bout, "\t");
min++;
}while(min<=max);
argv++;
}
return 0;
}
char*
nums(char *argv[])
{
char *q;
Rune r;
int w, rsz;
char utferr[UTFmax];
r = Runeerror;
rsz = runetochar(utferr, &r);
while(*argv){
q = *argv;
while(*q){
w = chartorune(&r, q);
if(r==Runeerror){
if(strlen(q) != rsz || memcmp(q, utferr, rsz) != 0){
fprint(2, "unicode: invalid utf string %s\n", *argv);
return "bad utf";
}
}
Bprint(&bout, "%.6x\n", r);
q += w;
}
argv++;
}
return 0;
}
char*
chars(char *argv[])
{
char *q;
int m;
while(*argv){
q = *argv;
if(strchr(hex, q[0]) == 0){
err:
fprint(2, "unicode: bad unicode value %s\n", *argv);
return "bad char";
}
m = strtoul(q, &q, 16);
if(m<0 || m>Runemax || *q!=0)
goto err;
Bprint(&bout, "%C", m);
if(!text)
Bprint(&bout, "\n");
argv++;
}
return 0;
}