mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 00:13:01 -05:00
add winfsp-tests and ext/tlib
This commit is contained in:
parent
a71ca19644
commit
abdc76ea2e
@ -101,7 +101,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\inc;..\..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -116,7 +116,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\inc;..\..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -133,7 +133,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\inc;..\..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -152,7 +152,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\inc;..\..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
184
build/VStudio/testing/winfsp-tests.vcxproj
Normal file
184
build/VStudio/testing/winfsp-tests.vcxproj
Normal file
@ -0,0 +1,184 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{262DF8CC-E7A8-4460-A22C-683CBA322C32}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>winfsptests</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc;..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc;..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc;..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc;..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\ext\tlib\testsuite.c">
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</SDLCheck>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</SDLCheck>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</SDLCheck>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</SDLCheck>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
28
build/VStudio/testing/winfsp-tests.vcxproj.filters
Normal file
28
build/VStudio/testing/winfsp-tests.vcxproj.filters
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source\tlib">
|
||||
<UniqueIdentifier>{1b7df6fa-185e-4a53-bfac-a4bbf82bba70}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\ext\tlib\testsuite.c">
|
||||
<Filter>Source\tlib</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
||||
<Filter>Source\tlib</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -7,9 +7,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winfsp.dll", "winfsp_dll.vc
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winfsp.sys", "winfsp_sys.vcxproj", "{C85C26BA-8C22-4D30-83DA-46C3548E6332}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{69439FD1-C07D-4BF1-98DC-3CCFECE53A49}"
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{69439FD1-C07D-4BF1-98DC-3CCFECE53A49}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mirror", "samples\mirror.vcxproj", "{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mirror", "testing\mirror.vcxproj", "{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winfsp-tests", "testing\winfsp-tests.vcxproj", "{262DF8CC-E7A8-4460-A22C-683CBA322C32}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -43,11 +45,20 @@ Global
|
||||
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x64.Build.0 = Release|x64
|
||||
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.Build.0 = Release|Win32
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.Build.0 = Debug|x64
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.Build.0 = Debug|Win32
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.ActiveCfg = Release|x64
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.Build.0 = Release|x64
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.ActiveCfg = Release|Win32
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
{262DF8CC-E7A8-4460-A22C-683CBA322C32} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -102,7 +102,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WINFSP_DLL_INTERNAL;WIN32;_DEBUG;_WINDOWS;_USRDLL;WINFSPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@ -117,7 +117,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WINFSP_DLL_INTERNAL;_DEBUG;_WINDOWS;_USRDLL;WINFSPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@ -134,7 +134,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WINFSP_DLL_INTERNAL;WIN32;NDEBUG;_WINDOWS;_USRDLL;WINFSPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@ -153,7 +153,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WINFSP_DLL_INTERNAL;NDEBUG;_WINDOWS;_USRDLL;WINFSPDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -96,7 +96,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WINFSP_SYS_INTERNAL; _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -105,7 +105,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WINFSP_SYS_INTERNAL; _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -114,7 +114,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WINFSP_SYS_INTERNAL; _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -123,7 +123,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\..\inc;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WINFSP_SYS_INTERNAL; _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
2
ext/tlib/Commit.txt
Normal file
2
ext/tlib/Commit.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Taked from secfs.core/src/tlib codebase:
|
||||
commit 16296d2ac64a7d532b1c486dd3c44af5865d4851
|
75
ext/tlib/callstack.c
Normal file
75
ext/tlib/callstack.c
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file tlib/callstack.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/callstack.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib, "dbghelp.lib")
|
||||
#elif defined(__APPLE__) || defined(__linux__)
|
||||
#include <dlfcn.h>
|
||||
#include <execinfo.h>
|
||||
#else
|
||||
#error tlib/callstack.c not implemented for this platform
|
||||
#endif
|
||||
|
||||
void tlib_callstack(size_t skip, size_t count, struct tlib_callstack_s *stack)
|
||||
{
|
||||
if (count > TLIB_MAX_SYMRET)
|
||||
count = TLIB_MAX_SYMRET;
|
||||
size_t naddrs = skip + count;
|
||||
if (naddrs > TLIB_MAX_SYMCAP)
|
||||
naddrs = TLIB_MAX_SYMCAP;
|
||||
memset((void *)stack->syms, 0, sizeof stack->syms);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
/* SymInitialize()/SymFromAddr() are not thread-safe. Furthermore SymInitialize() should
|
||||
* not be called more than once per process.
|
||||
*/
|
||||
HANDLE hproc = GetCurrentProcess();
|
||||
static SYMBOL_INFO *syminfo = 0;
|
||||
void *addrs[TLIB_MAX_SYMCAP];
|
||||
size_t i = 0;
|
||||
if (0 == syminfo)
|
||||
{
|
||||
syminfo = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO) + TLIB_MAX_SYMLEN);
|
||||
if (0 == syminfo)
|
||||
return;
|
||||
SymInitialize(hproc, 0, TRUE);
|
||||
}
|
||||
memset(syminfo, 0, sizeof(SYMBOL_INFO));
|
||||
syminfo->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
syminfo->MaxNameLen = TLIB_MAX_SYMLEN;
|
||||
naddrs = CaptureStackBackTrace(0, naddrs, addrs, 0);
|
||||
for (void **p = addrs + skip, **endp = addrs + naddrs; endp > p; p++)
|
||||
{
|
||||
DWORD64 displacement = 0;
|
||||
if (SymFromAddr(hproc, (DWORD64)*p, &displacement, syminfo))
|
||||
{
|
||||
stack->syms[i] = stack->symbuf[i];
|
||||
strncpy(stack->symbuf[i], syminfo->Name, TLIB_MAX_SYMLEN);
|
||||
stack->symbuf[i][TLIB_MAX_SYMLEN] = '\0';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__) || defined(__linux__)
|
||||
void *addrs[TLIB_MAX_SYMCAP];
|
||||
naddrs = backtrace(addrs, naddrs);
|
||||
size_t i = 0;
|
||||
Dl_info syminfo;
|
||||
for (void **p = addrs + skip, **endp = addrs + naddrs; endp > p; p++)
|
||||
{
|
||||
if (dladdr(*p, &syminfo) && 0 != syminfo.dli_sname)
|
||||
{
|
||||
stack->syms[i] = stack->symbuf[i];
|
||||
strncpy(stack->symbuf[i], syminfo.dli_sname, TLIB_MAX_SYMLEN);
|
||||
stack->symbuf[i][TLIB_MAX_SYMLEN] = '\0';
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
26
ext/tlib/callstack.h
Normal file
26
ext/tlib/callstack.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file tlib/callstack.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
||||
#define TLIB_CALLSTACK_H_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
enum
|
||||
{
|
||||
TLIB_MAX_SYMLEN = 63,
|
||||
TLIB_MAX_SYMRET = 8,
|
||||
TLIB_MAX_SYMCAP = 62, /* max number of frames to capture (Windows restriction) */
|
||||
};
|
||||
|
||||
struct tlib_callstack_s
|
||||
{
|
||||
const char *syms[TLIB_MAX_SYMRET + 1];
|
||||
char symbuf[TLIB_MAX_SYMRET][TLIB_MAX_SYMLEN + 1];
|
||||
};
|
||||
void tlib_callstack(size_t skip, size_t count, struct tlib_callstack_s *stack);
|
||||
|
||||
#endif
|
13
ext/tlib/injected/allfunc.h
Normal file
13
ext/tlib/injected/allfunc.h
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @file tlib/injected/allfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
||||
#define TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
||||
|
||||
#include <tlib/injected/curlfunc.h>
|
||||
#include <tlib/injected/stdfunc.h>
|
||||
|
||||
#endif
|
35
ext/tlib/injected/curlfunc.c
Normal file
35
ext/tlib/injected/curlfunc.c
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @file tlib/injected/curlfunc.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injected/curlfunc.h>
|
||||
#define TLIB_INJECTIONS_ENABLED
|
||||
#include <tlib/injection.h>
|
||||
|
||||
#undef curl_easy_init
|
||||
#undef curl_multi_init
|
||||
#undef curl_multi_add_handle
|
||||
#undef curl_multi_perform
|
||||
|
||||
CURL *tlib_curl_easy_init(void)
|
||||
{
|
||||
TLIB_INJECT("curl_easy_init", return 0);
|
||||
return curl_easy_init();
|
||||
}
|
||||
CURLM *tlib_curl_multi_init(void)
|
||||
{
|
||||
TLIB_INJECT("curl_multi_init", return 0);
|
||||
return curl_multi_init();
|
||||
}
|
||||
CURLMcode tlib_curl_multi_add_handle(CURLM *mh, CURL *eh)
|
||||
{
|
||||
TLIB_INJECT("curl_multi_add_handle", return CURLM_INTERNAL_ERROR);
|
||||
return curl_multi_add_handle(mh, eh);
|
||||
}
|
||||
CURLMcode tlib_curl_multi_perform(CURLM *mh, int *running_handles)
|
||||
{
|
||||
TLIB_INJECT("curl_multi_perform", return CURLM_INTERNAL_ERROR);
|
||||
return curl_multi_perform(mh, running_handles);
|
||||
}
|
24
ext/tlib/injected/curlfunc.h
Normal file
24
ext/tlib/injected/curlfunc.h
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @file tlib/injected/curlfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
||||
#define TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if defined(TLIB_INJECTIONS_ENABLED)
|
||||
#define curl_easy_init() tlib_curl_easy_init()
|
||||
#define curl_multi_init() tlib_curl_multi_init()
|
||||
#define curl_multi_add_handle(mh, eh) tlib_curl_multi_add_handle(mh, eh)
|
||||
#define curl_multi_perform(mh, rh) tlib_curl_multi_perform(mh, rh)
|
||||
#endif
|
||||
|
||||
CURL *tlib_curl_easy_init(void);
|
||||
CURLM *tlib_curl_multi_init(void);
|
||||
CURLMcode tlib_curl_multi_add_handle(CURLM *mh, CURL *eh);
|
||||
CURLMcode tlib_curl_multi_perform(CURLM *mh, int *running_handles);
|
||||
|
||||
#endif
|
29
ext/tlib/injected/stdfunc.c
Normal file
29
ext/tlib/injected/stdfunc.c
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file tlib/injected/stdfunc.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injected/stdfunc.h>
|
||||
#define TLIB_INJECTIONS_ENABLED
|
||||
#include <tlib/injection.h>
|
||||
|
||||
#undef calloc
|
||||
#undef malloc
|
||||
#undef realloc
|
||||
|
||||
void *tlib_calloc(size_t count, size_t size)
|
||||
{
|
||||
TLIB_INJECT("calloc", return 0);
|
||||
return calloc(count, size);
|
||||
}
|
||||
void *tlib_malloc(size_t size)
|
||||
{
|
||||
TLIB_INJECT("malloc", return 0);
|
||||
return malloc(size);
|
||||
}
|
||||
void *tlib_realloc(void *ptr, size_t size)
|
||||
{
|
||||
TLIB_INJECT("realloc", return 0);
|
||||
return realloc(ptr, size);
|
||||
}
|
23
ext/tlib/injected/stdfunc.h
Normal file
23
ext/tlib/injected/stdfunc.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @file tlib/injected/stdfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
||||
#define TLIB_INJECTED_STDFUNC_H_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(TLIB_INJECTIONS_ENABLED)
|
||||
#define calloc(count, size) tlib_calloc(count, size)
|
||||
#define malloc(size) tlib_malloc(size)
|
||||
#define realloc(ptr, size) tlib_realloc(ptr, size)
|
||||
#endif
|
||||
|
||||
void *tlib_calloc(size_t count, size_t size);
|
||||
void *tlib_malloc(size_t size);
|
||||
void *tlib_realloc(void *ptr, size_t size);
|
||||
|
||||
#endif
|
144
ext/tlib/injection.c
Normal file
144
ext/tlib/injection.c
Normal file
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* @file tlib/injection.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injection.h>
|
||||
#include <tlib/callstack.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#define NBUCKETS 256
|
||||
struct injection_cond_s
|
||||
{
|
||||
struct injection_cond_s *cnext;
|
||||
char *sym;
|
||||
unsigned trigger, count;
|
||||
};
|
||||
struct injection_entry_s
|
||||
{
|
||||
struct injection_entry_s *hnext;
|
||||
char *name;
|
||||
struct injection_cond_s *clist;
|
||||
};
|
||||
struct injection_htab_s
|
||||
{
|
||||
struct injection_entry_s **buckets;
|
||||
};
|
||||
|
||||
static inline size_t hash_chars(const char *s, size_t length)
|
||||
{
|
||||
/* djb2: see http://www.cse.yorku.ca/~oz/hash.html */
|
||||
size_t h = 5381;
|
||||
for (const char *t = s + length; t > s; ++s)
|
||||
h = 33 * h + *s;
|
||||
return h;
|
||||
}
|
||||
static struct injection_htab_s *injection_htab()
|
||||
{
|
||||
static struct injection_htab_s *htab;
|
||||
if (0 == htab)
|
||||
{
|
||||
htab = calloc(1, sizeof *htab);
|
||||
assert(0 != htab);
|
||||
htab->buckets = calloc(NBUCKETS, sizeof(struct injection_entry_s *));
|
||||
}
|
||||
return htab;
|
||||
}
|
||||
static struct injection_entry_s *injection_lookup(const char *name)
|
||||
{
|
||||
struct injection_htab_s *htab = injection_htab();
|
||||
size_t i = hash_chars(name, strlen(name)) & (NBUCKETS - 1);
|
||||
for (struct injection_entry_s *entry = htab->buckets[i]; entry; entry = entry->hnext)
|
||||
if (0 == strcmp(entry->name, name))
|
||||
return entry;
|
||||
return 0;
|
||||
}
|
||||
static struct injection_entry_s *injection_insert(const char *name)
|
||||
{
|
||||
struct injection_htab_s *htab = injection_htab();
|
||||
size_t i = hash_chars(name, strlen(name)) & (NBUCKETS - 1);
|
||||
struct injection_entry_s *entry = calloc(1, sizeof *entry);
|
||||
assert(0 != entry);
|
||||
entry->name = strdup(name);
|
||||
entry->hnext = htab->buckets[i];
|
||||
htab->buckets[i] = entry;
|
||||
return entry;
|
||||
}
|
||||
static struct injection_cond_s *injection_cond_get(struct injection_entry_s *entry, const char **syms)
|
||||
{
|
||||
struct injection_cond_s *deinjection_centry = 0;
|
||||
for (struct injection_cond_s *centry = entry->clist; centry; centry = centry->cnext)
|
||||
if ('*' == centry->sym[0] && '\0' == centry->sym[1])
|
||||
deinjection_centry = centry;
|
||||
else
|
||||
{
|
||||
for (const char *sym; 0 != (sym = *syms); syms++)
|
||||
if (0 == strcmp(centry->sym, sym))
|
||||
return centry;
|
||||
}
|
||||
return deinjection_centry;
|
||||
}
|
||||
static void injection_cond_set(struct injection_entry_s *entry, const char *sym, unsigned trigger)
|
||||
{
|
||||
for (struct injection_cond_s *centry = entry->clist; centry; centry = centry->cnext)
|
||||
if (0 == strcmp(centry->sym, sym))
|
||||
{
|
||||
centry->trigger = trigger;
|
||||
return;
|
||||
}
|
||||
struct injection_cond_s *centry = calloc(1, sizeof *centry);
|
||||
assert(0 != centry);
|
||||
centry->sym = strdup(sym);
|
||||
centry->trigger = trigger;
|
||||
centry->cnext = entry->clist;
|
||||
entry->clist = centry;
|
||||
}
|
||||
static void injection_cond_remove(struct injection_entry_s *entry, const char *sym)
|
||||
{
|
||||
struct injection_cond_s **p = &entry->clist;
|
||||
for (; *p; p = &(*p)->cnext)
|
||||
if (0 == strcmp((*p)->sym, sym))
|
||||
break;
|
||||
if (*p) /* did we find the condition? */
|
||||
{
|
||||
struct injection_cond_s *q = *p;
|
||||
*p = q->cnext;
|
||||
free(q->sym);
|
||||
free(q);
|
||||
}
|
||||
}
|
||||
|
||||
void *tlib_injection(const char *name)
|
||||
{
|
||||
struct injection_entry_s *entry = injection_lookup(name);
|
||||
if (0 == entry)
|
||||
entry = injection_insert(name);
|
||||
return entry;
|
||||
}
|
||||
int tlib_injection_trace(void *injection)
|
||||
{
|
||||
if (0 == ((struct injection_entry_s *)injection)->clist)
|
||||
return 0;
|
||||
struct tlib_callstack_s stack;
|
||||
tlib_callstack(2, TLIB_MAX_SYMRET, &stack);
|
||||
struct injection_cond_s *centry = injection_cond_get(injection, stack.syms);
|
||||
if (0 == centry)
|
||||
return 0;
|
||||
return centry->count++ == centry->trigger || ~0 == centry->trigger;
|
||||
}
|
||||
void tlib_injection_enable(const char *name, const char *sym, unsigned trigger)
|
||||
{
|
||||
struct injection_entry_s *entry = tlib_injection(name);
|
||||
injection_cond_set(entry, sym, trigger);
|
||||
}
|
||||
void tlib_injection_disable(const char *name, const char *sym)
|
||||
{
|
||||
struct injection_entry_s *entry = tlib_injection(name);
|
||||
injection_cond_remove(entry, sym);
|
||||
}
|
30
ext/tlib/injection.h
Normal file
30
ext/tlib/injection.h
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file tlib/injection.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
/* NOTE: This header may usefully be included multiple times.
|
||||
* The TLIB_INJECT() macro will be redefined based on whether
|
||||
* TLIB_INJECTIONS_ENABLED is defined.
|
||||
*/
|
||||
|
||||
#undef TLIB_INJECT
|
||||
#if defined(TLIB_INJECTIONS_ENABLED)
|
||||
#define TLIB_INJECT(name, stmt) \
|
||||
do\
|
||||
{\
|
||||
static void *injection = 0;\
|
||||
if (0 == injection)\
|
||||
injection = tlib_injection(name);\
|
||||
if (tlib_injection_trace(injection))\
|
||||
stmt;\
|
||||
} while (0)
|
||||
#else
|
||||
#define TLIB_INJECT(name, stmt) do {} while (0)
|
||||
#endif
|
||||
|
||||
void *tlib_injection(const char *name);
|
||||
int tlib_injection_trace(void *injection);
|
||||
void tlib_injection_enable(const char *name, const char *sym, unsigned trigger);
|
||||
void tlib_injection_disable(const char *name, const char *sym);
|
202
ext/tlib/testsuite.c
Normal file
202
ext/tlib/testsuite.c
Normal file
@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @file tlib/testsuite.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/testsuite.h>
|
||||
#include <limits.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
struct test
|
||||
{
|
||||
char name[64];
|
||||
void (*fn)(void);
|
||||
int optional;
|
||||
struct test *next;
|
||||
};
|
||||
static struct test test_suite_sentinel = { .next = &test_suite_sentinel };
|
||||
static struct test *test_suite_tail = &test_suite_sentinel;
|
||||
static struct test test_sentinel = { .next = &test_sentinel };
|
||||
static struct test *test_tail = &test_sentinel;
|
||||
static void add_test_to_list(const char *name, void (*fn)(void), int optional, struct test **tail)
|
||||
{
|
||||
struct test *test = calloc(1, sizeof *test);
|
||||
strncpy(test->name, name, sizeof test->name - 1);
|
||||
test->name[sizeof test->name - 1] = '\0';
|
||||
test->fn = fn;
|
||||
test->optional = optional;
|
||||
test->next = (*tail)->next;
|
||||
(*tail)->next = test;
|
||||
(*tail) = test;
|
||||
}
|
||||
void tlib_add_test_suite(const char *name, void (*fn)(void))
|
||||
{
|
||||
add_test_to_list(name, fn, 0, &test_suite_tail);
|
||||
}
|
||||
void tlib_add_test(const char *name, void (*fn)(void))
|
||||
{
|
||||
add_test_to_list(name, fn, 0, &test_tail);
|
||||
}
|
||||
void tlib_add_test_opt(const char *name, void (*fn)(void))
|
||||
{
|
||||
add_test_to_list(name, fn, 1, &test_tail);
|
||||
}
|
||||
|
||||
static FILE *tlib_out, *tlib_err;
|
||||
static jmp_buf test_jmp_buf, *test_jmp;
|
||||
static char assert_buf[256];
|
||||
static void test_printf(const char *fmt, ...);
|
||||
static double run_test(struct test *test)
|
||||
{
|
||||
time_t t0 = time(0);
|
||||
test->fn();
|
||||
time_t t1 = time(0);
|
||||
return difftime(t1, t0);
|
||||
}
|
||||
static void do_test_default(struct test *test, int testno)
|
||||
{
|
||||
if (0 != test)
|
||||
{
|
||||
snprintf(assert_buf, sizeof assert_buf, "KO\n ");
|
||||
char dispname[39 + 1];
|
||||
size_t displen = strlen(test->name);
|
||||
if (displen > sizeof dispname - 1)
|
||||
displen = sizeof dispname - 1;
|
||||
memcpy(dispname, test->name, displen);
|
||||
memset(dispname + displen, '.', sizeof dispname - 1 - displen);
|
||||
dispname[sizeof dispname - 1] = '\0';
|
||||
test_printf("%s ", dispname);
|
||||
double d = run_test(test);
|
||||
test_printf("OK %.0fs\n", d);
|
||||
}
|
||||
else
|
||||
test_printf("--- COMPLETE ---\n");
|
||||
}
|
||||
static void do_test_list(struct test *test, int testno)
|
||||
{
|
||||
if (0 != test)
|
||||
test_printf("%s\n", test->name);
|
||||
}
|
||||
static void do_test_tap(struct test *test, int testno)
|
||||
{
|
||||
if (0 != test)
|
||||
{
|
||||
snprintf(assert_buf, sizeof assert_buf, "not ok %d %s\n# ", testno + 1, test->name);
|
||||
run_test(test);
|
||||
test_printf("ok %d %s\n", testno + 1, test->name);
|
||||
}
|
||||
else
|
||||
test_printf("1..%d\n", testno);
|
||||
}
|
||||
static void test_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
FILE *f = tlib_out ? tlib_out : stdout;
|
||||
vfprintf(f, fmt, ap);
|
||||
fflush(f);
|
||||
va_end(ap);
|
||||
}
|
||||
void tlib_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
FILE *f = tlib_err ? tlib_err : stderr;
|
||||
vfprintf(f, fmt, ap);
|
||||
fflush(f);
|
||||
va_end(ap);
|
||||
}
|
||||
void tlib_run_tests(int argc, char *argv[])
|
||||
{
|
||||
argc--; argv++;
|
||||
void (*do_test)(struct test *, int) = do_test_default;
|
||||
int match_any = 1, no_abort = 0;
|
||||
unsigned long repeat = 1;
|
||||
for (char **ap = argv, **aendp = ap + argc; aendp > ap; ap++)
|
||||
{
|
||||
const char *a = *ap;
|
||||
if ('-' == a[0])
|
||||
{
|
||||
if (0 == strcmp("--list", a))
|
||||
do_test = do_test_list;
|
||||
else if (0 == strcmp("--tap", a))
|
||||
do_test = do_test_tap;
|
||||
else if (0 == strcmp("--no-abort", a))
|
||||
no_abort = 1;
|
||||
else if (0 == strcmp("--repeat-forever", a))
|
||||
repeat = ULONG_MAX;
|
||||
}
|
||||
else
|
||||
match_any = 0;
|
||||
}
|
||||
for (struct test *test = test_suite_tail->next->next; 0 != test->fn; test = test->next)
|
||||
test->fn();
|
||||
while (repeat--)
|
||||
{
|
||||
int testno = 0;
|
||||
for (struct test *test = test_tail->next->next; 0 != test->fn; test = test->next)
|
||||
{
|
||||
int match_arg = match_any && !test->optional;
|
||||
for (char **ap = argv, **aendp = ap + argc; aendp > ap; aendp--)
|
||||
{
|
||||
const char *a = aendp[-1];
|
||||
int sign = a[0];
|
||||
if ('+' == sign)
|
||||
a++;
|
||||
else if ('-' == sign)
|
||||
{
|
||||
if ('-' == a[1])
|
||||
continue;
|
||||
a++;
|
||||
}
|
||||
size_t l = strlen(a);
|
||||
if (0 == (0 < l && '*' == a[l - 1] ?
|
||||
strncmp(test->name, a, l - 1) : strcmp(test->name, a)))
|
||||
{
|
||||
if ('+' == sign)
|
||||
match_arg = 1;
|
||||
else if ('-' == sign)
|
||||
match_arg = 0;
|
||||
else
|
||||
match_arg = !test->optional;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match_arg)
|
||||
continue;
|
||||
assert_buf[0] = '\0';
|
||||
if (no_abort)
|
||||
{
|
||||
test_jmp = &test_jmp_buf;
|
||||
if (0 == setjmp(*test_jmp))
|
||||
do_test(test, testno);
|
||||
test_jmp = 0;
|
||||
}
|
||||
else
|
||||
do_test(test, testno);
|
||||
testno++;
|
||||
}
|
||||
do_test(0, testno);
|
||||
}
|
||||
}
|
||||
void tlib__assert(const char *func, const char *file, int line, const char *expr)
|
||||
{
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
const char *p = strrchr(file, '\\');
|
||||
#else
|
||||
const char *p = strrchr(file, '/');
|
||||
#endif
|
||||
file = 0 != p ? p + 1 : file;
|
||||
if (0 == func)
|
||||
test_printf("%sASSERT(%s) failed at: %s:%d\n", assert_buf, expr, file, line);
|
||||
else
|
||||
test_printf("%sASSERT(%s) failed at %s:%d:%s\n", assert_buf, expr, file, line, func);
|
||||
if (0 != test_jmp)
|
||||
longjmp(*test_jmp, 1);
|
||||
}
|
112
ext/tlib/testsuite.h
Normal file
112
ext/tlib/testsuite.h
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file tlib/testsuite.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
||||
#define TLIB_TESTSUITE_H_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Assert macro
|
||||
*
|
||||
* This macro works similarly to the Standard C assert macro, except for the following differences:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The macro always checks the specified expression regardless of the NDEBUG macro.</li>
|
||||
* <li>The macro aborts the execution of the current test, but not necessarily the execution of the
|
||||
* whole testsuite.</li>
|
||||
* </ul>
|
||||
*/
|
||||
#define ASSERT(expr)\
|
||||
(!(expr) ? (tlib__assert(__func__, __FILE__, __LINE__, #expr), abort()) : (void)0)
|
||||
|
||||
/**
|
||||
* Register a test suite for execution.
|
||||
*
|
||||
* Test suites are simple functions with prototype <code>void testsuite()</code>. When executed
|
||||
* they register individual test cases for execution.
|
||||
*/
|
||||
#define TESTSUITE(fn)\
|
||||
do\
|
||||
{\
|
||||
void fn(void);\
|
||||
tlib_add_test_suite(#fn, fn);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Register a test case for execution.
|
||||
*
|
||||
* Test cases are simple functions with prototype <code>void testcase()</code>.
|
||||
*/
|
||||
#define TEST(fn)\
|
||||
do\
|
||||
{\
|
||||
void fn(void);\
|
||||
tlib_add_test(#fn, fn);\
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Register an optional test case for execution.
|
||||
*
|
||||
* Test cases are simple functions with prototype <code>void testcase()</code>.
|
||||
* Optional tests are not executed by default.
|
||||
*/
|
||||
#define TEST_OPT(fn)\
|
||||
do\
|
||||
{\
|
||||
void fn(void);\
|
||||
tlib_add_test_opt(#fn, fn);\
|
||||
} while (0)
|
||||
|
||||
void tlib_add_test_suite(const char *name, void (*fn)(void));
|
||||
void tlib_add_test(const char *name, void (*fn)(void));
|
||||
void tlib_add_test_opt(const char *name, void (*fn)(void));
|
||||
|
||||
/**
|
||||
* Printf function.
|
||||
*
|
||||
* Use this to produce output in the appropriate tlib file stream. This function uses the local
|
||||
* printf facilities and understands the same format strings.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
void tlib_printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
#else
|
||||
void tlib_printf(const char *fmt, ...);
|
||||
#endif
|
||||
/**
|
||||
* Run tests.
|
||||
*
|
||||
* This function will first execute all registered test suites, thus giving them the chance to
|
||||
* register any test cases. It will then execute all registered test cases according to the
|
||||
* command line arguments passed in argv. The command line syntax is a follows:
|
||||
*
|
||||
* Usage: testprog [--list][[--tap][--no-abort][--repeat-forever] [[+-]TESTNAME...]
|
||||
*
|
||||
* <ul>
|
||||
* <li>--list - list tests only</li>
|
||||
* <li>--tap - produce output in TAP format</li>
|
||||
* <li>--no-abort - do not abort all tests when an ASSERT fails
|
||||
* (only the current test is aborted)</li>
|
||||
* <li>--repeat-forever - repeat tests forever</li>
|
||||
* </ul>
|
||||
*
|
||||
* By default all test cases are executed unless specific test cases are named. By default optional
|
||||
* test cases are not executed. To execute a specific test case specify its TESTNAME; if it is an
|
||||
* optional test case specify +TESTNAME. To excluse a test case specify -TESTNAME.
|
||||
*
|
||||
* TESTNAME may also contain a single asterisk at the end; for example, mytest* will match all test
|
||||
* cases that have names starting with "mytest".
|
||||
*
|
||||
* @param argc
|
||||
* Argument count.
|
||||
* @param argv
|
||||
* Argument vector.
|
||||
*/
|
||||
void tlib_run_tests(int argc, char *argv[]);
|
||||
|
||||
void tlib__assert(const char *func, const char *file, int line, const char *expr);
|
||||
|
||||
#endif
|
11
tst/winfsp-tests/mount-test.c
Normal file
11
tst/winfsp-tests/mount-test.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <winfsp/winfsp.h>
|
||||
#include <tlib/testsuite.h>
|
||||
|
||||
void mount_test(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mount_tests(void)
|
||||
{
|
||||
TEST(mount_test);
|
||||
}
|
8
tst/winfsp-tests/winfsp-tests.c
Normal file
8
tst/winfsp-tests/winfsp-tests.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <tlib/testsuite.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
TESTSUITE(mount_tests);
|
||||
tlib_run_tests(argc, argv);
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user