예제 #1
0
파일: jsstr.c 프로젝트: GYGit/reactos
static int jsstr_cmp_str(jsstr_t *jsstr, const WCHAR *str, unsigned len)
{
    int ret;

    switch(jsstr_tag(jsstr)) {
    case JSSTR_INLINE:
        ret = memcmp(jsstr_as_inline(jsstr)->buf, str, len*sizeof(WCHAR));
        return ret || jsstr_length(jsstr) == len ? ret : 1;
    case JSSTR_HEAP:
        ret = memcmp(jsstr_as_heap(jsstr)->buf, str, len*sizeof(WCHAR));
        return ret || jsstr_length(jsstr) == len ? ret : 1;
    case JSSTR_ROPE: {
        jsstr_rope_t *rope = jsstr_as_rope(jsstr);
        unsigned left_len = jsstr_length(rope->left);

        ret = jsstr_cmp_str(rope->left, str, min(len, left_len));
        if(ret || len <= left_len)
            return ret;
        return jsstr_cmp_str(rope->right, str+left_len, len-left_len);
    }
    }

    assert(0);
    return 0;
}
예제 #2
0
파일: jsstr.c 프로젝트: GYGit/reactos
static int ropes_cmp(jsstr_rope_t *left, jsstr_rope_t *right)
{
    WCHAR left_buf[TMP_BUF_SIZE], right_buf[TMP_BUF_SIZE];
    unsigned left_len = jsstr_length(&left->str);
    unsigned right_len = jsstr_length(&right->str);
    unsigned cmp_off = 0, cmp_size;
    int ret;

    /* FIXME: We can avoid temporary buffers here. */
    while(cmp_off < min(left_len, right_len)) {
        cmp_size = min(left_len, right_len) - cmp_off;
        if(cmp_size > TMP_BUF_SIZE)
            cmp_size = TMP_BUF_SIZE;

        jsstr_rope_extract(left, cmp_off, cmp_size, left_buf);
        jsstr_rope_extract(right, cmp_off, cmp_size, right_buf);
        ret = memcmp(left_buf, right_buf, cmp_size);
        if(ret)
            return ret;

        cmp_off += cmp_size;
    }

    return left_len - right_len;
}
예제 #3
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT strbuf_append_jsstr(strbuf_t *buf, jsstr_t *str)
{
    if(!strbuf_ensure_size(buf, buf->len+jsstr_length(str)))
        return E_OUTOFMEMORY;

    jsstr_flush(str, buf->buf+buf->len);
    buf->len += jsstr_length(str);
    return S_OK;
}
예제 #4
0
파일: jsstr.c 프로젝트: RareHare/reactos
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
{
    int len1 = jsstr_length(str1);
    int len2 = jsstr_length(str2);
    int ret;

    ret = memcmp(str1->str, str2->str, min(len1, len2)*sizeof(WCHAR));
    if(!ret)
        ret = len1 - len2;

    return ret;
}
예제 #5
0
파일: jsstr.c 프로젝트: GYGit/reactos
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1, len2;
    jsstr_t *ret;
    WCHAR *ptr;

    len1 = jsstr_length(str1);
    if(!len1)
        return jsstr_addref(str2);

    len2 = jsstr_length(str2);
    if(!len2)
        return jsstr_addref(str1);

    if(len1 + len2 >= JSSTR_SHORT_STRING_LENGTH) {
        unsigned depth, depth2;
        jsstr_rope_t *rope;

        depth = jsstr_is_rope(str1) ? jsstr_as_rope(str1)->depth : 0;
        depth2 = jsstr_is_rope(str2) ? jsstr_as_rope(str2)->depth : 0;
        if(depth2 > depth)
            depth = depth2;

        if(depth++ < JSSTR_MAX_ROPE_DEPTH) {
            if(len1+len2 > JSSTR_MAX_LENGTH)
                return NULL;

            rope = heap_alloc(sizeof(*rope));
            if(!rope)
                return NULL;

            jsstr_init(&rope->str, len1+len2, JSSTR_ROPE);
            rope->left = jsstr_addref(str1);
            rope->right = jsstr_addref(str2);
            rope->depth = depth;
            return &rope->str;
        }
    }

    ptr = jsstr_alloc_buf(len1+len2, &ret);
    if(!ret)
        return NULL;

    jsstr_flush(str1, ptr);
    jsstr_flush(str2, ptr+len1);
    return ret;

}
예제 #6
0
파일: jsregexp.c 프로젝트: RareHare/reactos
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;
}
예제 #7
0
파일: jsregexp.c 프로젝트: RareHare/reactos
static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
         unsigned argc, jsval_t *argv, jsval_t *r)
{
    TRACE("\n");

    switch(flags) {
    case DISPATCH_PROPERTYGET: {
        jsstr_t *ret;

        ret = jsstr_substr(ctx->last_match, ctx->last_match_index+ctx->last_match_length,
                jsstr_length(ctx->last_match) - ctx->last_match_index - ctx->last_match_length);
        if(!ret)
            return E_OUTOFMEMORY;

        *r = jsval_string(ret);
        break;
    }
    case DISPATCH_PROPERTYPUT:
        break;
    default:
        FIXME("unsupported flags\n");
        return E_NOTIMPL;
    }

    return S_OK;
}
예제 #8
0
파일: json.c 프로젝트: AmesianX/wine
/* ECMA-262 5.1 Edition    15.12.3 */
static HRESULT JSON_stringify(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    stringify_ctx_t stringify_ctx = {ctx, NULL,0,0, NULL,0,0, {0}};
    HRESULT hres;

    TRACE("\n");

    if(argc >= 2 && is_object_instance(argv[1])) {
        FIXME("Replacer %s not yet supported\n", debugstr_jsval(argv[1]));
        return E_NOTIMPL;
    }

    if(argc >= 3) {
        jsval_t space_val;

        hres = maybe_to_primitive(ctx, argv[2], &space_val);
        if(FAILED(hres))
            return hres;

        if(is_number(space_val)) {
            double n = get_number(space_val);
            if(n >= 1) {
                int i, len;
                if(n > 10)
                    n = 10;
                len = floor(n);
                for(i=0; i < len; i++)
                    stringify_ctx.gap[i] = ' ';
                stringify_ctx.gap[len] = 0;
            }
        }else if(is_string(space_val)) {
            jsstr_t *space_str = get_string(space_val);
            size_t len = jsstr_length(space_str);
            if(len > 10)
                len = 10;
            jsstr_extract(space_str, 0, len, stringify_ctx.gap);
        }

        jsval_release(space_val);
    }

    hres = stringify(&stringify_ctx, argv[0]);
    if(SUCCEEDED(hres) && r) {
        assert(!stringify_ctx.stack_top);

        if(hres == S_OK) {
            jsstr_t *ret = jsstr_alloc_len(stringify_ctx.buf, stringify_ctx.buf_len);
            if(ret)
                *r = jsval_string(ret);
            else
                hres = E_OUTOFMEMORY;
        }else {
            *r = jsval_undefined();
        }
    }

    heap_free(stringify_ctx.buf);
    heap_free(stringify_ctx.stack);
    return hres;
}
예제 #9
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT String_toUpperCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                                  jsval_t *r)
{
    jsstr_t *str;
    HRESULT hres;

    TRACE("\n");

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

    if(r) {
        jsstr_t *ret;
        WCHAR *buf;

        buf = jsstr_alloc_buf(jsstr_length(str), &ret);
        if(!buf) {
            jsstr_release(str);
            return E_OUTOFMEMORY;
        }

        jsstr_flush(str, buf);
        struprW(buf);
        *r = jsval_string(ret);
    }
    jsstr_release(str);
    return S_OK;
}
예제 #10
0
파일: array.c 프로젝트: Moteesh/reactos
/* ECMA-262 3rd Edition    15.4.4.5 */
static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    jsdisp_t *jsthis;
    DWORD length;
    HRESULT hres;

    TRACE("\n");

    hres = get_length(ctx, vthis, &jsthis, &length);
    if(FAILED(hres))
        return hres;

    if(argc) {
        const WCHAR *sep;
        jsstr_t *sep_str;

        hres = to_flat_string(ctx, argv[0], &sep_str, &sep);
        if(FAILED(hres))
            return hres;

        hres = array_join(ctx, jsthis, length, sep, jsstr_length(sep_str), r);

        jsstr_release(sep_str);
    }else {
        hres = array_join(ctx, jsthis, length, default_separatorW, strlenW(default_separatorW), r);
    }

    return hres;
}
예제 #11
0
/* ECMA-262 3rd Edition    9.2 */
HRESULT to_boolean(jsval_t val, BOOL *ret)
{
    switch(jsval_type(val)) {
    case JSV_UNDEFINED:
    case JSV_NULL:
        *ret = FALSE;
        return S_OK;
    case JSV_OBJECT:
        *ret = get_object(val) != NULL;
        return S_OK;
    case JSV_STRING:
        *ret = jsstr_length(get_string(val)) != 0;
        return S_OK;
    case JSV_NUMBER:
        *ret = !isnan(get_number(val)) && get_number(val);
        return S_OK;
    case JSV_BOOL:
        *ret = get_bool(val);
        return S_OK;
    case JSV_VARIANT:
        FIXME("unimplemented for variant %s\n", debugstr_variant(get_variant(val)));
        return E_NOTIMPL;
    }

    assert(0);
    return E_FAIL;
}
예제 #12
0
파일: string.c 프로젝트: jre-wine/wine
/* ECMA-262 3rd Edition    15.5.4.15 */
static HRESULT String_substring(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                                jsval_t *r)
{
    INT start=0, end, length;
    jsstr_t *str;
    double d;
    HRESULT hres;

    TRACE("\n");

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

    length = jsstr_length(str);
    if(argc >= 1) {
        hres = to_integer(ctx, argv[0], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        if(d >= 0)
            start = is_int32(d) ? min(length, d) : length;
    }

    if(argc >= 2) {
        hres = to_integer(ctx, argv[1], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        if(d >= 0)
            end = is_int32(d) ? min(length, d) : length;
        else
            end = 0;
    } else {
        end = length;
    }

    if(start > end) {
        INT tmp = start;
        start = end;
        end = tmp;
    }

    if(r) {
        jsstr_t *ret = jsstr_substr(str, start, end-start);
        if(ret)
            *r = jsval_string(ret);
        else
            hres = E_OUTOFMEMORY;
    }
    jsstr_release(str);
    return hres;
}
예제 #13
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT String_get_length(script_ctx_t *ctx, jsdisp_t *jsthis, jsval_t *r)
{
    StringInstance *string = (StringInstance*)jsthis;

    TRACE("%p\n", jsthis);

    *r = jsval_number(jsstr_length(string->str));
    return S_OK;
}
예제 #14
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT do_attribute_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, unsigned argc, jsval_t *argv, jsval_t *r,
                                       const WCHAR *tagname, const WCHAR *attrname)
{
    jsstr_t *str, *attr_value = NULL;
    HRESULT hres;

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

    if(argc) {
        hres = to_string(ctx, argv[0], &attr_value);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }
    } else {
        attr_value = jsstr_undefined();
    }

    if(r) {
        unsigned attrname_len = strlenW(attrname);
        unsigned tagname_len = strlenW(tagname);
        jsstr_t *ret;
        WCHAR *ptr;

        ptr = jsstr_alloc_buf(2*tagname_len + attrname_len + jsstr_length(attr_value) + jsstr_length(str) + 9, &ret);
        if(ptr) {
            *ptr++ = '<';
            memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
            ptr += tagname_len;
            *ptr++ = ' ';
            memcpy(ptr, attrname, attrname_len*sizeof(WCHAR));
            ptr += attrname_len;
            *ptr++ = '=';
            *ptr++ = '"';
            ptr += jsstr_flush(attr_value, ptr);
            *ptr++ = '"';
            *ptr++ = '>';
            ptr += jsstr_flush(str, ptr);

            *ptr++ = '<';
            *ptr++ = '/';
            memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
            ptr += tagname_len;
            *ptr = '>';

            *r = jsval_string(ret);
        } else {
            hres = E_OUTOFMEMORY;
        }
    }

    jsstr_release(attr_value);
    jsstr_release(str);
    return hres;
}
예제 #15
0
파일: jsstr.c 프로젝트: GYGit/reactos
const WCHAR *jsstr_rope_flatten(jsstr_rope_t *str)
{
    WCHAR *buf;

    buf = heap_alloc((jsstr_length(&str->str)+1) * sizeof(WCHAR));
    if(!buf)
        return NULL;

    jsstr_flush(str->left, buf);
    jsstr_flush(str->right, buf+jsstr_length(str->left));
    buf[jsstr_length(&str->str)] = 0;

    /* Trasform to heap string */
    jsstr_release(str->left);
    jsstr_release(str->right);
    str->str.length_flags |= JSSTR_FLAG_FLAT;
    return jsstr_as_heap(&str->str)->buf = buf;
}
예제 #16
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT String_indexOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                              jsval_t *r)
{
    jsstr_t *search_jsstr, *jsstr;
    const WCHAR *search_str, *str;
    int length, pos = 0;
    INT ret = -1;
    HRESULT hres;

    TRACE("\n");

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

    length = jsstr_length(jsstr);
    if(!argc) {
        if(r)
            *r = jsval_number(-1);
        jsstr_release(jsstr);
        return S_OK;
    }

    hres = to_flat_string(ctx, argv[0], &search_jsstr, &search_str);
    if(FAILED(hres)) {
        jsstr_release(jsstr);
        return hres;
    }

    if(argc >= 2) {
        double d;

        hres = to_integer(ctx, argv[1], &d);
        if(SUCCEEDED(hres) && d > 0.0)
            pos = is_int32(d) ? min(length, d) : length;
    }

    if(SUCCEEDED(hres)) {
        const WCHAR *ptr;

        ptr = strstrW(str+pos, search_str);
        if(ptr)
            ret = ptr - str;
        else
            ret = -1;
    }

    jsstr_release(search_jsstr);
    jsstr_release(jsstr);
    if(FAILED(hres))
        return hres;

    if(r)
        *r = jsval_number(ret);
    return S_OK;
}
예제 #17
0
파일: jsutils.c 프로젝트: RareHare/reactos
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
{
    switch(jsval_type(val)) {
    case JSV_UNDEFINED:
        V_VT(retv) = VT_EMPTY;
        return S_OK;
    case JSV_NULL:
        V_VT(retv) = VT_NULL;
        return S_OK;
    case JSV_OBJECT:
        V_VT(retv) = VT_DISPATCH;
        if(get_object(val))
            IDispatch_AddRef(get_object(val));
        V_DISPATCH(retv) = get_object(val);
        return S_OK;
    case JSV_STRING: {
        jsstr_t *str = get_string(val);

        V_VT(retv) = VT_BSTR;
        if(str->length_flags & JSSTR_FLAG_NULLBSTR) {
            V_BSTR(retv) = NULL;
        } else {
            V_BSTR(retv) = SysAllocStringLen(NULL, jsstr_length(str));
            if(V_BSTR(retv))
                jsstr_flush(str, V_BSTR(retv));
            else
                return E_OUTOFMEMORY;
        }
        return S_OK;
    }
    case JSV_NUMBER: {
        double n = get_number(val);

        if(is_int32(n)) {
            V_VT(retv) = VT_I4;
            V_I4(retv) = n;
        } else {
            V_VT(retv) = VT_R8;
            V_R8(retv) = n;
        }

        return S_OK;
    }
    case JSV_BOOL:
        V_VT(retv) = VT_BOOL;
        V_BOOL(retv) = get_bool(val) ? VARIANT_TRUE : VARIANT_FALSE;
        return S_OK;
    case JSV_VARIANT:
        V_VT(retv) = VT_EMPTY;
        return VariantCopy(retv, get_variant(val));
    }

    assert(0);
    return E_FAIL;
}
예제 #18
0
파일: jsstr.c 프로젝트: RareHare/reactos
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1, len2;
    jsstr_t *ret;

    len1 = jsstr_length(str1);
    if(!len1)
        return jsstr_addref(str2);

    len2 = jsstr_length(str2);
    if(!len2)
        return jsstr_addref(str1);

    ret = jsstr_alloc_buf(len1+len2);
    if(!ret)
        return NULL;

    jsstr_flush(str1, ret->str);
    jsstr_flush(str2, ret->str+len1);
    return ret;
}
예제 #19
0
파일: string.c 프로젝트: jre-wine/wine
/* ECMA-262 3rd Edition    B.2.3 */
static HRESULT String_substr(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                             jsval_t *r)
{
    int start=0, len, length;
    jsstr_t *str;
    double d;
    HRESULT hres;

    TRACE("\n");

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

    length = jsstr_length(str);
    if(argc >= 1) {
        hres = to_integer(ctx, argv[0], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        if(d >= 0)
            start = is_int32(d) ? min(length, d) : length;
    }

    if(argc >= 2) {
        hres = to_integer(ctx, argv[1], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        if(d >= 0.0)
            len = is_int32(d) ? min(length-start, d) : length-start;
        else
            len = 0;
    } else {
        len = length-start;
    }

    hres = S_OK;
    if(r) {
        jsstr_t *ret = jsstr_substr(str, start, len);
        if(ret)
            *r = jsval_string(ret);
        else
            hres = E_OUTOFMEMORY;
    }

    jsstr_release(str);
    return hres;
}
예제 #20
0
파일: jsstr.c 프로젝트: GYGit/reactos
int jsstr_cmp(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1 = jsstr_length(str1);
    unsigned len2 = jsstr_length(str2);
    const WCHAR *str;
    int ret;

    str = jsstr_try_flat(str2);
    if(str) {
        ret = jsstr_cmp_str(str1, str, min(len1, len2));
        return ret || len1 == len2 ? ret : -1;
    }

    str = jsstr_try_flat(str1);
    if(str) {
        ret = jsstr_cmp_str(str2, str, min(len1, len2));
        return ret || len1 == len2 ? -ret : 1;
    }

    return ropes_cmp(jsstr_as_rope(str1), jsstr_as_rope(str2));
}
예제 #21
0
jsstr_t *jsstr_concat(jsstr_t *str1, jsstr_t *str2)
{
    unsigned len1, len2;
    jsstr_t *ret;

    len1 = jsstr_length(str1);
    if(!len1)
        return jsstr_addref(str2);

    len2 = jsstr_length(str2);
    if(!len2)
        return jsstr_addref(str1);

    ret = jsstr_alloc_buf(len1+len2);
    if(!ret)
        return NULL;

    memcpy(ret->str, str1->str, len1*sizeof(WCHAR));
    memcpy(ret->str+len1, str2->str, len2*sizeof(WCHAR));
    return ret;
}
예제 #22
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);
}
예제 #23
0
파일: string.c 프로젝트: jre-wine/wine
static unsigned String_idx_length(jsdisp_t *jsdisp)
{
    StringInstance *string = (StringInstance*)jsdisp;

    /*
     * NOTE: For invoke version < 2, indexed array is not implemented at all.
     * Newer jscript.dll versions implement it on string type, not class,
     * which is not how it should work according to spec. IE9 implements it
     * properly, but it uses its own JavaScript engine inside MSHTML. We
     * implement it here, but in the way IE9 and spec work.
     */
    return string->dispex.ctx->version < 2 ? 0 : jsstr_length(string->str);
}
예제 #24
0
파일: jsstr.c 프로젝트: GYGit/reactos
static void jsstr_rope_extract(jsstr_rope_t *str, unsigned off, unsigned len, WCHAR *buf)
{
    unsigned left_len = jsstr_length(str->left);

    if(left_len <= off) {
        jsstr_extract(str->right, off-left_len, len, buf);
    }else if(left_len >= len+off) {
        jsstr_extract(str->left, off, len, buf);
    }else {
        left_len -= off;
        jsstr_extract(str->left, off, left_len, buf);
        jsstr_extract(str->right, 0, len-left_len, buf+left_len);
    }
}
예제 #25
0
파일: jsregexp.c 프로젝트: RareHare/reactos
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp,
        DWORD rem_flags, jsstr_t *str, match_state_t *ret)
{
    HRESULT hres;

    hres = regexp_execute(regexp->jsregexp, ctx, &ctx->tmp_heap,
            str->str, jsstr_length(str), ret);
    if(FAILED(hres))
        return hres;
    if(hres == S_FALSE) {
        if(rem_flags & REM_RESET_INDEX)
            set_last_index(regexp, 0);
        return S_FALSE;
    }

    if(!(rem_flags & REM_NO_CTX_UPDATE) && ctx->last_match != str) {
        jsstr_release(ctx->last_match);
        ctx->last_match = jsstr_addref(str);
    }

    if(!(rem_flags & REM_NO_CTX_UPDATE)) {
        DWORD i, n = min(sizeof(ctx->match_parens)/sizeof(ctx->match_parens[0]), ret->paren_count);

        for(i=0; i < n; i++) {
            if(ret->parens[i].index == -1) {
                ctx->match_parens[i].index = 0;
                ctx->match_parens[i].length = 0;
            }else {
                ctx->match_parens[i].index = ret->parens[i].index;
                ctx->match_parens[i].length = ret->parens[i].length;
            }
        }

        if(n < sizeof(ctx->match_parens)/sizeof(ctx->match_parens[0]))
            memset(ctx->match_parens+n, 0, sizeof(ctx->match_parens) - n*sizeof(ctx->match_parens[0]));
    }

    set_last_index(regexp, ret->cp-str->str);

    if(!(rem_flags & REM_NO_CTX_UPDATE)) {
        ctx->last_match_index = ret->cp-str->str-ret->match_len;
        ctx->last_match_length = ret->match_len;
    }

    return S_OK;
}
예제 #26
0
파일: string.c 프로젝트: jre-wine/wine
static HRESULT do_attributeless_tag_format(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r, const WCHAR *tagname)
{
    unsigned tagname_len;
    jsstr_t *str, *ret;
    WCHAR *ptr;
    HRESULT hres;

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

    if(!r) {
        jsstr_release(str);
        return S_OK;
    }

    tagname_len = strlenW(tagname);

    ptr = jsstr_alloc_buf(jsstr_length(str) + 2*tagname_len + 5, &ret);
    if(!ret) {
        jsstr_release(str);
        return E_OUTOFMEMORY;
    }

    *ptr++ = '<';
    memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
    ptr += tagname_len;
    *ptr++ = '>';

    ptr += jsstr_flush(str, ptr);
    jsstr_release(str);

    *ptr++ = '<';
    *ptr++ = '/';
    memcpy(ptr, tagname, tagname_len*sizeof(WCHAR));
    ptr += tagname_len;
    *ptr = '>';

    *r = jsval_string(ret);
    return S_OK;
}
예제 #27
0
파일: string.c 프로젝트: jre-wine/wine
/* ECMA-262 3rd Edition    15.5.4.5 */
static HRESULT String_charCodeAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                                 jsval_t *r)
{
    jsstr_t *str;
    DWORD idx = 0;
    HRESULT hres;

    TRACE("\n");

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

    if(argc > 0) {
        double d;

        hres = to_integer(ctx, argv[0], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }

        if(!is_int32(d) || d < 0 || d >= jsstr_length(str)) {
            jsstr_release(str);
            if(r)
                *r = jsval_number(NAN);
            return S_OK;
        }

        idx = d;
    }

    if(r) {
        WCHAR c;
        jsstr_extract(str, idx, 1, &c);
        *r = jsval_number(c);
    }

    jsstr_release(str);
    return S_OK;
}
예제 #28
0
파일: string.c 프로젝트: jre-wine/wine
/* ECMA-262 3rd Edition    15.5.4.5 */
static HRESULT String_charAt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                             jsval_t *r)
{
    jsstr_t *str, *ret;
    INT pos = 0;
    HRESULT hres;

    TRACE("\n");

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

    if(argc) {
        double d;

        hres = to_integer(ctx, argv[0], &d);
        if(FAILED(hres)) {
            jsstr_release(str);
            return hres;
        }
        pos = is_int32(d) ? d : -1;
    }

    if(!r) {
        jsstr_release(str);
        return S_OK;
    }

    if(0 <= pos && pos < jsstr_length(str)) {
        ret = jsstr_substr(str, pos, 1);
        if(!ret)
            return E_OUTOFMEMORY;
    } else {
        ret = jsstr_empty();
    }

    *r = jsval_string(ret);
    return S_OK;
}
예제 #29
0
파일: json.c 프로젝트: AmesianX/wine
/* ECMA-262 5.1 Edition    15.12.2 */
static HRESULT JSON_parse(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r)
{
    json_parse_ctx_t parse_ctx;
    const WCHAR *buf;
    jsstr_t *str;
    jsval_t ret;
    HRESULT hres;

    if(argc != 1) {
        FIXME("Unsupported args\n");
        return E_INVALIDARG;
    }

    hres = to_flat_string(ctx, argv[0], &str, &buf);
    if(FAILED(hres))
        return hres;

    TRACE("%s\n", debugstr_w(buf));

    parse_ctx.ptr = buf;
    parse_ctx.end = buf + jsstr_length(str);
    parse_ctx.ctx = ctx;
    hres = parse_json_value(&parse_ctx, &ret);
    jsstr_release(str);
    if(FAILED(hres))
        return hres;

    if(skip_spaces(&parse_ctx)) {
        FIXME("syntax error\n");
        jsval_release(ret);
        return E_FAIL;
    }

    if(r)
        *r = ret;
    else
        jsval_release(ret);
    return S_OK;
}
예제 #30
0
파일: function.c 프로젝트: 340211173/wine
static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *argv, IDispatch **ret)
{
    WCHAR *str = NULL, *ptr;
    unsigned len = 0, i = 0;
    bytecode_t *code;
    jsdisp_t *function;
    jsstr_t **params = NULL;
    int j = 0;
    HRESULT hres = S_OK;

    static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
    static const WCHAR function_beginW[] = {')',' ','{','\n'};
    static const WCHAR function_endW[] = {'\n','}',0};

    if(argc) {
        params = heap_alloc(argc*sizeof(*params));
        if(!params)
            return E_OUTOFMEMORY;

        if(argc > 2)
            len = (argc-2)*2; /* separating commas */
        for(i=0; i < argc; i++) {
            hres = to_string(ctx, argv[i], params+i);
            if(FAILED(hres))
                break;
            len += jsstr_length(params[i]);
        }
    }

    if(SUCCEEDED(hres)) {
        len += (sizeof(function_anonymousW) + sizeof(function_beginW) + sizeof(function_endW)) / sizeof(WCHAR);
        str = heap_alloc(len*sizeof(WCHAR));
        if(str) {
            memcpy(str, function_anonymousW, sizeof(function_anonymousW));
            ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
            if(argc > 1) {
                while(1) {
                    ptr += jsstr_flush(params[j], ptr);
                    if(++j == argc-1)
                        break;
                    *ptr++ = ',';
                    *ptr++ = ' ';
                }
            }
            memcpy(ptr, function_beginW, sizeof(function_beginW));
            ptr += sizeof(function_beginW)/sizeof(WCHAR);
            if(argc)
                ptr += jsstr_flush(params[argc-1], ptr);
            memcpy(ptr, function_endW, sizeof(function_endW));

            TRACE("%s\n", debugstr_w(str));
        }else {
            hres = E_OUTOFMEMORY;
        }
    }

    while(i)
        jsstr_release(params[--i]);
    heap_free(params);
    if(FAILED(hres))
        return hres;

    hres = compile_script(ctx, str, NULL, NULL, FALSE, FALSE, &code);
    heap_free(str);
    if(FAILED(hres))
        return hres;

    if(code->global_code.func_cnt != 1 || code->global_code.var_cnt) {
        ERR("Invalid parser result!\n");
        release_bytecode(code);
        return E_UNEXPECTED;
    }

    hres = create_source_function(ctx, code, code->global_code.funcs, NULL, &function);
    release_bytecode(code);
    if(FAILED(hres))
        return hres;

    *ret = to_disp(function);
    return S_OK;
}