static void str_gsub (void) { int32 srcl; const char *src = luaL_check_lstr(1, &srcl); const char *p = luaL_check_string(2); lua_Object newp = lua_getparam(3); int32 max_s = (int32)luaL_opt_number(4, srcl+1); int32 anchor = (*p == '^') ? (p++, 1) : 0; int32 n = 0; struct Capture cap; luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3, "string or function expected"); luaL_resetbuffer(); cap.src_end = src+srcl; while (n < max_s) { const char *e; cap.level = 0; e = match(src, p, &cap); if (e) { n++; add_s(newp, &cap); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < cap.src_end) luaL_addchar(*src++); else break; if (anchor) break; } addnchar(src, cap.src_end-src); closeandpush(); lua_pushnumber(n); /* number of substitutions */ }
static void str_rep (void) { int32 l; const char *s = luaL_check_lstr(1, &l); int32 n = (int32)luaL_check_number(2); luaL_resetbuffer(); while (n-- > 0) addnchar(s, l); closeandpush(); }
static void add_s (lua_Object newp, struct Capture *cap) { if (lua_isstring(newp)) { const char *news = lua_getstring(newp); int32 l = lua_strlen(newp); int32 i; for (i=0; i<l; i++) { if (news[i] != ESC) luaL_addchar(news[i]); else { i++; /* skip ESC */ if (!isdigit((byte)news[i])) luaL_addchar(news[i]); else { int32 level = check_cap(news[i], cap); addnchar(cap->capture[level].init, cap->capture[level].len); } } } } else { /* is a function */ lua_Object res; int32 status; int32 oldbuff; lua_beginblock(); push_captures(cap); /* function may use buffer, so save it and create a new one */ oldbuff = luaL_newbuffer(0); status = lua_callfunction(newp); /* restore old buffer */ luaL_oldbuffer(oldbuff); if (status != 0) { lua_endblock(); lua_error(NULL); } res = lua_getresult(1); if (lua_isstring(res)) addnchar(lua_getstring(res), lua_strlen(res)); lua_endblock(); } }
/* ** Return the substring of a string */ static void str_sub (void) { char *s = luaL_check_string(1); long l = strlen(s); long start = (long)luaL_check_number(2); long end = (long)luaL_opt_number(3, -1); if (start < 0) start = l+start+1; if (end < 0) end = l+end+1; if (1 <= start && start <= end && end <= l) { luaI_emptybuff(); addnchar(s+start-1, end-start+1); lua_pushstring(luaI_addchar(0)); } else lua_pushstring(""); }
static void add_s (lua_Object newp, lua_Object table, int n) { if (lua_isstring(newp)) { char *news = lua_getstring(newp); while (*news) { if (*news != ESC || !isdigit((unsigned char)*++news)) luaI_addchar(*news++); else { int l = check_cap(*news++, num_captures); addnchar(capture[l].init, capture[l].len); } } } else if (lua_isfunction(newp)) { lua_Object res; struct lbuff oldbuff; int status; lua_beginblock(); if (lua_istable(table)) { lua_pushobject(table); lua_pushnumber(n); } push_captures(); /* function may use lbuffer, so save it and create a new one */ oldbuff = lbuffer; lbuffer.b = NULL; lbuffer.max = lbuffer.size = 0; status = lua_callfunction(newp); /* restore old buffer */ free(lbuffer.b); lbuffer = oldbuff; if (status != 0) lua_error(NULL); res = lua_getresult(1); addstr(lua_isstring(res) ? lua_getstring(res) : ""); lua_endblock(); } else luaL_arg_check(0, 3, NULL); }
static void addstr (char *s) { addnchar(s, strlen(s)); }