9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

unicode.c (1956B)


      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
     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*
     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*
     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*
    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 }