Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
d1cc31ce
Commit
d1cc31ce
authored
Jul 01, 2022
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add qsort_s.
Implementation copied from msvcrt. Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
00eff14f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
127 additions
and
30 deletions
+127
-30
misc.c
dlls/ntdll/misc.c
+126
-28
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-0
string.c
dlls/ntdll/tests/string.c
+0
-2
No files found.
dlls/ntdll/misc.c
View file @
d1cc31ce
...
...
@@ -37,49 +37,147 @@ LPCSTR debugstr_us( const UNICODE_STRING *us )
return
debugstr_wn
(
us
->
Buffer
,
us
->
Length
/
sizeof
(
WCHAR
));
}
static
void
NTDLL_mergesort
(
void
*
arr
,
void
*
barr
,
size_t
elemsize
,
int
(
__cdecl
*
compar
)(
const
void
*
,
const
void
*
),
size_t
left
,
size_t
right
)
{
if
(
right
>
left
)
{
size_t
i
,
j
,
k
,
m
;
m
=
left
+
(
right
-
left
)
/
2
;
NTDLL_mergesort
(
arr
,
barr
,
elemsize
,
compar
,
left
,
m
);
NTDLL_mergesort
(
arr
,
barr
,
elemsize
,
compar
,
m
+
1
,
right
);
#define X(a,i) ((char*)a+elemsize*(i))
for
(
k
=
left
,
i
=
left
,
j
=
m
+
1
;
i
<=
m
&&
j
<=
right
;
k
++
)
{
if
(
compar
(
X
(
arr
,
i
),
X
(
arr
,
j
))
<=
0
)
{
memcpy
(
X
(
barr
,
k
),
X
(
arr
,
i
),
elemsize
);
i
++
;
}
else
{
memcpy
(
X
(
barr
,
k
),
X
(
arr
,
j
),
elemsize
);
j
++
;
static
int
__cdecl
compare_wrapper
(
void
*
ctx
,
const
void
*
e1
,
const
void
*
e2
)
{
int
(
__cdecl
*
compare
)(
const
void
*
,
const
void
*
)
=
ctx
;
return
compare
(
e1
,
e2
);
}
static
inline
void
swap
(
char
*
l
,
char
*
r
,
size_t
size
)
{
char
tmp
;
while
(
size
--
)
{
tmp
=
*
l
;
*
l
++
=
*
r
;
*
r
++
=
tmp
;
}
}
static
void
small_sort
(
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
CDECL
*
compar
)(
void
*
,
const
void
*
,
const
void
*
),
void
*
context
)
{
size_t
e
,
i
;
char
*
max
,
*
p
;
for
(
e
=
nmemb
;
e
>
1
;
e
--
)
{
max
=
base
;
for
(
i
=
1
;
i
<
e
;
i
++
)
{
p
=
(
char
*
)
base
+
i
*
size
;
if
(
compar
(
context
,
p
,
max
)
>
0
)
max
=
p
;
}
if
(
p
!=
max
)
swap
(
p
,
max
,
size
);
}
}
static
void
quick_sort
(
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
CDECL
*
compar
)(
void
*
,
const
void
*
,
const
void
*
),
void
*
context
)
{
size_t
stack_lo
[
8
*
sizeof
(
size_t
)],
stack_hi
[
8
*
sizeof
(
size_t
)];
size_t
beg
,
end
,
lo
,
hi
,
med
;
int
stack_pos
;
stack_pos
=
0
;
stack_lo
[
stack_pos
]
=
0
;
stack_hi
[
stack_pos
]
=
nmemb
-
1
;
#define X(i) ((char*)base+size*(i))
while
(
stack_pos
>=
0
)
{
beg
=
stack_lo
[
stack_pos
];
end
=
stack_hi
[
stack_pos
--
];
if
(
end
-
beg
<
8
)
{
small_sort
(
X
(
beg
),
end
-
beg
+
1
,
size
,
compar
,
context
);
continue
;
}
lo
=
beg
;
hi
=
end
;
med
=
lo
+
(
hi
-
lo
+
1
)
/
2
;
if
(
compar
(
context
,
X
(
lo
),
X
(
med
))
>
0
)
swap
(
X
(
lo
),
X
(
med
),
size
);
if
(
compar
(
context
,
X
(
lo
),
X
(
hi
))
>
0
)
swap
(
X
(
lo
),
X
(
hi
),
size
);
if
(
compar
(
context
,
X
(
med
),
X
(
hi
))
>
0
)
swap
(
X
(
med
),
X
(
hi
),
size
);
lo
++
;
hi
--
;
while
(
1
)
{
while
(
lo
<=
hi
)
{
if
(
lo
!=
med
&&
compar
(
context
,
X
(
lo
),
X
(
med
))
>
0
)
break
;
lo
++
;
}
while
(
med
!=
hi
)
{
if
(
compar
(
context
,
X
(
hi
),
X
(
med
))
<=
0
)
break
;
hi
--
;
}
if
(
hi
<
lo
)
break
;
swap
(
X
(
lo
),
X
(
hi
),
size
);
if
(
hi
==
med
)
med
=
lo
;
lo
++
;
hi
--
;
}
while
(
hi
>
beg
)
{
if
(
hi
!=
med
&&
compar
(
context
,
X
(
hi
),
X
(
med
))
!=
0
)
break
;
hi
--
;
}
if
(
i
<=
m
)
memcpy
(
X
(
barr
,
k
),
X
(
arr
,
i
),
(
m
-
i
+
1
)
*
elemsize
);
else
memcpy
(
X
(
barr
,
k
),
X
(
arr
,
j
),
(
right
-
j
+
1
)
*
elemsize
);
memcpy
(
X
(
arr
,
left
),
X
(
barr
,
left
),
(
right
-
left
+
1
)
*
elemsize
);
if
(
hi
-
beg
>=
end
-
lo
)
{
stack_lo
[
++
stack_pos
]
=
beg
;
stack_hi
[
stack_pos
]
=
hi
;
stack_lo
[
++
stack_pos
]
=
lo
;
stack_hi
[
stack_pos
]
=
end
;
}
else
{
stack_lo
[
++
stack_pos
]
=
lo
;
stack_hi
[
stack_pos
]
=
end
;
stack_lo
[
++
stack_pos
]
=
beg
;
stack_hi
[
stack_pos
]
=
hi
;
}
}
#undef X
}
/*********************************************************************
* qsort_s (NTDLL.@)
*/
void
__cdecl
qsort_s
(
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
__cdecl
*
compar
)(
void
*
,
const
void
*
,
const
void
*
),
void
*
context
)
{
const
size_t
total_size
=
nmemb
*
size
;
if
(
!
base
&&
nmemb
)
return
;
if
(
!
size
)
return
;
if
(
!
compar
)
return
;
if
(
total_size
/
size
!=
nmemb
)
return
;
if
(
nmemb
<
2
)
return
;
quick_sort
(
base
,
nmemb
,
size
,
compar
,
context
);
}
/*********************************************************************
* qsort (NTDLL.@)
*/
void
__cdecl
qsort
(
void
*
base
,
size_t
nmemb
,
size_t
size
,
int
(
__cdecl
*
compar
)(
const
void
*
,
const
void
*
)
)
{
void
*
secondarr
;
if
(
nmemb
<
2
||
size
==
0
)
return
;
secondarr
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
nmemb
*
size
);
NTDLL_mergesort
(
base
,
secondarr
,
size
,
compar
,
0
,
nmemb
-
1
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
secondarr
);
qsort_s
(
base
,
nmemb
,
size
,
compare_wrapper
,
compar
);
}
/*********************************************************************
* bsearch (NTDLL.@)
*/
...
...
dlls/ntdll/ntdll.spec
View file @
d1cc31ce
...
...
@@ -1603,6 +1603,7 @@
@ cdecl memset(ptr long long)
@ cdecl pow(double double)
@ cdecl qsort(ptr long long ptr)
@ cdecl qsort_s(ptr long long ptr ptr)
@ cdecl sin(double)
@ varargs sprintf(ptr str) NTDLL_sprintf
@ varargs sprintf_s(ptr long str)
...
...
dlls/ntdll/tests/string.c
View file @
d1cc31ce
...
...
@@ -1452,11 +1452,9 @@ static void test_qsort(void)
ok
(
!
strcmp
(
strarr2
[
0
],
"!"
),
"badly sorted, strar2r[0] is %s
\n
"
,
strarr2
[
0
]);
ok
(
!
strcmp
(
strarr2
[
1
],
"Hello"
),
"badly sorted, strarr2[1] is %s
\n
"
,
strarr2
[
1
]);
ok
(
!
strcmp
(
strarr2
[
2
],
"Sorted"
),
"badly sorted, strarr2[2] is %s
\n
"
,
strarr2
[
2
]);
todo_wine
{
ok
(
!
strcmp
(
strarr2
[
3
],
"wine"
),
"badly sorted, strarr2[3] is %s
\n
"
,
strarr2
[
3
]);
ok
(
!
strcmp
(
strarr2
[
4
],
"WINE"
),
"badly sorted, strarr2[4] is %s
\n
"
,
strarr2
[
4
]);
ok
(
!
strcmp
(
strarr2
[
5
],
"Wine"
),
"badly sorted, strarr2[5] is %s
\n
"
,
strarr2
[
5
]);
}
ok
(
!
strcmp
(
strarr2
[
6
],
"World"
),
"badly sorted, strarr2[6] is %s
\n
"
,
strarr2
[
6
]);
}
...
...
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