imapfilter/src/pcre.c
Lefteris Chatzimparmpas 2cafede975 Use session pointer to denote accounts
Instead of the account details, a pointer to the C structure is used in
Lua, stored as light userdata.

The 1.x deprecated configuration format has been removed, partly due to
the above change, and partly because it has been included for long
enough now.
2012-02-14 22:13:15 +01:00

276 lines
5.8 KiB
C

#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <pcre.h>
#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),
#if LUA_VERSION_NUM < 502
lua_objlen(lua, 2),
#else
lua_rawlen(lua, 2),
#endif
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)
{
#if LUA_VERSION_NUM < 502
luaL_register(lua, "ifre", ifrelib);
#else
luaL_newlib(lua, ifrelib);
lua_setglobal(lua, "ifre");
#endif
return 1;
}