rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 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>0xFFFF || *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>0xFFFF || 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>0xFFFF || *q!=0) |
| 115 | goto err; |
| 116 | Bprint(&bout, "%C", m); |
| 117 | if(!text) |
| 118 | Bprint(&bout, "\n"); |
| 119 | argv++; |
| 120 | } |
| 121 | return 0; |
| 122 | } |