mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	fixed CONFIG_ALL_UNICODE compilation
This commit is contained in:
		
							parent
							
								
									9bd10d8eb9
								
							
						
					
					
						commit
						1be68b3345
					
				
							
								
								
									
										402
									
								
								libunicode.c
									
									
									
									
									
								
							
							
						
						
									
										402
									
								
								libunicode.c
									
									
									
									
									
								
							@ -537,6 +537,207 @@ int cr_invert(CharRange *cr)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CASE_U (1 << 0)
 | 
				
			||||||
 | 
					#define CASE_L (1 << 1)
 | 
				
			||||||
 | 
					#define CASE_F (1 << 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* use the case conversion table to generate range of characters.
 | 
				
			||||||
 | 
					   CASE_U: set char if modified by uppercasing,
 | 
				
			||||||
 | 
					   CASE_L: set char if modified by lowercasing,
 | 
				
			||||||
 | 
					   CASE_F: set char if modified by case folding,
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int unicode_case1(CharRange *cr, int case_mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#define MR(x) (1 << RUN_TYPE_ ## x)
 | 
				
			||||||
 | 
					    const uint32_t tab_run_mask[3] = {
 | 
				
			||||||
 | 
					        MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) |
 | 
				
			||||||
 | 
					        MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					#undef MR
 | 
				
			||||||
 | 
					    uint32_t mask, v, code, type, len, i, idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (case_mask == 0)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    mask = 0;
 | 
				
			||||||
 | 
					    for(i = 0; i < 3; i++) {
 | 
				
			||||||
 | 
					        if ((case_mask >> i) & 1)
 | 
				
			||||||
 | 
					            mask |= tab_run_mask[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for(idx = 0; idx < countof(case_conv_table1); idx++) {
 | 
				
			||||||
 | 
					        v = case_conv_table1[idx];
 | 
				
			||||||
 | 
					        type = (v >> (32 - 17 - 7 - 4)) & 0xf;
 | 
				
			||||||
 | 
					        code = v >> (32 - 17);
 | 
				
			||||||
 | 
					        len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
				
			||||||
 | 
					        if ((mask >> type) & 1) {
 | 
				
			||||||
 | 
					            //            printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1);
 | 
				
			||||||
 | 
					            switch(type) {
 | 
				
			||||||
 | 
					            case RUN_TYPE_UL:
 | 
				
			||||||
 | 
					                if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
 | 
				
			||||||
 | 
					                    goto def_case;
 | 
				
			||||||
 | 
					                code += ((case_mask & CASE_U) != 0);
 | 
				
			||||||
 | 
					                for(i = 0; i < len; i += 2) {
 | 
				
			||||||
 | 
					                    if (cr_add_interval(cr, code + i, code + i + 1))
 | 
				
			||||||
 | 
					                        return -1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case RUN_TYPE_LSU:
 | 
				
			||||||
 | 
					                if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
 | 
				
			||||||
 | 
					                    goto def_case;
 | 
				
			||||||
 | 
					                if (!(case_mask & CASE_U)) {
 | 
				
			||||||
 | 
					                    if (cr_add_interval(cr, code, code + 1))
 | 
				
			||||||
 | 
					                        return -1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (cr_add_interval(cr, code + 1, code + 2))
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					                if (case_mask & CASE_U) {
 | 
				
			||||||
 | 
					                    if (cr_add_interval(cr, code + 2, code + 3))
 | 
				
			||||||
 | 
					                        return -1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					            def_case:
 | 
				
			||||||
 | 
					                if (cr_add_interval(cr, code, code + len))
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int point_cmp(const void *p1, const void *p2, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t v1 = *(uint32_t *)p1;
 | 
				
			||||||
 | 
					    uint32_t v2 = *(uint32_t *)p2;
 | 
				
			||||||
 | 
					    return (v1 > v2) - (v1 < v2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void cr_sort_and_remove_overlap(CharRange *cr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t start, end, start1, end1, i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* the resulting ranges are not necessarily sorted and may overlap */
 | 
				
			||||||
 | 
					    rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL);
 | 
				
			||||||
 | 
					    j = 0;
 | 
				
			||||||
 | 
					    for(i = 0; i < cr->len; ) {
 | 
				
			||||||
 | 
					        start = cr->points[i];
 | 
				
			||||||
 | 
					        end = cr->points[i + 1];
 | 
				
			||||||
 | 
					        i += 2;
 | 
				
			||||||
 | 
					        while (i < cr->len) {
 | 
				
			||||||
 | 
					            start1 = cr->points[i];
 | 
				
			||||||
 | 
					            end1 = cr->points[i + 1];
 | 
				
			||||||
 | 
					            if (start1 > end) {
 | 
				
			||||||
 | 
					                /* |------|
 | 
				
			||||||
 | 
					                 *           |-------| */
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            } else if (end1 <= end) {
 | 
				
			||||||
 | 
					                /* |------|
 | 
				
			||||||
 | 
					                 *    |--| */
 | 
				
			||||||
 | 
					                i += 2;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                /* |------|
 | 
				
			||||||
 | 
					                 *     |-------| */
 | 
				
			||||||
 | 
					                end = end1;
 | 
				
			||||||
 | 
					                i += 2;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        cr->points[j] = start;
 | 
				
			||||||
 | 
					        cr->points[j + 1] = end;
 | 
				
			||||||
 | 
					        j += 2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cr->len = j;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* canonicalize a character set using the JS regex case folding rules
 | 
				
			||||||
 | 
					   (see lre_canonicalize()) */
 | 
				
			||||||
 | 
					int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CharRange cr_inter, cr_mask, cr_result, cr_sub;
 | 
				
			||||||
 | 
					    uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func);
 | 
				
			||||||
 | 
					    cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func);
 | 
				
			||||||
 | 
					    cr_init(&cr_result, cr->mem_opaque, cr->realloc_func);
 | 
				
			||||||
 | 
					    cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cr_invert(&cr_mask))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* cr_inter = cr & cr_mask */
 | 
				
			||||||
 | 
					    /* cr_sub = cr & ~cr_mask */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* use the case conversion table to compute the result */
 | 
				
			||||||
 | 
					    d_start = -1;
 | 
				
			||||||
 | 
					    d_end = -1;
 | 
				
			||||||
 | 
					    idx = 0;
 | 
				
			||||||
 | 
					    v = case_conv_table1[idx];
 | 
				
			||||||
 | 
					    code = v >> (32 - 17);
 | 
				
			||||||
 | 
					    len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
				
			||||||
 | 
					    for(i = 0; i < cr_inter.len; i += 2) {
 | 
				
			||||||
 | 
					        start = cr_inter.points[i];
 | 
				
			||||||
 | 
					        end = cr_inter.points[i + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(c = start; c < end; c++) {
 | 
				
			||||||
 | 
					            for(;;) {
 | 
				
			||||||
 | 
					                if (c >= code && c < code + len)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                idx++;
 | 
				
			||||||
 | 
					                assert(idx < countof(case_conv_table1));
 | 
				
			||||||
 | 
					                v = case_conv_table1[idx];
 | 
				
			||||||
 | 
					                code = v >> (32 - 17);
 | 
				
			||||||
 | 
					                len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            d = lre_case_folding_entry(c, idx, v, is_unicode);
 | 
				
			||||||
 | 
					            /* try to merge with the current interval */
 | 
				
			||||||
 | 
					            if (d_start == -1) {
 | 
				
			||||||
 | 
					                d_start = d;
 | 
				
			||||||
 | 
					                d_end = d + 1;
 | 
				
			||||||
 | 
					            } else if (d_end == d) {
 | 
				
			||||||
 | 
					                d_end++;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                cr_add_interval(&cr_result, d_start, d_end);
 | 
				
			||||||
 | 
					                d_start = d;
 | 
				
			||||||
 | 
					                d_end = d + 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (d_start != -1) {
 | 
				
			||||||
 | 
					        if (cr_add_interval(&cr_result, d_start, d_end))
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* the resulting ranges are not necessarily sorted and may overlap */
 | 
				
			||||||
 | 
					    cr_sort_and_remove_overlap(&cr_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* or with the character not affected by the case folding */
 | 
				
			||||||
 | 
					    cr->len = 0;
 | 
				
			||||||
 | 
					    if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION))
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cr_free(&cr_inter);
 | 
				
			||||||
 | 
					    cr_free(&cr_mask);
 | 
				
			||||||
 | 
					    cr_free(&cr_result);
 | 
				
			||||||
 | 
					    cr_free(&cr_sub);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					 fail:
 | 
				
			||||||
 | 
					    cr_free(&cr_inter);
 | 
				
			||||||
 | 
					    cr_free(&cr_mask);
 | 
				
			||||||
 | 
					    cr_free(&cr_result);
 | 
				
			||||||
 | 
					    cr_free(&cr_sub);
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_ALL_UNICODE
 | 
					#ifdef CONFIG_ALL_UNICODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BOOL lre_is_id_start(uint32_t c)
 | 
					BOOL lre_is_id_start(uint32_t c)
 | 
				
			||||||
@ -1296,207 +1497,6 @@ static int unicode_prop1(CharRange *cr, int prop_idx)
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CASE_U (1 << 0)
 | 
					 | 
				
			||||||
#define CASE_L (1 << 1)
 | 
					 | 
				
			||||||
#define CASE_F (1 << 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* use the case conversion table to generate range of characters.
 | 
					 | 
				
			||||||
   CASE_U: set char if modified by uppercasing,
 | 
					 | 
				
			||||||
   CASE_L: set char if modified by lowercasing,
 | 
					 | 
				
			||||||
   CASE_F: set char if modified by case folding,
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int unicode_case1(CharRange *cr, int case_mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#define MR(x) (1 << RUN_TYPE_ ## x)
 | 
					 | 
				
			||||||
    const uint32_t tab_run_mask[3] = {
 | 
					 | 
				
			||||||
        MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) |
 | 
					 | 
				
			||||||
        MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
#undef MR
 | 
					 | 
				
			||||||
    uint32_t mask, v, code, type, len, i, idx;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (case_mask == 0)
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    mask = 0;
 | 
					 | 
				
			||||||
    for(i = 0; i < 3; i++) {
 | 
					 | 
				
			||||||
        if ((case_mask >> i) & 1)
 | 
					 | 
				
			||||||
            mask |= tab_run_mask[i];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for(idx = 0; idx < countof(case_conv_table1); idx++) {
 | 
					 | 
				
			||||||
        v = case_conv_table1[idx];
 | 
					 | 
				
			||||||
        type = (v >> (32 - 17 - 7 - 4)) & 0xf;
 | 
					 | 
				
			||||||
        code = v >> (32 - 17);
 | 
					 | 
				
			||||||
        len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
					 | 
				
			||||||
        if ((mask >> type) & 1) {
 | 
					 | 
				
			||||||
            //            printf("%d: type=%d %04x %04x\n", idx, type, code, code + len - 1);
 | 
					 | 
				
			||||||
            switch(type) {
 | 
					 | 
				
			||||||
            case RUN_TYPE_UL:
 | 
					 | 
				
			||||||
                if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
 | 
					 | 
				
			||||||
                    goto def_case;
 | 
					 | 
				
			||||||
                code += ((case_mask & CASE_U) != 0);
 | 
					 | 
				
			||||||
                for(i = 0; i < len; i += 2) {
 | 
					 | 
				
			||||||
                    if (cr_add_interval(cr, code + i, code + i + 1))
 | 
					 | 
				
			||||||
                        return -1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            case RUN_TYPE_LSU:
 | 
					 | 
				
			||||||
                if ((case_mask & CASE_U) && (case_mask & (CASE_L | CASE_F)))
 | 
					 | 
				
			||||||
                    goto def_case;
 | 
					 | 
				
			||||||
                if (!(case_mask & CASE_U)) {
 | 
					 | 
				
			||||||
                    if (cr_add_interval(cr, code, code + 1))
 | 
					 | 
				
			||||||
                        return -1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (cr_add_interval(cr, code + 1, code + 2))
 | 
					 | 
				
			||||||
                    return -1;
 | 
					 | 
				
			||||||
                if (case_mask & CASE_U) {
 | 
					 | 
				
			||||||
                    if (cr_add_interval(cr, code + 2, code + 3))
 | 
					 | 
				
			||||||
                        return -1;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
            def_case:
 | 
					 | 
				
			||||||
                if (cr_add_interval(cr, code, code + len))
 | 
					 | 
				
			||||||
                    return -1;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int point_cmp(const void *p1, const void *p2, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t v1 = *(uint32_t *)p1;
 | 
					 | 
				
			||||||
    uint32_t v2 = *(uint32_t *)p2;
 | 
					 | 
				
			||||||
    return (v1 > v2) - (v1 < v2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void cr_sort_and_remove_overlap(CharRange *cr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    uint32_t start, end, start1, end1, i, j;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* the resulting ranges are not necessarily sorted and may overlap */
 | 
					 | 
				
			||||||
    rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL);
 | 
					 | 
				
			||||||
    j = 0;
 | 
					 | 
				
			||||||
    for(i = 0; i < cr->len; ) {
 | 
					 | 
				
			||||||
        start = cr->points[i];
 | 
					 | 
				
			||||||
        end = cr->points[i + 1];
 | 
					 | 
				
			||||||
        i += 2;
 | 
					 | 
				
			||||||
        while (i < cr->len) {
 | 
					 | 
				
			||||||
            start1 = cr->points[i];
 | 
					 | 
				
			||||||
            end1 = cr->points[i + 1];
 | 
					 | 
				
			||||||
            if (start1 > end) {
 | 
					 | 
				
			||||||
                /* |------|
 | 
					 | 
				
			||||||
                 *           |-------| */
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            } else if (end1 <= end) {
 | 
					 | 
				
			||||||
                /* |------|
 | 
					 | 
				
			||||||
                 *    |--| */
 | 
					 | 
				
			||||||
                i += 2;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                /* |------|
 | 
					 | 
				
			||||||
                 *     |-------| */
 | 
					 | 
				
			||||||
                end = end1;
 | 
					 | 
				
			||||||
                i += 2;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        cr->points[j] = start;
 | 
					 | 
				
			||||||
        cr->points[j + 1] = end;
 | 
					 | 
				
			||||||
        j += 2;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    cr->len = j;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* canonicalize a character set using the JS regex case folding rules
 | 
					 | 
				
			||||||
   (see lre_canonicalize()) */
 | 
					 | 
				
			||||||
int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CharRange cr_inter, cr_mask, cr_result, cr_sub;
 | 
					 | 
				
			||||||
    uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func);
 | 
					 | 
				
			||||||
    cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func);
 | 
					 | 
				
			||||||
    cr_init(&cr_result, cr->mem_opaque, cr->realloc_func);
 | 
					 | 
				
			||||||
    cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U))
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (cr_invert(&cr_mask))
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
    if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* cr_inter = cr & cr_mask */
 | 
					 | 
				
			||||||
    /* cr_sub = cr & ~cr_mask */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* use the case conversion table to compute the result */
 | 
					 | 
				
			||||||
    d_start = -1;
 | 
					 | 
				
			||||||
    d_end = -1;
 | 
					 | 
				
			||||||
    idx = 0;
 | 
					 | 
				
			||||||
    v = case_conv_table1[idx];
 | 
					 | 
				
			||||||
    code = v >> (32 - 17);
 | 
					 | 
				
			||||||
    len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
					 | 
				
			||||||
    for(i = 0; i < cr_inter.len; i += 2) {
 | 
					 | 
				
			||||||
        start = cr_inter.points[i];
 | 
					 | 
				
			||||||
        end = cr_inter.points[i + 1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for(c = start; c < end; c++) {
 | 
					 | 
				
			||||||
            for(;;) {
 | 
					 | 
				
			||||||
                if (c >= code && c < code + len)
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                idx++;
 | 
					 | 
				
			||||||
                assert(idx < countof(case_conv_table1));
 | 
					 | 
				
			||||||
                v = case_conv_table1[idx];
 | 
					 | 
				
			||||||
                code = v >> (32 - 17);
 | 
					 | 
				
			||||||
                len = (v >> (32 - 17 - 7)) & 0x7f;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            d = lre_case_folding_entry(c, idx, v, is_unicode);
 | 
					 | 
				
			||||||
            /* try to merge with the current interval */
 | 
					 | 
				
			||||||
            if (d_start == -1) {
 | 
					 | 
				
			||||||
                d_start = d;
 | 
					 | 
				
			||||||
                d_end = d + 1;
 | 
					 | 
				
			||||||
            } else if (d_end == d) {
 | 
					 | 
				
			||||||
                d_end++;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                cr_add_interval(&cr_result, d_start, d_end);
 | 
					 | 
				
			||||||
                d_start = d;
 | 
					 | 
				
			||||||
                d_end = d + 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (d_start != -1) {
 | 
					 | 
				
			||||||
        if (cr_add_interval(&cr_result, d_start, d_end))
 | 
					 | 
				
			||||||
            goto fail;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* the resulting ranges are not necessarily sorted and may overlap */
 | 
					 | 
				
			||||||
    cr_sort_and_remove_overlap(&cr_result);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* or with the character not affected by the case folding */
 | 
					 | 
				
			||||||
    cr->len = 0;
 | 
					 | 
				
			||||||
    if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION))
 | 
					 | 
				
			||||||
        goto fail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cr_free(&cr_inter);
 | 
					 | 
				
			||||||
    cr_free(&cr_mask);
 | 
					 | 
				
			||||||
    cr_free(&cr_result);
 | 
					 | 
				
			||||||
    cr_free(&cr_sub);
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
 fail:
 | 
					 | 
				
			||||||
    cr_free(&cr_inter);
 | 
					 | 
				
			||||||
    cr_free(&cr_mask);
 | 
					 | 
				
			||||||
    cr_free(&cr_result);
 | 
					 | 
				
			||||||
    cr_free(&cr_sub);
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    POP_GC,
 | 
					    POP_GC,
 | 
				
			||||||
    POP_PROP,
 | 
					    POP_PROP,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user