| 760 | |
| 761 | |
| 762 | static int str_gsub (lua_State *L) { |
| 763 | size_t srcl, lp; |
| 764 | const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ |
| 765 | const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ |
| 766 | const char *lastmatch = NULL; /* end of last match */ |
| 767 | int tr = lua_type(L, 3); /* replacement type */ |
| 768 | lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ |
| 769 | int anchor = (*p == '^'); |
| 770 | lua_Integer n = 0; /* replacement count */ |
| 771 | MatchState ms; |
| 772 | luaL_Buffer b; |
| 773 | luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || |
| 774 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, |
| 775 | "string/function/table expected"); |
| 776 | luaL_buffinit(L, &b); |
| 777 | if (anchor) { |
| 778 | p++; lp--; /* skip anchor character */ |
| 779 | } |
| 780 | prepstate(&ms, L, src, srcl, p, lp); |
| 781 | while (n < max_s) { |
| 782 | const char *e; |
| 783 | reprepstate(&ms); /* (re)prepare state for new match */ |
| 784 | if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ |
| 785 | n++; |
| 786 | add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ |
| 787 | src = lastmatch = e; |
| 788 | } |
| 789 | else if (src < ms.src_end) /* otherwise, skip one character */ |
| 790 | luaL_addchar(&b, *src++); |
| 791 | else break; /* end of subject */ |
| 792 | if (anchor) break; |
| 793 | } |
| 794 | luaL_addlstring(&b, src, ms.src_end-src); |
| 795 | luaL_pushresult(&b); |
| 796 | lua_pushinteger(L, n); /* number of substitutions */ |
| 797 | return 2; |
| 798 | } |
| 799 | |
| 800 | /* }====================================================== */ |
| 801 |
nothing calls this directly
no test coverage detected