aboutsummaryrefslogtreecommitdiff
path: root/Lua/lbp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Lua/lbp.c')
-rw-r--r--Lua/lbp.c147
1 files changed, 123 insertions, 24 deletions
diff --git a/Lua/lbp.c b/Lua/lbp.c
index 15d549b..a44db92 100644
--- a/Lua/lbp.c
+++ b/Lua/lbp.c
@@ -21,6 +21,99 @@
#define luaL_register(L, _, R) luaL_setfuncs(L, R, 0)
#endif
+static int MATCH_METATABLE = 0;
+
+static void push_matchstring(lua_State *L, file_t *f, match_t *m)
+{
+ char *buf = NULL;
+ size_t size = 0;
+ FILE *out = open_memstream(&buf, &size);
+ printer_t pr = {
+ .file = f,
+ .context_before = NO_CONTEXT,
+ .context_after = NO_CONTEXT,
+ .use_color = 0,
+ .lineformat = "",
+ };
+ print_match(out, &pr, m);
+ fflush(out);
+ lua_pushlstring(L, buf, size);
+ fclose(out);
+}
+
+static int Ltostring(lua_State *L)
+{
+ match_t **m = (match_t**)lua_touserdata(L, 1);
+ push_matchstring(L, NULL, *m);
+ return 1;
+}
+
+static int Lgc(lua_State *L)
+{
+ match_t **m = (match_t**)lua_touserdata(L, 1);
+ recycle_if_unused(m);
+ return 0;
+}
+
+static int Llen(lua_State *L)
+{
+ match_t **m = (match_t**)lua_touserdata(L, 1);
+ lua_pushinteger(L, (int)((*m)->end - (*m)->start));
+ return 1;
+}
+
+static int Lindex(lua_State *L)
+{
+ match_t **m = (match_t**)lua_touserdata(L, 1);
+ int type = lua_type(L, 2);
+ match_t *ret = NULL;
+ if (type == LUA_TNUMBER) {
+ int n = luaL_checkinteger(L, 2);
+ if (n == 0) {
+ push_matchstring(L, NULL, *m);
+ return 1;
+ } else if (n > 0) {
+ ret = get_numbered_capture(*m, n);
+ }
+ } else if (type == LUA_TSTRING) {
+ size_t len;
+ const char *name = luaL_checklstring(L, 2, &len);
+ ret = get_named_capture(*m, name, len);
+ }
+
+ if (ret) {
+ match_t **userdata = (match_t**)lua_newuserdatauv(L, sizeof(match_t*), 0);
+ *userdata = ret;
+ lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+ return 0;
+}
+
+static const luaL_Reg Rinstance_metamethods[] =
+{
+ {"__len", Llen},
+ {"__tostring", Ltostring},
+ {"__index", Lindex},
+ {"__gc", Lgc},
+ {NULL, NULL}
+};
+
+// static void push_match(lua_State *L, match_t *m)
+// {
+// lua_createtable(L, 0, 1);
+// lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
+// lua_gettable(L, LUA_REGISTRYINDEX);
+// lua_setmetatable(L, -2);
+
+// push_matchstring(L, m);
+// lua_rawseti(L, -2, 0);
+// int n = 1;
+// assign_captures(L, m, &n);
+// }
+
static int Lmatch(lua_State *L)
{
size_t textlen, patlen;
@@ -33,7 +126,7 @@ static int Lmatch(lua_State *L)
file_t *pat_file = spoof_file(NULL, "<pattern argument>", pat_text, patlen);
pat_t *pat = bp_pattern(pat_file, pat_file->start);
if (!pat) {
- destroy_file(&pat_file);
+ // destroy_file(&pat_file);
luaL_error(L, "Pattern failed to compile: %s", pat_text);
return 0;
}
@@ -42,29 +135,30 @@ static int Lmatch(lua_State *L)
match_t *m = NULL;
int ret = 0;
if (next_match(&m, NULL, text_file, pat, NULL, false)) {
- char *buf = NULL;
- size_t size = 0;
- FILE *out = open_memstream(&buf, &size);
- printer_t pr = {
- .file = text_file,
- .context_before = NO_CONTEXT,
- .context_after = NO_CONTEXT,
- .use_color = 0,
- .lineformat = "",
- };
- print_match(out, &pr, m);
- fflush(out);
- lua_pushlstring(L, buf, size);
+
+ // lua_createtable(L, 0, 1);
+
+ match_t **userdata = (match_t**)lua_newuserdatauv(L, sizeof(match_t*), 0);
+ *userdata = m;
+ lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
+ lua_gettable(L, LUA_REGISTRYINDEX);
+ lua_setmetatable(L, -2);
+ // push_matchstring(L, text_file, m);
+ // lua_rawseti(L, -2, 0);
+ // int n = 1;
+ // assign_captures(L, text_file, m, &n);
+
lua_pushinteger(L, (int)(m->start - text_file->start) + index);
lua_pushinteger(L, (int)(m->end - m->start));
- fclose(out);
- stop_matching(&m);
+
+ // stop_matching(&m);
ret = 3;
}
- destroy_file(&pat_file);
- destroy_file(&text_file);
+ // destroy_file(&pat_file);
+ // destroy_file(&text_file);
+
return ret;
}
@@ -81,15 +175,15 @@ static int Lreplace(lua_State *L)
file_t *pat_file = spoof_file(NULL, "<pattern argument>", pat_text, patlen);
pat_t *pat = bp_pattern(pat_file, pat_file->start);
if (!pat) {
- destroy_file(&pat_file);
+ // destroy_file(&pat_file);
luaL_error(L, "Pattern failed to compile: %s", pat_text);
return 0;
}
file_t *rep_file = spoof_file(NULL, "<replacement argument>", rep_text, replen);
pat = bp_replacement(rep_file, pat, rep_file->start);
if (!pat) {
- destroy_file(&pat_file);
- destroy_file(&rep_file);
+ // destroy_file(&pat_file);
+ // destroy_file(&rep_file);
luaL_error(L, "Replacement failed to compile: %s", rep_text);
return 0;
}
@@ -116,15 +210,20 @@ static int Lreplace(lua_State *L)
lua_pushinteger(L, replacements);
fclose(out);
- destroy_file(&pat_file);
- destroy_file(&rep_file);
- destroy_file(&text_file);
+ // destroy_file(&pat_file);
+ // destroy_file(&rep_file);
+ // destroy_file(&text_file);
return 2;
}
LUALIB_API int luaopen_bp(lua_State *L)
{
+ lua_pushlightuserdata(L, (void*)&MATCH_METATABLE);
+ lua_createtable(L, 0, 4);
+ luaL_register(L, NULL, Rinstance_metamethods);
+ lua_settable(L, LUA_REGISTRYINDEX);
+
lua_createtable(L, 0, 2);
lua_pushcfunction(L, Lmatch);
lua_setfield(L, -2, "match");