mirror of
https://github.com/vxcontrol/lualibs-lrexlib.git
synced 2026-07-01 23:44:04 -04:00
Various improvements to GNU regex support:
1. Change default syntax to POSIX_EXTENDED, as agreed with Shmuel. 2. Add setsyntax function to set the syntax. Use it to run a much smaller emacs_sets.lua, while using common_sets.lua (with normal syntax) as the main test. This commit also introduces preliminary untested code to support translation arrays, and code to parse a syntax argument so per-regex syntax can be selected.
This commit is contained in:
+2
-2
@@ -113,8 +113,8 @@ Notes
|
||||
that are formed from the RE_SYNTAX_xxx identifiers defined in regex.h, by
|
||||
means of omitting the RE_SYNTAX\_ part. For example, RE_SYNTAX_GREP becomes
|
||||
``"GREP"`` on the Lua side. The default value, used when the parameter is
|
||||
not supplied or ``nil``, is either ``"EMACS"`` (at start-up), or the value
|
||||
set by the last setsyntax_ call.
|
||||
not supplied or ``nil``, is either ``"POSIX_EXTENDED"`` (at start-up),
|
||||
or the value set by the last setsyntax_ call.
|
||||
|
||||
**Oniguruma:** parameter *syntax* (*syn*) must be one of the predefined
|
||||
strings that are formed from the ONIG_SYNTAX_xxx identifiers defined in
|
||||
|
||||
@@ -20,6 +20,10 @@ static int generate_error (lua_State *L, const TUserdata *ud, int errcode);
|
||||
# define ALG_OPTSYNTAX(a,b,c)
|
||||
#endif
|
||||
|
||||
#ifndef ALG_OPTTRANSLATE
|
||||
# define ALG_OPTTRANSLATE(a,b,c)
|
||||
#endif
|
||||
|
||||
#ifndef DO_NAMED_SUBPATTERNS
|
||||
#define DO_NAMED_SUBPATTERNS(a,b,c)
|
||||
#endif
|
||||
@@ -118,6 +122,7 @@ static void checkarg_new (lua_State *L, TArgComp *argC) {
|
||||
argC->pattern = luaL_checklstring (L, 1, &argC->patlen);
|
||||
argC->cflags = ALG_GETCFLAGS (L, 2);
|
||||
ALG_OPTLOCALE (argC, L, 3);
|
||||
ALG_OPTTRANSLATE (argC, L, 3);
|
||||
ALG_OPTSYNTAX (argC, L, 4);
|
||||
}
|
||||
|
||||
@@ -138,6 +143,7 @@ static void checkarg_gsub (lua_State *L, TArgComp *argC, TArgExec *argE) {
|
||||
argC->cflags = ALG_GETCFLAGS (L, 5);
|
||||
argE->eflags = luaL_optint (L, 6, ALG_EFLAGS_DFLT);
|
||||
ALG_OPTLOCALE (argC, L, 7);
|
||||
ALG_OPTTRANSLATE (argC, L, 7);
|
||||
ALG_OPTSYNTAX (argC, L, 8);
|
||||
}
|
||||
|
||||
@@ -151,6 +157,7 @@ static void checkarg_find_func (lua_State *L, TArgComp *argC, TArgExec *argE) {
|
||||
argC->cflags = ALG_GETCFLAGS (L, 4);
|
||||
argE->eflags = luaL_optint (L, 5, ALG_EFLAGS_DFLT);
|
||||
ALG_OPTLOCALE (argC, L, 6);
|
||||
ALG_OPTTRANSLATE (argC, L, 6);
|
||||
ALG_OPTSYNTAX (argC, L, 7);
|
||||
}
|
||||
|
||||
@@ -163,6 +170,7 @@ static void checkarg_gmatch_split (lua_State *L, TArgComp *argC, TArgExec *argE)
|
||||
argC->cflags = ALG_GETCFLAGS (L, 3);
|
||||
argE->eflags = luaL_optint (L, 4, ALG_EFLAGS_DFLT);
|
||||
ALG_OPTLOCALE (argC, L, 5);
|
||||
ALG_OPTTRANSLATE (argC, L, 5);
|
||||
ALG_OPTSYNTAX (argC, L, 6);
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -31,10 +31,12 @@ typedef struct { /* compile arguments */
|
||||
size_t patlen;
|
||||
void * ud;
|
||||
int cflags;
|
||||
const char * locale; /* PCRE, Oniguruma */
|
||||
const unsigned char * tables; /* PCRE */
|
||||
int tablespos; /* PCRE */
|
||||
void * syntax; /* Oniguruma */
|
||||
const char * locale; /* PCRE, Oniguruma */
|
||||
const unsigned char * tables; /* PCRE */
|
||||
int tablespos; /* PCRE */
|
||||
void * syntax; /* Oniguruma */
|
||||
const unsigned char * translate; /* GNU */
|
||||
int gnusyn; /* GNU */
|
||||
} TArgComp;
|
||||
|
||||
typedef struct { /* exec arguments */
|
||||
|
||||
+96
-49
@@ -39,6 +39,12 @@ static int getcflags (lua_State *L, int pos);
|
||||
unsigned __REPB_PREFIX(newline_anchor) : 1;
|
||||
*/
|
||||
|
||||
static void opttranslate (TArgComp *argC, lua_State *L, int pos);
|
||||
#define ALG_OPTTRANSLATE(a,b,c) opttranslate(a,b,c)
|
||||
|
||||
static void optsyntax (TArgComp *argC, lua_State *L, int pos);
|
||||
#define ALG_OPTSYNTAX(a,b,c) optsyntax(a,b,c)
|
||||
|
||||
#define ALG_NOMATCH -1 /* FIXME: -2 for internal error is also possible; take arg like ALG_ISMATCH */
|
||||
#define ALG_ISMATCH(res) ((res) >= 0)
|
||||
#define ALG_SUBBEG(ud,n) ud->match.start[n]
|
||||
@@ -81,30 +87,10 @@ static int getcflags (lua_State *L, int pos) {
|
||||
case LUA_TNIL:
|
||||
return ALG_CFLAGS_DFLT;
|
||||
default:
|
||||
return luaL_typeerror (L, pos, "FIXME: translation tables not yet implemented");
|
||||
return luaL_typeerror (L, pos, "FIXME: compilation flags not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
|
||||
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
|
||||
isn't minimal, since other operators, such as \`, aren't disabled. */
|
||||
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
|
||||
|
||||
#define RE_SYNTAX_POSIX_EXTENDED \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
|
||||
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
|
||||
| RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||
|
||||
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
|
||||
removed and RE_NO_BK_REFS is added. */
|
||||
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
|
||||
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
|
||||
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||
|
||||
static int generate_error (lua_State *L, const TUserdata *ud, int errcode) {
|
||||
const char *errmsg;
|
||||
switch (errcode) {
|
||||
@@ -118,24 +104,99 @@ static int generate_error (lua_State *L, const TUserdata *ud, int errcode) {
|
||||
errmsg = "internal error in GNU regex";
|
||||
break;
|
||||
default:
|
||||
errmsg = "internal error in lrexlib";
|
||||
errmsg = "unknown error";
|
||||
}
|
||||
return luaL_error (L, "%s", errmsg);
|
||||
}
|
||||
|
||||
#define ALG_TRANSLATE_SIZE (UCHAR_MAX + 1)
|
||||
static void opttranslate (TArgComp *argC, lua_State *L, int pos) {
|
||||
if (!lua_isnoneornil (L, pos)) {
|
||||
unsigned i;
|
||||
|
||||
argC->translate = (const unsigned char *) Lmalloc (L, ALG_TRANSLATE_SIZE);
|
||||
memset ((unsigned char *) argC->translate, 0, ALG_TRANSLATE_SIZE); /* initialize all members to 0 */
|
||||
for (i = 0; i < ALG_TRANSLATE_SIZE; i++) {
|
||||
lua_pushinteger (L, i);
|
||||
lua_gettable (L, pos);
|
||||
if (lua_tostring (L, -1))
|
||||
((unsigned char *) argC->translate)[i] = *lua_tostring (L, -1);
|
||||
lua_pop (L, 1);
|
||||
}
|
||||
} else
|
||||
argC->translate = NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char * name;
|
||||
int value;
|
||||
} EncPair;
|
||||
|
||||
/* ATTENTION:
|
||||
This array must always be kept alphabetically sorted, as it's used in the
|
||||
binary search, so take care when manually inserting new elements.
|
||||
*/
|
||||
static EncPair Syntaxes[] = {
|
||||
{ "AWK", RE_SYNTAX_AWK },
|
||||
{ "ED", RE_SYNTAX_ED },
|
||||
{ "EGREP", RE_SYNTAX_EGREP },
|
||||
{ "EMACS", RE_SYNTAX_EMACS },
|
||||
{ "GNU_AWK", RE_SYNTAX_GNU_AWK },
|
||||
{ "GREP", RE_SYNTAX_GREP },
|
||||
{ "POSIX_AWK", RE_SYNTAX_POSIX_AWK },
|
||||
{ "POSIX_BASIC", RE_SYNTAX_POSIX_BASIC },
|
||||
{ "POSIX_EGREP", RE_SYNTAX_POSIX_EGREP },
|
||||
{ "POSIX_EXTENDED", RE_SYNTAX_POSIX_EXTENDED },
|
||||
{ "POSIX_MINIMAL_BASIC", RE_SYNTAX_POSIX_MINIMAL_BASIC },
|
||||
{ "POSIX_MINIMAL_EXTENDED", RE_SYNTAX_POSIX_MINIMAL_EXTENDED },
|
||||
{ "SED", RE_SYNTAX_SED },
|
||||
};
|
||||
|
||||
static int fcmp (const void *p1, const void *p2) {
|
||||
return strcmp (((EncPair*) p1)->name, ((EncPair*) p2)->name);
|
||||
}
|
||||
|
||||
static int getsyntax (lua_State *L, int pos) {
|
||||
EncPair key, *found;
|
||||
if ((key.name = luaL_optstring (L, pos, NULL)) == NULL)
|
||||
return RE_SYNTAX_POSIX_EXTENDED;
|
||||
found = (EncPair*) bsearch (&key, Syntaxes, sizeof (Syntaxes) / sizeof (EncPair),
|
||||
sizeof (EncPair), fcmp);
|
||||
if (found == NULL)
|
||||
luaL_argerror (L, pos, "invalid or unsupported syntax string");
|
||||
return found->value;
|
||||
}
|
||||
|
||||
static void optsyntax (TArgComp *argC, lua_State *L, int pos) {
|
||||
argC->gnusyn = getsyntax (L, pos);
|
||||
}
|
||||
|
||||
/*
|
||||
rex.setsyntax (syntax)
|
||||
@param syntax: one of the predefined strings listed in array 'Syntaxes'
|
||||
@return: nothing
|
||||
*/
|
||||
static int LGnu_setsyntax (lua_State *L) {
|
||||
(void) luaL_checkstring (L, 1);
|
||||
re_set_syntax (getsyntax (L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compile_regex (lua_State *L, const TArgComp *argC, TGnu **pud) {
|
||||
const char *res;
|
||||
TGnu *ud;
|
||||
reg_syntax_t old_syntax;
|
||||
/* reg_syntax_t old_syntax; */
|
||||
int ret;
|
||||
|
||||
ud = (TGnu *)lua_newuserdata (L, sizeof (TGnu));
|
||||
memset (ud, 0, sizeof (TGnu)); /* initialize all members to 0 */
|
||||
|
||||
/* translate table is never written to, so this cast is safe */
|
||||
/* FIXME: ud->r.translate = (unsigned char *) translate; */
|
||||
/* FIXME: take syntax parameter in cflags */
|
||||
/* old_syntax = re_set_syntax (cflags->syntax); */
|
||||
|
||||
/* translate table is never written to, so this cast is safe */
|
||||
ud->r.translate = (unsigned char *) argC->translate;
|
||||
|
||||
old_syntax = re_set_syntax (RE_SYNTAX_EMACS); /* FIXME: take syntax parameter in cflags */
|
||||
res = re_compile_pattern (argC->pattern, argC->patlen, &ud->r);
|
||||
if (res != NULL) {
|
||||
ud->errmsg = res;
|
||||
@@ -151,7 +212,7 @@ static int compile_regex (lua_State *L, const TArgComp *argC, TGnu **pud) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
re_set_syntax (old_syntax);
|
||||
/* FIXME: re_set_syntax (old_syntax); */
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -206,26 +267,10 @@ static int Gnu_tostring (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static flag_pair gnu_flags[] =
|
||||
{
|
||||
{ "SYNTAX_EMACS", RE_SYNTAX_EMACS },
|
||||
{ "SYNTAX_AWK", RE_SYNTAX_AWK },
|
||||
{ "SYNTAX_GNU_AWK", RE_SYNTAX_GNU_AWK },
|
||||
{ "SYNTAX_POSIX_AWK", RE_SYNTAX_POSIX_AWK },
|
||||
{ "SYNTAX_GREP", RE_SYNTAX_GREP },
|
||||
{ "SYNTAX_EGREP", RE_SYNTAX_EGREP },
|
||||
{ "SYNTAX_POSIX_EGREP", RE_SYNTAX_POSIX_EGREP },
|
||||
{ "SYNTAX_ED", RE_SYNTAX_ED },
|
||||
{ "SYNTAX_SED", RE_SYNTAX_SED },
|
||||
{ "SYNTAX_POSIX_BASIC", RE_SYNTAX_POSIX_BASIC },
|
||||
/*---------------------------------------------------------------------------*/
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static int Gnu_get_flags (lua_State *L) {
|
||||
const flag_pair* fps[] = { gnu_flags, NULL };
|
||||
return get_flags (L, fps);
|
||||
}
|
||||
/* static int Gnu_get_flags (lua_State *L) { */
|
||||
/* const flag_pair* fps[] = { gnu_flags, NULL }; */
|
||||
/* return get_flags (L, fps); */
|
||||
/* } */
|
||||
|
||||
static const luaL_reg gnumeta[] = {
|
||||
{ "exec", ud_exec },
|
||||
@@ -247,15 +292,17 @@ static const luaL_reg rexlib[] = {
|
||||
{ "gsub", gsub },
|
||||
{ "split", split },
|
||||
{ "new", ud_new },
|
||||
{ "flags", Gnu_get_flags },
|
||||
/* { "flags", Gnu_get_flags }, */
|
||||
{ "plainfind", plainfind_func },
|
||||
/* { "set_syntax", set_syntax }, */
|
||||
{ "setsyntax", LGnu_setsyntax },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Open the library */
|
||||
REX_API int REX_OPENLIB (lua_State *L)
|
||||
{
|
||||
re_set_syntax (RE_SYNTAX_POSIX_EXTENDED);
|
||||
|
||||
/* create a new function environment to serve as a metatable for methods */
|
||||
lua_newtable (L);
|
||||
lua_pushvalue (L, -1);
|
||||
|
||||
+1
-175
@@ -30,10 +30,7 @@ local function set_f_gmatch (lib, flg)
|
||||
Name = "Function gmatch",
|
||||
Func = test_gmatch,
|
||||
--{ subj patt results }
|
||||
{ {"ab", lib.new"."}, {{"a",N}, {"b",N} } },
|
||||
{ {("abcd"):rep(3), "\\(.\\)b.\\(d\\)"}, {{"a","d"},{"a","d"},{"a","d"}} },
|
||||
{ {"abcd", ".*" }, {{"abcd",N},{"",N} } },--zero-length match
|
||||
{ {"abc", "^." }, {{"a",N}} },--anchored pattern
|
||||
}
|
||||
end
|
||||
|
||||
@@ -52,19 +49,7 @@ local function set_f_split (lib, flg)
|
||||
Name = "Function split",
|
||||
Func = test_split,
|
||||
--{ subj patt results }
|
||||
{ {"ab", lib.new","}, {{"ab",N,N}, } },
|
||||
{ {"ab", ","}, {{"ab",N,N}, } },
|
||||
{ {",", ","}, {{"",",",N}, {"", N, N}, } },
|
||||
{ {",,", ","}, {{"",",",N}, {"",",",N}, {"",N,N} } },
|
||||
{ {"a,b", ","}, {{"a",",",N}, {"b",N,N}, } },
|
||||
{ {",a,b", ","}, {{"",",",N}, {"a",",",N}, {"b",N,N}} },
|
||||
{ {"a,b,", ","}, {{"a",",",N}, {"b",",",N}, {"",N,N} } },
|
||||
{ {"a,,b", ","}, {{"a",",",N}, {"",",",N}, {"b",N,N}} },
|
||||
{ {"ab<78>c", "<\\(.\\)\\(.\\)>"}, {{"ab","7","8"}, {"c",N,N}, } },
|
||||
{ {"abc", "^."}, {{"", "a",N}, {"bc",N,N}, } },--anchored pattern
|
||||
{ {"abc", "^"}, {{"", "", N}, {"abc",N,N}, } },
|
||||
-- { {"abc", "$"}, {{"abc","",N}, {"",N,N}, } },
|
||||
-- { {"abc", "^|$"}, {{"", "", N}, {"abc","",N},{"",N,N},} },
|
||||
}
|
||||
end
|
||||
|
||||
@@ -73,12 +58,6 @@ local function set_f_find (lib, flg)
|
||||
Name = "Function find",
|
||||
Func = lib.find,
|
||||
-- {subj, patt, st}, { results }
|
||||
{ {"abcd", lib.new".+"}, { 1,4 } }, -- [none]
|
||||
{ {"abcd", ".+"}, { 1,4 } }, -- [none]
|
||||
{ {"abcd", ".+", 2}, { 2,4 } }, -- positive st
|
||||
{ {"abcd", ".+", -2}, { 3,4 } }, -- negative st
|
||||
{ {"abcd", ".*"}, { 1,4 } }, -- [none]
|
||||
{ {"abc", "bc"}, { 2,3 } }, -- [none]
|
||||
{ {"abcd", "\\(.\\)b.\\(d\\)"}, { 1,4,"a","d" }}, -- [captures]
|
||||
}
|
||||
end
|
||||
@@ -88,12 +67,6 @@ local function set_f_match (lib, flg)
|
||||
Name = "Function match",
|
||||
Func = lib.match,
|
||||
-- {subj, patt, st}, { results }
|
||||
{ {"abcd", lib.new".+"}, {"abcd"} }, -- [none]
|
||||
{ {"abcd", ".+"}, {"abcd"} }, -- [none]
|
||||
{ {"abcd", ".+", 2}, {"bcd"} }, -- positive st
|
||||
{ {"abcd", ".+", -2}, {"cd"} }, -- negative st
|
||||
{ {"abcd", ".*"}, {"abcd"} }, -- [none]
|
||||
{ {"abc", "bc"}, {"bc"} }, -- [none]
|
||||
{ {"abcd", "\\(.\\)b.\\(d\\)"}, {"a","d"} }, -- [captures]
|
||||
}
|
||||
end
|
||||
@@ -103,11 +76,6 @@ local function set_m_exec (lib, flg)
|
||||
Name = "Method exec",
|
||||
Method = "exec",
|
||||
--{patt}, {subj, st} { results }
|
||||
{ {".+"}, {"abcd"}, {1,4,{}} }, -- [none]
|
||||
{ {".+"}, {"abcd",2}, {2,4,{}} }, -- positive st
|
||||
{ {".+"}, {"abcd",-2}, {3,4,{}} }, -- negative st
|
||||
{ {".*"}, {"abcd"}, {1,4,{}} }, -- [none]
|
||||
{ {"bc"}, {"abc"}, {2,3,{}} }, -- [none]
|
||||
{ { "\\(.\\)b.\\(d\\)"}, {"abcd"}, {1,4,{1,1,4,4}}},--[captures]
|
||||
{ {"\\(a+\\)6+\\(b+\\)"}, {"Taa66bbT",2}, {2,7,{2,3,6,7}}},--[st+captures]
|
||||
}
|
||||
@@ -118,11 +86,6 @@ local function set_m_tfind (lib, flg)
|
||||
Name = "Method tfind",
|
||||
Method = "tfind",
|
||||
--{patt}, {subj, st} { results }
|
||||
{ {".+"}, {"abcd"}, {1,4,{}} }, -- [none]
|
||||
{ {".+"}, {"abcd",2}, {2,4,{}} }, -- positive st
|
||||
{ {".+"}, {"abcd",-2}, {3,4,{}} }, -- negative st
|
||||
{ {".*"}, {"abcd"}, {1,4,{}} }, -- [none]
|
||||
{ {"bc"}, {"abc"}, {2,3,{}} }, -- [none]
|
||||
{ {"\\(.\\)b.\\(d\\)"}, {"abcd"}, {1,4,{"a","d"}}},--[captures]
|
||||
}
|
||||
end
|
||||
@@ -132,11 +95,6 @@ local function set_m_find (lib, flg)
|
||||
Name = "Method find",
|
||||
Method = "find",
|
||||
--{patt}, {subj, st} { results }
|
||||
{ {".+"}, {"abcd"}, {1,4} }, -- [none]
|
||||
{ {".+"}, {"abcd",2}, {2,4} }, -- positive st
|
||||
{ {".+"}, {"abcd",-2}, {3,4} }, -- negative st
|
||||
{ {".*"}, {"abcd"}, {1,4} }, -- [none]
|
||||
{ {"bc"}, {"abc"}, {2,3} }, -- [none]
|
||||
{ {"\\(.\\)b.\\(d\\)"}, {"abcd"}, {1,4,"a","d"}},--[captures]
|
||||
}
|
||||
end
|
||||
@@ -146,107 +104,20 @@ local function set_m_match (lib, flg)
|
||||
Name = "Method match",
|
||||
Method = "match",
|
||||
--{patt}, {subj, st} { results }
|
||||
{ {".+"}, {"abcd"}, {"abcd"} }, -- [none]
|
||||
{ {".+"}, {"abcd",2}, {"bcd" } }, -- positive st
|
||||
{ {".+"}, {"abcd",-2}, {"cd" } }, -- negative st
|
||||
{ {".*"}, {"abcd"}, {"abcd"} }, -- [none]
|
||||
{ {"bc"}, {"abc"}, {"bc" } }, -- [none]
|
||||
{{ "\\(.\\)b.\\(d\\)"}, {"abcd"}, {"a","d"} }, --[captures]
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_plainfind (lib, flg)
|
||||
return {
|
||||
Name = "Function plainfind",
|
||||
Func = lib.plainfind,
|
||||
--{ subj, patt, st, ci } { results }
|
||||
{ {"abcd", "bc"}, {2,3} }, -- [none]
|
||||
{ {"abcd", "dc"}, {N} }, -- [none]
|
||||
{ {"abcd", "cd"}, {3,4} }, -- positive st
|
||||
{ {"abcd", "cd", 3}, {3,4} }, -- positive st
|
||||
{ {"abcd", "cd", 4}, {N} }, -- failing st
|
||||
{ {"abcd", "bc", 2}, {2,3} }, -- positive st
|
||||
{ {"abcd", "bc", -4}, {2,3} }, -- negative st
|
||||
{ {"abcd", "bc", 3}, {N} }, -- failing st
|
||||
{ {"abcd", "BC"}, {N} }, -- case sensitive
|
||||
{ {"abcd", "BC", N, true}, {2,3} }, -- case insensitive
|
||||
{ {"ab\0cd", "b\0c"}, {2,4} }, -- contains nul
|
||||
{ {"abcd", "", 1}, {1,0} }, -- empty pattern
|
||||
{ {"abcd", "", 5}, {5,4} }, -- empty pattern
|
||||
{ {"abcd", "", 6}, {N} }, -- empty pattern
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub1 (lib, flg)
|
||||
local subj, pat = "abcdef", "[abef]+"
|
||||
local cpat = lib.new(pat)
|
||||
return {
|
||||
Name = "Function gsub, set1",
|
||||
Func = get_gsub (lib),
|
||||
--{ s, p, f, n, res1, res2, res3 },
|
||||
{ {subj, cpat, "", 0}, {subj, 0, 0} }, -- test "n" + empty_replace
|
||||
{ {subj, pat, "", 0}, {subj, 0, 0} }, -- test "n" + empty_replace
|
||||
{ {subj, pat, "", -1}, {subj, 0, 0} }, -- test "n" + empty_replace
|
||||
{ {subj, pat, "", 1}, {"cdef", 1, 1} },
|
||||
{ {subj, pat, "", 2}, {"cd", 2, 2} },
|
||||
{ {subj, pat, "", 3}, {"cd", 2, 2} },
|
||||
{ {subj, pat, "" }, {"cd", 2, 2} },
|
||||
{ {subj, pat, "#", 0}, {subj, 0, 0} }, -- test "n" + non-empty_replace
|
||||
{ {subj, pat, "#", 1}, {"#cdef", 1, 1} },
|
||||
{ {subj, pat, "#", 2}, {"#cd#", 2, 2} },
|
||||
{ {subj, pat, "#", 3}, {"#cd#", 2, 2} },
|
||||
{ {subj, pat, "#" }, {"#cd#", 2, 2} },
|
||||
{ {"abc", "^.", "#" }, {"#bc", 1, 1} }, -- anchored pattern
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub2 (lib, flg)
|
||||
local subj, pat = "abc", "\\([ac]\\)"
|
||||
return {
|
||||
Name = "Function gsub, set2",
|
||||
Func = get_gsub (lib),
|
||||
--{ s, p, f, n, res1, res2, res3 },
|
||||
{ {subj, pat, "<%1>" }, {"<a>b<c>", 2, 2} }, -- test non-escaped chars in f
|
||||
{ {subj, pat, "%<%1%>" }, {"<a>b<c>", 2, 2} }, -- test escaped chars in f
|
||||
{ {subj, pat, "" }, {"b", 2, 2} }, -- test empty replace
|
||||
{ {subj, pat, "1" }, {"1b1", 2, 2} }, -- test odd and even %'s in f
|
||||
{ {subj, pat, "%1" }, {"abc", 2, 2} },
|
||||
{ {subj, pat, "%%1" }, {"%1b%1", 2, 2} },
|
||||
{ {subj, pat, "%%%1" }, {"%ab%c", 2, 2} },
|
||||
{ {subj, pat, "%%%%1" }, {"%%1b%%1", 2, 2} },
|
||||
{ {subj, pat, "%%%%%1" }, {"%%ab%%c", 2, 2} },
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub3 (lib, flg)
|
||||
return {
|
||||
Name = "Function gsub, set3",
|
||||
Func = get_gsub (lib),
|
||||
--{ s, p, f, n, res1,res2,res3 },
|
||||
{ {"abc", "a", "%0" }, {"abc", 1, 1} }, -- test (in)valid capture index
|
||||
{ {"abc", "a", "%1" }, {"abc", 1, 1} },
|
||||
{ {"abc", "[ac]", "%1" }, {"abc", 2, 2} },
|
||||
{ {"abc", "\\(a\\)", "%1" }, {"abc", 1, 1} },
|
||||
{ {"abc", "\\(a\\)", "%2" }, "invalid capture index" },
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub4 (lib, flg)
|
||||
return {
|
||||
Name = "Function gsub, set4",
|
||||
Func = get_gsub (lib),
|
||||
--{ s, p, f, n, res1, res2, res3 },
|
||||
{ {"a2c3", ".", "#" }, {"####", 4, 4} }, -- test .
|
||||
{ {"a2c3", ".+", "#" }, {"#", 1, 1} }, -- test .+
|
||||
{ {"a2c3", ".*", "#" }, {"##", 2, 2} }, -- test .*
|
||||
{ {"/* */ */", "\\/\\*\\(.*\\)\\*\\/", "#" }, {"#", 1, 1} },
|
||||
{ {"a2c3", "[0-9]", "#" }, {"a#c#", 2, 2} }, -- test %d
|
||||
{ {"a2c3", "[^0-9]", "#" }, {"#2#3", 2, 2} }, -- test %D
|
||||
{ {"a \t\nb", "[ \t\n]", "#" }, {"a###b", 3, 3} }, -- test %s
|
||||
{ {"a \t\nb", "[^ \t\n]", "#" }, {"# \t\n#", 2, 2} }, -- test %S
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub5 (lib, flg)
|
||||
local function frep1 () end -- returns nothing
|
||||
local function frep2 () return "#" end -- ignores arguments
|
||||
@@ -262,13 +133,6 @@ local function set_f_gsub5 (lib, flg)
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", frep1 }, {subj, 1, 0} },
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", frep2 }, {"#", 1, 1} },
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", frep3 }, {"2,3", 1, 1} },
|
||||
{ {subj, "a.c.", frep3 }, {subj, 1, 1} },
|
||||
{ {subj, "z*", frep1 }, {subj, 5, 0} },
|
||||
{ {subj, "z*", frep2 }, {"#a#2#c#3#", 5, 5} },
|
||||
{ {subj, "z*", frep3 }, {subj, 5, 5} },
|
||||
{ {subj, subj, frep4 }, "invalid return type" },
|
||||
{ {"abc",".", frep5 }, {"777", 3, 3} },
|
||||
{ {"abc",".", frep6 }, {"777", 3, 3} },
|
||||
}
|
||||
end
|
||||
|
||||
@@ -282,45 +146,12 @@ local function set_f_gsub6 (lib, flg)
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", tab1 }, {subj, 1, 0} },
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", tab2 }, {"56", 1, 1} },
|
||||
{ {subj, "a\\(.\\)c\\(.\\)", tab3 }, "invalid replacement type" },
|
||||
{ {subj, "a.c.", tab1 }, {subj, 1, 0} },
|
||||
{ {subj, "a.c.", tab2 }, {subj, 1, 0} },
|
||||
{ {subj, "a.c.", tab3 }, {subj, 1, 0} },
|
||||
}
|
||||
end
|
||||
|
||||
local function set_f_gsub8 (lib, flg)
|
||||
local subj, patt, repl = "abcdef", "..", "*"
|
||||
return {
|
||||
Name = "Function gsub, set8",
|
||||
Func = get_gsub (lib),
|
||||
--{ s, p, f, n, res1, res2, res3 },
|
||||
{ {subj, patt, repl, function() end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return nil end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return false end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return true end }, {"***", 3, 3} },
|
||||
{ {subj, patt, repl, function() return {} end }, {"***", 3, 3} },
|
||||
{ {subj, patt, repl, function() return "#" end }, {"###", 3, 3} },
|
||||
{ {subj, patt, repl, function() return 57 end }, {"575757", 3, 3} },
|
||||
{ {subj, patt, repl, function (from) return from end }, {"135", 3, 3} },
|
||||
{ {subj, patt, repl, function (from, to) return to end }, {"246", 3, 3} },
|
||||
{ {subj, patt, repl, function (from,to,rep) return rep end },
|
||||
{"***", 3, 3} },
|
||||
{ {subj, patt, repl, function (from, to, rep) return rep..to..from end },
|
||||
{"*21*43*65", 3, 3} },
|
||||
{ {subj, patt, repl, function() return nil end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return nil, nil end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return nil, false end }, {"abcdef", 3, 0} },
|
||||
{ {subj, patt, repl, function() return nil, true end }, {"ab**", 3, 2} },
|
||||
{ {subj, patt, repl, function() return true, true end }, {"***", 3, 3} },
|
||||
{ {subj, patt, repl, function() return nil, 0 end }, {"abcdef", 1, 0} },
|
||||
{ {subj, patt, repl, function() return true, 0 end }, {"*cdef", 1, 1} },
|
||||
{ {subj, patt, repl, function() return nil, 1 end }, {"ab*ef", 2, 1} },
|
||||
{ {subj, patt, repl, function() return true, 1 end }, {"**ef", 2, 2} },
|
||||
}
|
||||
end
|
||||
|
||||
return function (libname)
|
||||
local lib = require (libname)
|
||||
_G[libname].setsyntax ("EMACS")
|
||||
return {
|
||||
set_f_gmatch (lib),
|
||||
set_f_split (lib),
|
||||
@@ -330,13 +161,8 @@ return function (libname)
|
||||
set_m_tfind (lib),
|
||||
set_m_find (lib),
|
||||
set_m_match (lib),
|
||||
set_f_gsub1 (lib),
|
||||
set_f_gsub2 (lib),
|
||||
set_f_gsub3 (lib),
|
||||
set_f_gsub4 (lib),
|
||||
set_f_gsub5 (lib),
|
||||
set_f_gsub6 (lib),
|
||||
set_f_gsub8 (lib),
|
||||
set_f_plainfind (lib),
|
||||
}
|
||||
end
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ local function test_library (libname, setfile, verbose)
|
||||
end
|
||||
|
||||
local avail_tests = {
|
||||
gnu = { lib = "rex_gnu", "emacs_sets", },
|
||||
gnu = { lib = "rex_gnu", "common_sets", "emacs_sets", }, -- N.B. emacs_sets must come last as it globally sets the syntax
|
||||
posix = { lib = "rex_posix", "common_sets", "posix_sets", },
|
||||
spencer = { lib = "rex_spencer", "common_sets", "posix_sets", "spencer_sets" },
|
||||
posix1 = { lib = "rex_posix1", "common_sets", "posix_sets", "spencer_sets" },
|
||||
|
||||
Reference in New Issue
Block a user