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

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

    str = jsstr_flatten(src);
    if(!str)
        return E_OUTOFMEMORY;

    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, str, jsstr_length(regexp->str), flags, FALSE);
    if(!regexp->jsregexp) {
        WARN("regexp_new failed\n");
        jsdisp_release(&regexp->dispex);
        return E_FAIL;
    }

    *ret = &regexp->dispex;
    return S_OK;
}
Ejemplo n.º 2
0
HRESULT regexp_match_next(script_ctx_t *ctx, jsdisp_t *dispex,
        DWORD rem_flags, jsstr_t *jsstr, match_state_t **ret)
{
    RegExpInstance *regexp = (RegExpInstance*)dispex;
    match_state_t *match;
    heap_pool_t *mark;
    const WCHAR *str;
    HRESULT hres;

    if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & REG_GLOB)) {
        if(rem_flags & REM_ALLOC_RESULT)
            *ret = NULL;
        return S_FALSE;
    }

    str = jsstr_flatten(jsstr);
    if(!str)
        return E_OUTOFMEMORY;

    if(rem_flags & REM_ALLOC_RESULT) {
        match = alloc_match_state(regexp->jsregexp, NULL, str);
        if(!match)
            return E_OUTOFMEMORY;
        *ret = match;
    }

    mark = heap_pool_mark(&ctx->tmp_heap);

    if(rem_flags & REM_NO_PARENS) {
        match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, NULL);
        if(!match) {
            heap_pool_clear(mark);
            return E_OUTOFMEMORY;
        }
        match->cp = (*ret)->cp;
        match->match_len = (*ret)->match_len;
    }else {
        match = *ret;
    }

    hres = do_regexp_match_next(ctx, regexp, rem_flags, jsstr, str, match);

    if(rem_flags & REM_NO_PARENS) {
        (*ret)->cp = match->cp;
        (*ret)->match_len = match->match_len;
    }

    heap_pool_clear(mark);

    if(hres != S_OK && (rem_flags & REM_ALLOC_RESULT)) {
        heap_free(match);
        *ret = NULL;
    }

    return hres;
}
Ejemplo n.º 3
0
HRESULT create_regexp_var(script_ctx_t *ctx, jsval_t src_arg, jsval_t *flags_arg, jsdisp_t **ret)
{
    unsigned flags, opt_len = 0;
    const WCHAR *opt = NULL;
    jsstr_t *src;
    HRESULT hres;

    if(is_object_instance(src_arg)) {
        jsdisp_t *obj;

        obj = iface_to_jsdisp((IUnknown*)get_object(src_arg));
        if(obj) {
            if(is_class(obj, JSCLASS_REGEXP)) {
                RegExpInstance *regexp = (RegExpInstance*)obj;

                hres = create_regexp(ctx, regexp->str, regexp->jsregexp->flags, ret);
                jsdisp_release(obj);
                return hres;
            }

            jsdisp_release(obj);
        }
    }

    if(!is_string(src_arg)) {
        FIXME("src_arg = %s\n", debugstr_jsval(src_arg));
        return E_NOTIMPL;
    }

    src = get_string(src_arg);

    if(flags_arg) {
        jsstr_t *opt_str;

        if(!is_string(*flags_arg)) {
            FIXME("unimplemented for %s\n", debugstr_jsval(*flags_arg));
            return E_NOTIMPL;
        }

        opt_str = get_string(*flags_arg);
        opt = jsstr_flatten(opt_str);
        if(!opt)
            return E_OUTOFMEMORY;
        opt_len = jsstr_length(opt_str);
    }

    hres = parse_regexp_flags(opt, opt_len, &flags);
    if(FAILED(hres))
        return hres;

    return create_regexp(ctx, src, flags, ret);
}
Ejemplo n.º 4
0
static HRESULT get_string_flat_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t **jsval, const WCHAR **val)
{
    HRESULT hres;

    hres = get_string_val(ctx, jsthis, jsval);
    if(FAILED(hres))
        return hres;

    *val = jsstr_flatten(*jsval);
    if(*val)
        return S_OK;

    jsstr_release(*jsval);
    return E_OUTOFMEMORY;
}
Ejemplo n.º 5
0
HRESULT to_flat_string(script_ctx_t *ctx, jsval_t val, jsstr_t **str, const WCHAR **ret_str)
{
    HRESULT hres;

    hres = to_string(ctx, val, str);
    if(FAILED(hres))
        return hres;

    *ret_str = jsstr_flatten(*str);
    if(!*ret_str) {
        jsstr_release(*str);
        return E_OUTOFMEMORY;
    }

    return S_OK;
}
Ejemplo n.º 6
0
Archivo: json.c Proyecto: AmesianX/wine
/* ECMA-262 5.1 Edition    15.12.3 (abstract operation Str) */
static HRESULT stringify(stringify_ctx_t *ctx, jsval_t val)
{
    jsval_t value;
    HRESULT hres;

    if(is_object_instance(val) && get_object(val)) {
        jsdisp_t *obj;
        DISPID id;

        obj = iface_to_jsdisp((IUnknown*)get_object(val));
        if(!obj)
            return S_FALSE;

        hres = jsdisp_get_id(obj, toJSONW, 0, &id);
        jsdisp_release(obj);
        if(hres == S_OK)
            FIXME("Use toJSON.\n");
    }

    /* FIXME: Support replacer replacer. */

    hres = maybe_to_primitive(ctx->ctx, val, &value);
    if(FAILED(hres))
        return hres;

    switch(jsval_type(value)) {
    case JSV_NULL:
        if(!append_string(ctx, nullW))
            hres = E_OUTOFMEMORY;
        break;
    case JSV_BOOL:
        if(!append_string(ctx, get_bool(value) ? trueW : falseW))
            hres = E_OUTOFMEMORY;
        break;
    case JSV_STRING: {
        jsstr_t *str = get_string(value);
        const WCHAR *ptr = jsstr_flatten(str);
        if(ptr)
            hres = json_quote(ctx, ptr, jsstr_length(str));
        else
            hres = E_OUTOFMEMORY;
        break;
    }
    case JSV_NUMBER: {
        double n = get_number(value);
        if(is_finite(n)) {
            const WCHAR *ptr;
            jsstr_t *str;

            /* FIXME: Optimize. There is no need for jsstr_t here. */
            hres = double_to_string(n, &str);
            if(FAILED(hres))
                break;

            ptr = jsstr_flatten(str);
            assert(ptr != NULL);
            hres = ptr && !append_string_len(ctx, ptr, jsstr_length(str)) ? E_OUTOFMEMORY : S_OK;
            jsstr_release(str);
        }else {
            if(!append_string(ctx, nullW))
                hres = E_OUTOFMEMORY;
        }
        break;
    }
    case JSV_OBJECT: {
        jsdisp_t *obj;

        obj = iface_to_jsdisp((IUnknown*)get_object(value));
        if(!obj) {
            hres = S_FALSE;
            break;
        }

        if(!is_callable(obj))
            hres = is_class(obj, JSCLASS_ARRAY) ? stringify_array(ctx, obj) : stringify_object(ctx, obj);
        else
            hres = S_FALSE;

        jsdisp_release(obj);
        break;
    }
    case JSV_UNDEFINED:
        hres = S_FALSE;
        break;
    case JSV_VARIANT:
        FIXME("VARIANT\n");
        hres = E_NOTIMPL;
        break;
    }

    jsval_release(value);
    return hres;
}
Ejemplo n.º 7
0
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, jsstr_t *jsstr, jsval_t *r)
{
    static const WCHAR indexW[] = {'i','n','d','e','x',0};
    static const WCHAR inputW[] = {'i','n','p','u','t',0};
    static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};

    RegExpInstance *regexp = (RegExpInstance*)re;
    match_result_t *match_result;
    unsigned match_cnt, i;
    const WCHAR *str;
    jsdisp_t *array;
    HRESULT hres;

    str = jsstr_flatten(jsstr);
    if(!str)
        return E_OUTOFMEMORY;

    if(!(regexp->jsregexp->flags & REG_GLOB)) {
        match_state_t *match;
        heap_pool_t *mark;

        mark = heap_pool_mark(&ctx->tmp_heap);
        match = alloc_match_state(regexp->jsregexp, &ctx->tmp_heap, str);
        if(!match) {
            heap_pool_clear(mark);
            return E_OUTOFMEMORY;
        }

        hres = regexp_match_next(ctx, &regexp->dispex, 0, jsstr, &match);
        if(FAILED(hres)) {
            heap_pool_clear(mark);
            return hres;
        }

        if(r) {
            if(hres == S_OK) {
                IDispatch *ret;

                hres = create_match_array(ctx, jsstr, match, &ret);
                if(SUCCEEDED(hres))
                    *r = jsval_disp(ret);
            }else {
                *r = jsval_null();
            }
        }

        heap_pool_clear(mark);
        return S_OK;
    }

    hres = regexp_match(ctx, &regexp->dispex, jsstr, FALSE, &match_result, &match_cnt);
    if(FAILED(hres))
        return hres;

    if(!match_cnt) {
        TRACE("no match\n");

        if(r)
            *r = jsval_null();
        return S_OK;
    }

    hres = create_array(ctx, match_cnt, &array);
    if(FAILED(hres))
        return hres;

    for(i=0; i < match_cnt; i++) {
        jsstr_t *tmp_str;

        tmp_str = jsstr_substr(jsstr, match_result[i].index, match_result[i].length);
        if(!tmp_str) {
            hres = E_OUTOFMEMORY;
            break;
        }

        hres = jsdisp_propput_idx(array, i, jsval_string(tmp_str));
        jsstr_release(tmp_str);
        if(FAILED(hres))
            break;
    }

    while(SUCCEEDED(hres)) {
        hres = jsdisp_propput_name(array, indexW, jsval_number(match_result[match_cnt-1].index));
        if(FAILED(hres))
            break;

        hres = jsdisp_propput_name(array, lastIndexW,
                jsval_number(match_result[match_cnt-1].index + match_result[match_cnt-1].length));
        if(FAILED(hres))
            break;

        hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr));
        break;
    }

    heap_free(match_result);

    if(SUCCEEDED(hres) && r)
        *r = jsval_obj(array);
    else
        jsdisp_release(array);
    return hres;
}
Ejemplo n.º 8
0
static HRESULT create_match_array(script_ctx_t *ctx, jsstr_t *input_str,
        const match_state_t *result, IDispatch **ret)
{
    const WCHAR *input;
    jsdisp_t *array;
    jsstr_t *str;
    DWORD i;
    HRESULT hres = S_OK;

    static const WCHAR indexW[] = {'i','n','d','e','x',0};
    static const WCHAR inputW[] = {'i','n','p','u','t',0};
    static const WCHAR lastIndexW[] = {'l','a','s','t','I','n','d','e','x',0};
    static const WCHAR zeroW[] = {'0',0};

    input = jsstr_flatten(input_str);
    if(!input)
        return E_OUTOFMEMORY;

    hres = create_array(ctx, result->paren_count+1, &array);
    if(FAILED(hres))
        return hres;

    for(i=0; i < result->paren_count; i++) {
        if(result->parens[i].index != -1)
            str = jsstr_substr(input_str, result->parens[i].index, result->parens[i].length);
        else
            str = jsstr_empty();
        if(!str) {
            hres = E_OUTOFMEMORY;
            break;
        }

        hres = jsdisp_propput_idx(array, i+1, jsval_string(str));
        jsstr_release(str);
        if(FAILED(hres))
            break;
    }

    while(SUCCEEDED(hres)) {
        hres = jsdisp_propput_name(array, indexW, jsval_number(result->cp-input-result->match_len));
        if(FAILED(hres))
            break;

        hres = jsdisp_propput_name(array, lastIndexW, jsval_number(result->cp-input));
        if(FAILED(hres))
            break;

        hres = jsdisp_propput_name(array, inputW, jsval_string(jsstr_addref(input_str)));
        if(FAILED(hres))
            break;

        str = jsstr_alloc_len(result->cp-result->match_len, result->match_len);
        if(!str) {
            hres = E_OUTOFMEMORY;
            break;
        }
        hres = jsdisp_propput_name(array, zeroW, jsval_string(str));
        jsstr_release(str);
        break;
    }

    if(FAILED(hres)) {
        jsdisp_release(array);
        return hres;
    }

    *ret = to_disp(array);
    return S_OK;
}
Ejemplo n.º 9
0
static HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, jsstr_t *jsstr, BOOL gflag,
        match_result_t **match_result, DWORD *result_cnt)
{
    RegExpInstance *This = (RegExpInstance*)dispex;
    match_result_t *ret = NULL;
    match_state_t *result;
    DWORD i=0, ret_size = 0;
    heap_pool_t *mark;
    const WCHAR *str;
    HRESULT hres;

    mark = heap_pool_mark(&ctx->tmp_heap);

    str = jsstr_flatten(jsstr);
    if(!str)
        return E_OUTOFMEMORY;

    result = alloc_match_state(This->jsregexp, &ctx->tmp_heap, str);
    if(!result) {
        heap_pool_clear(mark);
        return E_OUTOFMEMORY;
    }

    while(1) {
        hres = do_regexp_match_next(ctx, This, 0, jsstr, str, result);
        if(hres == S_FALSE) {
            hres = S_OK;
            break;
        }

        if(FAILED(hres))
            break;

        if(ret_size == i) {
            if(ret) {
                match_result_t *old_ret = ret;

                ret = heap_realloc(old_ret, (ret_size <<= 1) * sizeof(match_result_t));
                if(!ret)
                    heap_free(old_ret);
            }else {
                ret = heap_alloc((ret_size=4) * sizeof(match_result_t));
            }
            if(!ret) {
                hres = E_OUTOFMEMORY;
                break;
            }
        }

        ret[i].index = result->cp - str - result->match_len;
        ret[i++].length = result->match_len;

        if(!gflag && !(This->jsregexp->flags & REG_GLOB)) {
            hres = S_OK;
            break;
        }
    }

    heap_pool_clear(mark);
    if(FAILED(hres)) {
        heap_free(ret);
        return hres;
    }

    *match_result = ret;
    *result_cnt = i;
    return S_OK;
}
Ejemplo n.º 10
0
/* ECMA-262 3rd Edition    9.3.1 */
static HRESULT str_to_number(jsstr_t *str, double *ret)
{
    const WCHAR *ptr;
    BOOL neg = FALSE;
    DOUBLE d = 0.0;

    static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};

    ptr = jsstr_flatten(str);
    if(!ptr)
        return E_OUTOFMEMORY;

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr == '-') {
        neg = TRUE;
        ptr++;
    }else if(*ptr == '+') {
        ptr++;
    }

    if(!strncmpW(ptr, infinityW, sizeof(infinityW)/sizeof(WCHAR))) {
        ptr += sizeof(infinityW)/sizeof(WCHAR);
        while(*ptr && isspaceW(*ptr))
            ptr++;

        if(*ptr)
            *ret = NAN;
        else
            *ret = neg ? -INFINITY : INFINITY;
        return S_OK;
    }

    if(*ptr == '0' && ptr[1] == 'x') {
        DWORD l = 0;

        ptr += 2;
        while((l = hex_to_int(*ptr)) != -1) {
            d = d*16 + l;
            ptr++;
        }

        *ret = d;
        return S_OK;
    }

    while(isdigitW(*ptr))
        d = d*10 + (*ptr++ - '0');

    if(*ptr == 'e' || *ptr == 'E') {
        BOOL eneg = FALSE;
        LONG l = 0;

        ptr++;
        if(*ptr == '-') {
            ptr++;
            eneg = TRUE;
        }else if(*ptr == '+') {
            ptr++;
        }

        while(isdigitW(*ptr))
            l = l*10 + (*ptr++ - '0');
        if(eneg)
            l = -l;

        d *= pow(10, l);
    }else if(*ptr == '.') {
        DOUBLE dec = 0.1;

        ptr++;
        while(isdigitW(*ptr)) {
            d += dec * (*ptr++ - '0');
            dec *= 0.1;
        }
    }

    while(isspaceW(*ptr))
        ptr++;

    if(*ptr) {
        *ret = NAN;
        return S_OK;
    }

    if(neg)
        d = -d;

    *ret = d;
    return S_OK;
}