in GaiaXAndroidQuickJS/quickjs/gxquickjs/unicode_gen.c [2183:2445]
void find_decomp_run(DecompEntry *tab_de, int i)
{
DecompEntry de_s, *de = &de_s;
CCInfo *ci, *ci1, *ci2;
int l, j, n, len_max;
ci = &unicode_db[i];
l = ci->decomp_len;
if (l == 0) {
tab_de[i].cost = tab_de[i + 1].cost;
return;
}
/* the offset for the compose table has only 6 bits, so we must
limit if it can be used by the compose table */
if (!ci->is_compat && !ci->is_excluded && l == 2)
len_max = 64;
else
len_max = 127;
tab_de[i].cost = 0x7fffffff;
if (!is_16bit(ci->decomp_data, l)) {
assert(l <= 2);
n = 1;
for(;;) {
de->code = i;
de->len = n;
de->type = DECOMP_TYPE_LL1 + l - 1;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
/* Note: we accept a hole */
if (!(ci1->decomp_len == 0 ||
(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat)))
break;
n++;
}
return;
}
if (l <= 7) {
n = 1;
for(;;) {
de->code = i;
de->len = n;
if (l == 1 && n == 1) {
de->type = DECOMP_TYPE_C1;
} else {
assert(l <= 8);
de->type = DECOMP_TYPE_L1 + l - 1;
}
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
/* Note: we accept a hole */
if (!(ci1->decomp_len == 0 ||
(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat &&
is_16bit(ci1->decomp_data, l))))
break;
n++;
}
}
if (l <= 8 || l == 18) {
int c_min, c_max, c;
c_min = c_max = -1;
n = 1;
for(;;) {
ci1 = &unicode_db[i + n - 1];
for(j = 0; j < l; j++) {
c = ci1->decomp_data[j];
if (c == 0x20) {
/* we accept space for Arabic */
} else if (c_min == -1) {
c_min = c_max = c;
} else {
c_min = min_int(c_min, c);
c_max = max_int(c_max, c);
}
}
if ((c_max - c_min) > 254)
break;
de->code = i;
de->len = n;
if (l == 18)
de->type = DECOMP_TYPE_B18;
else
de->type = DECOMP_TYPE_B1 + l - 1;
de->c_len = l;
de->c_min = c_min;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
if (!(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat))
break;
n++;
}
}
/* find an ascii run */
if (l <= 5 && is_short_tab(ci->decomp_data, l)) {
n = 1;
for(;;) {
de->code = i;
de->len = n;
de->type = DECOMP_TYPE_S1 + l - 1;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
/* Note: we accept a hole */
if (!(ci1->decomp_len == 0 ||
(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat &&
is_short_tab(ci1->decomp_data, l))))
break;
n++;
}
}
/* check if a single char is increasing */
if (l <= 4) {
int idx1, idx;
for(idx1 = 1; (idx = decomp_incr_tab[l - 1][idx1]) >= 0; idx1++) {
n = 1;
for(;;) {
de->code = i;
de->len = n;
de->type = decomp_incr_tab[l - 1][0] + idx1 - 1;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
if (!(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat))
goto next1;
for(j = 0; j < l; j++) {
if (j == idx) {
if (ci1->decomp_data[j] != ci->decomp_data[j] + n)
goto next1;
} else {
if (ci1->decomp_data[j] != ci->decomp_data[j])
goto next1;
}
}
n++;
}
next1: ;
}
}
if (l == 3) {
n = 1;
for(;;) {
de->code = i;
de->len = n;
de->type = DECOMP_TYPE_PAT3;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
if (!(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat &&
ci1->decomp_data[1] <= 0xffff &&
ci1->decomp_data[0] == ci->decomp_data[0] &&
ci1->decomp_data[l - 1] == ci->decomp_data[l - 1]))
break;
n++;
}
}
if (l == 2 && is_short(ci->decomp_data[1])) {
n = 1;
for(;;) {
de->code = i;
de->len = n;
de->type = DECOMP_TYPE_LS2;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
if (!((i + n) <= CHARCODE_MAX && n < len_max))
break;
ci1 = &unicode_db[i + n];
if (!(ci1->decomp_len == 0 ||
(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat &&
ci1->decomp_data[0] <= 0xffff &&
is_short(ci1->decomp_data[1]))))
break;
n++;
}
}
if (l == 2) {
BOOL is_16bit;
n = 0;
is_16bit = FALSE;
for(;;) {
if (!((i + n + 1) <= CHARCODE_MAX && n + 2 <= len_max))
break;
ci1 = &unicode_db[i + n];
if (!(ci1->decomp_len == l &&
ci1->is_compat == ci->is_compat &&
is_short(ci1->decomp_data[1])))
break;
if (!is_16bit && !is_short(ci1->decomp_data[0]))
is_16bit = TRUE;
ci2 = &unicode_db[i + n + 1];
if (!(ci2->decomp_len == l &&
ci2->is_compat == ci->is_compat &&
ci2->decomp_data[0] == to_lower_simple(ci1->decomp_data[0]) &&
ci2->decomp_data[1] == ci1->decomp_data[1]))
break;
n += 2;
de->code = i;
de->len = n;
de->type = DECOMP_TYPE_S2_UL + is_16bit;
de->c_len = l;
de->cost = get_decomp_run_size(de) + tab_de[i + n].cost;
if (de->cost < tab_de[i].cost) {
tab_de[i] = *de;
}
}
}
}