Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
[PATCH vkd3d 1/4] libs/vkd3d: Implement cube shader resource views.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
include/vkd3d_d3d12.idl | 2 +-
libs/vkd3d/resource.c | 43 +++++++++++++++++++++++++++++++++++++------
2 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index 5bfc76718873..ec7df5653faa 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -945,7 +945,7 @@ typedef struct D3D12_TEXCUBE_ARRAY_SRV
{
UINT MostDetailedMip;
UINT MipLevels;
- UINT First2DArraySlice;
+ UINT First2DArrayFace;
UINT NumCubes;
FLOAT ResourceMinLODClamp;
} D3D12_TEXCUBE_ARRAY_SRV;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index e45c90083229..e1a5adf3364d 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1150,6 +1150,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
struct d3d12_device *device, struct d3d12_resource *resource,
const D3D12_SHADER_RESOURCE_VIEW_DESC *desc)
{
+ uint32_t miplevel_idx, miplevel_count, layer_idx, layer_count;
const struct vkd3d_format *format;
VkImageViewType vk_view_type;
struct vkd3d_view *view;
@@ -1174,22 +1175,52 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
return;
}
- if (desc)
- FIXME("Unhandled SRV desc %p.\n", desc);
-
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, desc ? desc->Format : 0)))
{
FIXME("Failed to find format for %#x.\n", resource->desc.Format);
return;
}
+ vk_view_type = resource->desc.DepthOrArraySize > 1
+ ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
+ miplevel_idx = 0;
+ miplevel_count = VK_REMAINING_MIP_LEVELS;
+ layer_idx = 0;
+ layer_count = VK_REMAINING_ARRAY_LAYERS;
+ if (desc)
+ {
+ if (desc->Shader4ComponentMapping != D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING)
+ FIXME("Ignoring component mapping %#x.\n", desc->Shader4ComponentMapping);
+
+ switch (desc->ViewDimension)
+ {
+ case D3D12_SRV_DIMENSION_TEXTURECUBE:
+ vk_view_type = VK_IMAGE_VIEW_TYPE_CUBE;
+ miplevel_idx = desc->u.TextureCube.MostDetailedMip;
+ miplevel_count = desc->u.TextureCube.MipLevels;
+ layer_count = 6;
+ if (desc->u.TextureCube.ResourceMinLODClamp)
+ FIXME("Unhandled min LOD clamp %.8e.\n", desc->u.TextureCube.ResourceMinLODClamp);
+ break;
+ case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY:
+ vk_view_type = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
+ miplevel_idx = desc->u.TextureCubeArray.MostDetailedMip;
+ miplevel_count = desc->u.TextureCubeArray.MipLevels;
+ layer_idx = desc->u.TextureCubeArray.First2DArrayFace;
+ layer_count = 6 * desc->u.TextureCubeArray.NumCubes;
+ if (desc->u.TextureCubeArray.ResourceMinLODClamp)
+ FIXME("Unhandled min LOD clamp %.8e.\n", desc->u.TextureCubeArray.ResourceMinLODClamp);
+ break;
+ default:
+ FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension);
+ }
+ }
+
if (!(view = vkd3d_view_create()))
return;
- vk_view_type = resource->desc.DepthOrArraySize > 1
- ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
if (vkd3d_create_texture_view(device, resource, format, vk_view_type,
- 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS, true, &view->u.vk_image_view) < 0)
+ miplevel_idx, miplevel_count, layer_idx, layer_count, true, &view->u.vk_image_view) < 0)
{
vkd3d_free(view);
return;
--
2.16.4
June 27, 2018
[PATCH] include/d3d12: Fix typos.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
include/d3d12.idl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/d3d12.idl b/include/d3d12.idl
index 69220e674cd7..43e9c2dca3bb 100644
--- a/include/d3d12.idl
+++ b/include/d3d12.idl
@@ -944,7 +944,7 @@ typedef struct D3D12_TEXCUBE_ARRAY_SRV
{
UINT MostDetailedMip;
UINT MipLevels;
- UINT First2DArraySlice;
+ UINT First2DArrayFace;
UINT NumCubes;
FLOAT ResourceMinLODClamp;
} D3D12_TEXCUBE_ARRAY_SRV;
@@ -2172,7 +2172,7 @@ interface ID3D12RootSignatureDeserializer : IUnknown
ID3DBlob **blob, ID3DBlob **error_blob);
typedef HRESULT (__stdcall *PFN_D3D12_CREATE_DEVICE)(IUnknown *adapter,
- D3D_FEATURE_LEVEL minmum_feature_level, REFIID iid, void **device);
+ D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device);
[local] HRESULT __stdcall D3D12CreateDevice(IUnknown *adapter,
D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device);
--
2.16.4
June 27, 2018
[PATCH v2] msvcp120: Add test for Concurrent_vector_Internal_resize and reverse.
by Piotr Caban
From: Hua Meng <161220092(a)smail.nju.edu.cn>
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
v2:
- added test for vector capacity after _Internal_reserve call
dlls/msvcp120/tests/msvcp120.c | 90
++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
June 27, 2018
[PATCH 5/5] schedsvc: Use current time as trigger begin time when necessary.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/schedsvc/atsvc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c
index b463be6960..a0e0727b31 100644
--- a/dlls/schedsvc/atsvc.c
+++ b/dlls/schedsvc/atsvc.c
@@ -170,6 +170,9 @@ static BOOL trigger_get_next_runtime(const TASK_TRIGGER *trigger, const FILETIME
FileTimeToSystemTime(current_ft, ¤t_st);
get_begin_time(trigger, &begin_ft);
+ if (CompareFileTime(&begin_ft, current_ft) < 0)
+ begin_ft = *current_ft;
+
get_end_time(trigger, &end_ft);
switch (trigger->TriggerType)
--
2.16.3
June 27, 2018
[PATCH 4/5] schedsvc: Avoid an infinite loop.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/schedsvc/atsvc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c
index df4185eac2..b463be6960 100644
--- a/dlls/schedsvc/atsvc.c
+++ b/dlls/schedsvc/atsvc.c
@@ -194,6 +194,9 @@ static BOOL trigger_get_next_runtime(const TASK_TRIGGER *trigger, const FILETIME
break;
case TASK_TIME_TRIGGER_DAILY:
+ if (!trigger->Type.Daily.DaysInterval)
+ break; /* avoid infinite loop */
+
st = current_st;
st.wHour = trigger->wStartHour;
st.wMinute = trigger->wStartMinute;
--
2.16.3
June 27, 2018
[PATCH 3/5] schedsvc: Minor cleanup.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/schedsvc/atsvc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/schedsvc/atsvc.c b/dlls/schedsvc/atsvc.c
index b8adc7279d..df4185eac2 100644
--- a/dlls/schedsvc/atsvc.c
+++ b/dlls/schedsvc/atsvc.c
@@ -99,7 +99,7 @@ static void filetime_add_ms(FILETIME *ft, LONGLONG ms)
LONGLONG ll;
} *ftll = (union u_ftll *)ft;
- ftll->ll += ms * (ULONGLONG)10000;
+ ftll->ll += ms * (LONGLONG)10000;
}
static void filetime_add_minutes(FILETIME *ft, LONG minutes)
@@ -117,7 +117,7 @@ static void filetime_add_days(FILETIME *ft, LONG days)
filetime_add_hours(ft, (LONGLONG)days * 24);
}
-static void filetime_add_weeks(FILETIME *ft, ULONG weeks)
+static void filetime_add_weeks(FILETIME *ft, LONG weeks)
{
filetime_add_days(ft, (LONGLONG)weeks * 7);
}
@@ -250,7 +250,7 @@ static BOOL trigger_get_next_runtime(const TASK_TRIGGER *trigger, const FILETIME
return FALSE;
}
-static BOOL job_get_next_runtime(struct job_t *job, FILETIME *current_ft, FILETIME *next_rt)
+static BOOL job_get_next_runtime(struct job_t *job, const FILETIME *current_ft, FILETIME *next_rt)
{
FILETIME trigger_rt;
BOOL have_next_rt = FALSE;
@@ -307,7 +307,7 @@ BOOL get_next_runtime(LARGE_INTEGER *rt)
return have_next_rt;
}
-static BOOL job_runs_at(struct job_t *job, FILETIME *begin_ft, FILETIME *end_ft)
+static BOOL job_runs_at(struct job_t *job, const FILETIME *begin_ft, const FILETIME *end_ft)
{
FILETIME job_ft;
--
2.16.3
June 27, 2018
[PATCH 2/5] mstask: Avoid an infinite loop.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/mstask/task.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c
index 6492f16986..6c27b76c95 100644
--- a/dlls/mstask/task.c
+++ b/dlls/mstask/task.c
@@ -532,6 +532,9 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
break;
case TASK_TIME_TRIGGER_DAILY:
+ if (!This->trigger[i].Type.Daily.DaysInterval)
+ break; /* avoid infinite loop */
+
st = current_st;
st.wHour = This->trigger[i].wStartHour;
st.wMinute = This->trigger[i].wStartMinute;
--
2.16.3
June 27, 2018
[PATCH 1/5] mstask: Use current time as trigger begin time when necessary.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/mstask/task.c | 42 +++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/dlls/mstask/task.c b/dlls/mstask/task.c
index 490229ae71..6492f16986 100644
--- a/dlls/mstask/task.c
+++ b/dlls/mstask/task.c
@@ -481,7 +481,7 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
TaskImpl *This = impl_from_ITask(iface);
HRESULT hr = SCHED_S_TASK_NO_VALID_TRIGGERS;
SYSTEMTIME st, current_st;
- FILETIME current_ft, begin_ft, end_ft, best_ft;
+ FILETIME current_ft, trigger_ft, begin_ft, end_ft, best_ft;
BOOL have_best_time = FALSE;
DWORD i;
@@ -494,12 +494,16 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
}
GetLocalTime(¤t_st);
+ SystemTimeToFileTime(¤t_st, ¤t_ft);
for (i = 0; i < This->trigger_count; i++)
{
if (!(This->trigger[i].rgFlags & TASK_TRIGGER_FLAG_DISABLED))
{
get_begin_time(&This->trigger[i], &begin_ft);
+ if (CompareFileTime(&begin_ft, ¤t_ft) < 0)
+ begin_ft = current_ft;
+
get_end_time(&This->trigger[i], &end_ft);
switch (This->trigger[i].TriggerType)
@@ -516,12 +520,12 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
st.wMinute = This->trigger[i].wStartMinute;
st.wSecond = 0;
st.wMilliseconds = 0;
- SystemTimeToFileTime(&st, ¤t_ft);
- if (CompareFileTime(&begin_ft, ¤t_ft) <= 0 && CompareFileTime(¤t_ft, &end_ft) < 0)
+ SystemTimeToFileTime(&st, &trigger_ft);
+ if (CompareFileTime(&begin_ft, &trigger_ft) <= 0 && CompareFileTime(&trigger_ft, &end_ft) < 0)
{
- if (!have_best_time || CompareFileTime(¤t_ft, &best_ft) < 0)
+ if (!have_best_time || CompareFileTime(&trigger_ft, &best_ft) < 0)
{
- best_ft = current_ft;
+ best_ft = trigger_ft;
have_best_time = TRUE;
}
}
@@ -533,20 +537,20 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
st.wMinute = This->trigger[i].wStartMinute;
st.wSecond = 0;
st.wMilliseconds = 0;
- SystemTimeToFileTime(&st, ¤t_ft);
- while (CompareFileTime(¤t_ft, &end_ft) < 0)
+ SystemTimeToFileTime(&st, &trigger_ft);
+ while (CompareFileTime(&trigger_ft, &end_ft) < 0)
{
- if (CompareFileTime(¤t_ft, &begin_ft) >= 0)
+ if (CompareFileTime(&trigger_ft, &begin_ft) >= 0)
{
- if (!have_best_time || CompareFileTime(¤t_ft, &best_ft) < 0)
+ if (!have_best_time || CompareFileTime(&trigger_ft, &best_ft) < 0)
{
- best_ft = current_ft;
+ best_ft = trigger_ft;
have_best_time = TRUE;
}
break;
}
- filetime_add_days(¤t_ft, This->trigger[i].Type.Daily.DaysInterval);
+ filetime_add_days(&trigger_ft, This->trigger[i].Type.Daily.DaysInterval);
}
break;
@@ -559,18 +563,18 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
st.wMinute = This->trigger[i].wStartMinute;
st.wSecond = 0;
st.wMilliseconds = 0;
- SystemTimeToFileTime(&st, ¤t_ft);
- while (CompareFileTime(¤t_ft, &end_ft) < 0)
+ SystemTimeToFileTime(&st, &trigger_ft);
+ while (CompareFileTime(&trigger_ft, &end_ft) < 0)
{
- FileTimeToSystemTime(¤t_ft, &st);
+ FileTimeToSystemTime(&trigger_ft, &st);
- if (CompareFileTime(¤t_ft, &begin_ft) >= 0)
+ if (CompareFileTime(&trigger_ft, &begin_ft) >= 0)
{
if (This->trigger[i].Type.Weekly.rgfDaysOfTheWeek & (1 << st.wDayOfWeek))
{
- if (!have_best_time || CompareFileTime(¤t_ft, &best_ft) < 0)
+ if (!have_best_time || CompareFileTime(&trigger_ft, &best_ft) < 0)
{
- best_ft = current_ft;
+ best_ft = trigger_ft;
have_best_time = TRUE;
}
break;
@@ -578,9 +582,9 @@ static HRESULT WINAPI MSTASK_ITask_GetNextRunTime(ITask *iface, SYSTEMTIME *rt)
}
if (st.wDayOfWeek == 0 && This->trigger[i].Type.Weekly.WeeksInterval > 1) /* Sunday, goto next week */
- filetime_add_weeks(¤t_ft, This->trigger[i].Type.Weekly.WeeksInterval - 1);
+ filetime_add_weeks(&trigger_ft, This->trigger[i].Type.Weekly.WeeksInterval - 1);
else /* check next weekday */
- filetime_add_days(¤t_ft, 1);
+ filetime_add_days(&trigger_ft, 1);
}
break;
--
2.16.3
June 27, 2018
[PATCH] testbot/web: Let GetHtmlLine() detect and format the timeout errors.
by Francois Gouget
It already handles filtering and highlighting errors so it makes sense
to also have if reformat the timeout errors for the log summary.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index e5f792929..e7e53d208 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -253,6 +253,11 @@ sub GetHtmlLine($$$)
return undef if ($Category ne "error" and !$FullLog);
my $Html = $self->escapeHTML($Line);
+ if (!$FullLog and $Html =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
+ {
+ my $Unit = $1;
+ return $Unit ne "" ? "$Unit: Timeout" : "Timeout";
+ }
if ($FullLog and $Category ne "none")
{
# Highlight all line categories in the full log
@@ -414,15 +419,7 @@ sub GenerateBody($)
print "<pre><code>";
$LogFirst = 0;
}
- if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
- {
- my $Unit = $1 ne "" ? "$1: " : "";
- print "${Unit}Timeout\n";
- }
- else
- {
- print "$Html\n";
- }
+ print "$Html\n";
}
close($LogFile);
--
2.18.0
June 27, 2018
[PATCH] testbot: Track patches to the Wine modules separately.
by Francois Gouget
Patches to the dlls and programs modules don't require a rebuild of
the native Wine tools.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/PatchUtils.pm | 13 +++++++++++++
testbot/lib/WineTestBot/Patches.pm | 3 ++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index b2bfe6a9a..811c3b8b2 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -193,6 +193,19 @@ sub _HandleFile($$$)
}
$Tests->{$Module}->{Files}->{$File} = $Change;
}
+ elsif ($FilePath =~ m~^(dlls|programs)/([^/]+)/([^/\s]+)$~)
+ {
+ my ($Root, $Dir, $File) = ($1, $2, $3);
+ my $Module = ($Root eq "programs") ? "$Dir.exe" : $Dir;
+ $Impacts->{IsWinePatch} = 1;
+ $Impacts->{ModuleBuild} = 1;
+
+ if ($File eq "Makefile.in" and $Change ne "modify")
+ {
+ # This adds / removes a directory
+ $Impacts->{MakeMakefiles} = 1;
+ }
+ }
else
{
my $WineFiles = $Impacts->{WineFiles} || $_WineFiles;
diff --git a/testbot/lib/WineTestBot/Patches.pm b/testbot/lib/WineTestBot/Patches.pm
index fe333d943..50f720861 100644
--- a/testbot/lib/WineTestBot/Patches.pm
+++ b/testbot/lib/WineTestBot/Patches.pm
@@ -136,7 +136,8 @@ sub Submit($$$)
$PastImpacts = GetPatchImpact($PatchFileName) if ($IsSet);
my $Impacts = GetPatchImpact("$DataDir/patches/" . $self->Id, undef, $PastImpacts);
- if (!$Impacts->{WineBuild} and !$Impacts->{TestBuild})
+ if (!$Impacts->{WineBuild} and !$Impacts->{ModuleBuild} and
+ !$Impacts->{TestBuild})
{
if ($Impacts->{IsWinePatch})
{
--
2.18.0
June 27, 2018
[PATCH] testbot/WineRun*: Prefix the TestBot errors so they are easy to identify.
by Francois Gouget
Some scripts may need to detect them.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 2 +-
testbot/bin/WineRunReconfig.pl | 2 +-
testbot/bin/WineRunTask.pl | 2 +-
testbot/bin/WineRunWineTest.pl | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 176ade6b6..90b9f030a 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -269,7 +269,7 @@ sub FatalError($;$)
my ($ErrMessage, $Retry) = @_;
LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
- LogTaskError($ErrMessage);
+ LogTaskError("BotError: $ErrMessage");
WrapUpAndExit('boterror', $Retry);
}
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index aa0cf955e..8a3d955a7 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -269,7 +269,7 @@ sub FatalError($;$)
my ($ErrMessage, $Retry) = @_;
LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
- LogTaskError($ErrMessage);
+ LogTaskError("BotError: $ErrMessage");
WrapUpAndExit('boterror', $Retry);
}
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 821ca55ea..fb2966303 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -319,7 +319,7 @@ sub FatalError($;$)
my ($ErrMessage, $Retry) = @_;
LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
- LogTaskError($ErrMessage);
+ LogTaskError("BotError: $ErrMessage");
WrapUpAndExit('boterror', undef, $Retry);
}
diff --git a/testbot/bin/WineRunWineTest.pl b/testbot/bin/WineRunWineTest.pl
index 83cf5821b..1e43f9a41 100755
--- a/testbot/bin/WineRunWineTest.pl
+++ b/testbot/bin/WineRunWineTest.pl
@@ -320,7 +320,7 @@ sub FatalError($;$)
my ($ErrMessage, $Retry) = @_;
LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
- LogTaskError($ErrMessage);
+ LogTaskError("BotError: $ErrMessage");
WrapUpAndExit('boterror', undef, $Retry);
}
--
2.18.0
June 27, 2018
[PATCH] testbot/CheckForWinetestUpdate: Fix the Wine reconfig timeout.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/CheckForWinetestUpdate.pl | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/testbot/bin/CheckForWinetestUpdate.pl b/testbot/bin/CheckForWinetestUpdate.pl
index d3ef384c7..a570a1b80 100755
--- a/testbot/bin/CheckForWinetestUpdate.pl
+++ b/testbot/bin/CheckForWinetestUpdate.pl
@@ -286,7 +286,9 @@ sub AddReconfigJob($)
Debug(" $VMKey $VMType reconfig\n");
my $Task = $BuildStep->Tasks->Add();
$Task->VM($VM);
- $Task->Timeout($ReconfigTimeout);
+ $Task->Timeout($VMType eq "wine" ?
+ 3 * $WineReconfigTimeout : # 3 full Wine builds
+ $ReconfigTimeout); # 1 overall timeout
}
# Save the build step so the others can reference it.
--
2.18.0
June 27, 2018
[PATCH] testbot/web: Compile patches on wow64 if 64 bit tests have been selected.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Submit.pl | 45 ++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index 9fa252a11..38aa75fcb 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -858,30 +858,35 @@ sub OnSubmit($)
my $VMs = CreateVMs();
$VMs->AddFilter("Type", ["wine"]);
my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
- foreach my $VMKey (@$SortedKeys)
+ foreach my $Build ("win32", "wow64")
{
- my $VM = $VMs->GetItem($VMKey);
- my $FieldName = "vm_" . $self->CGI->escapeHTML($VMKey);
- next if (!$self->GetParam($FieldName)); # skip unselected VMs
+ next if ($Build eq "wow64" and !defined($self->GetParam("Run64")));
- if (!$Tasks)
+ foreach my $VMKey (@$SortedKeys)
{
- # First create the Wine test step
- my $WineStep = $Steps->Add();
- $WineStep->FileName($BaseName);
- $WineStep->FileType($FileType);
- $WineStep->InStaging(!1);
- $WineStep->Type("build");
- $WineStep->DebugLevel($self->GetParam("DebugLevel"));
- $WineStep->ReportSuccessfulTests(defined($self->GetParam("ReportSuccessfulTests")));
- $Tasks = $WineStep->Tasks;
- }
+ my $VM = $VMs->GetItem($VMKey);
+ my $FieldName = "vm_" . $self->CGI->escapeHTML($VMKey);
+ next if (!$self->GetParam($FieldName)); # skip unselected VMs
- # Then add a task for this VM
- my $Task = $Tasks->Add();
- $Task->VM($VM);
- $Task->CmdLineArg("win32");
- $Task->Timeout($WineReconfigTimeout);
+ if (!$Tasks)
+ {
+ # First create the Wine test step
+ my $WineStep = $Steps->Add();
+ $WineStep->FileName($BaseName);
+ $WineStep->FileType($FileType);
+ $WineStep->InStaging(!1);
+ $WineStep->Type("build");
+ $WineStep->DebugLevel($self->GetParam("DebugLevel"));
+ $WineStep->ReportSuccessfulTests(defined($self->GetParam("ReportSuccessfulTests")));
+ $Tasks = $WineStep->Tasks;
+ }
+
+ # Then add a task for this VM
+ my $Task = $Tasks->Add();
+ $Task->VM($VM);
+ $Task->CmdLineArg($Build);
+ $Task->Timeout($WineReconfigTimeout);
+ }
}
}
--
2.18.0
June 27, 2018
[PATCH] testbot: Fix the detection of the start and skipped report lines.
by Francois Gouget
This now matches the Wine report parser.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/LogUtils.pm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 2d3042ec7..bccf30db3 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -408,7 +408,7 @@ sub GetLogLineCategory($)
return "todo";
}
if ($Line =~ /: Tests skipped: / or
- $Line =~ /^\w+:\w+ skipped /)
+ $Line =~ /^[_.a-z0-9-]+:[_a-z0-9]* skipped /)
{
return "skip";
}
@@ -431,7 +431,7 @@ sub GetLogLineCategory($)
return "error";
}
if ($Line =~ /^\+ \S/ or
- $Line =~ /^\w+:\w+ start / or
+ $Line =~ /^[_.a-z0-9-]+:[_a-z0-9]* start / or
# Build messages
$Line =~ /^(?:Build|Reconfig|Task): ok/)
{
--
2.18.0
June 27, 2018
[PATCH 3/3] testbot: Run WineTest on Wine VMs after commits.
by Francois Gouget
WineReconfig.pl now knows how to retrieve and cache the Gecko and Mono
addons, and how to create new wineprefixes. These are then captured by
the updated snapshot and are thus ready to use to run tests.
CheckForWinetestUpdate.pl creates additional steps to rerun the full
WineTest suite on the Wine VMs if the Wine rebuild was successful.
Running WineTest is handled by WineTest.pl and WineRunWineTest.pl
collects the corresponding reports in the latest directory in files
named '<vm>_<build>.report' where build is one of win32, wow32 or
wow64.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/CheckForWinetestUpdate.pl | 44 +++++-
testbot/bin/WineRunWineTest.pl | 218 ++++++++++++++++++++++----
testbot/bin/build/WineReconfig.pl | 189 ++++++++++++++++++++--
testbot/bin/build/WineTest.pl | 118 ++++++++++++--
testbot/lib/WineTestBot/LogUtils.pm | 8 +-
testbot/lib/WineTestBot/Utils.pm | 19 ++-
6 files changed, 537 insertions(+), 59 deletions(-)
diff --git a/testbot/bin/CheckForWinetestUpdate.pl b/testbot/bin/CheckForWinetestUpdate.pl
index 74c59955f..d3ef384c7 100755
--- a/testbot/bin/CheckForWinetestUpdate.pl
+++ b/testbot/bin/CheckForWinetestUpdate.pl
@@ -273,10 +273,10 @@ sub AddReconfigJob($)
# Add a step to the job
my $Steps = $NewJob->Steps;
- my $NewStep = $Steps->Add();
- $NewStep->Type("reconfig");
- $NewStep->FileType("none");
- $NewStep->InStaging(!1);
+ my $BuildStep = $Steps->Add();
+ $BuildStep->Type("reconfig");
+ $BuildStep->FileType("none");
+ $BuildStep->InStaging(!1);
# And a task for each VM
my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
@@ -284,14 +284,46 @@ sub AddReconfigJob($)
{
my $VM = $VMs->GetItem($VMKey);
Debug(" $VMKey $VMType reconfig\n");
- my $Task = $NewStep->Tasks->Add();
+ my $Task = $BuildStep->Tasks->Add();
$Task->VM($VM);
$Task->Timeout($ReconfigTimeout);
}
- # Save it all
+ # Save the build step so the others can reference it.
my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
if (defined $ErrMessage)
+ {
+ Error "Failed to save the build step: $ErrMessage\n";
+ return 0;
+ }
+
+ if ($VMType eq "wine")
+ {
+ # Add steps to run WineTest on Wine
+ foreach my $Build ("win32", "wow32", "wow64")
+ {
+ # Add a step to the job
+ my $NewStep = $Steps->Add();
+ $NewStep->PreviousNo($BuildStep->No);
+ $NewStep->Type("suite");
+ $NewStep->FileType("none");
+ $NewStep->InStaging(!1);
+
+ foreach my $VMKey (@$SortedKeys)
+ {
+ my $VM = $VMs->GetItem($VMKey);
+ Debug(" $VMKey $Build\n");
+ my $Task = $NewStep->Tasks->Add();
+ $Task->VM($VM);
+ $Task->CmdLineArg($Build);
+ $Task->Timeout($SuiteTimeout);
+ }
+ }
+ }
+
+ # Save it all
+ ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
+ if (defined $ErrMessage)
{
Error "Failed to save the Reconfig job: $ErrMessage\n";
return 0;
diff --git a/testbot/bin/WineRunWineTest.pl b/testbot/bin/WineRunWineTest.pl
index 53a2a0929..83cf5821b 100755
--- a/testbot/bin/WineRunWineTest.pl
+++ b/testbot/bin/WineRunWineTest.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl -Tw
# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
#
-# Makes sure the Wine patches compile.
+# Makes sure the Wine patches compile or run WineTest.
# See the bin/build/WineTest.pl script.
#
# Copyright 2018 Francois Gouget
@@ -46,6 +46,7 @@ use WineTestBot::PatchUtils;
use WineTestBot::VMs;
use WineTestBot::Log;
use WineTestBot::LogUtils;
+use WineTestBot::Utils;
use WineTestBot::Engine::Notify;
@@ -67,6 +68,35 @@ sub Error(@)
}
+#
+# Task helpers
+#
+
+sub TakeScreenshot($$)
+{
+ my ($VM, $FileName) = @_;
+
+ my $Domain = $VM->GetDomain();
+ my ($ErrMessage, $ImageSize, $ImageBytes) = $Domain->CaptureScreenImage();
+ if (!defined $ErrMessage)
+ {
+ if (open(my $Screenshot, ">", $FileName))
+ {
+ print $Screenshot $ImageBytes;
+ close($Screenshot);
+ }
+ else
+ {
+ Error "Could not open the screenshot file for writing: $!\n";
+ }
+ }
+ elsif ($Domain->IsPoweredOn())
+ {
+ Error "Could not capture a screenshot: $ErrMessage\n";
+ }
+}
+
+
#
# Setup and command line processing
#
@@ -190,15 +220,17 @@ sub LogTaskError($)
}
}
-sub WrapUpAndExit($;$$)
+sub WrapUpAndExit($;$$$)
{
- my ($Status, $Retry, $Timeout) = @_;
+ my ($Status, $TestFailures, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
+
+ Debug(Elapsed($Start), " Taking a screenshot\n");
+ TakeScreenshot($VM, "$TaskDir/screenshot.png");
- my $TestFailures;
my $Tries = $Task->TestFailures || 0;
if ($Retry)
{
@@ -253,6 +285,30 @@ sub WrapUpAndExit($;$$)
$VM->Save();
}
+ if ($Step->Type eq 'suite' and $Status eq 'completed' and !$TimedOut)
+ {
+ my $BuildList = $Task->CmdLineArg;
+ $BuildList =~ s/ .*$//;
+ foreach my $Build (split /,/, $BuildList)
+ {
+ # Keep the old report if the new one is missing
+ my $RptFileName = "$Build.report";
+ if (-f "$TaskDir/$RptFileName" and !-z "$TaskDir/$RptFileName")
+ {
+ # Update the reference VM suite results for WineSendLog.pl
+ my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name,
+ "_$Build");
+ unlink("$LatestBaseName.log");
+ link("$TaskDir/$RptFileName", "$LatestBaseName.log");
+ unlink("$LatestBaseName.err");
+ if (-f "$TaskDir/err" and !-z "$TaskDir/err")
+ {
+ link("$TaskDir/err", "$LatestBaseName.err");
+ }
+ }
+ }
+ }
+
my $Result = $VM->Name .": ". $VM->Status ." Status: $Status Failures: ". (defined $TestFailures ? $TestFailures : "unset");
LogMsg "Task $JobId/$StepNo/$TaskNo done ($Result)\n";
Debug(Elapsed($Start), " Done. $Result\n");
@@ -266,12 +322,12 @@ sub FatalError($;$)
LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
LogTaskError($ErrMessage);
- WrapUpAndExit('boterror', $Retry);
+ WrapUpAndExit('boterror', undef, $Retry);
}
-sub FatalTAError($$)
+sub FatalTAError($$;$)
{
- my ($TA, $ErrMessage) = @_;
+ my ($TA, $ErrMessage, $PossibleCrash) = @_;
$ErrMessage .= ": ". $TA->GetLastError() if (defined $TA);
# A TestAgent operation failed, see if the VM is still accessible
@@ -297,7 +353,13 @@ sub FatalTAError($$)
else
{
# Ignore the TestAgent error, it's irrelevant
- $ErrMessage = "The test VM is powered off!\n";
+ $ErrMessage = "The test VM is powered off! Did the test shut it down?\n";
+ }
+ if ($PossibleCrash and !$Task->CanRetry())
+ {
+ # The test did it!
+ LogTaskError($ErrMessage);
+ WrapUpAndExit('completed', 1);
}
FatalError($ErrMessage, $Retry);
}
@@ -320,33 +382,78 @@ elsif (!$VM->GetDomain()->IsPoweredOn())
FatalError("The VM is not powered on\n");
}
-if ($Step->FileType ne "patchdlls")
+if (($Step->Type eq "suite" and $Step->FileType ne "none") or
+ ($Step->Type ne "suite" and $Step->FileType ne "patchdlls"))
{
FatalError("Unexpected file type '". $Step->FileType ."' found\n");
}
#
-# Run the task
+# Setup the VM
#
+my $TA = $VM->GetAgent();
+Debug(Elapsed($Start), " Setting the time\n");
+if (!$TA->SetTime())
+{
+ # Not a fatal error. Try the next port in case the VM runs a privileged
+ # TestAgentd daemon there.
+ my $PrivilegedTA = $VM->GetAgent(1);
+ if (!$PrivilegedTA->SetTime())
+ {
+ LogTaskError("Unable to set the VM system time: ". $PrivilegedTA->GetLastError() .". Maybe the TestAgentd process is missing the required privileges.\n");
+ $PrivilegedTA->Disconnect();
+ }
+}
my $FileName = $Step->GetFullFileName();
-my $TA = $VM->GetAgent();
-Debug(Elapsed($Start), " Sending '$FileName'\n");
-if (!$TA->SendFile($FileName, "staging/patch.diff", 0))
+if (defined $FileName)
{
- FatalTAError($TA, "Could not copy the patch to the VM");
+ Debug(Elapsed($Start), " Sending '$FileName'\n");
+ if (!$TA->SendFile($FileName, "staging/patch.diff", 0))
+ {
+ FatalTAError($TA, "Could not copy the patch to the VM");
+ }
}
+
my $Script = "#!/bin/sh\n".
- "( set -x\n" .
- " ../bin/build/WineTest.pl ". $Task->CmdLineArg ." build patch.diff\n".
- ") >Task.log 2>&1\n";
+ "( set -x\n".
+ " ../bin/build/WineTest.pl ";
+if ($Step->Type eq "suite")
+{
+ my $Tag = lc($VM->Name);
+ $Tag =~ s/^$TagPrefix//;
+ $Tag =~ s/[^a-zA-Z0-9]/-/g;
+ $Script .= $Task->CmdLineArg .",submit winetest $TagPrefix-$Tag ";
+ if (defined $WebHostName)
+ {
+ my $StepTask = 100 * $StepNo + $TaskNo;
+ $Script .= "-u \"http://$WebHostName/JobDetails.pl?Key=$JobId&s$StepTask=1#k$StepTask\" ";
+ }
+ my $Info = $VM->Description ? $VM->Description : "";
+ if ($VM->Details)
+ {
+ $Info .= ": " if ($Info ne "");
+ $Info .= $VM->Details;
+ }
+ $Script .= join(" ", "-m", ShQuote($AdminEMail), "-i", ShQuote($Info));
+}
+else
+{
+ $Script .= $Task->CmdLineArg ." build patch.diff";
+}
+$Script .= "\n) >Task.log 2>&1\n";
Debug(Elapsed($Start), " Sending the script: [$Script]\n");
if (!$TA->SendFileFromString($Script, "task", $TestAgent::SENDFILE_EXE))
{
FatalTAError($TA, "Could not send the task script to the VM");
}
+
+#
+# Run the test
+#
+
Debug(Elapsed($Start), " Starting the script\n");
my $Pid = $TA->Run(["./task"], 0);
if (!$Pid)
@@ -357,10 +464,11 @@ if (!$Pid)
#
# From that point on we want to at least try to grab the task log
-# before giving up
+# and a screenshot before giving up
#
-my ($NewStatus, $ErrMessage, $TAError, $TaskTimedOut);
+my $NewStatus = 'completed';
+my ($TaskFailures, $TaskTimedOut, $ErrMessage, $TAError, $PossibleCrash);
Debug(Elapsed($Start), " Waiting for the script (", $Task->Timeout, "s timeout)\n");
if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
{
@@ -368,11 +476,19 @@ if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
if ($ErrMessage =~ /timed out waiting for the child process/)
{
$ErrMessage = "The task timed out\n";
- $NewStatus = "badbuild";
+ if ($Step->Type eq "build")
+ {
+ $NewStatus = "badbuild";
+ }
+ else
+ {
+ $TaskFailures = 1;
+ }
$TaskTimedOut = 1;
}
else
{
+ $PossibleCrash = 1 if ($Step->Type ne "build");
$TAError = "An error occurred while waiting for the task to complete: $ErrMessage";
$ErrMessage = undef;
}
@@ -399,10 +515,11 @@ if ($TA->GetFile("Task.log", "$TaskDir/log"))
{
FatalError("$Result\n", "retry");
}
- else
+ elsif ($Result ne "missing" or $Step->Type ne "suite")
{
- # If the result line is missing we probably already have an error message
- # that explains why.
+ # There is no build and thus no result line when running WineTest.
+ # Otherwise if the result line is missing we probably already have an
+ # error message that explains why.
$NewStatus = "badbuild";
}
}
@@ -411,15 +528,62 @@ elsif (!defined $TAError)
$TAError = "An error occurred while retrieving the task log: ". $TA->GetLastError();
}
+#
+# Grab the test logs if any
+#
+
+my $TimedOut;
+if ($Step->Type ne "build")
+{
+ my $TaskDir = $Task->CreateDir();
+ my $BuildList = $Task->CmdLineArg;
+ $BuildList =~ s/ .*$//;
+ foreach my $Build (split /,/, $BuildList)
+ {
+ my $RptFileName = "$Build.report";
+ Debug(Elapsed($Start), " Retrieving '$RptFileName'\n");
+ if ($TA->GetFile($RptFileName, "$TaskDir/$RptFileName"))
+ {
+ chmod 0664, "$TaskDir/$RptFileName";
+
+ (my $LogFailures, my $LogErrors, $TimedOut) = ParseWineTestReport("$TaskDir/$RptFileName", 1, $Step->Type eq "suite", $TaskTimedOut);
+ if (!defined $LogFailures and @$LogErrors == 1)
+ {
+ # Could not open the file
+ $NewStatus = 'boterror';
+ Error "Unable to open '$RptFileName' for reading: $!\n";
+ LogTaskError("Unable to open '$RptFileName' for reading: $!\n");
+ }
+ else
+ {
+ # $LogFailures can legitimately be undefined in case of a timeout
+ $TaskFailures += $LogFailures || 0;
+ foreach my $Error (@$LogErrors)
+ {
+ LogTaskError("$Error\n");
+ }
+ }
+ }
+ elsif (!defined $TAError and
+ $TA->GetLastError() !~ /: No such file or directory/)
+ {
+ $TAError = "An error occurred while retrieving $RptFileName: ". $TA->GetLastError();
+ $NewStatus = 'boterror';
+ }
+ }
+}
+
+Debug(Elapsed($Start), " Disconnecting\n");
+$TA->Disconnect();
+
# Report the task errors even though they may have been caused by
# TestAgent trouble.
LogTaskError($ErrMessage) if (defined $ErrMessage);
-FatalTAError(undef, $TAError) if (defined $TAError);
-$TA->Disconnect();
+FatalTAError(undef, $TAError, $PossibleCrash) if (defined $TAError);
#
# Wrap up
#
-WrapUpAndExit($NewStatus, undef, $TaskTimedOut);
+WrapUpAndExit($NewStatus, $TaskFailures, undef, $TaskTimedOut || $TimedOut);
diff --git a/testbot/bin/build/WineReconfig.pl b/testbot/bin/build/WineReconfig.pl
index b030051c6..e3f14e243 100755
--- a/testbot/bin/build/WineReconfig.pl
+++ b/testbot/bin/build/WineReconfig.pl
@@ -40,6 +40,9 @@ my $Name0 = $0;
$Name0 =~ s+^.*/++;
+use Digest::SHA;
+use File::Path;
+
use WineTestBot::Config;
use WineTestBot::PatchUtils;
@@ -126,7 +129,7 @@ sub BuildWine($$$$)
{
my ($Targets, $NoRm, $Build, $Extras) = @_;
- return 1 if (!$Targets->{$Build});
+ return 1 if (!$Targets->{build} or !$Targets->{$Build});
mkdir "$DataDir/build-$Build" if (!-d "$DataDir/build-$Build");
# If $NoRm is not set, rebuild from scratch to make sure cruft will not
@@ -134,7 +137,7 @@ sub BuildWine($$$$)
InfoMsg "\nRebuilding the $Build Wine\n";
system("cd '$DataDir/build-$Build' && set -x && ".
($NoRm ? "" : "rm -rf * && ") .
- "time ../wine/configure $Extras --disable-winetest && ".
+ "time ../wine/configure $Extras && ".
"time make -j$ncpus");
if ($? != 0)
{
@@ -146,6 +149,154 @@ sub BuildWine($$$$)
}
+#
+# WinePrefix helpers
+#
+
+sub VerifyAddOn($$)
+{
+ my ($AddOn, $Arch) = @_;
+
+ my $Sha256 = Digest::SHA->new(256);
+ eval { $Sha256->addfile("$DataDir/$AddOn->{name}/$AddOn->{filename}") };
+ return "$@" if ($@);
+
+ my $Checksum = $Sha256->hexdigest();
+ return undef if ($Checksum eq $AddOn->{$Arch});
+ return "Bad checksum for '$AddOn->{filename}'";
+}
+
+sub UpdateAddOn($$$)
+{
+ my ($AddOn, $Name, $Arch) = @_;
+
+ if (!defined $AddOn)
+ {
+ LogMsg "Could not get information on the $Name addon\n";
+ return 0;
+ }
+ if (!$AddOn->{version})
+ {
+ LogMsg "Could not get the $Name version\n";
+ return 0;
+ }
+ if (!$AddOn->{$Arch})
+ {
+ LogMsg "Could not get the $Name $Arch checksum\n";
+ return 0;
+ }
+
+ $AddOn->{filename} = "wine". ($Name eq "gecko" ? "_" : "-") .
+ "$Name-$AddOn->{version}".
+ ($Arch eq "" ? "" : "-$Arch") .".msi";
+ return 1 if (!VerifyAddOn($AddOn, $Arch));
+
+ InfoMsg "Downloading $AddOn->{filename}\n";
+ mkdir "$DataDir/$Name";
+
+ my $Url="http://dl.winehq.org/wine/wine-$Name/$AddOn->{version}/$AddOn->{filename}";
+ for (1..3)
+ {
+ system("cd '$DataDir/$Name' && set -x && ".
+ "wget --no-verbose -O- '$Url' >'$AddOn->{filename}'");
+ last if ($? == 0);
+ }
+ my $ErrMessage = VerifyAddOn($AddOn, $Arch);
+ return 1 if (!defined $ErrMessage);
+ LogMsg "$ErrMessage\n";
+ return 0;
+}
+
+sub UpdateAddOns($)
+{
+ my ($Targets) = @_;
+ return 1 if (!$Targets->{addons});
+
+ my %AddOns;
+ if (open(my $fh, "<", "$DataDir/wine/dlls/appwiz.cpl/addons.c"))
+ {
+ my $Arch = "";
+ while (my $Line= <$fh>)
+ {
+ if ($Line =~ /^\s*#\s*define\s+ARCH_STRING\s+"([^"]+)"/)
+ {
+ $Arch = $1;
+ }
+ elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_VERSION\s*"([^"]+)"/)
+ {
+ my ($AddOn, $Version) = ($1, $2);
+ $AddOn =~ tr/A-Z/a-z/;
+ $AddOns{$AddOn}->{name} = $AddOn;
+ $AddOns{$AddOn}->{version} = $Version;
+ }
+ elsif ($Line =~ /^\s*#\s*define\s*(GECKO|MONO)_SHA\s*"([^"]+)"/)
+ {
+ my ($AddOn, $Checksum) = ($1, $2);
+ $AddOn =~ tr/A-Z/a-z/;
+ $AddOns{$AddOn}->{$Arch} = $Checksum;
+ $Arch = "";
+ }
+ }
+ close($fh);
+ }
+ else
+ {
+ LogMsg "Could not open 'wine/dlls/appwiz.cpl/addons.c': $!\n";
+ return 0;
+ }
+
+ return UpdateAddOn($AddOns{gecko}, "gecko", "x86") &&
+ UpdateAddOn($AddOns{gecko}, "gecko", "x86_64") &&
+ UpdateAddOn($AddOns{mono}, "mono", "");
+}
+
+# See also WineTest.pl
+sub SetupWineEnvironment($)
+{
+ my ($Build) = @_;
+
+ $ENV{WINEPREFIX} = "$DataDir/wineprefix-$Build";
+ $ENV{DISPLAY} ||= ":0.0";
+}
+
+# See also WineTest.pl
+sub RunWine($$$)
+{
+ my ($Build, $Cmd, $CmdArgs) = @_;
+
+ my $Magic = `cd '$DataDir/build-$Build' && file $Cmd`;
+ my $Wine = ($Magic =~ /ELF 64/ ? "./wine64" : "./wine");
+ return system("cd '$DataDir/build-$Build' && set -x && ".
+ "time $Wine $Cmd $CmdArgs");
+}
+
+# Setup a brand new WinePrefix ready for use for testing.
+# This way we do it once instead of doing it for every test, thus saving
+# time. Note that this requires using a different wineprefix for each build.
+sub NewWinePrefix($$)
+{
+ my ($Targets, $Build) = @_;
+
+ return 1 if (!$Targets->{wineprefix} or !$Targets->{$Build});
+
+ InfoMsg "\nRecreating the $Build wineprefix\n";
+ SetupWineEnvironment($Build);
+ rmtree($ENV{WINEPREFIX});
+
+ # Crash dialogs cause delays so disable them
+ if (RunWine($Build, "./programs/reg/reg.exe.so", "ADD HKCU\\\\Software\\\\Wine\\\\WineDbg /v ShowCrashDialog /t REG_DWORD /d 0"))
+ {
+ LogMsg "Failed to disable the $Build build crash dialogs: $!\n";
+ return 0;
+ }
+
+ # Ensure the WinePrefix has been fully created before updating the snapshot
+ system("cd '$DataDir/build-$Build' && ./server/wineserver -w");
+
+ return 1;
+}
+
+
#
# Setup and command line processing
#
@@ -154,7 +305,7 @@ $ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
my %AllTargets;
-map { $AllTargets{$_} = 1 } qw(update win32 wow32 wow64);
+map { $AllTargets{$_} = 1 } qw(update addons build wineprefix win32 wow32 wow64);
my ($Usage, $TargetList, $NoRm);
while (@ARGV)
@@ -212,15 +363,18 @@ if (defined $Usage)
}
print "Usage: $Name0 [--no-rm] [--help] [TARGETS]\n";
print "\n";
- print "Performs all the tasks needed for the host to be ready to test new patches: update the Wine source and rebuild the Wine binaries.\n";
+ print "Performs all the tasks needed for the host to be ready to test new patches: update the Wine source and addons, and rebuild the Wine binaries.\n";
print "\n";
print "Where:\n";
print " TARGETS Is a comma-separated list of targets to process. By default all\n";
print " targets are processed.\n";
print " - update: Update Wine's source code.\n";
- print " - win32: Rebuild the regular 32 bit Wine.\n";
- print " - wow32: Rebuild the 32 bit WoW Wine.\n";
- print " - wow64: Rebuild the 64 bit WoW Wine.\n";
+ print " - build: Update the Wine builds.\n";
+ print " - addons: Update the Gecko and Mono Wine addons.\n";
+ print " - wineprefix: Update the wineprefixes.\n";
+ print " - win32: Apply the above to the regular 32 bit Wine.\n";
+ print " - wow32: Apply the above to the 32 bit WoW Wine.\n";
+ print " - wow64: Apply the above to the 64 bit WoW Wine.\n";
print " --no-rm Don't rebuild from scratch.\n";
print " --help Shows this usage message.\n";
exit 0;
@@ -240,16 +394,25 @@ if ($DataDir =~ /'/)
#
-# Run the builds
+# Run the builds and/or tests
#
CountCPUs();
-if (!BuildTestAgentd() ||
- !GitPull($Targets) ||
- !BuildWine($Targets, $NoRm, "win32", "") ||
- !BuildWine($Targets, $NoRm, "wow64", "--enable-win64") ||
- !BuildWine($Targets, $NoRm, "wow32", "--with-wine64='$DataDir/build-wow64'"))
+if (!BuildTestAgentd() or
+ !GitPull($Targets) or
+ !UpdateAddOns($Targets) or
+ !BuildWine($Targets, $NoRm, "win32", "") or
+ !BuildWine($Targets, $NoRm, "wow64", "--enable-win64") or
+ !BuildWine($Targets, $NoRm, "wow32", "--with-wine64='$DataDir/build-wow64'") or
+ !NewWinePrefix($Targets, "win32") or
+ # The wow32 and wow64 wineprefixes:
+ # - Are essentially identical.
+ # - Must be created after both WoW builds have been updated.
+ # - Make it possible to run the wow32 and wow64 tests in separate prefixes,
+ # thus ensuring they don't interfere with each other.
+ !NewWinePrefix($Targets, "wow64") or
+ !NewWinePrefix($Targets, "wow32"))
{
exit(1);
}
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
index 3be81485e..518deae99 100755
--- a/testbot/bin/build/WineTest.pl
+++ b/testbot/bin/build/WineTest.pl
@@ -144,6 +144,62 @@ sub BuildWine($$)
}
+#
+# Test helpers
+#
+
+# See also WineReconfig.pl
+sub SetupWineEnvironment($)
+{
+ my ($Build) = @_;
+
+ $ENV{WINEPREFIX} = "$DataDir/wineprefix-$Build";
+ $ENV{DISPLAY} ||= ":0.0";
+}
+
+# See also WineReconfig.pl
+sub RunWine($$$)
+{
+ my ($Build, $Cmd, $CmdArgs) = @_;
+
+ my $Magic = `cd '$DataDir/build-$Build' && file $Cmd`;
+ my $Wine = ($Magic =~ /ELF 64/ ? "./wine64" : "./wine");
+ return system("cd '$DataDir/build-$Build' && set -x && ".
+ "time $Wine $Cmd $CmdArgs");
+}
+
+sub DailyWineTest($$$$)
+{
+ my ($Targets, $Build, $BaseTag, $Args) = @_;
+
+ return 1 if (!$Targets->{$Build});
+
+ InfoMsg "\nRunning WineTest in the $Build Wine\n";
+ SetupWineEnvironment($Build);
+
+ # Run WineTest. Ignore the exit code since it returns non-zero whenever
+ # there are test failures.
+ RunWine($Build, "./programs/winetest/winetest.exe.so",
+ "-c -o '../$Build.report' -t $BaseTag-$Build ". ShArgv2Cmd(@$Args));
+ if (!-f "$Build.report")
+ {
+ LogMsg "WineTest did not produce a report file\n";
+ return 0;
+ }
+
+ # Send the report to the website
+ if ($Targets->{submit} and
+ RunWine($Build, "./programs/winetest/winetest.exe.so",
+ "-c -s '../$Build.report'"))
+ {
+ LogMsg "WineTest failed to send the $Build report\n";
+ # Soldier on in case it's just a network issue
+ }
+
+ return 1;
+}
+
+
#
# Setup and command line processing
#
@@ -152,9 +208,9 @@ $ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
my %AllTargets;
-map { $AllTargets{$_} = 1 } qw(win32 wow32 wow64);
+map { $AllTargets{$_} = 1 } qw(win32 wow32 wow64 submit);
-my ($Usage, $TargetList, $Action, $FileName);
+my ($Usage, $TargetList, $Action, $FileName, $BaseTag);
while (@ARGV)
{
my $Arg = shift @ARGV;
@@ -177,6 +233,12 @@ while (@ARGV)
{
$Action = $Arg;
}
+ elsif (($Action || "") eq "winetest")
+ {
+ $BaseTag = $Arg;
+ # The remaining arguments are meant for WineTest
+ last;
+ }
elsif (!defined $FileName)
{
if (IsValidFileName($Arg))
@@ -230,6 +292,23 @@ if (!defined $Usage)
Error "you must specify the action to perform\n";
$Usage = 2;
}
+ elsif ($Action eq "winetest")
+ {
+ if (!defined $BaseTag)
+ {
+ Error "you must specify a base tag for WineTest\n";
+ $Usage = 2;
+ }
+ elsif ($BaseTag =~ m/^([\w_.\-]+)$/)
+ {
+ $BaseTag = $1;
+ }
+ else
+ {
+ Error "invalid WineTest base tag '$BaseTag'\n";
+ $Usage = 2;
+ }
+ }
elsif ($Action ne "build")
{
Error "invalid '$Action' action\n";
@@ -245,16 +324,23 @@ if (!defined $Usage)
if (defined $Usage)
{
print "Usage: $Name0 [--help] TARGETS build PATCH\n";
+ print "or $Name0 [--help] TARGETS winetest BASETAG ARGS\n";
print "\n";
- print "Applies the specified patch and rebuilds Wine.\n";
+ print "Tests the specified patch or runs WineTest in Wine.\n";
print "\n";
print "Where:\n";
- print " TARGETS Is a comma-separated list of targets for the build.\n";
+ print " TARGETS Is a comma-separated list of targets for the specified action.\n";
print " - win32: The regular 32 bit Wine build.\n";
print " - wow32: The 32 bit WoW Wine build.\n";
print " - wow64: The 64 bit WoW Wine build.\n";
+ print " - submit: Send the WineTest result to the website.\n";
print " build Verify that the patch compiles.\n";
print " PATCH Is the staging file containing the patch to test.\n";
+ print " winetest Run WineTest and submit the result to the website if the submit\n";
+ print " task was specified.\n";
+ print " BASETAG Is the tag for this WineTest run. Note that the build type is\n";
+ print " automatically added to this tag.\n";
+ print " ARGS The WineTest arguments.\n";
print " --help Shows this usage message.\n";
exit $Usage;
}
@@ -267,16 +353,28 @@ if ($DataDir =~ /'/)
#
-# Run the builds
+# Run the builds and tests
#
+# Clean up old reports
+map { unlink("$_.report") } keys %AllTargets;
+
CountCPUs();
-my $Impacts = ApplyPatch($FileName);
-exit(1) if (!$Impacts or
- !BuildWine($Targets, "win32") or
- !BuildWine($Targets, "wow64") or
- !BuildWine($Targets, "wow32"));
+if ($Action eq "build")
+{
+ my $Impacts = ApplyPatch($FileName);
+ exit(1) if (!$Impacts or
+ !BuildWine($Targets, "win32") or
+ !BuildWine($Targets, "wow64") or
+ !BuildWine($Targets, "wow32"));
+}
+elsif ($Action eq "winetest")
+{
+ exit(1) if (!DailyWineTest($Targets, "win32", $BaseTag, \@ARGV) or
+ !DailyWineTest($Targets, "wow64", $BaseTag, \@ARGV) or
+ !DailyWineTest($Targets, "wow32", $BaseTag, \@ARGV));
+}
LogMsg "ok\n";
exit;
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 363f80827..2d3042ec7 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -458,6 +458,7 @@ sub GetLogFileNames($;$)
my ($Dir, $IncludeOld) = @_;
my @Candidates = ("exe32.report", "exe64.report",
+ "win32.report", "wow32.report", "wow64.report",
"log", "err");
push @Candidates, "log.old", "err.old" if ($IncludeOld);
@@ -472,10 +473,13 @@ sub GetLogFileNames($;$)
my %_LogFileLabels = (
"exe32.report" => "32 bit Windows report",
"exe64.report" => "64 bit Windows report",
- "err" => "task errors",
+ "win32.report" => "32 bit Wine report",
+ "wow32.report" => "32 bit WoW Wine report",
+ "wow64.report" => "64 bit Wow Wine report",
"log" => "task log",
- "err.old" => "old task errors",
+ "err" => "task errors",
"log.old" => "old logs",
+ "err.old" => "old task errors",
);
=pod
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 111a56589..f64310b6b 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -29,7 +29,7 @@ use Exporter 'import';
our @EXPORT = qw(MakeSecureURL SecureConnection GenerateRandomString
OpenNewFile CreateNewFile CreateNewLink CreateNewDir
DurationToString BuildEMailRecipient IsValidFileName
- ShQuote);
+ ShQuote ShArgv2Cmd);
use Fcntl;
@@ -220,4 +220,21 @@ sub ShQuote($)
return "\"$Str\"";
}
+=pod
+=over 12
+
+=item C<ShArgv2Cmd()>
+
+Converts an argument list into a command line suitable for use in a shell.
+
+See also ShQuote().
+
+=back
+=cut
+
+sub ShArgv2Cmd(@)
+{
+ return join(' ', map { /[^a-zA-Z0-9\/.,+_-]/ ? ShQuote($_) : $_ } @_);
+}
+
1;
--
2.18.0
June 27, 2018
[PATCH 2/3] testbot/WineRunTask: Make the Wine report parser reusable.
by Francois Gouget
Moving it to LogUtils.pm makes it possible to reuse it in future
scripts.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 276 ++-----------------------
testbot/lib/WineTestBot/LogUtils.pm | 310 +++++++++++++++++++++++++++-
2 files changed, 322 insertions(+), 264 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 9faae28c3..821ca55ea 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -44,6 +44,7 @@ use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::VMs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::Engine::Notify;
@@ -527,275 +528,24 @@ Debug(Elapsed($Start), " Retrieving the report file to '$RptFileName'\n");
if ($TA->GetFile($RptFileName, "$TaskDir/$RptFileName"))
{
chmod 0664, "$TaskDir/$RptFileName";
- if (open(my $LogFile, "<", "$TaskDir/$RptFileName"))
- {
- # There is more than one test unit when running the full test suite so keep
- # track of the current one. Note that for the TestBot we don't count or
- # complain about misplaced skips.
- my ($CurrentDll, $CurrentUnit) = ("", "");
- my $UnitSize = 0;
- my ($LineFailures, $LineTodos, $LineSkips) = (0, 0, 0);
- my ($SummaryFailures, $SummaryTodos, $SummarySkips) = (0, 0, 0);
- my ($CurrentIsBroken, %CurrentPids, $CurrentRc, $LogFailures);
-
- sub CheckUnit($$)
- {
- my ($Unit, $Type) = @_;
- if ($Unit eq $CurrentUnit or $CurrentUnit eq "")
- {
- $IsWineTest = 1;
- }
- # To avoid issuing many duplicate errors,
- # only report the first misplaced message.
- elsif ($IsWineTest and !$CurrentIsBroken)
- {
- LogTaskError("$CurrentDll:$CurrentUnit contains a misplaced $Type message for $Unit\n");
- $LogFailures++;
- $CurrentIsBroken = 1;
- }
- }
-
- sub CheckSummaryCounter($$$)
- {
- my ($Count, $SCount, $Type) = @_;
-
- if ($Count != 0 and $SCount == 0)
- {
- LogTaskError("$CurrentDll:$CurrentUnit has unaccounted for $Type messages\n");
- $LogFailures++;
- }
- elsif ($Count == 0 and $SCount != 0)
- {
- LogTaskError("$CurrentDll:$CurrentUnit is missing some $Type messages\n");
- $LogFailures++;
- }
- }
-
- sub CloseTestUnit($)
- {
- my ($Last) = @_;
-
- # Verify the summary lines
- if (!$CurrentIsBroken)
- {
- CheckSummaryCounter($LineFailures, $SummaryFailures, "failure");
- CheckSummaryCounter($LineTodos, $SummaryTodos, "todo");
- CheckSummaryCounter($LineSkips, $SummarySkips, "skip");
- }
-
- # Note that the summary lines may count some failures twice
- # so only use them as a fallback.
- $LineFailures ||= $SummaryFailures;
-
- if ($UnitSize > $MaxUnitSize)
- {
- LogTaskError("$CurrentDll:$CurrentUnit prints too much data ($UnitSize bytes)\n");
- $LogFailures++;
- }
- if (!$CurrentIsBroken and defined $CurrentRc)
- {
- # Check the exit code, particularly against failures reported
- # after the 'done' line (e.g. by subprocesses).
- if ($LineFailures != 0 and $CurrentRc == 0)
- {
- LogTaskError("$CurrentDll:$CurrentUnit returned success despite having failures\n");
- $LogFailures++;
- }
- elsif (!$IsWineTest and $CurrentRc != 0)
- {
- LogTaskError("The test returned a non-zero exit code\n");
- $LogFailures++;
- }
- elsif ($IsWineTest and $LineFailures == 0 and $CurrentRc != 0)
- {
- LogTaskError("$CurrentDll:$CurrentUnit returned a non-zero exit code despite reporting no failures\n");
- $LogFailures++;
- }
- }
- # For executables TestLauncher's done line may not be recognizable.
- elsif ($IsWineTest and !defined $CurrentRc)
- {
- if (!$Last)
- {
- LogTaskError("$CurrentDll:$CurrentUnit has no done line (or it is garbled)\n");
- }
- elsif ($Last and !$TaskTimedOut)
- {
- LogTaskError("The report seems to have been truncated\n");
- }
- $LogFailures++;
- }
-
- $LogFailures += $LineFailures;
-
- $CurrentDll = $CurrentUnit = "";
- $UnitSize = 0;
- $LineFailures = $LineTodos = $LineSkips = 0;
- $SummaryFailures = $SummaryTodos = $SummarySkips = 0;
- $CurrentIsBroken = 0;
- $CurrentRc = undef;
- %CurrentPids = ();
- }
-
- foreach my $Line (<$LogFile>)
- {
- $UnitSize += length($Line);
- if ($Line =~ m%^([_.a-z0-9-]+):([_a-z0-9]*) (start|skipped) (?:-|[/_.a-z0-9]+) (?:-|[.0-9a-f]+)\r?$%)
- {
- my ($Dll, $Unit, $Type) = ($1, $2, $3);
-
- # Close the previous test unit
- CloseTestUnit(0) if ($CurrentDll ne "");
-
- ($CurrentDll, $CurrentUnit) = ($Dll, $Unit);
-
- # Recognize skipped messages in case we need to skip tests in the VMs
- $CurrentRc = 0 if ($Type eq "skipped");
- }
- elsif ($Line =~ /^([_a-z0-9]+)\.c:\d+: Test (?:failed|succeeded inside todo block): / or
- ($CurrentUnit ne "" and
- $Line =~ /($CurrentUnit)\.c:\d+: Test (?:failed|succeeded inside todo block): /))
- {
- CheckUnit($1, "failure");
- $LineFailures++;
- }
- elsif ($Line =~ /^([_a-z0-9]+)\.c:\d+: Test marked todo: / or
- ($CurrentUnit ne "" and
- $Line =~ /($CurrentUnit)\.c:\d+: Test marked todo: /))
- {
- CheckUnit($1, "todo");
- $LineTodos++;
- }
- # TestLauncher's skip message is quite broken
- elsif ($Line =~ /^([_a-z0-9]+)(?:\.c)?:\d+:? Tests? skipped: / or
- ($CurrentUnit ne "" and
- $Line =~ /($CurrentUnit)(?:\.c)?:\d+:? Tests? skipped: /))
- {
- my $Unit = $1;
- # Don't complain and don't count misplaced skips. Only complain if they
- # are misreported (see CloseTestUnit). Also TestLauncher uses the wrong
- # name in its skip message when skipping tests.
- if ($Unit eq $CurrentUnit or $CurrentUnit eq "" or $Unit eq $CurrentDll)
- {
- $LineSkips++;
- }
- }
- elsif ($Line =~ /^Fatal: test '([_a-z0-9]+)' does not exist/)
- {
- # This also replaces a test summary line.
- $CurrentPids{0} = 1;
- $SummaryFailures++;
- $IsWineTest = 1;
-
- $LineFailures++;
- }
- elsif ($Line =~ /^(?:([0-9a-f]+):)?([_.a-z0-9]+): unhandled exception [0-9a-fA-F]{8} at / or
- ($CurrentUnit ne "" and
- $Line =~ /(?:([0-9a-f]+):)?($CurrentUnit): unhandled exception [0-9a-fA-F]{8} at /))
- {
- my ($Pid, $Unit) = ($1, $2);
-
- if ($Unit eq $CurrentUnit)
- {
- # This also replaces a test summary line.
- $CurrentPids{$Pid || 0} = 1;
- $SummaryFailures++;
- }
- CheckUnit($Unit, "unhandled exception");
- $LineFailures++;
- }
- elsif ($Line =~ /^(?:([0-9a-f]+):)?([_a-z0-9]+): \d+ tests? executed \((\d+) marked as todo, (\d+) failures?\), (\d+) skipped\./ or
- ($CurrentUnit ne "" and
- $Line =~ /(?:([0-9a-f]+):)?($CurrentUnit): \d+ tests? executed \((\d+) marked as todo, (\d+) failures?\), (\d+) skipped\./))
- {
- my ($Pid, $Unit, $Todos, $Failures, $Skips) = ($1, $2, $3, $4, $5);
-
- # Dlls that have only one test unit will run it even if there is
- # no argument. Also TestLauncher uses the wrong name in its test
- # summary line when skipping tests.
- if ($Unit eq $CurrentUnit or $CurrentUnit eq "" or $Unit eq $CurrentDll)
- {
- # There may be more than one summary line due to child processes
- $CurrentPids{$Pid || 0} = 1;
- $SummaryFailures += $Failures;
- $SummaryTodos += $Todos;
- $SummarySkips += $Skips;
- $IsWineTest = 1;
- }
- else
- {
- CheckUnit($Unit, "test summary") if ($Todos or $Failures);
- }
- }
- elsif ($Line =~ /^([_.a-z0-9-]+):([_a-z0-9]*)(?::([0-9a-f]+))? done \((-?\d+)\)(?:\r?$| in)/ or
- ($CurrentDll ne "" and
- $Line =~ /(\Q$CurrentDll\E):([_a-z0-9]*)(?::([0-9a-f]+))? done \((-?\d+)\)(?:\r?$| in)/))
- {
- my ($Dll, $Unit, $Pid, $Rc) = ($1, $2, $3, $4);
-
- if ($IsWineTest and ($Dll ne $CurrentDll or $Unit ne $CurrentUnit))
- {
- # First close the current test unit taking into account
- # it may have been polluted by the new one.
- $LogFailures++;
- $CurrentIsBroken = 1;
- CloseTestUnit(0);
-
- # Then switch to the new one, warning it's missing a start line,
- # and that its results may be inconsistent.
- ($CurrentDll, $CurrentUnit) = ($Dll, $Unit);
- LogTaskError("$Dll:$Unit had no start line (or it is garbled)\n");
- $CurrentIsBroken = 1;
- }
-
- if ($Rc == 258)
- {
- # The done line will already be shown as a timeout (see JobDetails)
- # so record the failure but don't add an error message.
- $LogFailures++;
- $CurrentIsBroken = 1;
- $TimedOut = ($Step->Type ne "suite");
- }
- elsif ((!$Pid and !%CurrentPids) or
- ($Pid and !$CurrentPids{$Pid} and !$CurrentPids{0}))
- {
- # The main summary line is missing
- if ($Rc & 0xc0000000)
- {
- LogTaskError(sprintf("%s:%s crashed (%08x)\n", $Dll, $Unit, $Rc & 0xffffffff));
- $LogFailures++;
- $CurrentIsBroken = 1;
- }
- elsif ($IsWineTest and !$CurrentIsBroken)
- {
- LogTaskError("$Dll:$Unit has no test summary line (early exit of the main process?)\n");
- $LogFailures++;
- }
- }
- elsif ($Rc & 0xc0000000)
- {
- # We know the crash happened in the main process which means we got
- # an "unhandled exception" message. So there is no need to add an
- # extra message or to increment the failure count. Still note that
- # there may be inconsistencies (e.g. unreported todos or skips).
- $CurrentIsBroken = 1;
- }
- $CurrentRc = $Rc;
- }
- }
- $CurrentIsBroken = 1 if ($TaskTimedOut);
- CloseTestUnit(1);
- close($LogFile);
- # $LogFailures can legitimately be undefined in case of a timeout
- $TaskFailures += $LogFailures || 0;
- }
- else
+ (my $LogFailures, my $LogErrors, $TimedOut) = ParseWineTestReport("$TaskDir/$RptFileName", $IsWineTest, $Step->Type eq "suite", $TaskTimedOut);
+ if (!defined $LogFailures and @$LogErrors == 1)
{
+ # Could not open the file
$NewStatus = 'boterror';
Error "Unable to open '$RptFileName' for reading: $!\n";
LogTaskError("Unable to open '$RptFileName' for reading: $!\n");
}
+ else
+ {
+ # $LogFailures can legitimately be undefined in case of a timeout
+ $TaskFailures += $LogFailures || 0;
+ foreach my $Error (@$LogErrors)
+ {
+ LogTaskError("$Error\n");
+ }
+ }
}
elsif (!defined $TAError)
{
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 3dfd7c5e7..363f80827 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -27,7 +27,12 @@ WineTestBot::LogUtils - Provides functions to parse task logs
use Exporter 'import';
-our @EXPORT = qw(GetLogFileNames GetLogLabel GetLogLineCategory ParseTaskLog);
+our @EXPORT = qw(GetLogFileNames GetLogLabel GetLogLineCategory
+ ParseTaskLog ParseWineTestReport);
+
+use File::Basename;
+
+use WineTestBot::Config; # For $MaxUnitSize
#
@@ -75,6 +80,309 @@ sub ParseTaskLog($$)
}
+#
+# WineTest report parser
+#
+
+sub _NewCurrentUnit($$)
+{
+ my ($Dll, $Unit) = @_;
+
+ return {
+ # There is more than one test unit when running the full test suite so keep
+ # track of the current one. Note that for the TestBot we don't count or
+ # complain about misplaced skips.
+ Dll => $Dll,
+ Unit => $Unit,
+ UnitSize => 0,
+ LineFailures => 0,
+ LineTodos => 0,
+ LineSkips => 0,
+ SummaryFailures => 0,
+ SummaryTodos => 0,
+ SummarySkips => 0,
+ IsBroken => 0,
+ Rc => undef,
+ Pids => {},
+ };
+}
+
+sub _AddError($$;$)
+{
+ my ($Parser, $Error, $Cur) = @_;
+
+ $Error = "$Cur->{Dll}:$Cur->{Unit} $Error" if (defined $Cur);
+ push @{$Parser->{Errors}}, $Error;
+ $Parser->{Failures}++;
+}
+
+sub _CheckUnit($$$$)
+{
+ my ($Parser, $Cur, $Unit, $Type) = @_;
+
+ if ($Unit eq $Cur->{Unit} or $Cur->{Unit} eq "")
+ {
+ $Parser->{IsWineTest} = 1;
+ }
+ # To avoid issuing many duplicate errors,
+ # only report the first misplaced message.
+ elsif ($Parser->{IsWineTest} and !$Cur->{IsBroken})
+ {
+ _AddError($Parser, "contains a misplaced $Type message for $Unit", $Cur);
+ $Cur->{IsBroken} = 1;
+ }
+}
+
+sub _CheckSummaryCounter($$$$)
+{
+ my ($Parser, $Cur, $Field, $Type) = @_;
+
+ if ($Cur->{"Line$Field"} != 0 and $Cur->{"Summary$Field"} == 0)
+ {
+ _AddError($Parser, "has unaccounted for $Type messages", $Cur);
+ }
+ elsif ($Cur->{"Line$Field"} == 0 and $Cur->{"Summary$Field"} != 0)
+ {
+ _AddError($Parser, "is missing some $Type messages", $Cur);
+ }
+}
+
+sub _CloseTestUnit($$$)
+{
+ my ($Parser, $Cur, $Last) = @_;
+
+ # Verify the summary lines
+ if (!$Cur->{IsBroken})
+ {
+ _CheckSummaryCounter($Parser, $Cur, "Failures", "failure");
+ _CheckSummaryCounter($Parser, $Cur, "Todos", "todo");
+ _CheckSummaryCounter($Parser, $Cur, "Skips", "skip");
+ }
+
+ # Note that the summary lines may count some failures twice
+ # so only use them as a fallback.
+ $Cur->{LineFailures} ||= $Cur->{SummaryFailures};
+
+ if ($Cur->{UnitSize} > $MaxUnitSize)
+ {
+ _AddError($Parser, "prints too much data ($Cur->{UnitSize} bytes)", $Cur);
+ }
+ if (!$Cur->{IsBroken} and defined $Cur->{Rc})
+ {
+ # Check the exit code, particularly against failures reported
+ # after the 'done' line (e.g. by subprocesses).
+ if ($Cur->{LineFailures} != 0 and $Cur->{Rc} == 0)
+ {
+ _AddError($Parser, "returned success despite having failures", $Cur);
+ }
+ elsif (!$Parser->{IsWineTest} and $Cur->{Rc} != 0)
+ {
+ _AddError($Parser, "The test returned a non-zero exit code");
+ }
+ elsif ($Parser->{IsWineTest} and $Cur->{LineFailures} == 0 and $Cur->{Rc} != 0)
+ {
+ _AddError($Parser, "returned a non-zero exit code despite reporting no failures", $Cur);
+ }
+ }
+ # For executables TestLauncher's done line may not be recognizable.
+ elsif ($Parser->{IsWineTest} and !defined $Cur->{Rc})
+ {
+ if (!$Last)
+ {
+ _AddError($Parser, "has no done line (or it is garbled)", $Cur);
+ }
+ elsif ($Last and !$Parser->{TaskTimedOut})
+ {
+ _AddError($Parser, "The report seems to have been truncated");
+ }
+ }
+
+ $Parser->{Failures} += $Cur->{LineFailures};
+}
+
+=pod
+=over 12
+
+=item C<ParseWineTestReport()>
+
+Parses a Wine test report and returns the number of failures and extra errors,
+a list of extra errors, and whether the test timed out.
+
+=back
+=cut
+
+sub ParseWineTestReport($$$$)
+{
+ my ($FileName, $IsWineTest, $IsSuite, $TaskTimedOut) = @_;
+
+ my $LogFile;
+ if (!open($LogFile, "<", $FileName))
+ {
+ my $BaseName = basename($FileName);
+ return (undef, ["Unable to open '$BaseName' for reading: $!"], undef);
+ }
+
+ my $Parser = {
+ IsWineTest => $IsWineTest,
+ IsSuite => $IsSuite,
+ TaskTimedOut => $TaskTimedOut,
+
+ TimedOut => undef,
+ Failures => undef,
+ Errors => [],
+ };
+
+ my $Cur = _NewCurrentUnit("", "");
+ foreach my $Line (<$LogFile>)
+ {
+ $Cur->{UnitSize} += length($Line);
+ if ($Line =~ m%^([_.a-z0-9-]+):([_a-z0-9]*) (start|skipped) (?:-|[/_.a-z0-9]+) (?:-|[.0-9a-f]+)\r?$%)
+ {
+ my ($Dll, $Unit, $Type) = ($1, $2, $3);
+
+ # Close the previous test unit
+ _CloseTestUnit($Parser, $Cur, 0) if ($Cur->{Dll} ne "");
+ $Cur = _NewCurrentUnit($Dll, $Unit);
+
+ # Recognize skipped messages in case we need to skip tests in the VMs
+ $Cur->{Rc} = 0 if ($Type eq "skipped");
+ }
+ elsif ($Line =~ /^([_a-z0-9]+)\.c:\d+: Test (?:failed|succeeded inside todo block): / or
+ ($Cur->{Unit} ne "" and
+ $Line =~ /($Cur->{Unit})\.c:\d+: Test (?:failed|succeeded inside todo block): /))
+ {
+ _CheckUnit($Parser, $Cur, $1, "failure");
+ $Cur->{LineFailures}++;
+ }
+ elsif ($Line =~ /^([_a-z0-9]+)\.c:\d+: Test marked todo: / or
+ ($Cur->{Unit} ne "" and
+ $Line =~ /($Cur->{Unit})\.c:\d+: Test marked todo: /))
+ {
+ _CheckUnit($Parser, $Cur, $1, "todo");
+ $Cur->{LineTodos}++;
+ }
+ # TestLauncher's skip message is quite broken
+ elsif ($Line =~ /^([_a-z0-9]+)(?:\.c)?:\d+:? Tests? skipped: / or
+ ($Cur->{Unit} ne "" and
+ $Line =~ /($Cur->{Unit})(?:\.c)?:\d+:? Tests? skipped: /))
+ {
+ my $Unit = $1;
+ # Don't complain and don't count misplaced skips. Only complain if they
+ # are misreported (see _CloseTestUnit). Also TestLauncher uses the wrong
+ # name in its skip message when skipping tests.
+ if ($Unit eq $Cur->{Unit} or $Cur->{Unit} eq "" or $Unit eq $Cur->{Dll})
+ {
+ $Cur->{LineSkips}++;
+ }
+ }
+ elsif ($Line =~ /^Fatal: test '([_a-z0-9]+)' does not exist/)
+ {
+ # This also replaces a test summary line.
+ $Cur->{Pids}->{0} = 1;
+ $Cur->{SummaryFailures}++;
+ $Parser->{IsWineTest} = 1;
+
+ $Cur->{LineFailures}++;
+ }
+ elsif ($Line =~ /^(?:([0-9a-f]+):)?([_.a-z0-9]+): unhandled exception [0-9a-fA-F]{8} at / or
+ ($Cur->{Unit} ne "" and
+ $Line =~ /(?:([0-9a-f]+):)?($Cur->{Unit}): unhandled exception [0-9a-fA-F]{8} at /))
+ {
+ my ($Pid, $Unit) = ($1, $2);
+
+ if ($Unit eq $Cur->{Unit})
+ {
+ # This also replaces a test summary line.
+ $Cur->{Pids}->{$Pid || 0} = 1;
+ $Cur->{SummaryFailures}++;
+ }
+ _CheckUnit($Parser, $Cur, $Unit, "unhandled exception");
+ $Cur->{LineFailures}++;
+ }
+ elsif ($Line =~ /^(?:([0-9a-f]+):)?([_a-z0-9]+): \d+ tests? executed \((\d+) marked as todo, (\d+) failures?\), (\d+) skipped\./ or
+ ($Cur->{Unit} ne "" and
+ $Line =~ /(?:([0-9a-f]+):)?($Cur->{Unit}): \d+ tests? executed \((\d+) marked as todo, (\d+) failures?\), (\d+) skipped\./))
+ {
+ my ($Pid, $Unit, $Todos, $Failures, $Skips) = ($1, $2, $3, $4, $5);
+
+ # Dlls that have only one test unit will run it even if there is
+ # no argument. Also TestLauncher uses the wrong name in its test
+ # summary line when skipping tests.
+ if ($Unit eq $Cur->{Unit} or $Cur->{Unit} eq "" or $Unit eq $Cur->{Dll})
+ {
+ # There may be more than one summary line due to child processes
+ $Cur->{Pids}->{$Pid || 0} = 1;
+ $Cur->{SummaryFailures} += $Failures;
+ $Cur->{SummaryTodos} += $Todos;
+ $Cur->{SummarySkips} += $Skips;
+ $Parser->{IsWineTest} = 1;
+ }
+ else
+ {
+ _CheckUnit($Parser, $Cur, $Unit, "test summary") if ($Todos or $Failures);
+ }
+ }
+ elsif ($Line =~ /^([_.a-z0-9-]+):([_a-z0-9]*)(?::([0-9a-f]+))? done \((-?\d+)\)(?:\r?$| in)/ or
+ ($Cur->{Dll} ne "" and
+ $Line =~ /(\Q$Cur->{Dll}\E):([_a-z0-9]*)(?::([0-9a-f]+))? done \((-?\d+)\)(?:\r?$| in)/))
+ {
+ my ($Dll, $Unit, $Pid, $Rc) = ($1, $2, $3, $4);
+
+ if ($Parser->{IsWineTest} and ($Dll ne $Cur->{Dll} or $Unit ne $Cur->{Unit}))
+ {
+ # First close the current test unit taking into account
+ # it may have been polluted by the new one.
+ $Cur->{IsBroken} = 1;
+ _CloseTestUnit($Parser, $Cur, 0);
+
+ # Then switch to the new one, warning it's missing a start line,
+ # and that its results may be inconsistent.
+ ($Cur->{Dll}, $Cur->{Unit}) = ($Dll, $Unit);
+ _AddError($Parser, "had no start line (or it is garbled)", $Cur);
+ $Cur->{IsBroken} = 1;
+ }
+
+ if ($Rc == 258)
+ {
+ # The done line will already be shown as a timeout (see JobDetails)
+ # so record the failure but don't add an error message.
+ $Parser->{Failures}++;
+ $Cur->{IsBroken} = 1;
+ $Parser->{TimedOut} = $Parser->{IsSuite};
+ }
+ elsif ((!$Pid and !%{$Cur->{Pids}}) or
+ ($Pid and !$Cur->{Pids}->{$Pid} and !$Cur->{Pids}->{0}))
+ {
+ # The main summary line is missing
+ if ($Rc & 0xc0000000)
+ {
+ _AddError($Parser, sprintf("%s:%s crashed (%08x)", $Dll, $Unit, $Rc & 0xffffffff));
+ $Cur->{IsBroken} = 1;
+ }
+ elsif ($Parser->{IsWineTest} and !$Cur->{IsBroken})
+ {
+ _AddError($Parser, "$Dll:$Unit has no test summary line (early exit of the main process?)");
+ }
+ }
+ elsif ($Rc & 0xc0000000)
+ {
+ # We know the crash happened in the main process which means we got
+ # an "unhandled exception" message. So there is no need to add an
+ # extra message or to increment the failure count. Still note that
+ # there may be inconsistencies (e.g. unreported todos or skips).
+ $Cur->{IsBroken} = 1;
+ }
+ $Cur->{Rc} = $Rc;
+ }
+ }
+ $Cur->{IsBroken} = 1 if ($Parser->{TaskTimedOut});
+ _CloseTestUnit($Parser, $Cur, 1);
+ close($LogFile);
+
+ return ($Parser->{Failures}, $Parser->{Errors}, $Parser->{TimedOut});
+}
+
+
#
# Log querying and formatting
#
--
2.18.0
June 27, 2018
[PATCH 1/3] testbot/WineRunWineTest: Ignore other errors if we get a badpatch error.
by Francois Gouget
Just like finding a success line in the task log proves that it was
successful no matter what happened before, a 'badpatch' line
conclusively determines the task status.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This is the same patch as yesterday but integrated into this series
since they conflict if applied out of order.
testbot/bin/WineRunWineTest.pl | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineRunWineTest.pl b/testbot/bin/WineRunWineTest.pl
index 0aba7ecfc..53a2a0929 100755
--- a/testbot/bin/WineRunWineTest.pl
+++ b/testbot/bin/WineRunWineTest.pl
@@ -356,8 +356,8 @@ if (!$Pid)
#
-# From that point on we want to at least try to grab the task
-# log before giving up
+# From that point on we want to at least try to grab the task log
+# before giving up
#
my ($NewStatus, $ErrMessage, $TAError, $TaskTimedOut);
@@ -391,7 +391,9 @@ if ($TA->GetFile("Task.log", "$TaskDir/log"))
}
elsif ($Result eq "badpatch")
{
+ # This too is conclusive enough to ignore other errors.
$NewStatus = "badpatch";
+ $TAError = $ErrMessage = undef;
}
elsif ($Result =~ s/^nolog://)
{
--
2.18.0
June 27, 2018
Bug #45385 related to keyboard and probably wineserver - where to start the search
by John Found
I just reported bug #45385 (https://bugs.winehq.org/show_bug.cgi?id=45385) and want to try to fix it.
So I want to ask about some preliminary directions - where to check the code,
what is the general structure of the code related to the bug subject, possible suspicious places.
Here is the full bug report in order to save you a visit to the bug tracker:
> I noticed that the state of the keys sometimes sticks in pressed state.
>
> This happens when cycling windows with some shortcut key combination.
>
> For example if cycling with Alt+Tab, on pressing Alt, the program gets WM_KEYDOWN and the state of the VK_MENU becomes pressed. But after cycling windows, the program does not get WM_KEYUP because the window is not focused and VK_MENU (and the respective VK_LMENU or VK_RMENU) remain in pressed state.
>
> When cycling back to the program window, the window get focused only after releasing Alt key, so it does not get this event as well.
>
> If cycling windows with another shortcut key combination (for example Alt+Shift+Tab - for backward cycling) both VK_MENU and VK_SHIFT keys stick.
>
> In the same time, GetAsyncKeyState returns the proper state of the keys.
>
> Note1: The problem is obviously in the wineserver code, because it handles the key state tables for the different threads.
>
> Note2: The effect happens only sometimes. It seems the code for proper processing is already there, but some racing conditions have place.
>
> Note3: There is some probability that the effect is in result of my application code, but it never happens on real Windows, so I considered it a bug.
>
> Note4: I tried to workaround this problem by reading the whole table by GetAsyncKeyState and setting it then with SetKeyboardState on WM_ACTIVATE message of the main window. This workaround actually works, but is too ugly IMO.
> The same trick on WM_ACTIVATEAPP does not work.
--
John Found <johnfound(a)asm32.info>
June 27, 2018
[PATCH] msvcp120: Add test for Concurrent_vector_Internal_resize and reverse.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp120/tests/msvcp120.c | 86 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 2974482ec1..1a20f4ddde 100755
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -124,6 +124,8 @@ static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void
const void *b, const void *c, const void *d );
static void * (WINAPI *call_thiscall_func6)( void *func, void *this, const void *a,
const void *b, const void *c, const void *d, const void *e );
+static void * (WINAPI *call_thiscall_func7)( void *func, void *this, const void *a,
+ const void *b, const void *c, const void *d, const void *e, const void *f );
static void init_thiscall_thunk(void)
{
@@ -140,6 +142,7 @@ static void init_thiscall_thunk(void)
call_thiscall_func4 = (void *)thunk;
call_thiscall_func5 = (void *)thunk;
call_thiscall_func6 = (void *)thunk;
+ call_thiscall_func7 = (void *)thunk;
}
#define call_func1(func,_this) call_thiscall_func1(func,_this)
@@ -152,6 +155,8 @@ static void init_thiscall_thunk(void)
(const void*)(b),(const void*)(c),(const void*)(d))
#define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(const void*)(a),\
(const void*)(b),(const void*)(c),(const void*)(d),(const void*)(e))
+#define call_func7(func,_this,a,b,c,d,e,f) call_thiscall_func7(func,_this,(const void*)(a),\
+ (const void*)(b),(const void*)(c),(const void*)(d),(const void*)(e),(const void*)(f))
#else
#define init_thiscall_thunk()
@@ -161,6 +166,7 @@ static void init_thiscall_thunk(void)
#define call_func4(func,_this,a,b,c) func(_this,a,b,c)
#define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
#define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
+#define call_func7(func,_this,a,b,c,d,e,f) func(_this,a,b,c,d,e,f)
#endif /* __i386__ */
static inline float __port_infinity(void)
@@ -422,6 +428,11 @@ static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
static size_t (__thiscall *p_vector_base_v4__Internal_grow_to_at_least_with_result)(
vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
+static void (__thiscall *p_vector_base_v4__Internal_reserve)(
+ vector_base_v4*, size_t, size_t, size_t);
+static void (__thiscall *p_vector_base_v4__Internal_resize)(
+ vector_base_v4*, size_t, size_t, size_t, void (__cdecl*)(void*, size_t),
+ void (__cdecl *copy)(void*, const void*, size_t), const void*);
static HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -576,6 +587,10 @@ static BOOL init(void)
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z");
SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
"?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z");
+ SET(p_vector_base_v4__Internal_reserve,
+ "?_Internal_reserve(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAX_K00(a)Z");
+ SET(p_vector_base_v4__Internal_resize,
+ "?_Internal_resize(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAX_K00P6AXPEAX0(a)ZP6AX1PEBX0@Z3(a)Z");
} else {
SET(p_tr2_sys__File_size,
"?_File_size(a)sys@tr2(a)std@@YA_KPBD(a)Z");
@@ -699,6 +714,10 @@ static BOOL init(void)
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z");
SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
"?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z");
+ SET(p_vector_base_v4__Internal_reserve,
+ "?_Internal_reserve(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXIII(a)Z");
+ SET(p_vector_base_v4__Internal_resize,
+ "?_Internal_resize(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXIIIP6AXPAXI(a)ZP6AX0PBXI@Z2(a)Z");
#else
SET(p__Thrd_current,
"_Thrd_current");
@@ -750,6 +769,10 @@ static BOOL init(void)
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAIIIP6AXPAXPBXI(a)Z1@Z");
SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
"?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAIIIP6AXPAXPBXI(a)Z1@Z");
+ SET(p_vector_base_v4__Internal_reserve,
+ "?_Internal_reserve(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAXIII(a)Z");
+ SET(p_vector_base_v4__Internal_resize,
+ "?_Internal_resize(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXIIIP6AXPAXI(a)ZP6AX0PBXI@Z2(a)Z");
#endif
}
SET(p__Thrd_equal,
@@ -3082,6 +3105,69 @@ static void test_vector_base_v4(void)
CHECK_CALLED(concurrent_vector_int_destroy);
concurrent_vector_int_dtor(&v2);
+ /* test for _Internal_reserve */
+ concurrent_vector_int_ctor(&v2);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ vector_elem_count += 2;
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ call_func4(p_vector_base_v4__Internal_reserve,
+ &v2, 3, sizeof(int), 4);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ call_func4(p_vector_base_v4__Internal_reserve,
+ &v2, 5, sizeof(int), 8);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
+ &v2, concurrent_vector_int_destroy);
+ ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ concurrent_vector_int_dtor(&v2);
+
+ /* test for _Internal_resize */
+ concurrent_vector_int_ctor(&v2);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ vector_elem_count += 2;
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ i = 0;
+ SET_EXPECT(concurrent_vector_int_destroy);
+ call_func7(p_vector_base_v4__Internal_resize,
+ &v2, 1, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 1, "v2.early_size got %ld expected 1\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ call_func7(p_vector_base_v4__Internal_resize,
+ &v2, 3, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
+ &v2, concurrent_vector_int_destroy);
+ ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ concurrent_vector_int_dtor(&v2);
+
SET_EXPECT(concurrent_vector_int_destroy);
size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
&vector, concurrent_vector_int_destroy);
--
2.11.0
June 27, 2018
[PATCH] configure.ac: use -Wno-unused-command-line-argument if supported
by Austin English
This avoids ~9000 warnings like:
austin(a)gcc113:~$ grep 'warning: argument unused during compilation'
without-patch.build.log | sort -u
clang-6.0: warning: argument unused during compilation: '-I ../atl'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
../d3dcompiler_43' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../d3dx11_43'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../d3dx9_36'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
../../../include/msvcrt' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
../../include/msvcrt' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
../../../include' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../../include'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../include'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../msvcm80'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../msvcp90'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../msvcrt'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/include/dbus-1.0' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/include/freetype2' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/include/libpng12' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/include/libxml2' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/include/p11-kit-1' [-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I
/usr/lib/aarch64-linux-gnu/dbus-1.0/include'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../wscript'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ./..'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../..'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I .'
[-Wunused-command-line-argument]
clang-6.0: warning: argument unused during compilation: '-I ../xinput1_3'
[-Wunused-command-line-argument]
June 27, 2018
Re: [PATCH] d3dx9_36: fixed size to MBtoWC
by Matteo Bruni
With the subject changed to something along the lines of "d3dx9/tests:
Fix wide string size in MultiByteToWideChar() call." this is:
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
June 26, 2018
[PATCH] shlwapi/tests: Pass the correct buffer size to WideCharToMultiByte()
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/shlwapi/tests/string.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c
index c7a2f5d346..9114ad88e1 100644
--- a/dlls/shlwapi/tests/string.c
+++ b/dlls/shlwapi/tests/string.c
@@ -694,7 +694,7 @@ static void test_StrFormatKBSizeW(void)
while(result->value)
{
pStrFormatKBSizeW(result->value, szBuffW, 256);
- WideCharToMultiByte(CP_ACP,0,szBuffW,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR),NULL,NULL);
+ WideCharToMultiByte(CP_ACP, 0, szBuffW, -1, szBuff, ARRAY_SIZE(szBuff), NULL, NULL);
ok(!strcmp(result->kb_size, szBuff), "Formatted %s wrong: got %s, expected %s\n",
wine_dbgstr_longlong(result->value), szBuff, result->kb_size);
--
2.14.4
June 26, 2018
[PATCH] shlwapi/tests: Pass the correct buffer size to PathUnExpandEnvStringsW()
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/shlwapi/tests/path.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/shlwapi/tests/path.c b/dlls/shlwapi/tests/path.c
index d25620b3d5..4a6fbd91f6 100644
--- a/dlls/shlwapi/tests/path.c
+++ b/dlls/shlwapi/tests/path.c
@@ -1595,7 +1595,7 @@ static void test_PathUnExpandEnvStrings(void)
buffW[0] = 0;
lstrcpyW(pathW, sysdrvW);
lstrcatW(pathW, sysdrvW);
- ret = pPathUnExpandEnvStringsW(pathW, buffW, sizeof(buff)/sizeof(WCHAR));
+ ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(buffW));
ok(ret, "got %d\n", ret);
/* expected string */
lstrcpyW(pathW, sysdriveW);
--
2.14.4
June 26, 2018
[PATCH] shlwapi/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/shlwapi/tests/assoc.c | 8 +++---
dlls/shlwapi/tests/clist.c | 6 ++---
dlls/shlwapi/tests/istream.c | 6 ++---
dlls/shlwapi/tests/ordinal.c | 56 +++++++++++++++++++--------------------
dlls/shlwapi/tests/path.c | 20 +++++++-------
dlls/shlwapi/tests/string.c | 62 ++++++++++++++++++++++----------------------
dlls/shlwapi/tests/url.c | 42 +++++++++++++++---------------
7 files changed, 99 insertions(+), 101 deletions(-)
diff --git a/dlls/shlwapi/tests/assoc.c b/dlls/shlwapi/tests/assoc.c
index 266f3fd44a..4b461128dc 100644
--- a/dlls/shlwapi/tests/assoc.c
+++ b/dlls/shlwapi/tests/assoc.c
@@ -62,7 +62,7 @@ static void test_getstring_bad(void)
"Unexpected result : %08x\n", hr);
ok(len == 0xdeadbeef, "got %u\n", len);
- len = sizeof(buf)/sizeof(buf[0]);
+ len = ARRAY_SIZE(buf);
hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotBad, open, buf, &len);
ok(hr == E_FAIL ||
hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ ||
@@ -70,8 +70,8 @@ static void test_getstring_bad(void)
"Unexpected result : %08x\n", hr);
if (hr == S_OK)
{
- ok(len < sizeof(buf)/sizeof(buf[0]), "got %u\n", len);
- ok(!lstrcmpiW(buf + len - sizeof(openwith)/sizeof(openwith[0]), openwith), "wrong data\n");
+ ok(len < ARRAY_SIZE(buf), "got %u\n", len);
+ ok(!lstrcmpiW(buf + len - ARRAY_SIZE(openwith), openwith), "wrong data\n");
}
len = 0xdeadbeef;
@@ -105,7 +105,7 @@ static void test_getstring_bad(void)
hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /* Win8 */ ||
hr == S_FALSE, /* Win10 */
"Unexpected result : %08x\n", hr);
- ok((hr == S_FALSE && len < sizeof(buf)/sizeof(buf[0])) || len == 0xdeadbeef,
+ ok((hr == S_FALSE && len < ARRAY_SIZE(buf)) || len == 0xdeadbeef,
"got hr=%08x and len=%u\n", hr, len);
len = 0xdeadbeef;
diff --git a/dlls/shlwapi/tests/clist.c b/dlls/shlwapi/tests/clist.c
index b930470806..0adb0d47c0 100644
--- a/dlls/shlwapi/tests/clist.c
+++ b/dlls/shlwapi/tests/clist.c
@@ -362,8 +362,7 @@ static void test_CList(void)
if (hRet == S_OK)
{
/* 1 call for each element, + 1 for OK (use our null element for this) */
- ok(streamobj.writecalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST),
- "wrong call count\n");
+ ok(streamobj.writecalls == ARRAY_SIZE(SHLWAPI_CLIST_items), "wrong call count\n");
ok(streamobj.readcalls == 0,"called Read() in write\n");
ok(streamobj.seekcalls == 0,"called Seek() in write\n");
}
@@ -433,8 +432,7 @@ static void test_CList(void)
{
ok(streamobj.readbeyondend == FALSE, "read beyond end\n");
/* 2 calls per item, but only 1 for the terminator */
- ok(streamobj.readcalls == sizeof(SHLWAPI_CLIST_items)/sizeof(SHLWAPI_CLIST)*2-1,
- "wrong call count\n");
+ ok(streamobj.readcalls == ARRAY_SIZE(SHLWAPI_CLIST_items) * 2 - 1, "wrong call count\n");
ok(streamobj.writecalls == 0, "called Write() from create\n");
ok(streamobj.seekcalls == 0,"called Seek() from create\n");
diff --git a/dlls/shlwapi/tests/istream.c b/dlls/shlwapi/tests/istream.c
index 926f2f8157..300e9b9c00 100644
--- a/dlls/shlwapi/tests/istream.c
+++ b/dlls/shlwapi/tests/istream.c
@@ -726,12 +726,12 @@ START_TEST(istream)
int i, j, k;
- for (i = 0; i != sizeof(stgm_access)/sizeof(stgm_access[0]); i++) {
- for (j = 0; j != sizeof(stgm_sharing)/sizeof(stgm_sharing[0]); j ++) {
+ for (i = 0; i != ARRAY_SIZE(stgm_access); i++) {
+ for (j = 0; j != ARRAY_SIZE(stgm_sharing); j ++) {
test_SHCreateStreamOnFileA(stgm_access[i], stgm_sharing[j]);
test_SHCreateStreamOnFileW(stgm_access[i], stgm_sharing[j]);
- for (k = 0; k != sizeof(stgm_flags)/sizeof(stgm_flags[0]); k++)
+ for (k = 0; k != ARRAY_SIZE(stgm_flags); k++)
test_SHCreateStreamOnFileEx(stgm_access[i], stgm_sharing[j] | stgm_flags[k]);
}
}
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index db59e625f8..97e4606443 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -1862,14 +1862,14 @@ if (0)
/* all combinations documented as invalid succeeded */
flags = FDTF_SHORTTIME | FDTF_LONGTIME;
SetLastError(0xdeadbeef);
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
flags = FDTF_SHORTDATE | FDTF_LONGDATE;
SetLastError(0xdeadbeef);
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
@@ -1877,7 +1877,7 @@ if (0)
flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
SetLastError(0xdeadbeef);
buff[0] = 0; /* NT4 doesn't clear the buffer on failure */
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
ok(GetLastError() == 0xdeadbeef,
@@ -1885,67 +1885,67 @@ if (0)
/* now check returned strings */
flags = FDTF_SHORTTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
SetLastError(0xdeadbeef);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
flags = FDTF_LONGTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
/* both time flags */
flags = FDTF_LONGTIME | FDTF_SHORTTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");
flags = FDTF_SHORTDATE;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
flags = FDTF_LONGDATE;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
/* both date flags */
flags = FDTF_LONGDATE | FDTF_SHORTDATE;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
/* various combinations of date/time flags */
flags = FDTF_LONGDATE | FDTF_SHORTTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, ARRAY_SIZE(buff3));
ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
"expected (%s), got (%s) for time part\n",
wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
p1 = buff;
p2 = buff2;
@@ -1963,15 +1963,15 @@ if (0)
wine_dbgstr_w(buff2), wine_dbgstr_w(buff));
flags = FDTF_LONGDATE | FDTF_LONGTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, ARRAY_SIZE(buff3));
ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
"expected (%s), got (%s) for time part\n",
wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
p1 = buff;
p2 = buff2;
@@ -1989,25 +1989,25 @@ if (0)
wine_dbgstr_w(buff2), wine_dbgstr_w(buff));
flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
lstrcatW(buff2, spaceW);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, ARRAY_SIZE(buff3));
ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
lstrcatW(buff2, buff3);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
flags = FDTF_SHORTDATE | FDTF_LONGTIME;
- ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
+ ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff));
ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
"expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
- ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
+ ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, ARRAY_SIZE(buff2));
ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
lstrcatW(buff2, spaceW);
- ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
+ ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, ARRAY_SIZE(buff3));
ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
lstrcatW(buff2, buff3);
ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
@@ -2068,7 +2068,7 @@ static void test_SHGetObjectCompatFlags(void)
{
int j;
- for (j = 0; j < sizeof(values)/sizeof(struct compat_value); j++)
+ for (j = 0; j < ARRAY_SIZE(values); j++)
if (lstrcmpA(values[j].nameA, valueA) == 0)
{
expected |= values[j].value;
diff --git a/dlls/shlwapi/tests/path.c b/dlls/shlwapi/tests/path.c
index 91c66b7ef3..d25620b3d5 100644
--- a/dlls/shlwapi/tests/path.c
+++ b/dlls/shlwapi/tests/path.c
@@ -283,7 +283,7 @@ static void test_PathCreateFromUrl(void)
ok(len == 0xdeca, "got %x expected 0xdeca\n", len);
/* Test the decoding itself */
- for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_PATHFROMURL); i++) {
len = INTERNET_MAX_URL_LENGTH;
ret = pPathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
todo_wine_if (TEST_PATHFROMURL[i].todo & 0x1)
@@ -350,7 +350,7 @@ static void test_PathIsUrl(void)
size_t i;
BOOL ret;
- for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_PATH_IS_URL); i++) {
ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
ok(ret == TEST_PATH_IS_URL[i].expect,
"returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
@@ -1403,7 +1403,7 @@ static void test_PathCommonPrefixA(void)
static void test_PathUnquoteSpaces(void)
{
int i;
- for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(TEST_PATH_UNQUOTE_SPACES); i++)
{
char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
@@ -1484,10 +1484,10 @@ static void test_PathUnExpandEnvStrings(void)
ret = pPathUnExpandEnvStringsA(envvarA, buff, sizeof(buff));
ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError());
- ret = GetEnvironmentVariableW(computernameW, envvarW, sizeof(envvarW)/sizeof(WCHAR));
+ ret = GetEnvironmentVariableW(computernameW, envvarW, ARRAY_SIZE(envvarW));
ok(ret, "got %d\n", ret);
SetLastError(0xdeadbeef);
- ret = pPathUnExpandEnvStringsW(envvarW, buffW, sizeof(buffW)/sizeof(WCHAR));
+ ret = pPathUnExpandEnvStringsW(envvarW, buffW, ARRAY_SIZE(buffW));
ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError());
/* something that can't be represented with env var */
@@ -1559,7 +1559,7 @@ static void test_PathUnExpandEnvStrings(void)
lstrcpyW(pathW, nonpathW);
buffW[0] = 'x'; buffW[1] = 0;
SetLastError(0xdeadbeef);
- ret = pPathUnExpandEnvStringsW(pathW, buffW, sizeof(buffW)/sizeof(WCHAR));
+ ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(buffW));
ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError());
ok(buffW[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW));
@@ -1580,13 +1580,13 @@ static void test_PathUnExpandEnvStrings(void)
/* buffer size is enough to hold variable name only */
buffW[0] = 'x'; buffW[1] = 0;
SetLastError(0xdeadbeef);
- ret = pPathUnExpandEnvStringsW(pathW, buffW, sizeof(sysrootW)/sizeof(WCHAR));
+ ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(sysrootW));
ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError());
ok(buffW[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW));
/* enough size */
buffW[0] = 0;
- ret = pPathUnExpandEnvStringsW(pathW, buffW, sizeof(buffW)/sizeof(WCHAR));
+ ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(buffW));
ok(ret, "got %d\n", ret);
ok(!memcmp(buffW, sysrootW, sizeof(sysrootW) - sizeof(WCHAR)), "wrong return string %s\n", wine_dbgstr_w(buffW));
@@ -1626,7 +1626,7 @@ static void test_PathIsRelativeA(void)
return;
}
- num = sizeof(test_path_is_relative) / sizeof(test_path_is_relative[0]);
+ num = ARRAY_SIZE(test_path_is_relative);
for (i = 0; i < num; i++) {
ret = pPathIsRelativeA(test_path_is_relative[i].path);
ok(ret == test_path_is_relative[i].expect,
@@ -1646,7 +1646,7 @@ static void test_PathIsRelativeW(void)
return;
}
- num = sizeof(test_path_is_relative) / sizeof(test_path_is_relative[0]);
+ num = ARRAY_SIZE(test_path_is_relative);
for (i = 0; i < num; i++) {
path = GetWideString(test_path_is_relative[i].path);
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c
index 7f069a4849..c7a2f5d346 100644
--- a/dlls/shlwapi/tests/string.c
+++ b/dlls/shlwapi/tests/string.c
@@ -412,7 +412,7 @@ static void test_StrCpyW(void)
while(result->value)
{
- MultiByteToWideChar(CP_ACP,0,result->byte_size_64,-1,szSrc,sizeof(szSrc)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->byte_size_64, -1, szSrc, ARRAY_SIZE(szSrc));
lpRes = StrCpyW(szBuff, szSrc);
ok(!StrCmpW(szSrc, szBuff) && lpRes == szBuff, "Copied string %s wrong\n", result->byte_size_64);
@@ -476,7 +476,7 @@ static void test_StrToIntW(void)
while (result->string)
{
- MultiByteToWideChar(CP_ACP,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
return_val = StrToIntW(szBuff);
ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
result->string, return_val);
@@ -526,7 +526,7 @@ static void test_StrToIntExW(void)
while (result->string)
{
return_val = -1;
- MultiByteToWideChar(CP_ACP,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = StrToIntExW(szBuff, 0, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
@@ -540,7 +540,7 @@ static void test_StrToIntExW(void)
while (result->string)
{
return_val = -1;
- MultiByteToWideChar(CP_ACP,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
@@ -605,7 +605,7 @@ static void test_StrToInt64ExW(void)
while (result->string)
{
return_val = -1;
- MultiByteToWideChar(CP_ACP,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = pStrToInt64ExW(szBuff, 0, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
@@ -619,7 +619,7 @@ static void test_StrToInt64ExW(void)
while (result->string)
{
return_val = -1;
- MultiByteToWideChar(CP_ACP,0,result->string,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
bRet = pStrToInt64ExW(szBuff, STIF_SUPPORT_HEX, &return_val);
ok(!bRet || return_val != -1, "No result returned from '%s'\n",
result->string);
@@ -865,7 +865,7 @@ static void test_StrCpyNXA(void)
}
memset(dest, '\n', sizeof(dest));
- lpszRes = pStrCpyNXA(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
+ lpszRes = pStrCpyNXA(dest, lpSrc, ARRAY_SIZE(dest));
ok(lpszRes == dest + 5 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
"StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
@@ -886,7 +886,7 @@ static void test_StrCpyNXW(void)
}
memcpy(dest, lpInit, sizeof(lpInit));
- lpszRes = pStrCpyNXW(dest, lpSrc, sizeof(dest)/sizeof(dest[0]));
+ lpszRes = pStrCpyNXW(dest, lpSrc, ARRAY_SIZE(dest));
ok(lpszRes == dest + 5 && !memcmp(dest, lpRes, sizeof(dest)),
"StrCpyNXW: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
@@ -949,7 +949,7 @@ static void test_SHAnsiToAnsi(void)
}
memset(dest, '\n', sizeof(dest));
- dwRet = pSHAnsiToAnsi("hello", dest, sizeof(dest)/sizeof(dest[0]));
+ dwRet = pSHAnsiToAnsi("hello", dest, ARRAY_SIZE(dest));
ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
"SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
@@ -976,7 +976,7 @@ static void test_SHUnicodeToUnicode(void)
}
memcpy(dest, lpInit, sizeof(lpInit));
- dwRet = pSHUnicodeToUnicode(lpSrc, dest, sizeof(dest)/sizeof(dest[0]));
+ dwRet = pSHUnicodeToUnicode(lpSrc, dest, ARRAY_SIZE(dest));
ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)),
"SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
@@ -1158,7 +1158,7 @@ static void test_StrStrA(void)
ret = StrStrA("", "");
ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrA_cases)/sizeof(StrStrA_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrA_cases); i++)
{
ret = StrStrA(deadbeefA, StrStrA_cases[i].search);
ok(ret == StrStrA_cases[i].expect,
@@ -1212,7 +1212,7 @@ static void test_StrStrW(void)
ret = StrStrW(emptyW, emptyW);
ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrW_cases)/sizeof(StrStrW_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrW_cases); i++)
{
ret = StrStrW(deadbeefW, StrStrW_cases[i].search);
ok(ret == StrStrW_cases[i].expect,
@@ -1260,7 +1260,7 @@ static void test_StrStrIA(void)
ret = StrStrIA("", "");
ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrIA_cases)/sizeof(StrStrIA_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrIA_cases); i++)
{
ret = StrStrIA(deadbeefA, StrStrIA_cases[i].search);
ok(ret == StrStrIA_cases[i].expect,
@@ -1316,7 +1316,7 @@ static void test_StrStrIW(void)
ret = StrStrIW(emptyW, emptyW);
ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrIW_cases)/sizeof(StrStrIW_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrIW_cases); i++)
{
ret = StrStrIW(deadbeefW, StrStrIW_cases[i].search);
ok(ret == StrStrIW_cases[i].expect,
@@ -1343,13 +1343,13 @@ static void test_StrStrNW(void)
const WCHAR *expect;
} StrStrNW_cases[] =
{
- {emptyW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
- {deadW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
- {dead_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
- {adbeW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
- {adbe_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
- {beefW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
- {beef_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+ {emptyW, ARRAY_SIZE(deadbeefW), NULL},
+ {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
+ {dead_lowerW, ARRAY_SIZE(deadbeefW), NULL},
+ {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
+ {adbe_lowerW, ARRAY_SIZE(deadbeefW), NULL},
+ {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
+ {beef_lowerW, ARRAY_SIZE(deadbeefW), NULL},
{beefW, 0, NULL},
{beefW, 1, NULL},
{beefW, 2, NULL},
@@ -1386,7 +1386,7 @@ static void test_StrStrNW(void)
ret = pStrStrNW(emptyW, emptyW, 10);
ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrNW_cases)/sizeof(StrStrNW_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrNW_cases); i++)
{
ret = pStrStrNW(deadbeefW, StrStrNW_cases[i].search, StrStrNW_cases[i].count);
ok(ret == StrStrNW_cases[i].expect,
@@ -1426,14 +1426,14 @@ static void test_StrStrNIW(void)
const WCHAR *expect;
} StrStrNIW_cases[] =
{
- {emptyW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
- {deadW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
- {dead_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
- {adbeW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
- {adbe_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
- {beefW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
- {beef_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
- {cafeW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+ {emptyW, ARRAY_SIZE(deadbeefW), NULL},
+ {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
+ {dead_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW},
+ {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
+ {adbe_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
+ {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
+ {beef_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
+ {cafeW, ARRAY_SIZE(deadbeefW), NULL},
{beefW, 0, NULL},
{beefW, 1, NULL},
{beefW, 2, NULL},
@@ -1480,7 +1480,7 @@ static void test_StrStrNIW(void)
ret = pStrStrNIW(emptyW, emptyW, 10);
ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
- for (i = 0; i < sizeof(StrStrNIW_cases)/sizeof(StrStrNIW_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(StrStrNIW_cases); i++)
{
ret = pStrStrNIW(deadbeefW, StrStrNIW_cases[i].search, StrStrNIW_cases[i].count);
ok(ret == StrStrNIW_cases[i].expect,
diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c
index ac896b06e4..d30737f60a 100644
--- a/dlls/shlwapi/tests/url.c
+++ b/dlls/shlwapi/tests/url.c
@@ -539,7 +539,7 @@ static void test_UrlApplyScheme(void)
return;
}
- for(i = 0; i < sizeof(TEST_APPLY)/sizeof(TEST_APPLY[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_APPLY); i++) {
len = TEST_APPLY_MAX_LENGTH;
lstrcpyA(newurl, untouchedA);
res = pUrlApplySchemeA(TEST_APPLY[i].url, newurl, &len, TEST_APPLY[i].flags);
@@ -916,7 +916,7 @@ static void test_UrlEscapeA(void)
"got %d, expected %d\n", size, 1);
ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]);
- for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) {
CHAR ret_url[INTERNET_MAX_URL_LENGTH];
size = INTERNET_MAX_URL_LENGTH;
@@ -983,7 +983,7 @@ static void test_UrlEscapeW(void)
/* Check actual escaping */
- size = sizeof(overwrite)/sizeof(WCHAR);
+ size = ARRAY_SIZE(overwrite);
ret = pUrlEscapeW(overwrite, overwrite, &size, URL_ESCAPE_SPACES_ONLY);
ok(ret == S_OK, "got %x, expected S_OK\n", ret);
ok(size == 9, "got %d, expected 9\n", size);
@@ -997,12 +997,12 @@ static void test_UrlEscapeW(void)
ok(wc == 127, "String has changed, wc = %d\n", wc);
/* non-ASCII range */
- size = sizeof(ret_urlW)/sizeof(WCHAR);
+ size = ARRAY_SIZE(ret_urlW);
ret = pUrlEscapeW(naW, ret_urlW, &size, 0);
ok(ret == S_OK, "got %x, expected S_OK\n", ret);
ok(!lstrcmpW(naescapedW, ret_urlW), "got %s, expected %s\n", wine_dbgstr_w(ret_urlW), wine_dbgstr_w(naescapedW));
- for (i = 0; i < sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) {
WCHAR *urlW, *expected_urlW;
@@ -1018,7 +1018,7 @@ static void test_UrlEscapeW(void)
FreeWideString(expected_urlW);
}
- for(i=0; i<sizeof(TEST_ESCAPEW)/sizeof(TEST_ESCAPEW[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_ESCAPEW); i++) {
WCHAR ret_url[INTERNET_MAX_URL_LENGTH];
size = INTERNET_MAX_URL_LENGTH;
@@ -1113,7 +1113,7 @@ static void test_UrlCanonicalizeA(void)
test_url_canonicalize(-1, "", 0, S_OK, S_FALSE /* Vista/win2k8 */, "", FALSE);
/* test url-modification */
- for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_CANONICALIZE); i++) {
test_url_canonicalize(i, TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl,
TEST_CANONICALIZE[i].todo);
@@ -1185,7 +1185,7 @@ static void test_UrlCanonicalizeW(void)
BOOL choped;
int pos;
- MultiByteToWideChar(CP_ACP, 0, "http://www.winehq.org/X", -1, szUrl, sizeof(szUrl)/sizeof(szUrl[0]));
+ MultiByteToWideChar(CP_ACP, 0, "http://www.winehq.org/X", -1, szUrl, ARRAY_SIZE(szUrl));
pos = lstrlenW(szUrl) - 1;
szUrl[pos] = i;
urllen = INTERNET_MAX_URL_LENGTH;
@@ -1267,7 +1267,7 @@ static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFla
static void test_UrlCombine(void)
{
unsigned int i;
- for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_COMBINE); i++) {
test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
}
@@ -1288,7 +1288,7 @@ static void test_UrlCreateFromPath(void)
return;
}
- for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_URLFROMPATH); i++) {
len = INTERNET_MAX_URL_LENGTH;
ret = pUrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path);
@@ -1342,8 +1342,8 @@ static void test_UrlIs(void)
test_UrlIs_null(URLIS_OPAQUE);
test_UrlIs_null(URLIS_URL);
- for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
- MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, sizeof(wurl)/sizeof(*wurl));
+ for (i = 0; i < ARRAY_SIZE(TEST_PATH_IS_URL); i++) {
+ MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, ARRAY_SIZE(wurl));
ret = pUrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
ok( ret == TEST_PATH_IS_URL[i].expect,
@@ -1357,8 +1357,8 @@ static void test_UrlIs(void)
TEST_PATH_IS_URL[i].path, TEST_PATH_IS_URL[i].expect );
}
}
- for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
- MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, sizeof(wurl)/sizeof(*wurl));
+ for (i = 0; i < ARRAY_SIZE(TEST_URLIS_ATTRIBS); i++) {
+ MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, ARRAY_SIZE(wurl));
ret = pUrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
@@ -1403,7 +1403,7 @@ static void test_UrlUnescape(void)
win_skip("UrlUnescapeA not found\n");
return;
}
- for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(TEST_URL_UNESCAPE); i++) {
dwEscaped=INTERNET_MAX_URL_LENGTH;
res = pUrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0);
ok(res == S_OK,
@@ -1494,7 +1494,7 @@ static void test_ParseURL(void)
PARSEDURLW parsedw;
HRESULT hres;
- for(test = parse_url_tests; test < parse_url_tests + sizeof(parse_url_tests)/sizeof(*parse_url_tests); test++) {
+ for (test = parse_url_tests; test < parse_url_tests + ARRAY_SIZE(parse_url_tests); test++) {
memset(&parseda, 0xd0, sizeof(parseda));
parseda.cbSize = sizeof(parseda);
hres = pParseURLA(test->url, &parseda);
@@ -1516,7 +1516,7 @@ static void test_ParseURL(void)
ok(parseda.nScheme == 0xd0d0d0d0, "nScheme = %d\n", parseda.nScheme);
}
- MultiByteToWideChar(CP_ACP, 0, test->url, -1, url, sizeof(url)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, test->url, -1, url, ARRAY_SIZE(url));
memset(&parsedw, 0xd0, sizeof(parsedw));
parsedw.cbSize = sizeof(parsedw);
@@ -1595,23 +1595,23 @@ static void test_HashData(void)
"Expected HashData to return E_INVALIDARG, got 0x%08x\n", res);
/* Test passing valid pointers with sizes of zero. */
- for (i = 0; i < sizeof(input)/sizeof(BYTE); i++)
+ for (i = 0; i < ARRAY_SIZE(input); i++)
input[i] = 0x00;
- for (i = 0; i < sizeof(output)/sizeof(BYTE); i++)
+ for (i = 0; i < ARRAY_SIZE(output); i++)
output[i] = 0xFF;
res = pHashData(input, 0, output, 0);
ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res);
/* The buffers should be unchanged. */
- for (i = 0; i < sizeof(input)/sizeof(BYTE); i++)
+ for (i = 0; i < ARRAY_SIZE(input); i++)
{
ok(input[i] == 0x00, "Expected the input buffer to be unchanged\n");
if(input[i] != 0x00) break;
}
- for (i = 0; i < sizeof(output)/sizeof(BYTE); i++)
+ for (i = 0; i < ARRAY_SIZE(output); i++)
{
ok(output[i] == 0xFF, "Expected the output buffer to be unchanged\n");
if(output[i] != 0xFF) break;
--
2.14.4
June 26, 2018
Re: [PATCH vkd3d 10/12] libs/vkd3d: Add support for 2D array render target views.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018