libunicode.c 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124
  1. /*
  2. * Unicode utilities
  3. *
  4. * Copyright (c) 2017-2018 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include "cutils.h"
  30. #include "libunicode.h"
  31. #include "libunicode-table.h"
  32. enum {
  33. RUN_TYPE_U,
  34. RUN_TYPE_L,
  35. RUN_TYPE_UF,
  36. RUN_TYPE_LF,
  37. RUN_TYPE_UL,
  38. RUN_TYPE_LSU,
  39. RUN_TYPE_U2L_399_EXT2,
  40. RUN_TYPE_UF_D20,
  41. RUN_TYPE_UF_D1_EXT,
  42. RUN_TYPE_U_EXT,
  43. RUN_TYPE_LF_EXT,
  44. RUN_TYPE_UF_EXT2,
  45. RUN_TYPE_LF_EXT2,
  46. RUN_TYPE_UF_EXT3,
  47. };
  48. static int lre_case_conv1(uint32_t c, int conv_type)
  49. {
  50. uint32_t res[LRE_CC_RES_LEN_MAX];
  51. lre_case_conv(res, c, conv_type);
  52. return res[0];
  53. }
  54. /* case conversion using the table entry 'idx' with value 'v' */
  55. static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_t idx, uint32_t v)
  56. {
  57. uint32_t code, data, type, a, is_lower;
  58. is_lower = (conv_type != 0);
  59. type = (v >> (32 - 17 - 7 - 4)) & 0xf;
  60. data = ((v & 0xf) << 8) | case_conv_table2[idx];
  61. code = v >> (32 - 17);
  62. switch(type) {
  63. case RUN_TYPE_U:
  64. case RUN_TYPE_L:
  65. case RUN_TYPE_UF:
  66. case RUN_TYPE_LF:
  67. if (conv_type == (type & 1) ||
  68. (type >= RUN_TYPE_UF && conv_type == 2)) {
  69. c = c - code + (case_conv_table1[data] >> (32 - 17));
  70. }
  71. break;
  72. case RUN_TYPE_UL:
  73. a = c - code;
  74. if ((a & 1) != (1 - is_lower))
  75. break;
  76. c = (a ^ 1) + code;
  77. break;
  78. case RUN_TYPE_LSU:
  79. a = c - code;
  80. if (a == 1) {
  81. c += 2 * is_lower - 1;
  82. } else if (a == (1 - is_lower) * 2) {
  83. c += (2 * is_lower - 1) * 2;
  84. }
  85. break;
  86. case RUN_TYPE_U2L_399_EXT2:
  87. if (!is_lower) {
  88. res[0] = c - code + case_conv_ext[data >> 6];
  89. res[1] = 0x399;
  90. return 2;
  91. } else {
  92. c = c - code + case_conv_ext[data & 0x3f];
  93. }
  94. break;
  95. case RUN_TYPE_UF_D20:
  96. if (conv_type == 1)
  97. break;
  98. c = data + (conv_type == 2) * 0x20;
  99. break;
  100. case RUN_TYPE_UF_D1_EXT:
  101. if (conv_type == 1)
  102. break;
  103. c = case_conv_ext[data] + (conv_type == 2);
  104. break;
  105. case RUN_TYPE_U_EXT:
  106. case RUN_TYPE_LF_EXT:
  107. if (is_lower != (type - RUN_TYPE_U_EXT))
  108. break;
  109. c = case_conv_ext[data];
  110. break;
  111. case RUN_TYPE_LF_EXT2:
  112. if (!is_lower)
  113. break;
  114. res[0] = c - code + case_conv_ext[data >> 6];
  115. res[1] = case_conv_ext[data & 0x3f];
  116. return 2;
  117. case RUN_TYPE_UF_EXT2:
  118. if (conv_type == 1)
  119. break;
  120. res[0] = c - code + case_conv_ext[data >> 6];
  121. res[1] = case_conv_ext[data & 0x3f];
  122. if (conv_type == 2) {
  123. /* convert to lower */
  124. res[0] = lre_case_conv1(res[0], 1);
  125. res[1] = lre_case_conv1(res[1], 1);
  126. }
  127. return 2;
  128. default:
  129. case RUN_TYPE_UF_EXT3:
  130. if (conv_type == 1)
  131. break;
  132. res[0] = case_conv_ext[data >> 8];
  133. res[1] = case_conv_ext[(data >> 4) & 0xf];
  134. res[2] = case_conv_ext[data & 0xf];
  135. if (conv_type == 2) {
  136. /* convert to lower */
  137. res[0] = lre_case_conv1(res[0], 1);
  138. res[1] = lre_case_conv1(res[1], 1);
  139. res[2] = lre_case_conv1(res[2], 1);
  140. }
  141. return 3;
  142. }
  143. res[0] = c;
  144. return 1;
  145. }
  146. /* conv_type:
  147. 0 = to upper
  148. 1 = to lower
  149. 2 = case folding (= to lower with modifications)
  150. */
  151. int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
  152. {
  153. if (c < 128) {
  154. if (conv_type) {
  155. if (c >= 'A' && c <= 'Z') {
  156. c = c - 'A' + 'a';
  157. }
  158. } else {
  159. if (c >= 'a' && c <= 'z') {
  160. c = c - 'a' + 'A';
  161. }
  162. }
  163. } else {
  164. uint32_t v, code, len;
  165. int idx, idx_min, idx_max;
  166. idx_min = 0;
  167. idx_max = countof(case_conv_table1) - 1;
  168. while (idx_min <= idx_max) {
  169. idx = (unsigned)(idx_max + idx_min) / 2;
  170. v = case_conv_table1[idx];
  171. code = v >> (32 - 17);
  172. len = (v >> (32 - 17 - 7)) & 0x7f;
  173. if (c < code) {
  174. idx_max = idx - 1;
  175. } else if (c >= code + len) {
  176. idx_min = idx + 1;
  177. } else {
  178. return lre_case_conv_entry(res, c, conv_type, idx, v);
  179. }
  180. }
  181. }
  182. res[0] = c;
  183. return 1;
  184. }
  185. static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_unicode)
  186. {
  187. uint32_t res[LRE_CC_RES_LEN_MAX];
  188. int len;
  189. if (is_unicode) {
  190. len = lre_case_conv_entry(res, c, 2, idx, v);
  191. if (len == 1) {
  192. c = res[0];
  193. } else {
  194. /* handle the few specific multi-character cases (see
  195. unicode_gen.c:dump_case_folding_special_cases()) */
  196. if (c == 0xfb06) {
  197. c = 0xfb05;
  198. } else if (c == 0x01fd3) {
  199. c = 0x390;
  200. } else if (c == 0x01fe3) {
  201. c = 0x3b0;
  202. }
  203. }
  204. } else {
  205. if (likely(c < 128)) {
  206. if (c >= 'a' && c <= 'z')
  207. c = c - 'a' + 'A';
  208. } else {
  209. /* legacy regexp: to upper case if single char >= 128 */
  210. len = lre_case_conv_entry(res, c, FALSE, idx, v);
  211. if (len == 1 && res[0] >= 128)
  212. c = res[0];
  213. }
  214. }
  215. return c;
  216. }
  217. /* JS regexp specific rules for case folding */
  218. int lre_canonicalize(uint32_t c, BOOL is_unicode)
  219. {
  220. if (c < 128) {
  221. /* fast case */
  222. if (is_unicode) {
  223. if (c >= 'A' && c <= 'Z') {
  224. c = c - 'A' + 'a';
  225. }
  226. } else {
  227. if (c >= 'a' && c <= 'z') {
  228. c = c - 'a' + 'A';
  229. }
  230. }
  231. } else {
  232. uint32_t v, code, len;
  233. int idx, idx_min, idx_max;
  234. idx_min = 0;
  235. idx_max = countof(case_conv_table1) - 1;
  236. while (idx_min <= idx_max) {
  237. idx = (unsigned)(idx_max + idx_min) / 2;
  238. v = case_conv_table1[idx];
  239. code = v >> (32 - 17);
  240. len = (v >> (32 - 17 - 7)) & 0x7f;
  241. if (c < code) {
  242. idx_max = idx - 1;
  243. } else if (c >= code + len) {
  244. idx_min = idx + 1;
  245. } else {
  246. return lre_case_folding_entry(c, idx, v, is_unicode);
  247. }
  248. }
  249. }
  250. return c;
  251. }
  252. static uint32_t get_le24(const uint8_t *ptr)
  253. {
  254. return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
  255. }
  256. #define UNICODE_INDEX_BLOCK_LEN 32
  257. /* return -1 if not in table, otherwise the offset in the block */
  258. static int get_index_pos(uint32_t *pcode, uint32_t c,
  259. const uint8_t *index_table, int index_table_len)
  260. {
  261. uint32_t code, v;
  262. int idx_min, idx_max, idx;
  263. idx_min = 0;
  264. v = get_le24(index_table);
  265. code = v & ((1 << 21) - 1);
  266. if (c < code) {
  267. *pcode = 0;
  268. return 0;
  269. }
  270. idx_max = index_table_len - 1;
  271. code = get_le24(index_table + idx_max * 3);
  272. if (c >= code)
  273. return -1;
  274. /* invariant: tab[idx_min] <= c < tab2[idx_max] */
  275. while ((idx_max - idx_min) > 1) {
  276. idx = (idx_max + idx_min) / 2;
  277. v = get_le24(index_table + idx * 3);
  278. code = v & ((1 << 21) - 1);
  279. if (c < code) {
  280. idx_max = idx;
  281. } else {
  282. idx_min = idx;
  283. }
  284. }
  285. v = get_le24(index_table + idx_min * 3);
  286. *pcode = v & ((1 << 21) - 1);
  287. return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21);
  288. }
  289. static BOOL lre_is_in_table(uint32_t c, const uint8_t *table,
  290. const uint8_t *index_table, int index_table_len)
  291. {
  292. uint32_t code, b, bit;
  293. int pos;
  294. const uint8_t *p;
  295. pos = get_index_pos(&code, c, index_table, index_table_len);
  296. if (pos < 0)
  297. return FALSE; /* outside the table */
  298. p = table + pos;
  299. bit = 0;
  300. /* Compressed run length encoding:
  301. 00..3F: 2 packed lengths: 3-bit + 3-bit
  302. 40..5F: 5-bits plus extra byte for length
  303. 60..7F: 5-bits plus 2 extra bytes for length
  304. 80..FF: 7-bit length
  305. lengths must be incremented to get character count
  306. Ranges alternate between false and true return value.
  307. */
  308. for(;;) {
  309. b = *p++;
  310. if (b < 64) {
  311. code += (b >> 3) + 1;
  312. if (c < code)
  313. return bit;
  314. bit ^= 1;
  315. code += (b & 7) + 1;
  316. } else if (b >= 0x80) {
  317. code += b - 0x80 + 1;
  318. } else if (b < 0x60) {
  319. code += (((b - 0x40) << 8) | p[0]) + 1;
  320. p++;
  321. } else {
  322. code += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1;
  323. p += 2;
  324. }
  325. if (c < code)
  326. return bit;
  327. bit ^= 1;
  328. }
  329. }
  330. BOOL lre_is_cased(uint32_t c)
  331. {
  332. uint32_t v, code, len;
  333. int idx, idx_min, idx_max;
  334. idx_min = 0;
  335. idx_max = countof(case_conv_table1) - 1;
  336. while (idx_min <= idx_max) {
  337. idx = (unsigned)(idx_max + idx_min) / 2;
  338. v = case_conv_table1[idx];
  339. code = v >> (32 - 17);
  340. len = (v >> (32 - 17 - 7)) & 0x7f;
  341. if (c < code) {
  342. idx_max = idx - 1;
  343. } else if (c >= code + len) {
  344. idx_min = idx + 1;
  345. } else {
  346. return TRUE;
  347. }
  348. }
  349. return lre_is_in_table(c, unicode_prop_Cased1_table,
  350. unicode_prop_Cased1_index,
  351. sizeof(unicode_prop_Cased1_index) / 3);
  352. }
  353. BOOL lre_is_case_ignorable(uint32_t c)
  354. {
  355. return lre_is_in_table(c, unicode_prop_Case_Ignorable_table,
  356. unicode_prop_Case_Ignorable_index,
  357. sizeof(unicode_prop_Case_Ignorable_index) / 3);
  358. }
  359. /* character range */
  360. static __maybe_unused void cr_dump(CharRange *cr)
  361. {
  362. int i;
  363. for(i = 0; i < cr->len; i++)
  364. printf("%d: 0x%04x\n", i, cr->points[i]);
  365. }
  366. static void *cr_default_realloc(void *opaque, void *ptr, size_t size)
  367. {
  368. return realloc(ptr, size);
  369. }
  370. void cr_init(CharRange *cr, void *mem_opaque, DynBufReallocFunc *realloc_func)
  371. {
  372. cr->len = cr->size = 0;
  373. cr->points = NULL;
  374. cr->mem_opaque = mem_opaque;
  375. cr->realloc_func = realloc_func ? realloc_func : cr_default_realloc;
  376. }
  377. void cr_free(CharRange *cr)
  378. {
  379. cr->realloc_func(cr->mem_opaque, cr->points, 0);
  380. }
  381. int cr_realloc(CharRange *cr, int size)
  382. {
  383. int new_size;
  384. uint32_t *new_buf;
  385. if (size > cr->size) {
  386. new_size = max_int(size, cr->size * 3 / 2);
  387. new_buf = cr->realloc_func(cr->mem_opaque, cr->points,
  388. new_size * sizeof(cr->points[0]));
  389. if (!new_buf)
  390. return -1;
  391. cr->points = new_buf;
  392. cr->size = new_size;
  393. }
  394. return 0;
  395. }
  396. int cr_copy(CharRange *cr, const CharRange *cr1)
  397. {
  398. if (cr_realloc(cr, cr1->len))
  399. return -1;
  400. memcpy(cr->points, cr1->points, sizeof(cr->points[0]) * cr1->len);
  401. cr->len = cr1->len;
  402. return 0;
  403. }
  404. /* merge consecutive intervals and remove empty intervals */
  405. static void cr_compress(CharRange *cr)
  406. {
  407. int i, j, k, len;
  408. uint32_t *pt;
  409. pt = cr->points;
  410. len = cr->len;
  411. i = 0;
  412. j = 0;
  413. k = 0;
  414. while ((i + 1) < len) {
  415. if (pt[i] == pt[i + 1]) {
  416. /* empty interval */
  417. i += 2;
  418. } else {
  419. j = i;
  420. while ((j + 3) < len && pt[j + 1] == pt[j + 2])
  421. j += 2;
  422. /* just copy */
  423. pt[k] = pt[i];
  424. pt[k + 1] = pt[j + 1];
  425. k += 2;
  426. i = j + 2;
  427. }
  428. }
  429. cr->len = k;
  430. }
  431. /* union or intersection */
  432. int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
  433. const uint32_t *b_pt, int b_len, int op)
  434. {
  435. int a_idx, b_idx, is_in;
  436. uint32_t v;
  437. a_idx = 0;
  438. b_idx = 0;
  439. for(;;) {
  440. /* get one more point from a or b in increasing order */
  441. if (a_idx < a_len && b_idx < b_len) {
  442. if (a_pt[a_idx] < b_pt[b_idx]) {
  443. goto a_add;
  444. } else if (a_pt[a_idx] == b_pt[b_idx]) {
  445. v = a_pt[a_idx];
  446. a_idx++;
  447. b_idx++;
  448. } else {
  449. goto b_add;
  450. }
  451. } else if (a_idx < a_len) {
  452. a_add:
  453. v = a_pt[a_idx++];
  454. } else if (b_idx < b_len) {
  455. b_add:
  456. v = b_pt[b_idx++];
  457. } else {
  458. break;
  459. }
  460. /* add the point if the in/out status changes */
  461. switch(op) {
  462. case CR_OP_UNION:
  463. is_in = (a_idx & 1) | (b_idx & 1);
  464. break;
  465. case CR_OP_INTER:
  466. is_in = (a_idx & 1) & (b_idx & 1);
  467. break;
  468. case CR_OP_XOR:
  469. is_in = (a_idx & 1) ^ (b_idx & 1);
  470. break;
  471. case CR_OP_SUB:
  472. is_in = (a_idx & 1) & ((b_idx & 1) ^ 1);
  473. break;
  474. default:
  475. abort();
  476. }
  477. if (is_in != (cr->len & 1)) {
  478. if (cr_add_point(cr, v))
  479. return -1;
  480. }
  481. }
  482. cr_compress(cr);
  483. return 0;
  484. }
  485. int cr_op1(CharRange *cr, const uint32_t *b_pt, int b_len, int op)
  486. {
  487. CharRange a = *cr;
  488. int ret;
  489. cr->len = 0;
  490. cr->size = 0;
  491. cr->points = NULL;
  492. ret = cr_op(cr, a.points, a.len, b_pt, b_len, op);
  493. cr_free(&a);
  494. return ret;
  495. }
  496. int cr_invert(CharRange *cr)
  497. {
  498. int len;
  499. len = cr->len;
  500. if (cr_realloc(cr, len + 2))
  501. return -1;
  502. memmove(cr->points + 1, cr->points, len * sizeof(cr->points[0]));
  503. cr->points[0] = 0;
  504. cr->points[len + 1] = UINT32_MAX;
  505. cr->len = len + 2;
  506. cr_compress(cr);
  507. return 0;
  508. }
  509. #define CASE_U (1 << 0)
  510. #define CASE_L (1 << 1)
  511. #define CASE_F (1 << 2)
  512. /* use the case conversion table to generate range of characters.
  513. CASE_U: set char if modified by uppercasing,
  514. CASE_L: set char if modified by lowercasing,
  515. CASE_F: set char if modified by case folding,
  516. */
  517. static int unicode_case1(CharRange *cr, int case_mask)
  518. {
  519. #define MR(x) (1 << RUN_TYPE_ ## x)
  520. const uint32_t tab_run_mask[3] = {
  521. MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) |
  522. MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
  523. MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2),
  524. MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
  525. };
  526. #undef MR
  527. uint32_t mask, v, code, type, len, i, idx;
  528. if (case_mask == 0)
  529. return 0;
  530. mask = 0;
  531. for(i = 0; i < 3; i++) {
  532. if ((case_mask >> i) & 1)
  533. mask |= tab_run_mask[i];
  534. }
  535. for(idx = 0; idx < countof(case_conv_table1); idx++) {
  536. v = case_conv_table1[idx];
  537. type = (v >> (32 - 17 - 7 - 4)) & 0xf;
  538. code = v >> (32 - 17);
  539. len = (v >> (32 - 17 - 7)) & 0x7f;
  540. if ((mask >> type) & 1) {
  541. // printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1);
  542. switch(type) {
  543. case RUN_TYPE_UL:
  544. if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
  545. goto def_case;
  546. code += ((case_mask & CASE_U) != 0);
  547. for(i = 0; i < len; i += 2) {
  548. if (cr_add_interval(cr, code + i, code + i + 1))
  549. return -1;
  550. }
  551. break;
  552. case RUN_TYPE_LSU:
  553. if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
  554. goto def_case;
  555. if (!(case_mask & CASE_U)) {
  556. if (cr_add_interval(cr, code, code + 1))
  557. return -1;
  558. }
  559. if (cr_add_interval(cr, code + 1, code + 2))
  560. return -1;
  561. if (case_mask & CASE_U) {
  562. if (cr_add_interval(cr, code + 2, code + 3))
  563. return -1;
  564. }
  565. break;
  566. default:
  567. def_case:
  568. if (cr_add_interval(cr, code, code + len))
  569. return -1;
  570. break;
  571. }
  572. }
  573. }
  574. return 0;
  575. }
  576. static int point_cmp(const void *p1, const void *p2, void *arg)
  577. {
  578. uint32_t v1 = *(uint32_t *)p1;
  579. uint32_t v2 = *(uint32_t *)p2;
  580. return (v1 > v2) - (v1 < v2);
  581. }
  582. static void cr_sort_and_remove_overlap(CharRange *cr)
  583. {
  584. uint32_t start, end, start1, end1, i, j;
  585. /* the resulting ranges are not necessarily sorted and may overlap */
  586. rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL);
  587. j = 0;
  588. for(i = 0; i < cr->len; ) {
  589. start = cr->points[i];
  590. end = cr->points[i + 1];
  591. i += 2;
  592. while (i < cr->len) {
  593. start1 = cr->points[i];
  594. end1 = cr->points[i + 1];
  595. if (start1 > end) {
  596. /* |------|
  597. * |-------| */
  598. break;
  599. } else if (end1 <= end) {
  600. /* |------|
  601. * |--| */
  602. i += 2;
  603. } else {
  604. /* |------|
  605. * |-------| */
  606. end = end1;
  607. i += 2;
  608. }
  609. }
  610. cr->points[j] = start;
  611. cr->points[j + 1] = end;
  612. j += 2;
  613. }
  614. cr->len = j;
  615. }
  616. /* canonicalize a character set using the JS regex case folding rules
  617. (see lre_canonicalize()) */
  618. int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode)
  619. {
  620. CharRange cr_inter, cr_mask, cr_result, cr_sub;
  621. uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d;
  622. cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func);
  623. cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func);
  624. cr_init(&cr_result, cr->mem_opaque, cr->realloc_func);
  625. cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func);
  626. if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U))
  627. goto fail;
  628. if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
  629. goto fail;
  630. if (cr_invert(&cr_mask))
  631. goto fail;
  632. if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
  633. goto fail;
  634. /* cr_inter = cr & cr_mask */
  635. /* cr_sub = cr & ~cr_mask */
  636. /* use the case conversion table to compute the result */
  637. d_start = -1;
  638. d_end = -1;
  639. idx = 0;
  640. v = case_conv_table1[idx];
  641. code = v >> (32 - 17);
  642. len = (v >> (32 - 17 - 7)) & 0x7f;
  643. for(i = 0; i < cr_inter.len; i += 2) {
  644. start = cr_inter.points[i];
  645. end = cr_inter.points[i + 1];
  646. for(c = start; c < end; c++) {
  647. for(;;) {
  648. if (c >= code && c < code + len)
  649. break;
  650. idx++;
  651. assert(idx < countof(case_conv_table1));
  652. v = case_conv_table1[idx];
  653. code = v >> (32 - 17);
  654. len = (v >> (32 - 17 - 7)) & 0x7f;
  655. }
  656. d = lre_case_folding_entry(c, idx, v, is_unicode);
  657. /* try to merge with the current interval */
  658. if (d_start == -1) {
  659. d_start = d;
  660. d_end = d + 1;
  661. } else if (d_end == d) {
  662. d_end++;
  663. } else {
  664. cr_add_interval(&cr_result, d_start, d_end);
  665. d_start = d;
  666. d_end = d + 1;
  667. }
  668. }
  669. }
  670. if (d_start != -1) {
  671. if (cr_add_interval(&cr_result, d_start, d_end))
  672. goto fail;
  673. }
  674. /* the resulting ranges are not necessarily sorted and may overlap */
  675. cr_sort_and_remove_overlap(&cr_result);
  676. /* or with the character not affected by the case folding */
  677. cr->len = 0;
  678. if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION))
  679. goto fail;
  680. cr_free(&cr_inter);
  681. cr_free(&cr_mask);
  682. cr_free(&cr_result);
  683. cr_free(&cr_sub);
  684. return 0;
  685. fail:
  686. cr_free(&cr_inter);
  687. cr_free(&cr_mask);
  688. cr_free(&cr_result);
  689. cr_free(&cr_sub);
  690. return -1;
  691. }
  692. #ifdef CONFIG_ALL_UNICODE
  693. BOOL lre_is_id_start(uint32_t c)
  694. {
  695. return lre_is_in_table(c, unicode_prop_ID_Start_table,
  696. unicode_prop_ID_Start_index,
  697. sizeof(unicode_prop_ID_Start_index) / 3);
  698. }
  699. BOOL lre_is_id_continue(uint32_t c)
  700. {
  701. return lre_is_id_start(c) ||
  702. lre_is_in_table(c, unicode_prop_ID_Continue1_table,
  703. unicode_prop_ID_Continue1_index,
  704. sizeof(unicode_prop_ID_Continue1_index) / 3);
  705. }
  706. #define UNICODE_DECOMP_LEN_MAX 18
  707. typedef enum {
  708. DECOMP_TYPE_C1, /* 16 bit char */
  709. DECOMP_TYPE_L1, /* 16 bit char table */
  710. DECOMP_TYPE_L2,
  711. DECOMP_TYPE_L3,
  712. DECOMP_TYPE_L4,
  713. DECOMP_TYPE_L5, /* XXX: not used */
  714. DECOMP_TYPE_L6, /* XXX: could remove */
  715. DECOMP_TYPE_L7, /* XXX: could remove */
  716. DECOMP_TYPE_LL1, /* 18 bit char table */
  717. DECOMP_TYPE_LL2,
  718. DECOMP_TYPE_S1, /* 8 bit char table */
  719. DECOMP_TYPE_S2,
  720. DECOMP_TYPE_S3,
  721. DECOMP_TYPE_S4,
  722. DECOMP_TYPE_S5,
  723. DECOMP_TYPE_I1, /* increment 16 bit char value */
  724. DECOMP_TYPE_I2_0,
  725. DECOMP_TYPE_I2_1,
  726. DECOMP_TYPE_I3_1,
  727. DECOMP_TYPE_I3_2,
  728. DECOMP_TYPE_I4_1,
  729. DECOMP_TYPE_I4_2,
  730. DECOMP_TYPE_B1, /* 16 bit base + 8 bit offset */
  731. DECOMP_TYPE_B2,
  732. DECOMP_TYPE_B3,
  733. DECOMP_TYPE_B4,
  734. DECOMP_TYPE_B5,
  735. DECOMP_TYPE_B6,
  736. DECOMP_TYPE_B7,
  737. DECOMP_TYPE_B8,
  738. DECOMP_TYPE_B18,
  739. DECOMP_TYPE_LS2,
  740. DECOMP_TYPE_PAT3,
  741. DECOMP_TYPE_S2_UL,
  742. DECOMP_TYPE_LS2_UL,
  743. } DecompTypeEnum;
  744. static uint32_t unicode_get_short_code(uint32_t c)
  745. {
  746. static const uint16_t unicode_short_table[2] = { 0x2044, 0x2215 };
  747. if (c < 0x80)
  748. return c;
  749. else if (c < 0x80 + 0x50)
  750. return c - 0x80 + 0x300;
  751. else
  752. return unicode_short_table[c - 0x80 - 0x50];
  753. }
  754. static uint32_t unicode_get_lower_simple(uint32_t c)
  755. {
  756. if (c < 0x100 || (c >= 0x410 && c <= 0x42f))
  757. c += 0x20;
  758. else
  759. c++;
  760. return c;
  761. }
  762. static uint16_t unicode_get16(const uint8_t *p)
  763. {
  764. return p[0] | (p[1] << 8);
  765. }
  766. static int unicode_decomp_entry(uint32_t *res, uint32_t c,
  767. int idx, uint32_t code, uint32_t len,
  768. uint32_t type)
  769. {
  770. uint32_t c1;
  771. int l, i, p;
  772. const uint8_t *d;
  773. if (type == DECOMP_TYPE_C1) {
  774. res[0] = unicode_decomp_table2[idx];
  775. return 1;
  776. } else {
  777. d = unicode_decomp_data + unicode_decomp_table2[idx];
  778. switch(type) {
  779. case DECOMP_TYPE_L1:
  780. case DECOMP_TYPE_L2:
  781. case DECOMP_TYPE_L3:
  782. case DECOMP_TYPE_L4:
  783. case DECOMP_TYPE_L5:
  784. case DECOMP_TYPE_L6:
  785. case DECOMP_TYPE_L7:
  786. l = type - DECOMP_TYPE_L1 + 1;
  787. d += (c - code) * l * 2;
  788. for(i = 0; i < l; i++) {
  789. if ((res[i] = unicode_get16(d + 2 * i)) == 0)
  790. return 0;
  791. }
  792. return l;
  793. case DECOMP_TYPE_LL1:
  794. case DECOMP_TYPE_LL2:
  795. {
  796. uint32_t k, p;
  797. l = type - DECOMP_TYPE_LL1 + 1;
  798. k = (c - code) * l;
  799. p = len * l * 2;
  800. for(i = 0; i < l; i++) {
  801. c1 = unicode_get16(d + 2 * k) |
  802. (((d[p + (k / 4)] >> ((k % 4) * 2)) & 3) << 16);
  803. if (!c1)
  804. return 0;
  805. res[i] = c1;
  806. k++;
  807. }
  808. }
  809. return l;
  810. case DECOMP_TYPE_S1:
  811. case DECOMP_TYPE_S2:
  812. case DECOMP_TYPE_S3:
  813. case DECOMP_TYPE_S4:
  814. case DECOMP_TYPE_S5:
  815. l = type - DECOMP_TYPE_S1 + 1;
  816. d += (c - code) * l;
  817. for(i = 0; i < l; i++) {
  818. if ((res[i] = unicode_get_short_code(d[i])) == 0)
  819. return 0;
  820. }
  821. return l;
  822. case DECOMP_TYPE_I1:
  823. l = 1;
  824. p = 0;
  825. goto decomp_type_i;
  826. case DECOMP_TYPE_I2_0:
  827. case DECOMP_TYPE_I2_1:
  828. case DECOMP_TYPE_I3_1:
  829. case DECOMP_TYPE_I3_2:
  830. case DECOMP_TYPE_I4_1:
  831. case DECOMP_TYPE_I4_2:
  832. l = 2 + ((type - DECOMP_TYPE_I2_0) >> 1);
  833. p = ((type - DECOMP_TYPE_I2_0) & 1) + (l > 2);
  834. decomp_type_i:
  835. for(i = 0; i < l; i++) {
  836. c1 = unicode_get16(d + 2 * i);
  837. if (i == p)
  838. c1 += c - code;
  839. res[i] = c1;
  840. }
  841. return l;
  842. case DECOMP_TYPE_B18:
  843. l = 18;
  844. goto decomp_type_b;
  845. case DECOMP_TYPE_B1:
  846. case DECOMP_TYPE_B2:
  847. case DECOMP_TYPE_B3:
  848. case DECOMP_TYPE_B4:
  849. case DECOMP_TYPE_B5:
  850. case DECOMP_TYPE_B6:
  851. case DECOMP_TYPE_B7:
  852. case DECOMP_TYPE_B8:
  853. l = type - DECOMP_TYPE_B1 + 1;
  854. decomp_type_b:
  855. {
  856. uint32_t c_min;
  857. c_min = unicode_get16(d);
  858. d += 2 + (c - code) * l;
  859. for(i = 0; i < l; i++) {
  860. c1 = d[i];
  861. if (c1 == 0xff)
  862. c1 = 0x20;
  863. else
  864. c1 += c_min;
  865. res[i] = c1;
  866. }
  867. }
  868. return l;
  869. case DECOMP_TYPE_LS2:
  870. d += (c - code) * 3;
  871. if (!(res[0] = unicode_get16(d)))
  872. return 0;
  873. res[1] = unicode_get_short_code(d[2]);
  874. return 2;
  875. case DECOMP_TYPE_PAT3:
  876. res[0] = unicode_get16(d);
  877. res[2] = unicode_get16(d + 2);
  878. d += 4 + (c - code) * 2;
  879. res[1] = unicode_get16(d);
  880. return 3;
  881. case DECOMP_TYPE_S2_UL:
  882. case DECOMP_TYPE_LS2_UL:
  883. c1 = c - code;
  884. if (type == DECOMP_TYPE_S2_UL) {
  885. d += c1 & ~1;
  886. c = unicode_get_short_code(*d);
  887. d++;
  888. } else {
  889. d += (c1 >> 1) * 3;
  890. c = unicode_get16(d);
  891. d += 2;
  892. }
  893. if (c1 & 1)
  894. c = unicode_get_lower_simple(c);
  895. res[0] = c;
  896. res[1] = unicode_get_short_code(*d);
  897. return 2;
  898. }
  899. }
  900. return 0;
  901. }
  902. /* return the length of the decomposition (length <=
  903. UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */
  904. static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1)
  905. {
  906. uint32_t v, type, is_compat, code, len;
  907. int idx_min, idx_max, idx;
  908. idx_min = 0;
  909. idx_max = countof(unicode_decomp_table1) - 1;
  910. while (idx_min <= idx_max) {
  911. idx = (idx_max + idx_min) / 2;
  912. v = unicode_decomp_table1[idx];
  913. code = v >> (32 - 18);
  914. len = (v >> (32 - 18 - 7)) & 0x7f;
  915. // printf("idx=%d code=%05x len=%d\n", idx, code, len);
  916. if (c < code) {
  917. idx_max = idx - 1;
  918. } else if (c >= code + len) {
  919. idx_min = idx + 1;
  920. } else {
  921. is_compat = v & 1;
  922. if (is_compat1 < is_compat)
  923. break;
  924. type = (v >> (32 - 18 - 7 - 6)) & 0x3f;
  925. return unicode_decomp_entry(res, c, idx, code, len, type);
  926. }
  927. }
  928. return 0;
  929. }
  930. /* return 0 if no pair found */
  931. static int unicode_compose_pair(uint32_t c0, uint32_t c1)
  932. {
  933. uint32_t code, len, type, v, idx1, d_idx, d_offset, ch;
  934. int idx_min, idx_max, idx, d;
  935. uint32_t pair[2];
  936. idx_min = 0;
  937. idx_max = countof(unicode_comp_table) - 1;
  938. while (idx_min <= idx_max) {
  939. idx = (idx_max + idx_min) / 2;
  940. idx1 = unicode_comp_table[idx];
  941. /* idx1 represent an entry of the decomposition table */
  942. d_idx = idx1 >> 6;
  943. d_offset = idx1 & 0x3f;
  944. v = unicode_decomp_table1[d_idx];
  945. code = v >> (32 - 18);
  946. len = (v >> (32 - 18 - 7)) & 0x7f;
  947. type = (v >> (32 - 18 - 7 - 6)) & 0x3f;
  948. ch = code + d_offset;
  949. unicode_decomp_entry(pair, ch, d_idx, code, len, type);
  950. d = c0 - pair[0];
  951. if (d == 0)
  952. d = c1 - pair[1];
  953. if (d < 0) {
  954. idx_max = idx - 1;
  955. } else if (d > 0) {
  956. idx_min = idx + 1;
  957. } else {
  958. return ch;
  959. }
  960. }
  961. return 0;
  962. }
  963. /* return the combining class of character c (between 0 and 255) */
  964. static int unicode_get_cc(uint32_t c)
  965. {
  966. uint32_t code, n, type, cc, c1, b;
  967. int pos;
  968. const uint8_t *p;
  969. pos = get_index_pos(&code, c,
  970. unicode_cc_index, sizeof(unicode_cc_index) / 3);
  971. if (pos < 0)
  972. return 0;
  973. p = unicode_cc_table + pos;
  974. /* Compressed run length encoding:
  975. - 2 high order bits are combining class type
  976. - 0:0, 1:230, 2:extra byte linear progression, 3:extra byte
  977. - 00..2F: range length (add 1)
  978. - 30..37: 3-bit range-length + 1 extra byte
  979. - 38..3F: 3-bit range-length + 2 extra byte
  980. */
  981. for(;;) {
  982. b = *p++;
  983. type = b >> 6;
  984. n = b & 0x3f;
  985. if (n < 48) {
  986. } else if (n < 56) {
  987. n = (n - 48) << 8;
  988. n |= *p++;
  989. n += 48;
  990. } else {
  991. n = (n - 56) << 8;
  992. n |= *p++ << 8;
  993. n |= *p++;
  994. n += 48 + (1 << 11);
  995. }
  996. if (type <= 1)
  997. p++;
  998. c1 = code + n + 1;
  999. if (c < c1) {
  1000. switch(type) {
  1001. case 0:
  1002. cc = p[-1];
  1003. break;
  1004. case 1:
  1005. cc = p[-1] + c - code;
  1006. break;
  1007. case 2:
  1008. cc = 0;
  1009. break;
  1010. default:
  1011. case 3:
  1012. cc = 230;
  1013. break;
  1014. }
  1015. return cc;
  1016. }
  1017. code = c1;
  1018. }
  1019. }
  1020. static void sort_cc(int *buf, int len)
  1021. {
  1022. int i, j, k, cc, cc1, start, ch1;
  1023. for(i = 0; i < len; i++) {
  1024. cc = unicode_get_cc(buf[i]);
  1025. if (cc != 0) {
  1026. start = i;
  1027. j = i + 1;
  1028. while (j < len) {
  1029. ch1 = buf[j];
  1030. cc1 = unicode_get_cc(ch1);
  1031. if (cc1 == 0)
  1032. break;
  1033. k = j - 1;
  1034. while (k >= start) {
  1035. if (unicode_get_cc(buf[k]) <= cc1)
  1036. break;
  1037. buf[k + 1] = buf[k];
  1038. k--;
  1039. }
  1040. buf[k + 1] = ch1;
  1041. j++;
  1042. }
  1043. #if 0
  1044. printf("cc:");
  1045. for(k = start; k < j; k++) {
  1046. printf(" %3d", unicode_get_cc(buf[k]));
  1047. }
  1048. printf("\n");
  1049. #endif
  1050. i = j;
  1051. }
  1052. }
  1053. }
  1054. static void to_nfd_rec(DynBuf *dbuf,
  1055. const int *src, int src_len, int is_compat)
  1056. {
  1057. uint32_t c, v;
  1058. int i, l;
  1059. uint32_t res[UNICODE_DECOMP_LEN_MAX];
  1060. for(i = 0; i < src_len; i++) {
  1061. c = src[i];
  1062. if (c >= 0xac00 && c < 0xd7a4) {
  1063. /* Hangul decomposition */
  1064. c -= 0xac00;
  1065. dbuf_put_u32(dbuf, 0x1100 + c / 588);
  1066. dbuf_put_u32(dbuf, 0x1161 + (c % 588) / 28);
  1067. v = c % 28;
  1068. if (v != 0)
  1069. dbuf_put_u32(dbuf, 0x11a7 + v);
  1070. } else {
  1071. l = unicode_decomp_char(res, c, is_compat);
  1072. if (l) {
  1073. to_nfd_rec(dbuf, (int *)res, l, is_compat);
  1074. } else {
  1075. dbuf_put_u32(dbuf, c);
  1076. }
  1077. }
  1078. }
  1079. }
  1080. /* return 0 if not found */
  1081. static int compose_pair(uint32_t c0, uint32_t c1)
  1082. {
  1083. /* Hangul composition */
  1084. if (c0 >= 0x1100 && c0 < 0x1100 + 19 &&
  1085. c1 >= 0x1161 && c1 < 0x1161 + 21) {
  1086. return 0xac00 + (c0 - 0x1100) * 588 + (c1 - 0x1161) * 28;
  1087. } else if (c0 >= 0xac00 && c0 < 0xac00 + 11172 &&
  1088. (c0 - 0xac00) % 28 == 0 &&
  1089. c1 >= 0x11a7 && c1 < 0x11a7 + 28) {
  1090. return c0 + c1 - 0x11a7;
  1091. } else {
  1092. return unicode_compose_pair(c0, c1);
  1093. }
  1094. }
  1095. int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
  1096. UnicodeNormalizationEnum n_type,
  1097. void *opaque, DynBufReallocFunc *realloc_func)
  1098. {
  1099. int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len;
  1100. BOOL is_compat;
  1101. DynBuf dbuf_s, *dbuf = &dbuf_s;
  1102. is_compat = n_type >> 1;
  1103. dbuf_init2(dbuf, opaque, realloc_func);
  1104. if (dbuf_claim(dbuf, sizeof(int) * src_len))
  1105. goto fail;
  1106. /* common case: latin1 is unaffected by NFC */
  1107. if (n_type == UNICODE_NFC) {
  1108. for(i = 0; i < src_len; i++) {
  1109. if (src[i] >= 0x100)
  1110. goto not_latin1;
  1111. }
  1112. buf = (int *)dbuf->buf;
  1113. if (src_len != 0)
  1114. memcpy(buf, src, src_len * sizeof(int));
  1115. *pdst = (uint32_t *)buf;
  1116. return src_len;
  1117. not_latin1: ;
  1118. }
  1119. to_nfd_rec(dbuf, (const int *)src, src_len, is_compat);
  1120. if (dbuf_error(dbuf)) {
  1121. fail:
  1122. *pdst = NULL;
  1123. return -1;
  1124. }
  1125. buf = (int *)dbuf->buf;
  1126. buf_len = dbuf->size / sizeof(int);
  1127. sort_cc(buf, buf_len);
  1128. if (buf_len <= 1 || (n_type & 1) != 0) {
  1129. /* NFD / NFKD */
  1130. *pdst = (uint32_t *)buf;
  1131. return buf_len;
  1132. }
  1133. i = 1;
  1134. out_len = 1;
  1135. while (i < buf_len) {
  1136. /* find the starter character and test if it is blocked from
  1137. the character at 'i' */
  1138. last_cc = unicode_get_cc(buf[i]);
  1139. starter_pos = out_len - 1;
  1140. while (starter_pos >= 0) {
  1141. cc = unicode_get_cc(buf[starter_pos]);
  1142. if (cc == 0)
  1143. break;
  1144. if (cc >= last_cc)
  1145. goto next;
  1146. last_cc = 256;
  1147. starter_pos--;
  1148. }
  1149. if (starter_pos >= 0 &&
  1150. (p = compose_pair(buf[starter_pos], buf[i])) != 0) {
  1151. buf[starter_pos] = p;
  1152. i++;
  1153. } else {
  1154. next:
  1155. buf[out_len++] = buf[i++];
  1156. }
  1157. }
  1158. *pdst = (uint32_t *)buf;
  1159. return out_len;
  1160. }
  1161. /* char ranges for various unicode properties */
  1162. static int unicode_find_name(const char *name_table, const char *name)
  1163. {
  1164. const char *p, *r;
  1165. int pos;
  1166. size_t name_len, len;
  1167. p = name_table;
  1168. pos = 0;
  1169. name_len = strlen(name);
  1170. while (*p) {
  1171. for(;;) {
  1172. r = strchr(p, ',');
  1173. if (!r)
  1174. len = strlen(p);
  1175. else
  1176. len = r - p;
  1177. if (len == name_len && !memcmp(p, name, name_len))
  1178. return pos;
  1179. p += len + 1;
  1180. if (!r)
  1181. break;
  1182. }
  1183. pos++;
  1184. }
  1185. return -1;
  1186. }
  1187. /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2
  1188. if not found */
  1189. int unicode_script(CharRange *cr,
  1190. const char *script_name, BOOL is_ext)
  1191. {
  1192. int script_idx;
  1193. const uint8_t *p, *p_end;
  1194. uint32_t c, c1, b, n, v, v_len, i, type;
  1195. CharRange cr1_s, *cr1;
  1196. CharRange cr2_s, *cr2 = &cr2_s;
  1197. BOOL is_common;
  1198. script_idx = unicode_find_name(unicode_script_name_table, script_name);
  1199. if (script_idx < 0)
  1200. return -2;
  1201. is_common = (script_idx == UNICODE_SCRIPT_Common ||
  1202. script_idx == UNICODE_SCRIPT_Inherited);
  1203. if (is_ext) {
  1204. cr1 = &cr1_s;
  1205. cr_init(cr1, cr->mem_opaque, cr->realloc_func);
  1206. cr_init(cr2, cr->mem_opaque, cr->realloc_func);
  1207. } else {
  1208. cr1 = cr;
  1209. }
  1210. p = unicode_script_table;
  1211. p_end = unicode_script_table + countof(unicode_script_table);
  1212. c = 0;
  1213. while (p < p_end) {
  1214. b = *p++;
  1215. type = b >> 7;
  1216. n = b & 0x7f;
  1217. if (n < 96) {
  1218. } else if (n < 112) {
  1219. n = (n - 96) << 8;
  1220. n |= *p++;
  1221. n += 96;
  1222. } else {
  1223. n = (n - 112) << 16;
  1224. n |= *p++ << 8;
  1225. n |= *p++;
  1226. n += 96 + (1 << 12);
  1227. }
  1228. c1 = c + n + 1;
  1229. if (type != 0) {
  1230. v = *p++;
  1231. if (v == script_idx || script_idx == UNICODE_SCRIPT_Unknown) {
  1232. if (cr_add_interval(cr1, c, c1))
  1233. goto fail;
  1234. }
  1235. }
  1236. c = c1;
  1237. }
  1238. if (script_idx == UNICODE_SCRIPT_Unknown) {
  1239. /* Unknown is all the characters outside scripts */
  1240. if (cr_invert(cr1))
  1241. goto fail;
  1242. }
  1243. if (is_ext) {
  1244. /* add the script extensions */
  1245. p = unicode_script_ext_table;
  1246. p_end = unicode_script_ext_table + countof(unicode_script_ext_table);
  1247. c = 0;
  1248. while (p < p_end) {
  1249. b = *p++;
  1250. if (b < 128) {
  1251. n = b;
  1252. } else if (b < 128 + 64) {
  1253. n = (b - 128) << 8;
  1254. n |= *p++;
  1255. n += 128;
  1256. } else {
  1257. n = (b - 128 - 64) << 16;
  1258. n |= *p++ << 8;
  1259. n |= *p++;
  1260. n += 128 + (1 << 14);
  1261. }
  1262. c1 = c + n + 1;
  1263. v_len = *p++;
  1264. if (is_common) {
  1265. if (v_len != 0) {
  1266. if (cr_add_interval(cr2, c, c1))
  1267. goto fail;
  1268. }
  1269. } else {
  1270. for(i = 0; i < v_len; i++) {
  1271. if (p[i] == script_idx) {
  1272. if (cr_add_interval(cr2, c, c1))
  1273. goto fail;
  1274. break;
  1275. }
  1276. }
  1277. }
  1278. p += v_len;
  1279. c = c1;
  1280. }
  1281. if (is_common) {
  1282. /* remove all the characters with script extensions */
  1283. if (cr_invert(cr2))
  1284. goto fail;
  1285. if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len,
  1286. CR_OP_INTER))
  1287. goto fail;
  1288. } else {
  1289. if (cr_op(cr, cr1->points, cr1->len, cr2->points, cr2->len,
  1290. CR_OP_UNION))
  1291. goto fail;
  1292. }
  1293. cr_free(cr1);
  1294. cr_free(cr2);
  1295. }
  1296. return 0;
  1297. fail:
  1298. if (is_ext) {
  1299. cr_free(cr1);
  1300. cr_free(cr2);
  1301. }
  1302. goto fail;
  1303. }
  1304. #define M(id) (1U << UNICODE_GC_ ## id)
  1305. static int unicode_general_category1(CharRange *cr, uint32_t gc_mask)
  1306. {
  1307. const uint8_t *p, *p_end;
  1308. uint32_t c, c0, b, n, v;
  1309. p = unicode_gc_table;
  1310. p_end = unicode_gc_table + countof(unicode_gc_table);
  1311. c = 0;
  1312. /* Compressed range encoding:
  1313. initial byte:
  1314. bits 0..4: category number (special case 31)
  1315. bits 5..7: range length (add 1)
  1316. special case bits 5..7 == 7: read an extra byte
  1317. - 00..7F: range length (add 7 + 1)
  1318. - 80..BF: 6-bits plus extra byte for range length (add 7 + 128)
  1319. - C0..FF: 6-bits plus 2 extra bytes for range length (add 7 + 128 + 16384)
  1320. */
  1321. while (p < p_end) {
  1322. b = *p++;
  1323. n = b >> 5;
  1324. v = b & 0x1f;
  1325. if (n == 7) {
  1326. n = *p++;
  1327. if (n < 128) {
  1328. n += 7;
  1329. } else if (n < 128 + 64) {
  1330. n = (n - 128) << 8;
  1331. n |= *p++;
  1332. n += 7 + 128;
  1333. } else {
  1334. n = (n - 128 - 64) << 16;
  1335. n |= *p++ << 8;
  1336. n |= *p++;
  1337. n += 7 + 128 + (1 << 14);
  1338. }
  1339. }
  1340. c0 = c;
  1341. c += n + 1;
  1342. if (v == 31) {
  1343. /* run of Lu / Ll */
  1344. b = gc_mask & (M(Lu) | M(Ll));
  1345. if (b != 0) {
  1346. if (b == (M(Lu) | M(Ll))) {
  1347. goto add_range;
  1348. } else {
  1349. c0 += ((gc_mask & M(Ll)) != 0);
  1350. for(; c0 < c; c0 += 2) {
  1351. if (cr_add_interval(cr, c0, c0 + 1))
  1352. return -1;
  1353. }
  1354. }
  1355. }
  1356. } else if ((gc_mask >> v) & 1) {
  1357. add_range:
  1358. if (cr_add_interval(cr, c0, c))
  1359. return -1;
  1360. }
  1361. }
  1362. return 0;
  1363. }
  1364. static int unicode_prop1(CharRange *cr, int prop_idx)
  1365. {
  1366. const uint8_t *p, *p_end;
  1367. uint32_t c, c0, b, bit;
  1368. p = unicode_prop_table[prop_idx];
  1369. p_end = p + unicode_prop_len_table[prop_idx];
  1370. c = 0;
  1371. bit = 0;
  1372. /* Compressed range encoding:
  1373. 00..3F: 2 packed lengths: 3-bit + 3-bit
  1374. 40..5F: 5-bits plus extra byte for length
  1375. 60..7F: 5-bits plus 2 extra bytes for length
  1376. 80..FF: 7-bit length
  1377. lengths must be incremented to get character count
  1378. Ranges alternate between false and true return value.
  1379. */
  1380. while (p < p_end) {
  1381. c0 = c;
  1382. b = *p++;
  1383. if (b < 64) {
  1384. c += (b >> 3) + 1;
  1385. if (bit) {
  1386. if (cr_add_interval(cr, c0, c))
  1387. return -1;
  1388. }
  1389. bit ^= 1;
  1390. c0 = c;
  1391. c += (b & 7) + 1;
  1392. } else if (b >= 0x80) {
  1393. c += b - 0x80 + 1;
  1394. } else if (b < 0x60) {
  1395. c += (((b - 0x40) << 8) | p[0]) + 1;
  1396. p++;
  1397. } else {
  1398. c += (((b - 0x60) << 16) | (p[0] << 8) | p[1]) + 1;
  1399. p += 2;
  1400. }
  1401. if (bit) {
  1402. if (cr_add_interval(cr, c0, c))
  1403. return -1;
  1404. }
  1405. bit ^= 1;
  1406. }
  1407. return 0;
  1408. }
  1409. typedef enum {
  1410. POP_GC,
  1411. POP_PROP,
  1412. POP_CASE,
  1413. POP_UNION,
  1414. POP_INTER,
  1415. POP_XOR,
  1416. POP_INVERT,
  1417. POP_END,
  1418. } PropOPEnum;
  1419. #define POP_STACK_LEN_MAX 4
  1420. static int unicode_prop_ops(CharRange *cr, ...)
  1421. {
  1422. va_list ap;
  1423. CharRange stack[POP_STACK_LEN_MAX];
  1424. int stack_len, op, ret, i;
  1425. uint32_t a;
  1426. va_start(ap, cr);
  1427. stack_len = 0;
  1428. for(;;) {
  1429. op = va_arg(ap, int);
  1430. switch(op) {
  1431. case POP_GC:
  1432. assert(stack_len < POP_STACK_LEN_MAX);
  1433. a = va_arg(ap, int);
  1434. cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func);
  1435. if (unicode_general_category1(&stack[stack_len - 1], a))
  1436. goto fail;
  1437. break;
  1438. case POP_PROP:
  1439. assert(stack_len < POP_STACK_LEN_MAX);
  1440. a = va_arg(ap, int);
  1441. cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func);
  1442. if (unicode_prop1(&stack[stack_len - 1], a))
  1443. goto fail;
  1444. break;
  1445. case POP_CASE:
  1446. assert(stack_len < POP_STACK_LEN_MAX);
  1447. a = va_arg(ap, int);
  1448. cr_init(&stack[stack_len++], cr->mem_opaque, cr->realloc_func);
  1449. if (unicode_case1(&stack[stack_len - 1], a))
  1450. goto fail;
  1451. break;
  1452. case POP_UNION:
  1453. case POP_INTER:
  1454. case POP_XOR:
  1455. {
  1456. CharRange *cr1, *cr2, *cr3;
  1457. assert(stack_len >= 2);
  1458. assert(stack_len < POP_STACK_LEN_MAX);
  1459. cr1 = &stack[stack_len - 2];
  1460. cr2 = &stack[stack_len - 1];
  1461. cr3 = &stack[stack_len++];
  1462. cr_init(cr3, cr->mem_opaque, cr->realloc_func);
  1463. /* CR_OP_XOR may be used here */
  1464. if (cr_op(cr3, cr1->points, cr1->len,
  1465. cr2->points, cr2->len, op - POP_UNION + CR_OP_UNION))
  1466. goto fail;
  1467. cr_free(cr1);
  1468. cr_free(cr2);
  1469. *cr1 = *cr3;
  1470. stack_len -= 2;
  1471. }
  1472. break;
  1473. case POP_INVERT:
  1474. assert(stack_len >= 1);
  1475. if (cr_invert(&stack[stack_len - 1]))
  1476. goto fail;
  1477. break;
  1478. case POP_END:
  1479. goto done;
  1480. default:
  1481. abort();
  1482. }
  1483. }
  1484. done:
  1485. assert(stack_len == 1);
  1486. ret = cr_copy(cr, &stack[0]);
  1487. cr_free(&stack[0]);
  1488. return ret;
  1489. fail:
  1490. for(i = 0; i < stack_len; i++)
  1491. cr_free(&stack[i]);
  1492. return -1;
  1493. }
  1494. static const uint32_t unicode_gc_mask_table[] = {
  1495. M(Lu) | M(Ll) | M(Lt), /* LC */
  1496. M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo), /* L */
  1497. M(Mn) | M(Mc) | M(Me), /* M */
  1498. M(Nd) | M(Nl) | M(No), /* N */
  1499. M(Sm) | M(Sc) | M(Sk) | M(So), /* S */
  1500. M(Pc) | M(Pd) | M(Ps) | M(Pe) | M(Pi) | M(Pf) | M(Po), /* P */
  1501. M(Zs) | M(Zl) | M(Zp), /* Z */
  1502. M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn), /* C */
  1503. };
  1504. /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2
  1505. if not found */
  1506. int unicode_general_category(CharRange *cr, const char *gc_name)
  1507. {
  1508. int gc_idx;
  1509. uint32_t gc_mask;
  1510. gc_idx = unicode_find_name(unicode_gc_name_table, gc_name);
  1511. if (gc_idx < 0)
  1512. return -2;
  1513. if (gc_idx <= UNICODE_GC_Co) {
  1514. gc_mask = (uint64_t)1 << gc_idx;
  1515. } else {
  1516. gc_mask = unicode_gc_mask_table[gc_idx - UNICODE_GC_LC];
  1517. }
  1518. return unicode_general_category1(cr, gc_mask);
  1519. }
  1520. /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2
  1521. if not found */
  1522. int unicode_prop(CharRange *cr, const char *prop_name)
  1523. {
  1524. int prop_idx, ret;
  1525. prop_idx = unicode_find_name(unicode_prop_name_table, prop_name);
  1526. if (prop_idx < 0)
  1527. return -2;
  1528. prop_idx += UNICODE_PROP_ASCII_Hex_Digit;
  1529. ret = 0;
  1530. switch(prop_idx) {
  1531. case UNICODE_PROP_ASCII:
  1532. if (cr_add_interval(cr, 0x00, 0x7f + 1))
  1533. return -1;
  1534. break;
  1535. case UNICODE_PROP_Any:
  1536. if (cr_add_interval(cr, 0x00000, 0x10ffff + 1))
  1537. return -1;
  1538. break;
  1539. case UNICODE_PROP_Assigned:
  1540. ret = unicode_prop_ops(cr,
  1541. POP_GC, M(Cn),
  1542. POP_INVERT,
  1543. POP_END);
  1544. break;
  1545. case UNICODE_PROP_Math:
  1546. ret = unicode_prop_ops(cr,
  1547. POP_GC, M(Sm),
  1548. POP_PROP, UNICODE_PROP_Other_Math,
  1549. POP_UNION,
  1550. POP_END);
  1551. break;
  1552. case UNICODE_PROP_Lowercase:
  1553. ret = unicode_prop_ops(cr,
  1554. POP_GC, M(Ll),
  1555. POP_PROP, UNICODE_PROP_Other_Lowercase,
  1556. POP_UNION,
  1557. POP_END);
  1558. break;
  1559. case UNICODE_PROP_Uppercase:
  1560. ret = unicode_prop_ops(cr,
  1561. POP_GC, M(Lu),
  1562. POP_PROP, UNICODE_PROP_Other_Uppercase,
  1563. POP_UNION,
  1564. POP_END);
  1565. break;
  1566. case UNICODE_PROP_Cased:
  1567. ret = unicode_prop_ops(cr,
  1568. POP_GC, M(Lu) | M(Ll) | M(Lt),
  1569. POP_PROP, UNICODE_PROP_Other_Uppercase,
  1570. POP_UNION,
  1571. POP_PROP, UNICODE_PROP_Other_Lowercase,
  1572. POP_UNION,
  1573. POP_END);
  1574. break;
  1575. case UNICODE_PROP_Alphabetic:
  1576. ret = unicode_prop_ops(cr,
  1577. POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl),
  1578. POP_PROP, UNICODE_PROP_Other_Uppercase,
  1579. POP_UNION,
  1580. POP_PROP, UNICODE_PROP_Other_Lowercase,
  1581. POP_UNION,
  1582. POP_PROP, UNICODE_PROP_Other_Alphabetic,
  1583. POP_UNION,
  1584. POP_END);
  1585. break;
  1586. case UNICODE_PROP_Grapheme_Base:
  1587. ret = unicode_prop_ops(cr,
  1588. POP_GC, M(Cc) | M(Cf) | M(Cs) | M(Co) | M(Cn) | M(Zl) | M(Zp) | M(Me) | M(Mn),
  1589. POP_PROP, UNICODE_PROP_Other_Grapheme_Extend,
  1590. POP_UNION,
  1591. POP_INVERT,
  1592. POP_END);
  1593. break;
  1594. case UNICODE_PROP_Grapheme_Extend:
  1595. ret = unicode_prop_ops(cr,
  1596. POP_GC, M(Me) | M(Mn),
  1597. POP_PROP, UNICODE_PROP_Other_Grapheme_Extend,
  1598. POP_UNION,
  1599. POP_END);
  1600. break;
  1601. case UNICODE_PROP_XID_Start:
  1602. ret = unicode_prop_ops(cr,
  1603. POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl),
  1604. POP_PROP, UNICODE_PROP_Other_ID_Start,
  1605. POP_UNION,
  1606. POP_PROP, UNICODE_PROP_Pattern_Syntax,
  1607. POP_PROP, UNICODE_PROP_Pattern_White_Space,
  1608. POP_UNION,
  1609. POP_PROP, UNICODE_PROP_XID_Start1,
  1610. POP_UNION,
  1611. POP_INVERT,
  1612. POP_INTER,
  1613. POP_END);
  1614. break;
  1615. case UNICODE_PROP_XID_Continue:
  1616. ret = unicode_prop_ops(cr,
  1617. POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) |
  1618. M(Mn) | M(Mc) | M(Nd) | M(Pc),
  1619. POP_PROP, UNICODE_PROP_Other_ID_Start,
  1620. POP_UNION,
  1621. POP_PROP, UNICODE_PROP_Other_ID_Continue,
  1622. POP_UNION,
  1623. POP_PROP, UNICODE_PROP_Pattern_Syntax,
  1624. POP_PROP, UNICODE_PROP_Pattern_White_Space,
  1625. POP_UNION,
  1626. POP_PROP, UNICODE_PROP_XID_Continue1,
  1627. POP_UNION,
  1628. POP_INVERT,
  1629. POP_INTER,
  1630. POP_END);
  1631. break;
  1632. case UNICODE_PROP_Changes_When_Uppercased:
  1633. ret = unicode_case1(cr, CASE_U);
  1634. break;
  1635. case UNICODE_PROP_Changes_When_Lowercased:
  1636. ret = unicode_case1(cr, CASE_L);
  1637. break;
  1638. case UNICODE_PROP_Changes_When_Casemapped:
  1639. ret = unicode_case1(cr, CASE_U | CASE_L | CASE_F);
  1640. break;
  1641. case UNICODE_PROP_Changes_When_Titlecased:
  1642. ret = unicode_prop_ops(cr,
  1643. POP_CASE, CASE_U,
  1644. POP_PROP, UNICODE_PROP_Changes_When_Titlecased1,
  1645. POP_XOR,
  1646. POP_END);
  1647. break;
  1648. case UNICODE_PROP_Changes_When_Casefolded:
  1649. ret = unicode_prop_ops(cr,
  1650. POP_CASE, CASE_F,
  1651. POP_PROP, UNICODE_PROP_Changes_When_Casefolded1,
  1652. POP_XOR,
  1653. POP_END);
  1654. break;
  1655. case UNICODE_PROP_Changes_When_NFKC_Casefolded:
  1656. ret = unicode_prop_ops(cr,
  1657. POP_CASE, CASE_F,
  1658. POP_PROP, UNICODE_PROP_Changes_When_NFKC_Casefolded1,
  1659. POP_XOR,
  1660. POP_END);
  1661. break;
  1662. #if 0
  1663. case UNICODE_PROP_ID_Start:
  1664. ret = unicode_prop_ops(cr,
  1665. POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl),
  1666. POP_PROP, UNICODE_PROP_Other_ID_Start,
  1667. POP_UNION,
  1668. POP_PROP, UNICODE_PROP_Pattern_Syntax,
  1669. POP_PROP, UNICODE_PROP_Pattern_White_Space,
  1670. POP_UNION,
  1671. POP_INVERT,
  1672. POP_INTER,
  1673. POP_END);
  1674. break;
  1675. case UNICODE_PROP_ID_Continue:
  1676. ret = unicode_prop_ops(cr,
  1677. POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) |
  1678. M(Mn) | M(Mc) | M(Nd) | M(Pc),
  1679. POP_PROP, UNICODE_PROP_Other_ID_Start,
  1680. POP_UNION,
  1681. POP_PROP, UNICODE_PROP_Other_ID_Continue,
  1682. POP_UNION,
  1683. POP_PROP, UNICODE_PROP_Pattern_Syntax,
  1684. POP_PROP, UNICODE_PROP_Pattern_White_Space,
  1685. POP_UNION,
  1686. POP_INVERT,
  1687. POP_INTER,
  1688. POP_END);
  1689. break;
  1690. case UNICODE_PROP_Case_Ignorable:
  1691. ret = unicode_prop_ops(cr,
  1692. POP_GC, M(Mn) | M(Cf) | M(Lm) | M(Sk),
  1693. POP_PROP, UNICODE_PROP_Case_Ignorable1,
  1694. POP_XOR,
  1695. POP_END);
  1696. break;
  1697. #else
  1698. /* we use the existing tables */
  1699. case UNICODE_PROP_ID_Continue:
  1700. ret = unicode_prop_ops(cr,
  1701. POP_PROP, UNICODE_PROP_ID_Start,
  1702. POP_PROP, UNICODE_PROP_ID_Continue1,
  1703. POP_XOR,
  1704. POP_END);
  1705. break;
  1706. #endif
  1707. default:
  1708. if (prop_idx >= countof(unicode_prop_table))
  1709. return -2;
  1710. ret = unicode_prop1(cr, prop_idx);
  1711. break;
  1712. }
  1713. return ret;
  1714. }
  1715. #endif /* CONFIG_ALL_UNICODE */
  1716. /*---- lre codepoint categorizing functions ----*/
  1717. #define S UNICODE_C_SPACE
  1718. #define D UNICODE_C_DIGIT
  1719. #define X UNICODE_C_XDIGIT
  1720. #define U UNICODE_C_UPPER
  1721. #define L UNICODE_C_LOWER
  1722. #define _ UNICODE_C_UNDER
  1723. #define d UNICODE_C_DOLLAR
  1724. uint8_t const lre_ctype_bits[256] = {
  1725. 0, 0, 0, 0, 0, 0, 0, 0,
  1726. 0, S, S, S, S, S, 0, 0,
  1727. 0, 0, 0, 0, 0, 0, 0, 0,
  1728. 0, 0, 0, 0, 0, 0, 0, 0,
  1729. S, 0, 0, 0, d, 0, 0, 0,
  1730. 0, 0, 0, 0, 0, 0, 0, 0,
  1731. X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D,
  1732. X|D, X|D, 0, 0, 0, 0, 0, 0,
  1733. 0, X|U, X|U, X|U, X|U, X|U, X|U, U,
  1734. U, U, U, U, U, U, U, U,
  1735. U, U, U, U, U, U, U, U,
  1736. U, U, U, 0, 0, 0, 0, _,
  1737. 0, X|L, X|L, X|L, X|L, X|L, X|L, L,
  1738. L, L, L, L, L, L, L, L,
  1739. L, L, L, L, L, L, L, L,
  1740. L, L, L, 0, 0, 0, 0, 0,
  1741. 0, 0, 0, 0, 0, 0, 0, 0,
  1742. 0, 0, 0, 0, 0, 0, 0, 0,
  1743. 0, 0, 0, 0, 0, 0, 0, 0,
  1744. 0, 0, 0, 0, 0, 0, 0, 0,
  1745. S, 0, 0, 0, 0, 0, 0, 0,
  1746. 0, 0, 0, 0, 0, 0, 0, 0,
  1747. 0, 0, 0, 0, 0, 0, 0, 0,
  1748. 0, 0, 0, 0, 0, 0, 0, 0,
  1749. 0, 0, 0, 0, 0, 0, 0, 0,
  1750. 0, 0, 0, 0, 0, 0, 0, 0,
  1751. 0, 0, 0, 0, 0, 0, 0, 0,
  1752. 0, 0, 0, 0, 0, 0, 0, 0,
  1753. 0, 0, 0, 0, 0, 0, 0, 0,
  1754. 0, 0, 0, 0, 0, 0, 0, 0,
  1755. 0, 0, 0, 0, 0, 0, 0, 0,
  1756. 0, 0, 0, 0, 0, 0, 0, 0,
  1757. };
  1758. #undef S
  1759. #undef D
  1760. #undef X
  1761. #undef U
  1762. #undef L
  1763. #undef _
  1764. #undef d
  1765. /* code point ranges for Zs,Zl or Zp property */
  1766. static const uint16_t char_range_s[] = {
  1767. 10,
  1768. 0x0009, 0x000D + 1,
  1769. 0x0020, 0x0020 + 1,
  1770. 0x00A0, 0x00A0 + 1,
  1771. 0x1680, 0x1680 + 1,
  1772. 0x2000, 0x200A + 1,
  1773. /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */
  1774. /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */
  1775. 0x2028, 0x2029 + 1,
  1776. 0x202F, 0x202F + 1,
  1777. 0x205F, 0x205F + 1,
  1778. 0x3000, 0x3000 + 1,
  1779. /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */
  1780. 0xFEFF, 0xFEFF + 1,
  1781. };
  1782. BOOL lre_is_space_non_ascii(uint32_t c)
  1783. {
  1784. size_t i, n;
  1785. n = countof(char_range_s);
  1786. for(i = 5; i < n; i += 2) {
  1787. uint32_t low = char_range_s[i];
  1788. uint32_t high = char_range_s[i + 1];
  1789. if (c < low)
  1790. return FALSE;
  1791. if (c < high)
  1792. return TRUE;
  1793. }
  1794. return FALSE;
  1795. }
  1796. #define SEQ_MAX_LEN 16
  1797. static int unicode_sequence_prop1(int seq_prop_idx, UnicodeSequencePropCB *cb, void *opaque,
  1798. CharRange *cr)
  1799. {
  1800. int i, c, j;
  1801. uint32_t seq[SEQ_MAX_LEN];
  1802. switch(seq_prop_idx) {
  1803. case UNICODE_SEQUENCE_PROP_Basic_Emoji:
  1804. if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji1) < 0)
  1805. return -1;
  1806. for(i = 0; i < cr->len; i += 2) {
  1807. for(c = cr->points[i]; c < cr->points[i + 1]; c++) {
  1808. seq[0] = c;
  1809. cb(opaque, seq, 1);
  1810. }
  1811. }
  1812. cr->len = 0;
  1813. if (unicode_prop1(cr, UNICODE_PROP_Basic_Emoji2) < 0)
  1814. return -1;
  1815. for(i = 0; i < cr->len; i += 2) {
  1816. for(c = cr->points[i]; c < cr->points[i + 1]; c++) {
  1817. seq[0] = c;
  1818. seq[1] = 0xfe0f;
  1819. cb(opaque, seq, 2);
  1820. }
  1821. }
  1822. break;
  1823. case UNICODE_SEQUENCE_PROP_RGI_Emoji_Modifier_Sequence:
  1824. if (unicode_prop1(cr, UNICODE_PROP_Emoji_Modifier_Base) < 0)
  1825. return -1;
  1826. for(i = 0; i < cr->len; i += 2) {
  1827. for(c = cr->points[i]; c < cr->points[i + 1]; c++) {
  1828. for(j = 0; j < 5; j++) {
  1829. seq[0] = c;
  1830. seq[1] = 0x1f3fb + j;
  1831. cb(opaque, seq, 2);
  1832. }
  1833. }
  1834. }
  1835. break;
  1836. case UNICODE_SEQUENCE_PROP_RGI_Emoji_Flag_Sequence:
  1837. if (unicode_prop1(cr, UNICODE_PROP_RGI_Emoji_Flag_Sequence) < 0)
  1838. return -1;
  1839. for(i = 0; i < cr->len; i += 2) {
  1840. for(c = cr->points[i]; c < cr->points[i + 1]; c++) {
  1841. int c0, c1;
  1842. c0 = c / 26;
  1843. c1 = c % 26;
  1844. seq[0] = 0x1F1E6 + c0;
  1845. seq[1] = 0x1F1E6 + c1;
  1846. cb(opaque, seq, 2);
  1847. }
  1848. }
  1849. break;
  1850. case UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence:
  1851. {
  1852. int len, code, pres, k, mod, mod_count, mod_pos[2], hc_pos, n_mod, n_hc, mod1;
  1853. int mod_idx, hc_idx, i0, i1;
  1854. const uint8_t *tab = unicode_rgi_emoji_zwj_sequence;
  1855. for(i = 0; i < countof(unicode_rgi_emoji_zwj_sequence);) {
  1856. len = tab[i++];
  1857. k = 0;
  1858. mod = 0;
  1859. mod_count = 0;
  1860. hc_pos = -1;
  1861. for(j = 0; j < len; j++) {
  1862. code = tab[i++];
  1863. code |= tab[i++] << 8;
  1864. pres = code >> 15;
  1865. mod1 = (code >> 13) & 3;
  1866. code &= 0x1fff;
  1867. if (code < 0x1000) {
  1868. c = code + 0x2000;
  1869. } else {
  1870. c = 0x1f000 + (code - 0x1000);
  1871. }
  1872. if (c == 0x1f9b0)
  1873. hc_pos = k;
  1874. seq[k++] = c;
  1875. if (mod1 != 0) {
  1876. assert(mod_count < 2);
  1877. mod = mod1;
  1878. mod_pos[mod_count++] = k;
  1879. seq[k++] = 0; /* will be filled later */
  1880. }
  1881. if (pres) {
  1882. seq[k++] = 0xfe0f;
  1883. }
  1884. if (j < len - 1) {
  1885. seq[k++] = 0x200d;
  1886. }
  1887. }
  1888. /* genrate all the variants */
  1889. switch(mod) {
  1890. case 1:
  1891. n_mod = 5;
  1892. break;
  1893. case 2:
  1894. n_mod = 25;
  1895. break;
  1896. case 3:
  1897. n_mod = 20;
  1898. break;
  1899. default:
  1900. n_mod = 1;
  1901. break;
  1902. }
  1903. if (hc_pos >= 0)
  1904. n_hc = 4;
  1905. else
  1906. n_hc = 1;
  1907. for(hc_idx = 0; hc_idx < n_hc; hc_idx++) {
  1908. for(mod_idx = 0; mod_idx < n_mod; mod_idx++) {
  1909. if (hc_pos >= 0)
  1910. seq[hc_pos] = 0x1f9b0 + hc_idx;
  1911. switch(mod) {
  1912. case 1:
  1913. seq[mod_pos[0]] = 0x1f3fb + mod_idx;
  1914. break;
  1915. case 2:
  1916. case 3:
  1917. i0 = mod_idx / 5;
  1918. i1 = mod_idx % 5;
  1919. /* avoid identical values */
  1920. if (mod == 3 && i0 >= i1)
  1921. i0++;
  1922. seq[mod_pos[0]] = 0x1f3fb + i0;
  1923. seq[mod_pos[1]] = 0x1f3fb + i1;
  1924. break;
  1925. default:
  1926. break;
  1927. }
  1928. #if 0
  1929. for(j = 0; j < k; j++)
  1930. printf(" %04x", seq[j]);
  1931. printf("\n");
  1932. #endif
  1933. cb(opaque, seq, k);
  1934. }
  1935. }
  1936. }
  1937. }
  1938. break;
  1939. case UNICODE_SEQUENCE_PROP_RGI_Emoji_Tag_Sequence:
  1940. {
  1941. for(i = 0; i < countof(unicode_rgi_emoji_tag_sequence);) {
  1942. j = 0;
  1943. seq[j++] = 0x1F3F4;
  1944. for(;;) {
  1945. c = unicode_rgi_emoji_tag_sequence[i++];
  1946. if (c == 0x00)
  1947. break;
  1948. seq[j++] = 0xe0000 + c;
  1949. }
  1950. seq[j++] = 0xe007f;
  1951. cb(opaque, seq, j);
  1952. }
  1953. }
  1954. break;
  1955. case UNICODE_SEQUENCE_PROP_Emoji_Keycap_Sequence:
  1956. if (unicode_prop1(cr, UNICODE_PROP_Emoji_Keycap_Sequence) < 0)
  1957. return -1;
  1958. for(i = 0; i < cr->len; i += 2) {
  1959. for(c = cr->points[i]; c < cr->points[i + 1]; c++) {
  1960. seq[0] = c;
  1961. seq[1] = 0xfe0f;
  1962. seq[2] = 0x20e3;
  1963. cb(opaque, seq, 3);
  1964. }
  1965. }
  1966. break;
  1967. case UNICODE_SEQUENCE_PROP_RGI_Emoji:
  1968. /* all prevous sequences */
  1969. for(i = UNICODE_SEQUENCE_PROP_Basic_Emoji; i <= UNICODE_SEQUENCE_PROP_RGI_Emoji_ZWJ_Sequence; i++) {
  1970. int ret;
  1971. ret = unicode_sequence_prop1(i, cb, opaque, cr);
  1972. if (ret < 0)
  1973. return ret;
  1974. cr->len = 0;
  1975. }
  1976. break;
  1977. default:
  1978. return -2;
  1979. }
  1980. return 0;
  1981. }
  1982. /* build a unicode sequence property */
  1983. /* return -2 if not found, -1 if other error. 'cr' is used as temporary memory. */
  1984. int unicode_sequence_prop(const char *prop_name, UnicodeSequencePropCB *cb, void *opaque,
  1985. CharRange *cr)
  1986. {
  1987. int seq_prop_idx;
  1988. seq_prop_idx = unicode_find_name(unicode_sequence_prop_name_table, prop_name);
  1989. if (seq_prop_idx < 0)
  1990. return -2;
  1991. return unicode_sequence_prop1(seq_prop_idx, cb, opaque, cr);
  1992. }