| mkrunetype.awk - sbase - suckless unix tools | |
| git clone git://git.suckless.org/sbase | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| mkrunetype.awk (7613B) | |
| --- | |
| 1 # See LICENSE file for copyright and license details. | |
| 2 | |
| 3 BEGIN { | |
| 4 FS = ";" | |
| 5 # set up hexadecimal lookup table | |
| 6 for(i = 0; i < 16; i++) | |
| 7 hex[sprintf("%X",i)] = i; | |
| 8 HEADER = "/* Automatically generated by mkrunetype.awk */\n#incl… | |
| 9 HEADER_OTHER = "/* Automatically generated by mkrunetype.awk */\… | |
| 10 } | |
| 11 | |
| 12 $3 ~ /^L/ { alphav[alphac++] = $1; } | |
| 13 ($3 ~ /^Z/) || ($5 == "WS") || ($5 == "S") || ($5 == "B") { spacev[spac… | |
| 14 $3 == "Cc" { cntrlv[cntrlc++] = $1; } | |
| 15 $3 == "Lu" { upperv[upperc++] = $1; tolowerv[uppercc++] = ($14 == "") ? … | |
| 16 $3 == "Ll" { lowerv[lowerc++] = $1; toupperv[lowercc++] = ($13 == "") ? … | |
| 17 $3 == "Lt" { titlev[titlec++] = $1; } | |
| 18 $3 == "Nd" { digitv[digitc++] = $1; } | |
| 19 | |
| 20 END { | |
| 21 system("rm -f isalpharune.c isspacerune.c iscntrlrune.c upperrun… | |
| 22 | |
| 23 mkis("alpha", alphav, alphac, "isalpharune.c", q, ""); | |
| 24 mkis("space", spacev, spacec, "isspacerune.c", q, ""); | |
| 25 mkis("cntrl", cntrlv, cntrlc, "iscntrlrune.c", q, ""); | |
| 26 mkis("upper", upperv, upperc, "upperrune.c", tolowerv, "lower"… | |
| 27 mkis("lower", lowerv, lowerc, "lowerrune.c", toupperv, "upper"… | |
| 28 mkis("title", titlev, titlec, "istitlerune.c", q, ""); | |
| 29 mkis("digit", digitv, digitc, "isdigitrune.c", q, ""); | |
| 30 | |
| 31 system("rm -f isalnumrune.c isblankrune.c isprintrune.c isgraphr… | |
| 32 | |
| 33 otheris(); | |
| 34 } | |
| 35 | |
| 36 # parse hexadecimal rune index to int | |
| 37 function code(s) { | |
| 38 x = 0; | |
| 39 for(i = 1; i <= length(s); i++) { | |
| 40 c = substr(s, i, 1); | |
| 41 x = (x*16) + hex[c]; | |
| 42 } | |
| 43 return x; | |
| 44 } | |
| 45 | |
| 46 # generate 'is<name>rune' unicode lookup function | |
| 47 function mkis(name, runev, runec, file, casev, casename) { | |
| 48 rune1c = 0; | |
| 49 rune2c = 0; | |
| 50 rune3c = 0; | |
| 51 rune4c = 0; | |
| 52 mode = 1; | |
| 53 | |
| 54 #sort rune groups into singletons, ranges and laces | |
| 55 for(j = 0; j < runec; j++) { | |
| 56 # range | |
| 57 if(code(runev[j+1]) == code(runev[j])+1 && ((length(case… | |
| 58 code(casev[j+1]) == code(casev[j])+1) && j+1 < runec)… | |
| 59 if (mode == 2) { | |
| 60 continue; | |
| 61 } else if (mode == 3) { | |
| 62 rune3v1[rune3c] = runev[j]; | |
| 63 rune3c++; | |
| 64 } else if (mode == 4) { | |
| 65 rune4v1[rune4c] = runev[j]; | |
| 66 rune4c++; | |
| 67 } | |
| 68 mode = 2; | |
| 69 rune2v0[rune2c] = runev[j]; | |
| 70 if(length(casev) > 0) { | |
| 71 case2v[rune2c] = casev[j]; | |
| 72 } | |
| 73 continue; | |
| 74 } | |
| 75 # lace 1 | |
| 76 if(code(runev[j+1]) == code(runev[j])+2 && ((length(case… | |
| 77 (code(casev[j+1]) == code(runev[j+1])+1 && code(casev… | |
| 78 j+1 < runec) { | |
| 79 if (mode == 3) { | |
| 80 continue; | |
| 81 } else if (mode == 2) { | |
| 82 rune2v1[rune2c] = runev[j]; | |
| 83 rune2c++; | |
| 84 } else if (mode == 4) { | |
| 85 rune4v1[rune2c] = runev[j]; | |
| 86 rune4c++; | |
| 87 } | |
| 88 mode = 3; | |
| 89 rune3v0[rune3c] = runev[j]; | |
| 90 continue; | |
| 91 } | |
| 92 # lace 2 | |
| 93 if(code(runev[j+1]) == code(runev[j])+2 && ((length(case… | |
| 94 (code(casev[j+1]) == code(runev[j+1])-1 && code(casev… | |
| 95 j+1 < runec) { | |
| 96 if (mode == 4) { | |
| 97 continue; | |
| 98 } else if (mode == 2) { | |
| 99 rune2v1[rune2c] = runev[j]; | |
| 100 rune2c++; | |
| 101 } else if (mode == 3) { | |
| 102 rune3v1[rune2c] = runev[j]; | |
| 103 rune3c++; | |
| 104 } | |
| 105 mode = 4; | |
| 106 rune4v0[rune4c] = runev[j]; | |
| 107 continue; | |
| 108 } | |
| 109 # terminating case | |
| 110 if (mode == 1) { | |
| 111 rune1v[rune1c] = runev[j]; | |
| 112 if (length(casev) > 0) { | |
| 113 case1v[rune1c] = casev[j]; | |
| 114 } | |
| 115 rune1c++; | |
| 116 } else if (mode == 2) { | |
| 117 rune2v1[rune2c] = runev[j]; | |
| 118 rune2c++; | |
| 119 } else if (mode == 3) { | |
| 120 rune3v1[rune3c] = runev[j]; | |
| 121 rune3c++; | |
| 122 } else { #lace 2 | |
| 123 rune4v1[rune4c] = runev[j]; | |
| 124 rune4c++; | |
| 125 } | |
| 126 mode = 1; | |
| 127 } | |
| 128 print HEADER > file; | |
| 129 | |
| 130 #generate list of laces 1 | |
| 131 if(rune3c > 0) { | |
| 132 print "static const Rune "name"3[][2] = {" > file; | |
| 133 for(j = 0; j < rune3c; j++) { | |
| 134 print "\t{ 0x"rune3v0[j]", 0x"rune3v1[j]" }," > … | |
| 135 } | |
| 136 print "};\n" > file; | |
| 137 } | |
| 138 | |
| 139 #generate list of laces 2 | |
| 140 if(rune4c > 0) { | |
| 141 print "static const Rune "name"4[][2] = {" > file; | |
| 142 for(j = 0; j < rune4c; j++) { | |
| 143 print "\t{ 0x"rune4v0[j]", 0x"rune4v1[j]" }," > … | |
| 144 } | |
| 145 print "};\n" > file; | |
| 146 } | |
| 147 | |
| 148 # generate list of ranges | |
| 149 if(rune2c > 0) { | |
| 150 if(length(casev) > 0) { | |
| 151 print "static const Rune "name"2[][3] = {" > fil… | |
| 152 for(j = 0; j < rune2c; j++) { | |
| 153 print "\t{ 0x"rune2v0[j]", 0x"rune2v1[j]… | |
| 154 } | |
| 155 } else { | |
| 156 print "static const Rune "name"2[][2] = {" > file | |
| 157 for(j = 0; j < rune2c; j++) { | |
| 158 print "\t{ 0x"rune2v0[j]", 0x"rune2v1[j]… | |
| 159 } | |
| 160 } | |
| 161 print "};\n" > file; | |
| 162 } | |
| 163 | |
| 164 # generate list of singletons | |
| 165 if(rune1c > 0) { | |
| 166 if(length(casev) > 0) { | |
| 167 print "static const Rune "name"1[][2] = {" > fil… | |
| 168 for(j = 0; j < rune1c; j++) { | |
| 169 print "\t{ 0x"rune1v[j]", 0x"case1v[j]" … | |
| 170 } | |
| 171 } else { | |
| 172 print "static const Rune "name"1[] = {" > file; | |
| 173 for(j = 0; j < rune1c; j++) { | |
| 174 print "\t0x"rune1v[j]"," > file; | |
| 175 } | |
| 176 } | |
| 177 print "};\n" > file; | |
| 178 } | |
| 179 # generate lookup function | |
| 180 print "int\nis"name"rune(Rune r)\n{" > file; | |
| 181 if(rune4c > 0 || rune3c > 0) | |
| 182 print "\tconst Rune *match;\n" > file; | |
| 183 if(rune4c > 0) { | |
| 184 print "\tif((match = bsearch(&r, "name"4, nelem("name"4)… | |
| 185 print "\t\treturn !((r - match[0]) % 2);" > file; | |
| 186 } | |
| 187 if(rune3c > 0) { | |
| 188 print "\tif((match = bsearch(&r, "name"3, nelem("name"3)… | |
| 189 print "\t\treturn !((r - match[0]) % 2);" > file; | |
| 190 } | |
| 191 if(rune2c > 0) { | |
| 192 print "\tif(bsearch(&r, "name"2, nelem("name"2), sizeof … | |
| 193 } | |
| 194 if(rune1c > 0) { | |
| 195 print "\tif(bsearch(&r, "name"1, nelem("name"1), sizeof … | |
| 196 } | |
| 197 print "\treturn 0;\n}" > file; | |
| 198 | |
| 199 # generate case conversion function | |
| 200 if(length(casev) > 0) { | |
| 201 print "\nint\nto"casename"rune(Rune r)\n{\n\tRune *match… | |
| 202 if(rune4c > 0) { | |
| 203 print "\tmatch = bsearch(&r, "name"4, nelem("nam… | |
| 204 print "\tif (match)" > file; | |
| 205 print "\t\treturn ((r - match[0]) % 2) ? r : r -… | |
| 206 } | |
| 207 if(rune3c > 0) { | |
| 208 print "\tmatch = bsearch(&r, "name"3, nelem("nam… | |
| 209 print "\tif (match)" > file; | |
| 210 print "\t\treturn ((r - match[0]) % 2) ? r : r +… | |
| 211 } | |
| 212 if(rune2c > 0) { | |
| 213 print "\tmatch = bsearch(&r, "name"2, nelem("nam… | |
| 214 print "\tif (match)" > file; | |
| 215 print "\t\treturn match[2] + (r - match[0]);" > … | |
| 216 } | |
| 217 if(rune1c > 0) { | |
| 218 print "\tmatch = bsearch(&r, "name"1, nelem("nam… | |
| 219 print "\tif (match)" > file; | |
| 220 print "\t\treturn match[1];" > file; | |
| 221 } | |
| 222 print "\treturn r;\n}" > file; | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 function otheris() { | |
| 227 print HEADER_OTHER > "isalnumrune.c"; | |
| 228 print "int\nisalnumrune(Rune r)\n{\n\treturn isalpharune(r) || i… | |
| 229 print HEADER_OTHER > "isblankrune.c"; | |
| 230 print "int\nisblankrune(Rune r)\n{\n\treturn r == ' ' || r == '\… | |
| 231 print HEADER_OTHER > "isprintrune.c"; | |
| 232 print "int\nisprintrune(Rune r)\n{\n\treturn !iscntrlrune(r) && … | |
| 233 print "\t ((r < 0xFFF9) || (r > 0xFFFB));\n}" > "isprintru… | |
| 234 print HEADER_OTHER > "isgraphrune.c"; | |
| 235 print "int\nisgraphrune(Rune r)\n{\n\treturn !isspacerune(r) && … | |
| 236 print HEADER_OTHER > "ispunctrune.c"; | |
| 237 print "int\nispunctrune(Rune r)\n{\n\treturn isgraphrune(r) && !… | |
| 238 print HEADER_OTHER > "isxdigitrune.c"; | |
| 239 print "int\nisxdigitrune(Rune r)\n{\n\treturn (r >= '0' && (r - … | |
| 240 } |