From: K.Kosako Date: Tue, 27 Feb 2018 03:57:32 +0000 (+0900) Subject: add builtin callout (*ONLY(n)) X-Git-Tag: v6.8.0~142 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3e72c9edfbebadc70c7ff320e9636ea674ae968;p=onig add builtin callout (*ONLY(n)) --- diff --git a/src/ascii.c b/src/ascii.c index a0e0d67..556f4f9 100644 --- a/src/ascii.c +++ b/src/ascii.c @@ -39,11 +39,13 @@ init(void) int id; OnigType t_int; + OnigType t_long; OnigEncoding enc; char* name; enc = ONIG_ENCODING_ASCII; - t_int = ONIG_TYPE_INT; + t_int = ONIG_TYPE_INT; + t_long = ONIG_TYPE_LONG; name = "FAIL"; BC0_P(name, fail); name = "SUCCESS"; BC0_P(name, success); @@ -51,6 +53,8 @@ init(void) name = "ERROR"; BC1_P(name, error, &t_int); name = "COUNT"; BC0_P(name, count); name = "FAIL_COUNT"; BC0_R(name, count); + name = "ONLY"; BC1_B(name, only, &t_long); + #endif /* USE_CALLOUT */ inited = 1; diff --git a/src/oniguruma.h b/src/oniguruma.h index ee94ae4..96b4aa3 100644 --- a/src/oniguruma.h +++ b/src/oniguruma.h @@ -999,6 +999,8 @@ ONIG_EXTERN int onig_builtin_error P_((OnigCalloutArgs* args, void* user_data)); ONIG_EXTERN int onig_builtin_count P_((OnigCalloutArgs* args, void* user_data)); +ONIG_EXTERN +int onig_builtin_only P_((OnigCalloutArgs* args, void* user_data)); #ifdef __cplusplus } diff --git a/src/regexec.c b/src/regexec.c index 904331f..b34a6ce 100644 --- a/src/regexec.c +++ b/src/regexec.c @@ -5264,4 +5264,44 @@ onig_builtin_count(OnigCalloutArgs* args, void* user_data ARG_UNUSED) return ONIG_CALLOUT_SUCCESS; } +extern int +onig_builtin_only(OnigCalloutArgs* args, void* user_data ARG_UNUSED) +{ + int r; + int num; + int slot; + OnigType type; + OnigValue val; + OnigValue aval; + + num = args->num; + slot = 0; + r = onig_get_callout_data_by_callout_num(args->regex, args->msa->mp, num, slot, + &type, &val); + if (r != ONIG_NORMAL) return r; + + /* initial state */ + if (type == ONIG_TYPE_VOID) { + type = ONIG_TYPE_LONG; + val.l = 0; + } + + r = onig_get_arg_of_callout_args(args, 0, &type, &aval); + if (r != ONIG_NORMAL) return r; + + if (args->in == ONIG_CALLOUT_IN_RETRACTION) { + val.l--; + } + else { + if (val.l >= aval.l) return ONIG_CALLOUT_FAIL; + val.l++; + } + + r = onig_set_callout_data_by_callout_num(args->regex, args->msa->mp, num, slot, + ONIG_TYPE_LONG, &val); + if (r != ONIG_NORMAL) return r; + + return ONIG_CALLOUT_SUCCESS; +} + #endif /* USE_CALLOUT */ diff --git a/src/regint.h b/src/regint.h index caa8311..637e0c9 100644 --- a/src/regint.h +++ b/src/regint.h @@ -855,6 +855,15 @@ extern CalloutListEntry* onig_reg_callout_list_at(regex_t* reg, int num); if (id < 0) return id;\ } while(0) +#define BC1_B(name, func, ts) do {\ + int len = onigenc_str_bytelen_null(enc, (UChar* )name);\ + id = onig_set_callout_of_name(enc, ONIG_CALLOUT_TYPE_SINGLE,\ + (UChar* )(name), (UChar* )((name) + len),\ + ONIG_CALLOUT_IN_BOTH,\ + onig_builtin_ ## func, 0, 1, (ts), 0, 0);\ + if (id < 0) return id;\ +} while(0) + #endif /* USE_CALLOUT */