#include #include #include #include #include #include "imapfilter.h" static int ifre_flags(lua_State *lua); static int ifre_compile(lua_State *lua); static int ifre_exec(lua_State *lua); static int ifre_free(lua_State *lua); /* Lua imapfilter library of PCRE related functions. */ static const luaL_reg ifrelib[] = { { "flags", ifre_flags }, { "compile", ifre_compile }, { "exec", ifre_exec }, { "free", ifre_free }, { NULL, NULL } }; /* * Return PCRE available compile and exec flags. */ static int ifre_flags(lua_State *lua) { if (lua_gettop(lua) != 0) luaL_error(lua, "wrong number of arguments"); lua_newtable(lua); #ifdef PCRE_CASELESS set_table_number("CASELESS", PCRE_CASELESS); #endif #ifdef PCRE_MULTILINE set_table_number("MULTILINE", PCRE_MULTILINE); #endif #ifdef PCRE_DOTALL set_table_number("DOTALL", PCRE_DOTALL); #endif #ifdef PCRE_EXTENDED set_table_number("EXTENDED", PCRE_EXTENDED); #endif #ifdef PCRE_ANCHORED set_table_number("ANCHORED", PCRE_ANCHORED); #endif #ifdef PCRE_DOLLAR_ENDONLY set_table_number("DOLLAR_ENDONLY", PCRE_DOLLAR_ENDONLY); #endif #ifdef PCRE_EXTRA set_table_number("EXTRA", PCRE_EXTRA); #endif #ifdef PCRE_NOTBOL set_table_number("NOTBOL", PCRE_NOTBOL); #endif #ifdef PCRE_NOTEOL set_table_number("NOTEOL", PCRE_NOTEOL); #endif #ifdef PCRE_UNGREEDY set_table_number("UNGREEDY", PCRE_UNGREEDY); #endif #ifdef PCRE_NOTEMPTY set_table_number("NOTEMPTY", PCRE_NOTEMPTY); #endif #ifdef PCRE_UTF8 set_table_number("UTF8", PCRE_UTF8); #endif #ifdef PCRE_NO_AUTO_CAPTURE set_table_number("NO_AUTO_CAPTURE", PCRE_NO_AUTO_CAPTURE); #endif #ifdef PCRE_NO_UTF8_CHECK set_table_number("NO_UTF8_CHECK", PCRE_NO_UTF8_CHECK); #endif #ifdef PCRE_FIRSTLINE set_table_number("FIRSTLINE", PCRE_FIRSTLINE); #endif #ifdef PCRE_AUTO_CALLOUT set_table_number("AUTO_CALLOUT", PCRE_AUTO_CALLOUT); #endif #ifdef PCRE_PARTIAL set_table_number("PARTIAL", PCRE_PARTIAL); #endif #ifdef PCRE_DFA_SHORTEST set_table_number("DFA_SHORTEST", PCRE_DFA_SHORTEST); #endif #ifdef PCRE_DFA_RESTART set_table_number("DFA_RESTART", PCRE_DFA_RESTART); #endif #ifdef PCRE_FIRSTLINE set_table_number("FIRSTLINE", PCRE_FIRSTLINE); #endif #ifdef PCRE_DUPNAMES set_table_number("DUPNAMES", PCRE_DUPNAMES); #endif #ifdef PCRE_NEWLINE_CR set_table_number("NEWLINE_CR)", PCRE_NEWLINE_CR); #endif #ifdef PCRE_NEWLINE_LF set_table_number("NEWLINE_LF", PCRE_NEWLINE_LF); #endif #ifdef PCRE_NEWLINE_CRLF set_table_number("NEWLINE_CRLF", PCRE_NEWLINE_CRLF); #endif #ifdef PCRE_NEWLINE_ANY set_table_number("NEWLINE_ANY", PCRE_NEWLINE_ANY); #endif #ifdef PCRE_NEWLINE_ANYCRLF set_table_number("NEWLINE_ANYCRLF", PCRE_NEWLINE_ANYCRLF); #endif #ifdef PCRE_BSR_ANYCRLF set_table_number("PCRE_BSR_ANYCRLF", PCRE_BSR_ANYCRLF); #endif #ifdef PCRE_BSR_UNICODE set_table_number("PCRE_BSR_UNICODE", PCRE_BSR_UNICODE); #endif #ifdef PCRE_JAVASCRIPT_COMPAT set_table_number("PCRE_JAVASCRIPT_COMPAT", PCRE_JAVASCRIPT_COMPAT); #endif #ifdef PCRE_NO_START_OPTIMIZE set_table_number("PCRE_NO_START_OPTIMIZE", PCRE_NO_START_OPTIMIZE); #endif #ifdef PCRE_NO_START_OPTIMISE set_table_number("PCRE_NO_START_OPTIMISE", PCRE_NO_START_OPTIMISE); #endif #ifdef PCRE_PARTIAL_HARD set_table_number("PCRE_PARTIAL_HARD", PCRE_PARTIAL_HARD); #endif #ifdef PCRE_NOTEMPTY_ATSTART set_table_number("PCRE_NOTEMPTY_ATSTART", PCRE_NOTEMPTY_ATSTART); #endif #ifdef PCRE_UCP set_table_number("PCRE_UCP", PCRE_UCP); #endif return 1; } /* * Lua implementation of the PCRE compile function. */ static int ifre_compile(lua_State *lua) { pcre **re; const char *error; int erroffset; if (lua_gettop(lua) != 2) luaL_error(lua, "wrong number of arguments"); luaL_checktype(lua, 1, LUA_TSTRING); luaL_checktype(lua, 2, LUA_TNUMBER); re = (pcre **)(lua_newuserdata(lua, sizeof(pcre *))); *re = pcre_compile(lua_tostring(lua, 1), lua_tonumber(lua, 2), &error, &erroffset, NULL); if (*re == NULL) { fprintf(stderr, "RE failed at offset %d: %s\n", erroffset, error); lua_pop(lua, 1); } lua_remove(lua, 1); lua_remove(lua, 1); lua_pushboolean(lua, (*re != NULL)); lua_insert(lua, 1); return (*re != NULL ? 2 : 1); } /* * Lua implementation of the PCRE exec function. */ static int ifre_exec(lua_State *lua) { int i, n; pcre *re; int ovecsize; int *ovector; if (lua_gettop(lua) != 3) luaL_error(lua, "wrong number of arguments"); luaL_checktype(lua, 1, LUA_TUSERDATA); luaL_checktype(lua, 2, LUA_TSTRING); luaL_checktype(lua, 3, LUA_TNUMBER); re = *(pcre **)(lua_touserdata(lua, 1)); pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &ovecsize); ovector = (int *)xmalloc(sizeof(int) * (ovecsize + 1) * 3); for (i = 0; i <= ovecsize; i++) ovector[2 * i] = ovector[2 * i + 1] = -1; n = pcre_exec(re, NULL, lua_tostring(lua, 2), lua_strlen(lua, 2), 0, lua_tonumber(lua, 3), ovector, (ovecsize + 1) * 3); if (n > 0) for (i = 1; i < n; i++) if (ovector[2 * i] != -1 && ovector[2 * i + 1] != -1) lua_pushlstring(lua, lua_tostring(lua, 2) + ovector[2 * i], ovector[2 * i + 1] - ovector[2 * i]); else lua_pushnil(lua); xfree(ovector); lua_remove(lua, 1); lua_remove(lua, 1); lua_remove(lua, 1); lua_pushboolean(lua, (n > 0)); lua_insert(lua, 1); return (n > 0 ? n : 1); } /* * Lua implementation of a PCRE free function. */ static int ifre_free(lua_State *lua) { pcre *re; if (lua_gettop(lua) != 1) luaL_error(lua, "wrong number of arguments"); luaL_checktype(lua, 1, LUA_TUSERDATA); re = *(pcre **)(lua_touserdata(lua, 1)); xfree(re); lua_remove(lua, 1); return 0; } /* * Open imapfilter library of PCRE related functions. */ LUALIB_API int luaopen_ifre(lua_State *lua) { luaL_register(lua, "ifre", ifrelib); return 1; }