Ejemplo n.º 1
0
HRESULT create_regexp(script_ctx_t *ctx, jsstr_t *src, DWORD flags, jsdisp_t **ret)
{
    RegExpInstance *regexp;
    HRESULT hres;

    TRACE("%s %x\n", debugstr_jsstr(src), flags);

    hres = alloc_regexp(ctx, NULL, &regexp);
    if(FAILED(hres))
        return hres;

    regexp->str = jsstr_addref(src);
    regexp->last_index_val = jsval_number(0);

    regexp->jsregexp = regexp_new(ctx, &ctx->tmp_heap, regexp->str->str,
            jsstr_length(regexp->str), flags, FALSE);
    if(FAILED(hres)) {
        WARN("regexp_new failed\n");
        jsdisp_release(&regexp->dispex);
        return E_FAIL;
    }

    *ret = &regexp->dispex;
    return S_OK;
}
Ejemplo n.º 2
0
static HRESULT String_idx_get(jsdisp_t *jsdisp, unsigned idx, jsval_t *r)
{
    StringInstance *string = (StringInstance*)jsdisp;
    jsstr_t *ret;

    ret = jsstr_substr(string->str, idx, 1);
    if(!ret)
        return E_OUTOFMEMORY;

    TRACE("%p[%u] = %s\n", string, idx, debugstr_jsstr(ret));

    *r = jsval_string(ret);
    return S_OK;
}
Ejemplo n.º 3
0
const char *debugstr_jsval(const jsval_t v)
{
    switch(jsval_type(v)) {
    case JSV_UNDEFINED:
        return "undefined";
    case JSV_NULL:
        return "null";
    case JSV_OBJECT:
        return wine_dbg_sprintf("obj(%p)", get_object(v));
    case JSV_STRING:
        return wine_dbg_sprintf("str(%s)", debugstr_jsstr(get_string(v)));
    case JSV_NUMBER:
        return wine_dbg_sprintf("%lf", get_number(v));
    case JSV_BOOL:
        return get_bool(v) ? "true" : "false";
    case JSV_VARIANT:
        return debugstr_variant(get_variant(v));
    }

    assert(0);
    return NULL;
}
Ejemplo n.º 4
0
static HRESULT array_join(script_ctx_t *ctx, jsdisp_t *array, DWORD length, const WCHAR *sep, jsval_t *r)
{
    jsstr_t **str_tab, *ret;
    jsval_t val;
    DWORD i;
    HRESULT hres = E_FAIL;

    if(!length) {
        if(r)
            *r = jsval_string(jsstr_empty());
        return S_OK;
    }

    str_tab = heap_alloc_zero(length * sizeof(*str_tab));
    if(!str_tab)
        return E_OUTOFMEMORY;

    for(i=0; i < length; i++) {
        hres = jsdisp_get_idx(array, i, &val);
        if(hres == DISP_E_UNKNOWNNAME) {
            hres = S_OK;
            continue;
        } else if(FAILED(hres))
            break;

        if(!is_undefined(val) && !is_null(val)) {
            hres = to_string(ctx, val, str_tab+i);
            jsval_release(val);
            if(FAILED(hres))
                break;
        }
    }

    if(SUCCEEDED(hres)) {
        DWORD seplen = 0, len = 0;

        seplen = strlenW(sep);

        if(str_tab[0])
            len = jsstr_length(str_tab[0]);
        for(i=1; i < length; i++) {
            len += seplen;
            if(str_tab[i])
                len += jsstr_length(str_tab[i]);
            if(len > JSSTR_MAX_LENGTH) {
                hres = E_OUTOFMEMORY;
                break;
            }
        }

        if(SUCCEEDED(hres)) {
            WCHAR *ptr = NULL;

            ptr = jsstr_alloc_buf(len, &ret);
            if(ptr) {
                if(str_tab[0])
                    ptr += jsstr_flush(str_tab[0], ptr);

                for(i=1; i < length; i++) {
                    if(seplen) {
                        memcpy(ptr, sep, seplen*sizeof(WCHAR));
                        ptr += seplen;
                    }

                    if(str_tab[i])
                        ptr += jsstr_flush(str_tab[i], ptr);
                }
            }else {
                hres = E_OUTOFMEMORY;
            }
        }
    }

    for(i=0; i < length; i++) {
        if(str_tab[i])
            jsstr_release(str_tab[i]);
    }
    heap_free(str_tab);
    if(FAILED(hres))
        return hres;

    TRACE("= %s\n", debugstr_jsstr(ret));

    if(r)
        *r = jsval_string(ret);
    else
        jsstr_release(ret);
    return S_OK;
}
Ejemplo n.º 5
0
const char *debugstr_jsstr(jsstr_t *str)
{
    return jsstr_is_inline(str) ? debugstr_wn(jsstr_as_inline(str)->buf, jsstr_length(str))
        : jsstr_is_heap(str) ? debugstr_wn(jsstr_as_heap(str)->buf, jsstr_length(str))
        : wine_dbg_sprintf("%s...", debugstr_jsstr(jsstr_as_rope(str)->left));
}
Ejemplo n.º 6
0
/* ECMA-262 3rd Edition    15.5.4.11 */
static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                              jsval_t *r)
{
    const WCHAR *str, *match_str = NULL, *rep_str = NULL;
    jsstr_t *rep_jsstr, *match_jsstr, *jsstr;
    jsdisp_t *rep_func = NULL, *regexp = NULL;
    match_state_t *match = NULL, last_match = {0};
    strbuf_t ret = {NULL,0,0};
    DWORD re_flags = REM_NO_CTX_UPDATE|REM_ALLOC_RESULT;
    DWORD rep_len=0;
    HRESULT hres = S_OK;

    TRACE("\n");

    hres = get_string_flat_val(ctx, jsthis, &jsstr, &str);
    if(FAILED(hres))
        return hres;

    if(!argc) {
        if(r)
            *r = jsval_string(jsstr);
        else
            jsstr_release(jsstr);
        return S_OK;
    }

    if(is_object_instance(argv[0])) {
        regexp = iface_to_jsdisp(get_object(argv[0]));
        if(regexp && !is_class(regexp, JSCLASS_REGEXP)) {
            jsdisp_release(regexp);
            regexp = NULL;
        }
    }

    if(!regexp) {
        hres = to_flat_string(ctx, argv[0], &match_jsstr, &match_str);
        if(FAILED(hres)) {
            jsstr_release(jsstr);
            return hres;
        }
    }

    if(argc >= 2) {
        if(is_object_instance(argv[1])) {
            rep_func = iface_to_jsdisp(get_object(argv[1]));
            if(rep_func && !is_class(rep_func, JSCLASS_FUNCTION)) {
                jsdisp_release(rep_func);
                rep_func = NULL;
            }
        }

        if(!rep_func) {
            hres = to_flat_string(ctx, argv[1], &rep_jsstr, &rep_str);
            if(SUCCEEDED(hres))
                rep_len = jsstr_length(rep_jsstr);
        }
    }

    if(SUCCEEDED(hres)) {
        const WCHAR *ecp = str;

        while(1) {
            if(regexp) {
                hres = regexp_match_next(ctx, regexp, re_flags, jsstr, &match);
                re_flags = (re_flags | REM_CHECK_GLOBAL) & (~REM_ALLOC_RESULT);

                if(hres == S_FALSE) {
                    hres = S_OK;
                    break;
                }
                if(FAILED(hres))
                    break;

                last_match.cp = match->cp;
                last_match.match_len = match->match_len;
            } else {
                if(re_flags & REM_ALLOC_RESULT) {
                    re_flags &= ~REM_ALLOC_RESULT;
                    match = &last_match;
                    match->cp = str;
                }

                match->cp = strstrW(match->cp, match_str);
                if(!match->cp)
                    break;
                match->match_len = jsstr_length(match_jsstr);
                match->cp += match->match_len;
            }

            hres = strbuf_append(&ret, ecp, match->cp-ecp-match->match_len);
            ecp = match->cp;
            if(FAILED(hres))
                break;

            if(rep_func) {
                jsstr_t *cstr;

                hres = rep_call(ctx, rep_func, jsstr, str, match, &cstr);
                if(FAILED(hres))
                    break;

                hres = strbuf_append_jsstr(&ret, cstr);
                jsstr_release(cstr);
                if(FAILED(hres))
                    break;
            } else if(rep_str && regexp) {
                const WCHAR *ptr = rep_str, *ptr2;

                while((ptr2 = strchrW(ptr, '$'))) {
                    hres = strbuf_append(&ret, ptr, ptr2-ptr);
                    if(FAILED(hres))
                        break;

                    switch(ptr2[1]) {
                    case '$':
                        hres = strbuf_append(&ret, ptr2, 1);
                        ptr = ptr2+2;
                        break;
                    case '&':
                        hres = strbuf_append(&ret, match->cp-match->match_len, match->match_len);
                        ptr = ptr2+2;
                        break;
                    case '`':
                        hres = strbuf_append(&ret, str, match->cp-str-match->match_len);
                        ptr = ptr2+2;
                        break;
                    case '\'':
                        hres = strbuf_append(&ret, ecp, (str+jsstr_length(jsstr))-ecp);
                        ptr = ptr2+2;
                        break;
                    default: {
                        DWORD idx;

                        if(!isdigitW(ptr2[1])) {
                            hres = strbuf_append(&ret, ptr2, 1);
                            ptr = ptr2+1;
                            break;
                        }

                        idx = ptr2[1] - '0';
                        if(isdigitW(ptr2[2]) && idx*10 + (ptr2[2]-'0') <= match->paren_count) {
                            idx = idx*10 + (ptr[2]-'0');
                            ptr = ptr2+3;
                        } else if(idx && idx <= match->paren_count) {
                            ptr = ptr2+2;
                        } else {
                            hres = strbuf_append(&ret, ptr2, 1);
                            ptr = ptr2+1;
                            break;
                        }

                        if(match->parens[idx-1].index != -1)
                            hres = strbuf_append(&ret, str+match->parens[idx-1].index,
                                                 match->parens[idx-1].length);
                    }
                    }

                    if(FAILED(hres))
                        break;
                }

                if(SUCCEEDED(hres))
                    hres = strbuf_append(&ret, ptr, (rep_str+rep_len)-ptr);
                if(FAILED(hres))
                    break;
            } else if(rep_str) {
                hres = strbuf_append(&ret, rep_str, rep_len);
                if(FAILED(hres))
                    break;
            } else {
                static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d'};

                hres = strbuf_append(&ret, undefinedW, sizeof(undefinedW)/sizeof(WCHAR));
                if(FAILED(hres))
                    break;
            }

            if(!regexp)
                break;
            else if(!match->match_len)
                match->cp++;
        }

        if(SUCCEEDED(hres))
            hres = strbuf_append(&ret, ecp, str+jsstr_length(jsstr)-ecp);
    }

    if(rep_func)
        jsdisp_release(rep_func);
    if(rep_str)
        jsstr_release(rep_jsstr);
    if(match_str)
        jsstr_release(match_jsstr);
    if(regexp)
        heap_free(match);

    if(SUCCEEDED(hres) && last_match.cp && regexp) {
        jsstr_release(ctx->last_match);
        ctx->last_match = jsstr_addref(jsstr);
        ctx->last_match_index = last_match.cp-str-last_match.match_len;
        ctx->last_match_length = last_match.match_len;
    }

    if(regexp)
        jsdisp_release(regexp);
    jsstr_release(jsstr);

    if(SUCCEEDED(hres) && r) {
        jsstr_t *ret_str;

        ret_str = jsstr_alloc_len(ret.buf, ret.len);
        if(!ret_str)
            return E_OUTOFMEMORY;

        TRACE("= %s\n", debugstr_jsstr(ret_str));
        *r = jsval_string(ret_str);
    }

    heap_free(ret.buf);
    return hres;
}