nxt_int_t njs_regexp_create(njs_vm_t *vm, njs_value_t *value, u_char *start, size_t length, njs_regexp_flags_t flags) { njs_regexp_t *regexp; njs_regexp_pattern_t *pattern; if (length != 0) { pattern = njs_regexp_pattern_create(vm, start, length, flags); if (nxt_slow_path(pattern == NULL)) { return NXT_ERROR; } } else { pattern = vm->shared->empty_regexp_pattern; } regexp = njs_regexp_alloc(vm, pattern); if (nxt_fast_path(regexp != NULL)) { value->data.u.regexp = regexp; value->type = NJS_REGEXP; value->data.truth = 1; return NXT_OK; } return NXT_ERROR; }
njs_ret_t njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { size_t length; njs_regexp_t *regexp; njs_string_prop_t string; njs_regexp_flags_t flags; njs_regexp_pattern_t *pattern; flags = 0; switch (nargs) { default: length = njs_string_prop(&string, &args[2]); flags = njs_regexp_flags(&string.start, string.start + length, 1); if (nxt_slow_path(flags < 0)) { return NXT_ERROR; } /* Fall through. */ case 2: string.length = njs_string_prop(&string, &args[1]); if (string.length != 0) { break; } /* Fall through. */ case 1: string.start = (u_char *) "(?:)"; string.length = sizeof("(?:)") - 1; break; } pattern = njs_regexp_pattern_create(vm, string.start, string.length, flags); if (nxt_fast_path(pattern != NULL)) { regexp = njs_regexp_alloc(vm, pattern); if (nxt_fast_path(regexp != NULL)) { vm->retval.data.u.regexp = regexp; vm->retval.type = NJS_REGEXP; vm->retval.data.truth = 1; return NXT_OK; } } return NXT_ERROR; }
njs_token_t njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) { u_char *p; njs_lexer_t *lexer; njs_regexp_flags_t flags; njs_regexp_pattern_t *pattern; lexer = parser->lexer; for (p = lexer->start; p < lexer->end; p++) { if (*p == '\\') { p++; continue; } if (*p == '/') { lexer->text.start = lexer->start; lexer->text.length = p - lexer->text.start; p++; lexer->start = p; flags = njs_regexp_flags(&p, lexer->end, 0); if (nxt_slow_path(flags < 0)) { nxt_alert(&vm->trace, NXT_LEVEL_ERROR, "SyntaxError: Invalid RegExp flags \"%.*s\"", p - lexer->start, lexer->start); return NJS_TOKEN_ILLEGAL; } lexer->start = p; pattern = njs_regexp_pattern_create(vm, lexer->text.start, lexer->text.length, flags); if (nxt_slow_path(pattern == NULL)) { return NJS_TOKEN_ILLEGAL; } value->data.u.data = pattern; return NJS_TOKEN_REGEXP; } } nxt_alert(&vm->trace, NXT_LEVEL_ERROR, "SyntaxError: Unterminated RegExp \"%.*s\"", p - lexer->start - 1, lexer->start - 1); return NJS_TOKEN_ILLEGAL; }
njs_token_t njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, njs_value_t *value) { u_char *p; njs_lexer_t *lexer; njs_regexp_flags_t flags; njs_regexp_pattern_t *pattern; lexer = parser->lexer; for (p = lexer->start; p < lexer->end; p++) { if (*p == '\\') { p++; continue; } if (*p == '/') { lexer->text.data = lexer->start; lexer->text.len = p - lexer->text.data; p++; lexer->start = p; flags = njs_regexp_flags(&p, lexer->end, 0); if (nxt_slow_path(flags < 0)) { lexer->text.data = lexer->start; lexer->text.len = p - lexer->text.data; return njs_parser_error(vm, parser, NJS_PARSER_ERROR_REGEXP_FLAGS); } lexer->start = p; pattern = njs_regexp_pattern_create(vm, lexer->text.data, lexer->text.len, flags); if (nxt_slow_path(pattern == NULL)) { return NJS_TOKEN_ILLEGAL; } value->data.u.data = pattern; return NJS_TOKEN_REGEXP; } } lexer->text.data = lexer->start - 1; lexer->text.len = p - lexer->text.data; return njs_parser_error(vm, parser, NJS_PARSER_ERROR_UNTERMINATED_REGEXP); }