From 645081f64e9bc1f996326b74aed2f5cda2c62437 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 26 Oct 2022 20:26:58 -0400 Subject: Fixed lua to work with new API --- Lua/lbp.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- match.c | 15 +++++++++------ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/Lua/lbp.c b/Lua/lbp.c index 60dc9b9..b062973 100644 --- a/Lua/lbp.c +++ b/Lua/lbp.c @@ -33,9 +33,8 @@ static void push_match(lua_State *L, match_t *m, const char *start); lua_State *cur_state = NULL; -static void match_error(pat_t *pat, const char *msg) +static void match_error(const char *msg) { - (void)pat; lua_pushstring(cur_state, msg); lua_error(cur_state); } @@ -140,6 +139,19 @@ static void push_match(lua_State *L, match_t *m, const char *start) lua_setfield(L, -2, "after"); } +typedef struct { + lua_State *L; + const char *text; +} lua_match_context_t; + +static bp_match_behavior handle_match(match_t *m, int matchnum, void *data) +{ + (void)matchnum; + lua_match_context_t *ctx = data; + push_match(ctx->L, m, ctx->text); + return BP_STOP; +} + static int Lmatch(lua_State *L) { if (lua_isstring(L, 1)) { @@ -166,17 +178,29 @@ static int Lmatch(lua_State *L) if (index > (lua_Integer)strlen(text)+1) return 0; - match_t *m = NULL; - int ret = 0; cur_state = L; - if (next_match_safe(&m, text+index-1, &text[textlen], pat, builtins, NULL, false, match_error)) { - push_match(L, m, text); - stop_matching(&m); - ret = 1; - } + lua_match_context_t ctx = {.L=L, .text=text}; + bp_errhand_t prev_handler = set_match_error_handler(match_error); + int ret = each_match(handle_match, &ctx, text+index-1, &text[textlen], pat, builtins, NULL, false); + (void)set_match_error_handler(prev_handler); return ret; } +typedef struct { + FILE *out; + const char *prev, *text; +} lua_replace_context_t; + +static bp_match_behavior handle_replacement(match_t *m, int matchnum, void *data) +{ + (void)matchnum; + lua_replace_context_t *ctx = data; + fwrite(ctx->prev, sizeof(char), (size_t)(m->start - ctx->prev), ctx->out); + fprint_match(ctx->out, ctx->text, m, NULL); + ctx->prev = m->end; + return BP_CONTINUE; +} + static int Lreplace(lua_State *L) { if (lua_isstring(L, 1)) { @@ -204,16 +228,14 @@ static int Lreplace(lua_State *L) char *buf = NULL; size_t size = 0; FILE *out = open_memstream(&buf, &size); - int replacements = 0; const char *prev = text; pat_t *rep_pat = maybe_replacement.value.pat; cur_state = L; - for (match_t *m = NULL; next_match_safe(&m, text, &text[textlen], rep_pat, builtins, NULL, false, match_error); ) { - fwrite(prev, sizeof(char), (size_t)(m->start - prev), out); - fprint_match(out, text, m, NULL); - prev = m->end; - ++replacements; - } + + lua_replace_context_t ctx = {.out=out, .prev=text, .text=text}; + bp_errhand_t prev_handler = set_match_error_handler(match_error); + int replacements = each_match(handle_replacement, &ctx, text, &text[textlen], rep_pat, builtins, NULL, false); + (void)set_match_error_handler(prev_handler); fwrite(prev, sizeof(char), (size_t)(&text[textlen] - prev), out); fflush(out); lua_pushlstring(L, buf, size); diff --git a/match.c b/match.c index c07086f..1e895a5 100644 --- a/match.c +++ b/match.c @@ -74,6 +74,7 @@ static size_t recycle_all_matches(void); __attribute__((format(printf,1,2))) static inline void match_error(const char *fmt, ...) { + if (error_message) free(error_message); va_list args; va_start(args, fmt); vasprintf(&error_message, fmt, args); @@ -875,7 +876,8 @@ int each_match(bp_match_callback callback, void *userdata, const char *start, co return num_matches; } - if (setjmp(error_jump) == 0) { + bool hit_error = setjmp(error_jump) != 0; + if (!hit_error) { for (const char *str = start; str <= end; ) { match_t *m = _next_match(&ctx, str, pat, skip); if (!m) break; @@ -888,17 +890,18 @@ int each_match(bp_match_callback callback, void *userdata, const char *start, co str = m->end > str ? m->end : next_char(str, end); recycle_all_matches(); } - } else { - if (error_handler) - error_handler(error_message ? error_message : "An unknown error occurred"); + } + cache_destroy(&ctx); + free_all_matches(); + + if (hit_error && error_handler) { + error_handler(error_message ? error_message : "An unknown error occurred"); } if (error_message) { free(error_message); error_message = NULL; } - cache_destroy(&ctx); - free_all_matches(); return num_matches; } -- cgit v1.2.3