diff options
Diffstat (limited to 'Lua/lbp.c')
| -rw-r--r-- | Lua/lbp.c | 147 |
1 files changed, 123 insertions, 24 deletions
@@ -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"); |
