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;
}
Beispiel #2
0
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;
}