static int add_str(LuaMatchState *ms, char_buffer_st **b, const char *str, size_t len){ char_buffer_st *tmp = *b; if(tmp->used+len >= tmp->size){ tmp = (char_buffer_st*)realloc(tmp, sizeof(char_buffer_st) + tmp->size + NEW_SIZE(len)); if(!tmp){ ms->error = "not enough memory when reallocating"; return 0; } *b = tmp; } memcpy(&tmp->buf[tmp->used], str, len); tmp->used += len; return 1; }
char_buffer_st *lua_gsub(const char *src, size_t srcl, const char *p, size_t lp,const char *tr, size_t max_s, const char **error_ptr) { int anchor; size_t n; LuaMatchState ms; char_buffer_st *b; if(max_s == 0) max_s = srcl+1; anchor = (*p == '^'); n = NEW_SIZE(srcl); b = (char_buffer_st*)malloc(sizeof(char_buffer_st) + n); if(!b) return NULL; b->size = n; b->used = 0; n = 0; if (anchor) p++, lp--; // skip anchor character ms.error = 0; ms.src_init = src; ms.src_end = src+srcl; ms.p_end = p + lp; while (n < max_s) { const char *e; ms.level = 0; e = match(&ms, src, p); if(ms.error) goto free_and_null; if (e) { n++; if(!add_value(&ms, &b, src, e, tr)) goto free_and_null; } if (e && e>src) // non empty match? src = e; // skip it else if (src < ms.src_end){ if(!add_char(&ms, &b, *src++)) goto free_and_null; } else break; if (anchor) break; } if(!add_str(&ms, &b, src, ms.src_end-src)) goto free_and_null; b->buf[b->used] = '\0'; return b; free_and_null: if(b) free(b); if(error_ptr) *error_ptr = ms.error; return NULL; }