The patch was removed in the previous message 
So here it is (for real).
From 9091c40e22f6fd0ca2173ecbeb1f932502cc8ac6 Mon Sep 17 00:00:00 2001
From: “Jader H. Silva” [email protected]
Date: Fri, 13 Jul 2012 18:06:32 -0300
Subject: [PATCH] Add ngx.re.split function
src/ngx_http_lua_regex.c | 443
++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 443 insertions(+)
diff --git a/src/ngx_http_lua_regex.c b/src/ngx_http_lua_regex.c
index 108070c…aa5d445 100644
— a/src/ngx_http_lua_regex.c
+++ b/src/ngx_http_lua_regex.c
@@ -74,6 +74,7 @@ static int ngx_http_lua_ngx_re_match(lua_State *L);
static int ngx_http_lua_ngx_re_gmatch(lua_State *L);
static int ngx_http_lua_ngx_re_sub(lua_State *L);
static int ngx_http_lua_ngx_re_gsub(lua_State *L);
+static int ngx_http_lua_ngx_re_split(lua_State *L);
static void ngx_http_lua_regex_free_study_data(ngx_pool_t *pool,
pcre_extra *sd);
static ngx_int_t ngx_lua_regex_compile(ngx_lua_regex_compile_t *rc);
@@ -1611,6 +1612,445 @@ error:
return luaL_error(L, msg);
}
+static int
+ngx_http_lua_ngx_re_split(lua_State *L)
+{
but got %d",
-
nargs);
- }
-
- lua_pushlightuserdata(L, &ngx_http_lua_request_key);
- lua_rawget(L, LUA_GLOBALSINDEX);
- r = lua_touserdata(L, -1);
- lua_pop(L, 1);
-
- if (r == NULL) {
-
return luaL_error(L, "no request object found");
- }
-
- subj.data = (u_char *) luaL_checklstring(L, 1, &subj.len);
- pat.data = (u_char *) luaL_checklstring(L, 2, &pat.len);
-
- if (nargs >= 3) {
-
opts.data = (u_char *) luaL_checklstring(L, 3, &opts.len);
-
-
if (nargs == 4) {
-
limit = luaL_checkinteger(L, 4);
-
lua_pop(L, 1);
-
-
} else {/* nargs == 3 */
-
limit = -1;
-
}
-
- } else { /* nargs == 2 */
-
opts.data = (u_char *) "";
-
opts.len = 0;
- }
-
- ngx_memzero(&re_comp, sizeof(ngx_lua_regex_compile_t));
-
- /* stack: subj regex repl */
-
- re_comp.options = 0;
-
- flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 4);
-
- if (flags & NGX_LUA_RE_COMPILE_ONCE) {
-
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
-
pool = lmcf->pool;
-
-
dd("server pool %p", lmcf->pool);
-
-
lua_pushlightuserdata(L, &ngx_http_lua_regex_cache_key);
-
lua_rawget(L, LUA_REGISTRYINDEX); /* table */
-
-
lua_pushliteral(L, "s");
-
lua_pushinteger(L, tpl.len);
-
lua_pushliteral(L, ":");
-
lua_pushvalue(L, 2);
-
-
if (tpl.len != 0) {
-
lua_pushvalue(L, 3);
-
}
-
-
dd("options size: %d", (int) sizeof(re_comp.options));
-
-
lua_pushlstring(L, (char *) &re_comp.options,
sizeof(re_comp.options));
-
/* table regex opts */
-
-
if (tpl.len == 0) {
-
lua_concat(L, 5); /* table key */
-
-
} else {
-
lua_concat(L, 6); /* table key */
-
}
-
-
lua_pushvalue(L, -1); /* table key key */
-
-
dd("regex cache key: %.*s", (int) (pat.len +
sizeof(re_comp.options)),
-
lua_tostring(L, -1));
-
-
lua_rawget(L, -3); /* table key re */
-
re = lua_touserdata(L, -1);
-
-
lua_pop(L, 1); /* table key */
-
-
if (re) {
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"lua regex cache hit for split regex \"%s\" with
options "
-
"\"%s\"", pat.data, opts.data);
-
-
lua_pop(L, 2);
-
-
dd("restoring regex %p, ncaptures %d, captures %p",
re->regex,
-
re->ncaptures, re->captures);
-
-
re_comp.regex = re->regex;
-
sd = re->regex_sd;
-
re_comp.captures = re->ncaptures;
-
cap = re->captures;
-
ctpl = re->replace;
-
-
if (flags & NGX_LUA_RE_MODE_DFA) {
-
ovecsize = 2;
-
-
} else {
-
ovecsize = (re->ncaptures + 1) * 3;
-
}
-
-
goto exec;
-
}
-
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"lua regex cache miss for split regex \"%s\" with
options "
{
+
lmcf->regex_cache_max_entries) {
-
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
-
"lua exceeding regex cache max entries (%i)",
-
lmcf->regex_cache_max_entries);
-
-
lmcf->regex_cache_entries++;
-
}
-
-
pool = r->pool;
-
flags &= ~NGX_LUA_RE_COMPILE_ONCE;
-
}
-
- } else {
-
pool = r->pool;
- }
-
- re_comp.pattern = pat;
- re_comp.err.len = NGX_MAX_CONF_ERRSTR;
- re_comp.err.data = errstr;
- re_comp.pool = pool;
-
- dd(“compiling regex”);
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"lua compiling split regex \"%s\" with options \"%s\" "
-
"(compile once: %d) (dfa mode: %d) (jit mode: %d)",
-
pat.data, opts.data,
-
(flags & NGX_LUA_RE_COMPILE_ONCE) != 0,
-
(flags & NGX_LUA_RE_MODE_DFA) != 0,
-
(flags & NGX_LUA_RE_MODE_JIT) != 0);
-
- old_pool = ngx_http_lua_pcre_malloc_init(pool);
-
- rc = ngx_lua_regex_compile(&re_comp);
-
- ngx_http_lua_pcre_malloc_done(old_pool);
-
- if (rc != NGX_OK) {
-
dd("compile failed");
-
-
re_comp.err.data[re_comp.err.len] = '\0';
-
msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
-
pat.data, re_comp.err.data);
-
-
return luaL_argerror(L, 2, msg);
- }
-
+#if LUA_HAVE_PCRE_JIT
+
- if (flags & NGX_LUA_RE_MODE_JIT) {
-
-
old_pool = ngx_http_lua_pcre_malloc_init(pool);
-
-
sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);
-
-
ngx_http_lua_pcre_malloc_done(old_pool);
-
+# if (NGX_DEBUG)
-
dd("sd = %p", sd);
-
-
if (msg != NULL) {
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"pcre study failed with PCRE_STUDY_JIT_COMPILE: %s
(%p)",
-
msg, sd);
-
}
-
-
if (sd != NULL) {
-
int jitted;
-
-
old_pool = ngx_http_lua_pcre_malloc_init(pool);
-
-
pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);
-
-
ngx_http_lua_pcre_malloc_done(old_pool);
-
-
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"pcre JIT compiling result: %d", jitted);
-
}
+# endif /* NGX_DEBUG */
+
- } else {
-
-
old_pool = ngx_http_lua_pcre_malloc_init(pool);
-
-
sd = pcre_study(re_comp.regex, 0, &msg);
-
-
ngx_http_lua_pcre_malloc_done(old_pool);
-
+# if (NGX_DEBUG)
-
dd("sd = %p", sd);
-
-
if (msg != NULL) {
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"pcre_study failed with PCRE_STUDY_JIT_COMPILE: %s
(%p)",
+# endif /* NGX_DEBUG */
+#else /* LUA_HAVE_PCRE_JIT */
+
- if (flags & NGX_LUA_RE_MODE_JIT) {
-
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"your pcre build does not have JIT support and "
-
"the \"j\" regex option is ignored");
- }
-
+#endif /* LUA_HAVE_PCRE_JIT */
+
- dd(“compile done, captures %d”, re_comp.captures);
-
- if (flags & NGX_LUA_RE_MODE_DFA) {
-
ovecsize = 2;
-
- } else {
-
ovecsize = (re_comp.captures + 1) * 3;
- }
-
- cap = ngx_palloc(pool, ovecsize * sizeof(int));
- if (cap == NULL) {
-
flags &= ~NGX_LUA_RE_COMPILE_ONCE;
-
msg = "out of memory";
-
goto error;
- }
-
- if (flags & NGX_LUA_RE_COMPILE_ONCE) {
-
-
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-
"lua saving compiled sub regex (%d captures) into the
cache "
-
"(entries %i)", re_comp.captures,
-
lmcf ? lmcf->regex_cache_entries : 0);
-
-
re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
-
if (re == NULL) {
-
return luaL_error(L, "out of memory");
-
}
-
-
dd("saving regex %p, ncaptures %d, captures %p",
re_comp.regex,
-
re_comp.captures, cap);
-
-
re->regex = re_comp.regex;
-
re->regex_sd = sd;
-
re->ncaptures = re_comp.captures;
-
re->captures = cap;
-
re->replace = ctpl;
-
-
lua_pushlightuserdata(L, re); /* table key value */
-
lua_rawset(L, -3); /* table */
-
lua_pop(L, 1);
-
-
if (lmcf) {
-
lmcf->regex_cache_entries++;
-
}
- }
-
+exec:
+#if LUA_HAVE_PCRE_DFA
+
-
int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
-
rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,
-
offset, cap, ovecsize, ws,
NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT);
+
+#else /* LUA_HAVE_PCRE_DFA */
+
+#endif /* LUA_HAVE_PCRE_DFA */
+
offset,
cap,
"%s" "
-
"using \"%s\"", (int) rc, subj.data, pat.data);
-
goto error;
-
}
-
-
if (rc == 0) {
-
if (flags & NGX_LUA_RE_MODE_DFA) {
-
rc = 1;
-
-
} else {
-
msg = "capture size too small";
-
goto error;
-
}
-
}
-
-
dd("rc = %d", (int) rc);
-
-
count++;
-
-
luaL_buffinit(L, &luabuf);
-
-
luaL_addlstring(&luabuf, (char *) &subj.data[offset],
-
cap[0] - offset);
-
-
lua_pushnumber(L, count);
-
luaL_pushresult(&luabuf);
-
lua_settable(L, -3);
-
-
offset = cap[1];
-
- }
-
- if (count == 0) {
-
dd("no match, just the original subject");
-
-
lua_pushnumber(L, count+1);
-
lua_pushvalue(L, 1);
-
lua_settable(L, -3);
-
- } else {
-
if (offset != (int) subj.len) {
-
dd("adding trailer: %s (len %d)", &subj.data[offset],
-
(int) (subj.len - offset));
-
-
luaL_buffinit(L, &luabuf);
-
-
luaL_addlstring(&luabuf, (char *) &subj.data[offset],
-
subj.len - offset);
-
-
lua_pushnumber(L, count+1);
-
luaL_pushresult(&luabuf);
-
lua_settable(L, -3);
-
-
}
-
-
dd("the dst string: %s", lua_tostring(L, -1));
- }
-
- if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
-
if (sd) {
-
ngx_http_lua_regex_free_study_data(pool, sd);
-
}
-
-
if (re_comp.regex) {
-
ngx_pfree(pool, re_comp.regex);
-
}
-
-
if (ctpl) {
-
ngx_pfree(pool, ctpl);
-
}
-
-
if (cap) {
-
ngx_pfree(pool, cap);
-
}
- }
-
- return 1;
-
+error:
- if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
-
if (sd) {
-
ngx_http_lua_regex_free_study_data(pool, sd);
-
}
-
-
if (re_comp.regex) {
-
ngx_pfree(pool, re_comp.regex);
-
}
-
-
if (ctpl) {
-
ngx_pfree(pool, ctpl);
-
}
-
-
if (cap) {
-
ngx_pfree(pool, cap);
-
}
- }
-
- return luaL_error(L, msg);
+}
void
ngx_http_lua_inject_regex_api(lua_State *L)
@@ -1631,6 +2071,9 @@ ngx_http_lua_inject_regex_api(lua_State *L)
lua_pushcfunction(L, ngx_http_lua_ngx_re_gsub);
lua_setfield(L, -2, “gsub”);
- lua_pushcfunction(L, ngx_http_lua_ngx_re_split);
- lua_setfield(L, -2, “split”);
- lua_setfield(L, -2, “re”);
}
–
1.7.9.5
2012/7/13 Jader H. Silva [email protected]