static int parse_unicode_property()

in src/couch_quickjs/quickjs/libregexp.c [536:628]


static int parse_unicode_property(REParseState *s, CharRange *cr,
                                  const uint8_t **pp, BOOL is_inv)
{
    const uint8_t *p;
    char name[64], value[64];
    char *q;
    BOOL script_ext;
    int ret;

    p = *pp;
    if (*p != '{')
        return re_parse_error(s, "expecting '{' after \\p");
    p++;
    q = name;
    while (is_unicode_char(*p)) {
        if ((q - name) >= sizeof(name) - 1)
            goto unknown_property_name;
        *q++ = *p++;
    }
    *q = '\0';
    q = value;
    if (*p == '=') {
        p++;
        while (is_unicode_char(*p)) {
            if ((q - value) >= sizeof(value) - 1)
                return re_parse_error(s, "unknown unicode property value");
            *q++ = *p++;
        }
    }
    *q = '\0';
    if (*p != '}')
        return re_parse_error(s, "expecting '}'");
    p++;
    //    printf("name=%s value=%s\n", name, value);

    if (!strcmp(name, "Script") || !strcmp(name, "sc")) {
        script_ext = FALSE;
        goto do_script;
    } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) {
        script_ext = TRUE;
    do_script:
        cr_init(cr, s->opaque, lre_realloc);
        ret = unicode_script(cr, value, script_ext);
        if (ret) {
            cr_free(cr);
            if (ret == -2)
                return re_parse_error(s, "unknown unicode script");
            else
                goto out_of_memory;
        }
    } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) {
        cr_init(cr, s->opaque, lre_realloc);
        ret = unicode_general_category(cr, value);
        if (ret) {
            cr_free(cr);
            if (ret == -2)
                return re_parse_error(s, "unknown unicode general category");
            else
                goto out_of_memory;
        }
    } else if (value[0] == '\0') {
        cr_init(cr, s->opaque, lre_realloc);
        ret = unicode_general_category(cr, name);
        if (ret == -1) {
            cr_free(cr);
            goto out_of_memory;
        }
        if (ret < 0) {
            ret = unicode_prop(cr, name);
            if (ret) {
                cr_free(cr);
                if (ret == -2)
                    goto unknown_property_name;
                else
                    goto out_of_memory;
            }
        }
    } else {
    unknown_property_name:
        return re_parse_error(s, "unknown unicode property name");
    }

    if (is_inv) {
        if (cr_invert(cr)) {
            cr_free(cr);
            return -1;
        }
    }
    *pp = p;
    return 0;
 out_of_memory:
    return re_parse_out_of_memory(s);
}