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