From 5c4e1ea8dca744482879dfc15ed21fc24beb2775 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 11 May 2021 17:08:50 +0200 Subject: lib: implement regexp(), a function to construct regexp instances at runtime Provide a new ucode function regexp() which allows constructing regular expression instances from separate source and flag strings. Signed-off-by: Jo-Philipp Wich --- lib.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'lib.c') diff --git a/lib.c b/lib.c index 453f976..a24ed23 100644 --- a/lib.c +++ b/lib.c @@ -2470,6 +2470,61 @@ uc_assert(uc_vm *vm, size_t nargs) return ucv_get(cond); } +static uc_value_t * +uc_regexp(uc_vm *vm, size_t nargs) +{ + bool icase = false, newline = false, global = false, freeable; + uc_value_t *source = uc_get_arg(0); + uc_value_t *flags = uc_get_arg(1); + uc_value_t *regex = NULL; + char *p, *err = NULL; + + if (flags) { + if (ucv_type(flags) != UC_STRING) { + uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Given flags argument is not a string"); + + return NULL; + } + + for (p = ucv_string_get(flags); *p; p++) { + switch (*p) { + case 'i': + icase = true; + break; + + case 's': + newline = true; + break; + + case 'g': + global = true; + break; + + default: + uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Unrecognized flag character '%c'", *p); + + return NULL; + } + } + } + + p = uc_cast_string(vm, &source, &freeable); + regex = ucv_regexp_new(p, icase, newline, global, &err); + + if (freeable) + free(p); + + if (err) { + uc_vm_raise_exception(vm, EXCEPTION_SYNTAX, "%s", err); + ucv_put(regex); + free(err); + + return NULL; + } + + return regex; +} + static const uc_cfunction_list functions[] = { { "chr", uc_chr }, { "delete", uc_delete }, @@ -2521,7 +2576,8 @@ static const uc_cfunction_list functions[] = { { "proto", uc_proto }, { "sleep", uc_sleep }, { "assert", uc_assert }, - { "render", uc_render } + { "render", uc_render }, + { "regexp", uc_regexp } }; -- cgit v1.2.3