Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e0413ddf
Commit
e0413ddf
authored
Sep 25, 2008
by
Jacek Caban
Committed by
Alexandre Julliard
Sep 25, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jscript: Added String.replace implementation.
parent
b4796499
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
368 additions
and
4 deletions
+368
-4
jscript.h
dlls/jscript/jscript.h
+2
-0
regexp.c
dlls/jscript/regexp.c
+18
-0
string.c
dlls/jscript/string.c
+254
-2
api.js
dlls/jscript/tests/api.js
+23
-0
regexp.js
dlls/jscript/tests/regexp.js
+71
-2
No files found.
dlls/jscript/jscript.h
View file @
e0413ddf
...
@@ -197,6 +197,8 @@ typedef struct {
...
@@ -197,6 +197,8 @@ typedef struct {
DWORD
len
;
DWORD
len
;
}
match_result_t
;
}
match_result_t
;
HRESULT
regexp_match_next
(
DispatchEx
*
,
BOOL
,
const
WCHAR
*
,
DWORD
,
const
WCHAR
**
,
match_result_t
**
,
DWORD
*
,
DWORD
*
,
match_result_t
*
);
HRESULT
regexp_match
(
DispatchEx
*
,
const
WCHAR
*
,
DWORD
,
BOOL
,
match_result_t
**
,
DWORD
*
);
HRESULT
regexp_match
(
DispatchEx
*
,
const
WCHAR
*
,
DWORD
,
BOOL
,
match_result_t
**
,
DWORD
*
);
static
inline
VARIANT
*
get_arg
(
DISPPARAMS
*
dp
,
DWORD
i
)
static
inline
VARIANT
*
get_arg
(
DISPPARAMS
*
dp
,
DWORD
i
)
...
...
dlls/jscript/regexp.c
View file @
e0413ddf
...
@@ -3358,6 +3358,24 @@ static HRESULT do_regexp_match_next(RegExpInstance *regexp, const WCHAR *str, DW
...
@@ -3358,6 +3358,24 @@ static HRESULT do_regexp_match_next(RegExpInstance *regexp, const WCHAR *str, DW
return
S_OK
;
return
S_OK
;
}
}
HRESULT
regexp_match_next
(
DispatchEx
*
dispex
,
BOOL
gcheck
,
const
WCHAR
*
str
,
DWORD
len
,
const
WCHAR
**
cp
,
match_result_t
**
parens
,
DWORD
*
parens_size
,
DWORD
*
parens_cnt
,
match_result_t
*
ret
)
{
RegExpInstance
*
regexp
=
(
RegExpInstance
*
)
dispex
;
jsheap_t
*
mark
;
HRESULT
hres
;
if
(
gcheck
&&
!
(
regexp
->
jsregexp
->
flags
&
JSREG_GLOB
))
return
S_FALSE
;
mark
=
jsheap_mark
(
&
regexp
->
dispex
.
ctx
->
tmp_heap
);
hres
=
do_regexp_match_next
(
regexp
,
str
,
len
,
cp
,
parens
,
parens_size
,
parens_cnt
,
ret
);
jsheap_clear
(
mark
);
return
hres
;
}
HRESULT
regexp_match
(
DispatchEx
*
dispex
,
const
WCHAR
*
str
,
DWORD
len
,
BOOL
gflag
,
match_result_t
**
match_result
,
HRESULT
regexp_match
(
DispatchEx
*
dispex
,
const
WCHAR
*
str
,
DWORD
len
,
BOOL
gflag
,
match_result_t
**
match_result
,
DWORD
*
result_cnt
)
DWORD
*
result_cnt
)
{
{
...
...
dlls/jscript/string.c
View file @
e0413ddf
...
@@ -425,11 +425,263 @@ static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
...
@@ -425,11 +425,263 @@ static HRESULT String_match(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
return
S_OK
;
return
S_OK
;
}
}
typedef
struct
{
WCHAR
*
buf
;
DWORD
size
;
DWORD
len
;
}
strbuf_t
;
static
HRESULT
strbuf_append
(
strbuf_t
*
buf
,
const
WCHAR
*
str
,
DWORD
len
)
{
if
(
!
len
)
return
S_OK
;
if
(
len
+
buf
->
len
>
buf
->
size
)
{
WCHAR
*
new_buf
;
DWORD
new_size
;
new_size
=
buf
->
size
?
buf
->
size
<<
1
:
16
;
if
(
new_size
<
buf
->
len
+
len
)
new_size
=
buf
->
len
+
len
;
if
(
buf
->
buf
)
new_buf
=
heap_realloc
(
buf
->
buf
,
new_size
*
sizeof
(
WCHAR
));
else
new_buf
=
heap_alloc
(
new_size
*
sizeof
(
WCHAR
));
if
(
!
new_buf
)
return
E_OUTOFMEMORY
;
buf
->
buf
=
new_buf
;
buf
->
size
=
new_size
;
}
memcpy
(
buf
->
buf
+
buf
->
len
,
str
,
len
*
sizeof
(
WCHAR
));
buf
->
len
+=
len
;
return
S_OK
;
}
static
HRESULT
rep_call
(
DispatchEx
*
func
,
const
WCHAR
*
str
,
match_result_t
*
match
,
match_result_t
*
parens
,
DWORD
parens_cnt
,
LCID
lcid
,
BSTR
*
ret
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
DISPPARAMS
dp
=
{
NULL
,
NULL
,
0
,
0
};
VARIANTARG
*
args
,
*
arg
;
VARIANT
var
;
DWORD
i
;
HRESULT
hres
=
S_OK
;
dp
.
cArgs
=
parens_cnt
+
3
;
dp
.
rgvarg
=
args
=
heap_alloc_zero
(
sizeof
(
VARIANT
)
*
dp
.
cArgs
);
if
(
!
args
)
return
E_OUTOFMEMORY
;
arg
=
get_arg
(
&
dp
,
0
);
V_VT
(
arg
)
=
VT_BSTR
;
V_BSTR
(
arg
)
=
SysAllocStringLen
(
match
->
str
,
match
->
len
);
if
(
!
V_BSTR
(
arg
))
hres
=
E_OUTOFMEMORY
;
if
(
SUCCEEDED
(
hres
))
{
for
(
i
=
0
;
i
<
parens_cnt
;
i
++
)
{
arg
=
get_arg
(
&
dp
,
i
+
1
);
V_VT
(
arg
)
=
VT_BSTR
;
V_BSTR
(
arg
)
=
SysAllocStringLen
(
parens
[
i
].
str
,
parens
[
i
].
len
);
if
(
!
V_BSTR
(
arg
))
{
hres
=
E_OUTOFMEMORY
;
break
;
}
}
}
if
(
SUCCEEDED
(
hres
))
{
arg
=
get_arg
(
&
dp
,
parens_cnt
+
1
);
V_VT
(
arg
)
=
VT_I4
;
V_I4
(
arg
)
=
match
->
str
-
str
;
arg
=
get_arg
(
&
dp
,
parens_cnt
+
2
);
V_VT
(
arg
)
=
VT_BSTR
;
V_BSTR
(
arg
)
=
SysAllocString
(
str
);
if
(
!
V_BSTR
(
arg
))
hres
=
E_OUTOFMEMORY
;
}
if
(
SUCCEEDED
(
hres
))
hres
=
jsdisp_call_value
(
func
,
lcid
,
DISPATCH_METHOD
,
&
dp
,
&
var
,
ei
,
caller
);
for
(
i
=
0
;
i
<
parens_cnt
+
1
;
i
++
)
{
if
(
i
!=
parens_cnt
+
1
)
SysFreeString
(
V_BSTR
(
get_arg
(
&
dp
,
i
)));
}
heap_free
(
args
);
if
(
FAILED
(
hres
))
return
hres
;
hres
=
to_string
(
func
->
ctx
,
&
var
,
ei
,
ret
);
VariantClear
(
&
var
);
return
hres
;
}
/* ECMA-262 3rd Edition 15.5.4.11 */
static
HRESULT
String_replace
(
DispatchEx
*
dispex
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
static
HRESULT
String_replace
(
DispatchEx
*
dispex
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
sp
)
VARIANT
*
retv
,
jsexcept_t
*
ei
,
IServiceProvider
*
caller
)
{
{
FIXME
(
"
\n
"
);
DWORD
parens_cnt
,
parens_size
=
0
,
rep_len
=
0
,
length
;
BSTR
rep_str
=
NULL
,
match_str
=
NULL
,
ret_str
;
DispatchEx
*
rep_func
=
NULL
,
*
regexp
=
NULL
;
match_result_t
*
parens
=
NULL
,
match
;
const
WCHAR
*
str
;
strbuf_t
ret
=
{
NULL
,
0
,
0
};
BOOL
gcheck
=
FALSE
;
VARIANT
*
arg_var
;
HRESULT
hres
=
S_OK
;
TRACE
(
"
\n
"
);
if
(
is_class
(
dispex
,
JSCLASS_STRING
))
{
StringInstance
*
string
=
(
StringInstance
*
)
dispex
;
str
=
string
->
str
;
length
=
string
->
length
;
}
else
{
FIXME
(
"not String this
\n
"
);
return
E_NOTIMPL
;
return
E_NOTIMPL
;
}
if
(
!
arg_cnt
(
dp
))
{
if
(
retv
)
{
ret_str
=
SysAllocString
(
str
);
if
(
!
ret_str
)
return
E_OUTOFMEMORY
;
V_VT
(
retv
)
=
VT_BSTR
;
V_BSTR
(
retv
)
=
ret_str
;
}
return
S_OK
;
}
arg_var
=
get_arg
(
dp
,
0
);
switch
(
V_VT
(
arg_var
))
{
case
VT_DISPATCH
:
regexp
=
iface_to_jsdisp
((
IUnknown
*
)
V_DISPATCH
(
arg_var
));
if
(
regexp
)
{
if
(
is_class
(
regexp
,
JSCLASS_REGEXP
))
{
break
;
}
else
{
jsdisp_release
(
regexp
);
regexp
=
NULL
;
}
}
default:
hres
=
to_string
(
dispex
->
ctx
,
arg_var
,
ei
,
&
match_str
);
if
(
FAILED
(
hres
))
return
hres
;
}
if
(
arg_cnt
(
dp
)
>=
2
)
{
arg_var
=
get_arg
(
dp
,
1
);
switch
(
V_VT
(
arg_var
))
{
case
VT_DISPATCH
:
rep_func
=
iface_to_jsdisp
((
IUnknown
*
)
V_DISPATCH
(
arg_var
));
if
(
rep_func
)
{
if
(
is_class
(
rep_func
,
JSCLASS_FUNCTION
))
{
break
;
}
else
{
jsdisp_release
(
rep_func
);
rep_func
=
NULL
;
}
}
default:
hres
=
to_string
(
dispex
->
ctx
,
arg_var
,
ei
,
&
rep_str
);
if
(
FAILED
(
hres
))
break
;
if
(
strchrW
(
rep_str
,
'$'
))
{
FIXME
(
"unsupported $ in replace string
\n
"
);
hres
=
E_NOTIMPL
;
}
rep_len
=
SysStringLen
(
rep_str
);
}
}
if
(
SUCCEEDED
(
hres
))
{
const
WCHAR
*
cp
,
*
ecp
;
cp
=
ecp
=
str
;
while
(
1
)
{
if
(
regexp
)
{
hres
=
regexp_match_next
(
regexp
,
gcheck
,
str
,
length
,
&
cp
,
rep_func
?
&
parens
:
NULL
,
&
parens_size
,
&
parens_cnt
,
&
match
);
gcheck
=
TRUE
;
if
(
hres
==
S_FALSE
)
{
hres
=
S_OK
;
break
;
}
if
(
FAILED
(
hres
))
break
;
}
else
{
match
.
str
=
strstrW
(
cp
,
match_str
);
if
(
!
match
.
str
)
break
;
match
.
len
=
SysStringLen
(
match_str
);
cp
=
match
.
str
+
match
.
len
;
}
hres
=
strbuf_append
(
&
ret
,
ecp
,
match
.
str
-
ecp
);
ecp
=
match
.
str
+
match
.
len
;
if
(
FAILED
(
hres
))
break
;
if
(
rep_func
)
{
BSTR
cstr
;
hres
=
rep_call
(
rep_func
,
str
,
&
match
,
parens
,
parens_cnt
,
lcid
,
&
cstr
,
ei
,
caller
);
if
(
FAILED
(
hres
))
break
;
hres
=
strbuf_append
(
&
ret
,
cstr
,
SysStringLen
(
cstr
));
SysFreeString
(
cstr
);
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
(
SUCCEEDED
(
hres
))
hres
=
strbuf_append
(
&
ret
,
ecp
,
(
str
+
length
)
-
ecp
);
}
if
(
rep_func
)
jsdisp_release
(
rep_func
);
if
(
regexp
)
jsdisp_release
(
regexp
);
SysFreeString
(
rep_str
);
SysFreeString
(
match_str
);
heap_free
(
parens
);
if
(
SUCCEEDED
(
hres
)
&&
retv
)
{
ret_str
=
SysAllocStringLen
(
ret
.
buf
,
ret
.
len
);
if
(
!
ret_str
)
return
E_OUTOFMEMORY
;
V_VT
(
retv
)
=
VT_BSTR
;
V_BSTR
(
retv
)
=
ret_str
;
TRACE
(
"= %s
\n
"
,
debugstr_w
(
ret_str
));
}
heap_free
(
ret
.
buf
);
return
hres
;
}
}
static
HRESULT
String_search
(
DispatchEx
*
dispex
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
static
HRESULT
String_search
(
DispatchEx
*
dispex
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
dp
,
...
...
dlls/jscript/tests/api.js
View file @
e0413ddf
...
@@ -151,6 +151,29 @@ arr.concat = String.prototype.concat;
...
@@ -151,6 +151,29 @@ arr.concat = String.prototype.concat;
tmp
=
arr
.
concat
(
"d"
);
tmp
=
arr
.
concat
(
"d"
);
ok
(
tmp
===
"2,ad"
,
"arr.concat = "
+
tmp
);
ok
(
tmp
===
"2,ad"
,
"arr.concat = "
+
tmp
);
r
=
"- [test] -"
.
replace
(
"[test]"
,
"success"
);
ok
(
r
===
"- success -"
,
"r = "
+
r
+
" expected '- success -'"
);
r
=
"- [test] -"
.
replace
(
"[test]"
,
"success"
,
"test"
);
ok
(
r
===
"- success -"
,
"r = "
+
r
+
" expected '- success -'"
);
r
=
"test"
.
replace
();
ok
(
r
===
"test"
,
"r = "
+
r
+
" expected 'test'"
);
function
replaceFunc3
(
m
,
off
,
str
)
{
ok
(
arguments
.
length
===
3
,
"arguments.length = "
+
arguments
.
length
);
ok
(
m
===
"[test]"
,
"m = "
+
m
+
" expected [test1]"
);
ok
(
off
===
1
,
"off = "
+
off
+
" expected 0"
);
ok
(
str
===
"-[test]-"
,
"str = "
+
arguments
[
3
]);
return
"ret"
;
}
r
=
"-[test]-"
.
replace
(
"[test]"
,
replaceFunc3
);
ok
(
r
===
"-ret-"
,
"r = "
+
r
+
" expected '-ret-'"
);
r
=
"-[test]-"
.
replace
(
"[test]"
,
replaceFunc3
,
"test"
);
ok
(
r
===
"-ret-"
,
"r = "
+
r
+
" expected '-ret-'"
);
var
arr
=
new
Array
();
var
arr
=
new
Array
();
ok
(
typeof
(
arr
)
===
"object"
,
"arr () is not object"
);
ok
(
typeof
(
arr
)
===
"object"
,
"arr () is not object"
);
ok
((
arr
.
length
===
0
),
"arr.length is not 0"
);
ok
((
arr
.
length
===
0
),
"arr.length is not 0"
);
...
...
dlls/jscript/tests/regexp.js
View file @
e0413ddf
...
@@ -56,7 +56,6 @@ ok(typeof(m) === "object", "typeof m is not object");
...
@@ -56,7 +56,6 @@ ok(typeof(m) === "object", "typeof m is not object");
ok
(
m
.
length
===
1
,
"m.length is not 1"
);
ok
(
m
.
length
===
1
,
"m.length is not 1"
);
ok
(
m
[
"0"
]
===
"ab"
,
"m[0] is not
\"
ab
\"
"
);
ok
(
m
[
"0"
]
===
"ab"
,
"m[0] is not
\"
ab
\"
"
);
/*
m
=
"abcabc"
.
match
(
new
RegExp
(
"ab"
,
"g"
));
m
=
"abcabc"
.
match
(
new
RegExp
(
"ab"
,
"g"
));
ok
(
typeof
(
m
)
===
"object"
,
"typeof m is not object"
);
ok
(
typeof
(
m
)
===
"object"
,
"typeof m is not object"
);
ok
(
m
.
length
===
2
,
"m.length is not 1"
);
ok
(
m
.
length
===
2
,
"m.length is not 1"
);
...
@@ -74,5 +73,75 @@ ok(typeof(m) === "object", "typeof m is not object");
...
@@ -74,5 +73,75 @@ ok(typeof(m) === "object", "typeof m is not object");
ok
(
m
.
length
===
2
,
"m.length is not 1"
);
ok
(
m
.
length
===
2
,
"m.length is not 1"
);
ok
(
m
[
"0"
]
===
"ab"
,
"m[0] is not
\"
ab
\"
"
);
ok
(
m
[
"0"
]
===
"ab"
,
"m[0] is not
\"
ab
\"
"
);
ok
(
m
[
"1"
]
===
"ab"
,
"m[1] is not
\"
ab
\"
"
);
ok
(
m
[
"1"
]
===
"ab"
,
"m[1] is not
\"
ab
\"
"
);
*/
r
=
"- [test] -"
.
replace
(
/
\[([^\[]
+
)\]
/g
,
"success"
);
ok
(
r
===
"- success -"
,
"r = "
+
r
+
" expected '- success -'"
);
r
=
"[test] [test]"
.
replace
(
/
\[([^\[]
+
)\]
/g
,
"aa"
);
ok
(
r
===
"aa aa"
,
"r = "
+
r
+
"aa aa"
);
r
=
"[test] [test]"
.
replace
(
/
\[([^\[]
+
)\]
/
,
"aa"
);
ok
(
r
===
"aa [test]"
,
"r = "
+
r
+
" expected 'aa [test]'"
);
r
=
"- [test] -"
.
replace
(
/
\[([^\[]
+
)\]
/g
);
ok
(
r
===
"- undefined -"
,
"r = "
+
r
+
" expected '- undefined -'"
);
r
=
"- [test] -"
.
replace
(
/
\[([^\[]
+
)\]
/g
,
true
);
ok
(
r
===
"- true -"
,
"r = "
+
r
+
" expected '- true -'"
);
r
=
"- [test] -"
.
replace
(
/
\[([^\[]
+
)\]
/g
,
true
,
"test"
);
ok
(
r
===
"- true -"
,
"r = "
+
r
+
" expected '- true -'"
);
var
tmp
=
0
;
function
replaceFunc1
(
m
,
off
,
str
)
{
ok
(
arguments
.
length
===
3
,
"arguments.length = "
+
arguments
.
length
);
switch
(
tmp
)
{
case
0
:
ok
(
m
===
"[test1]"
,
"m = "
+
m
+
" expected [test1]"
);
ok
(
off
===
0
,
"off = "
+
off
+
" expected 0"
);
break
;
case
1
:
ok
(
m
===
"[test2]"
,
"m = "
+
m
+
" expected [test2]"
);
ok
(
off
===
8
,
"off = "
+
off
+
" expected 8"
);
break
;
default
:
ok
(
false
,
"unexpected call"
);
}
ok
(
str
===
"[test1] [test2]"
,
"str = "
+
arguments
[
3
]);
return
"r"
+
tmp
++
;
}
r
=
"[test1] [test2]"
.
replace
(
/
\[[^\[]
+
\]
/g
,
replaceFunc1
);
ok
(
r
===
"r0 r1"
,
"r = "
+
r
+
" expected 'r0 r1'"
);
tmp
=
0
;
function
replaceFunc2
(
m
,
subm
,
off
,
str
)
{
ok
(
arguments
.
length
===
4
,
"arguments.length = "
+
arguments
.
length
);
switch
(
tmp
)
{
case
0
:
ok
(
subm
===
"test1"
,
"subm = "
+
subm
);
ok
(
m
===
"[test1]"
,
"m = "
+
m
+
" expected [test1]"
);
ok
(
off
===
0
,
"off = "
+
off
+
" expected 0"
);
break
;
case
1
:
ok
(
subm
===
"test2"
,
"subm = "
+
subm
);
ok
(
m
===
"[test2]"
,
"m = "
+
m
+
" expected [test2]"
);
ok
(
off
===
8
,
"off = "
+
off
+
" expected 8"
);
break
;
default
:
ok
(
false
,
"unexpected call"
);
}
ok
(
str
===
"[test1] [test2]"
,
"str = "
+
arguments
[
3
]);
return
"r"
+
tmp
++
;
}
r
=
"[test1] [test2]"
.
replace
(
/
\[([^\[]
+
)\]
/g
,
replaceFunc2
);
ok
(
r
===
"r0 r1"
,
"r = '"
+
r
+
"' expected 'r0 r1'"
);
reportSuccess
();
reportSuccess
();
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment