mirror of
https://github.com/lua/lua
synced 2025-03-31 01:53:06 +03:00
first implementation of `gfind'
This commit is contained in:
parent
71c716e5a8
commit
c97dc294a9
62
lstrlib.c
62
lstrlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** $Id: lstrlib.c,v 1.77 2002/02/08 22:39:36 roberto Exp roberto $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -434,12 +434,18 @@ static void push_onecapture (MatchState *ms, int i) {
|
||||
}
|
||||
|
||||
|
||||
static int push_captures (MatchState *ms) {
|
||||
static int push_captures (MatchState *ms, const char *s, const char *e) {
|
||||
int i;
|
||||
luaL_check_stack(ms->L, ms->level, "too many captures");
|
||||
for (i=0; i<ms->level; i++)
|
||||
push_onecapture(ms, i);
|
||||
return ms->level; /* number of strings pushed */
|
||||
if (ms->level == 0 && s) { /* no explicit captures? */
|
||||
lua_pushlstring(ms->L, s, e-s); /* return whole match */
|
||||
return 1;
|
||||
}
|
||||
else { /* return all captures */
|
||||
for (i=0; i<ms->level; i++)
|
||||
push_onecapture(ms, i);
|
||||
return ms->level; /* number of strings pushed */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -472,7 +478,7 @@ static int str_find (lua_State *L) {
|
||||
if ((res=match(&ms, s1, p)) != NULL) {
|
||||
lua_pushnumber(L, s1-s+1); /* start */
|
||||
lua_pushnumber(L, res-s); /* end */
|
||||
return push_captures(&ms) + 2;
|
||||
return push_captures(&ms, NULL, 0) + 2;
|
||||
}
|
||||
} while (s1++<ms.src_end && !anchor);
|
||||
}
|
||||
@ -481,7 +487,44 @@ static int str_find (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static void add_s (MatchState *ms, luaL_Buffer *b) {
|
||||
static int gfind_aux (lua_State *L) {
|
||||
MatchState ms;
|
||||
const char *s = lua_tostring(L, lua_upvalueindex(1));
|
||||
size_t ls = lua_strlen(L, lua_upvalueindex(1));
|
||||
const char *p = lua_tostring(L, lua_upvalueindex(2));
|
||||
const char *src;
|
||||
ms.L = L;
|
||||
ms.src_init = s;
|
||||
ms.src_end = s+ls;
|
||||
for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3));
|
||||
src <= ms.src_end;
|
||||
src++) {
|
||||
const char *e;
|
||||
ms.level = 0;
|
||||
if ((e = match(&ms, src, p)) != NULL) {
|
||||
int newstart = e-s;
|
||||
if (e == src) newstart++; /* empty match? go at least one position */
|
||||
lua_pushnumber(L, newstart);
|
||||
lua_replace(L, lua_upvalueindex(3));
|
||||
return push_captures(&ms, src, e);
|
||||
}
|
||||
}
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
|
||||
static int gfind (lua_State *L) {
|
||||
luaL_check_string(L, 1);
|
||||
luaL_check_string(L, 2);
|
||||
lua_settop(L, 2);
|
||||
lua_pushnumber(L, 0);
|
||||
lua_pushcclosure(L, gfind_aux, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void add_s (MatchState *ms, luaL_Buffer *b,
|
||||
const char *s, const char *e) {
|
||||
lua_State *L = ms->L;
|
||||
if (lua_isstring(L, 3)) {
|
||||
const char *news = lua_tostring(L, 3);
|
||||
@ -505,7 +548,7 @@ static void add_s (MatchState *ms, luaL_Buffer *b) {
|
||||
else { /* is a function */
|
||||
int n;
|
||||
lua_pushvalue(L, 3);
|
||||
n = push_captures(ms);
|
||||
n = push_captures(ms, s, e);
|
||||
lua_rawcall(L, n, 1);
|
||||
if (lua_isstring(L, -1))
|
||||
luaL_addvalue(b); /* add return to accumulated result */
|
||||
@ -537,7 +580,7 @@ static int str_gsub (lua_State *L) {
|
||||
e = match(&ms, src, p);
|
||||
if (e) {
|
||||
n++;
|
||||
add_s(&ms, &b);
|
||||
add_s(&ms, &b, src, e);
|
||||
}
|
||||
if (e && e>src) /* non empty match? */
|
||||
src = e; /* skip it */
|
||||
@ -674,6 +717,7 @@ static const luaL_reg strlib[] = {
|
||||
{"concat", str_concat},
|
||||
{"format", str_format},
|
||||
{"strfind", str_find},
|
||||
{"gfind", gfind},
|
||||
{"gsub", str_gsub}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user