aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-20 13:35:12 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-20 13:35:12 +0100
commit9e188b09e38c6916ca74a65ad8298d9dd3587aa7 (patch)
tree54dd6c49a390b51ba1e2074de979b4f90dddaa59 /src/lua
parent8dc24577a0704c0d12cc716d073b3fee29794a2a (diff)
downloadrspamd-9e188b09e38c6916ca74a65ad8298d9dd3587aa7.tar.gz
rspamd-9e188b09e38c6916ca74a65ad8298d9dd3587aa7.zip
Add lua_regexp:matchn function.
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/lua_regexp.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/lua/lua_regexp.c b/src/lua/lua_regexp.c
index 34c240989..d8b3c8147 100644
--- a/src/lua/lua_regexp.c
+++ b/src/lua/lua_regexp.c
@@ -43,6 +43,7 @@ LUA_FUNCTION_DEF (regexp, get_cached);
LUA_FUNCTION_DEF (regexp, get_pattern);
LUA_FUNCTION_DEF (regexp, search);
LUA_FUNCTION_DEF (regexp, match);
+LUA_FUNCTION_DEF (regexp, matchn);
LUA_FUNCTION_DEF (regexp, split);
LUA_FUNCTION_DEF (regexp, destroy);
LUA_FUNCTION_DEF (regexp, gc);
@@ -50,6 +51,7 @@ LUA_FUNCTION_DEF (regexp, gc);
static const struct luaL_reg regexplib_m[] = {
LUA_INTERFACE_DEF (regexp, get_pattern),
LUA_INTERFACE_DEF (regexp, match),
+ LUA_INTERFACE_DEF (regexp, matchn),
LUA_INTERFACE_DEF (regexp, search),
LUA_INTERFACE_DEF (regexp, split),
LUA_INTERFACE_DEF (regexp, destroy),
@@ -346,6 +348,78 @@ lua_regexp_match (lua_State *L)
}
/***
+ * @method re:matchn(line, max_matches, [, raw_match])
+ * Matches line against the regular expression and return number of matches if line matches
+ * (partially or completely). This process stop when `max_matches` is reached.
+ * If `max_matches` is zero, then only a single match is counted which is equal to
+ * @see re:match If `max_matches` is negative, then all matches are considered.
+ *
+ * @param {string} line match the specified line against regexp object
+ * @param {number} max_matches maximum number of matches
+ * @param {bool} match raw regexp instead of utf8 one
+ * @return {table or nil} table of strings matched or nil
+ * @example
+ * local re = regexp.create_cached('/^\s*([0-9]+)\s*$/')
+ * -- returns nil
+ * local m1 = re:match('blah')
+ * local m2 = re:match(' 190 ')
+ */
+static int
+lua_regexp_matchn (lua_State *L)
+{
+ struct rspamd_lua_regexp *re = lua_check_regexp (L);
+ struct rspamd_lua_text *t;
+ const gchar *data = NULL, *start = NULL, *end = NULL;
+ gint max_matches, matches;
+ gsize len = 0;
+ gboolean raw = FALSE;
+
+ if (re && !IS_DESTROYED (re)) {
+ if (lua_type (L, 2) == LUA_TSTRING) {
+ data = luaL_checklstring (L, 2, &len);
+ }
+ else if (lua_type (L, 2) == LUA_TUSERDATA) {
+ t = lua_check_text (L, 2);
+ if (t != NULL) {
+ data = t->start;
+ len = t->len;
+ }
+ }
+
+ max_matches = lua_tonumber (L, 3);
+
+ if (lua_gettop (L) == 4) {
+ raw = lua_toboolean (L, 4);
+ }
+
+ if (data) {
+ matches = 0;
+
+ for (;;) {
+ if (rspamd_regexp_search (re->re, data, len, &start, &end, raw)) {
+ matches ++;
+ }
+ else {
+ break;
+ }
+
+ if (max_matches >= 0 && matches >= max_matches) {
+ break;
+ }
+ }
+
+ lua_pushnumber (L, matches);
+
+ return 1;
+ }
+ }
+
+ lua_pushnil (L);
+
+ return 1;
+}
+
+/***
* @method re:split(line)
* Split line using the specified regular expression.
* Breaks the string on the pattern, and returns an array of the tokens.