static int re_check_advance()

in GaiaXAndroidQuickJS/quickjs/gxquickjs/libregexp.c [950:1030]


static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len)
{
    int pos, opcode, ret, len, i;
    uint32_t val, last;
    BOOL has_back_reference;
    uint8_t capture_bitmap[CAPTURE_COUNT_MAX];
    
    ret = -2; /* not known yet */
    pos = 0;
    has_back_reference = FALSE;
    memset(capture_bitmap, 0, sizeof(capture_bitmap));
    
    while (pos < bc_buf_len) {
        opcode = bc_buf[pos];
        len = reopcode_info[opcode].size;
        switch(opcode) {
        case REOP_range:
            val = get_u16(bc_buf + pos + 1);
            len += val * 4;
            goto simple_char;
        case REOP_range32:
            val = get_u16(bc_buf + pos + 1);
            len += val * 8;
            goto simple_char;
        case REOP_char:
        case REOP_char32:
        case REOP_dot:
        case REOP_any:
        simple_char:
            if (ret == -2)
                ret = 1;
            break;
        case REOP_line_start:
        case REOP_line_end:
        case REOP_push_i32:
        case REOP_push_char_pos:
        case REOP_drop:
        case REOP_word_boundary:
        case REOP_not_word_boundary:
        case REOP_prev:
            /* no effect */
            break;
        case REOP_save_start:
        case REOP_save_end:
            val = bc_buf[pos + 1];
            capture_bitmap[val] |= 1;
            break;
        case REOP_save_reset:
            {
                val = bc_buf[pos + 1];
                last = bc_buf[pos + 2];
                while (val < last)
                    capture_bitmap[val++] |= 1;
            }
            break;
        case REOP_back_reference:
        case REOP_backward_back_reference:
            val = bc_buf[pos + 1];
            capture_bitmap[val] |= 2;
            has_back_reference = TRUE;
            break;
        default:
            /* safe behvior: we cannot predict the outcome */
            if (ret == -2)
                ret = 0;
            break;
        }
        pos += len;
    }
    if (has_back_reference) {
        /* check if there is back reference which references a capture
           made in the some code */
        for(i = 0; i < CAPTURE_COUNT_MAX; i++) {
            if (capture_bitmap[i] == 3)
                return -1;
        }
    }
    if (ret == -2)
        ret = 0;
    return ret;
}