| 940 | |
| 941 | |
| 942 | static int str_gsub (lua_State *L) { |
| 943 | size_t srcl, lp; |
| 944 | const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ |
| 945 | const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ |
| 946 | const char *lastmatch = NULL; /* end of last match */ |
| 947 | int tr = lua_type(L, 3); /* replacement type */ |
| 948 | lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ |
| 949 | int anchor = (*p == '^'); |
| 950 | lua_Integer n = 0; /* replacement count */ |
| 951 | int changed = 0; /* change flag */ |
| 952 | MatchState ms; |
| 953 | luaL_Buffer b; |
| 954 | luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || |
| 955 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, |
| 956 | "string/function/table"); |
| 957 | luaL_buffinit(L, &b); |
| 958 | if (anchor) { |
| 959 | p++; lp--; /* skip anchor character */ |
| 960 | } |
| 961 | prepstate(&ms, L, src, srcl, p, lp); |
| 962 | while (n < max_s) { |
| 963 | const char *e; |
| 964 | reprepstate(&ms); /* (re)prepare state for new match */ |
| 965 | if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ |
| 966 | n++; |
| 967 | changed = add_value(&ms, &b, src, e, tr) | changed; |
| 968 | src = lastmatch = e; |
| 969 | } |
| 970 | else if (src < ms.src_end) /* otherwise, skip one character */ |
| 971 | luaL_addchar(&b, *src++); |
| 972 | else break; /* end of subject */ |
| 973 | if (anchor) break; |
| 974 | } |
| 975 | if (!changed) /* no changes? */ |
| 976 | lua_pushvalue(L, 1); /* return original string */ |
| 977 | else { /* something changed */ |
| 978 | luaL_addlstring(&b, src, ms.src_end-src); |
| 979 | luaL_pushresult(&b); /* create and return new string */ |
| 980 | } |
| 981 | lua_pushinteger(L, n); /* number of substitutions */ |
| 982 | return 2; |
| 983 | } |
| 984 | |
| 985 | /* }====================================================== */ |
| 986 |
nothing calls this directly
no test coverage detected