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);
}