coverage: implement profiling to output Scilab values 50/20650/8
Clément DAVID [Wed, 5 Dec 2018 19:23:26 +0000 (20:23 +0100)]
 * `profileEnable()` instrument the Scilab code
 * `profileDisable()` de-instrument the Scilab code
 * `profileGetInfo()` output the counters as a Scilab data-structure
 * Plot and Show are not ported

Change-Id: Ifa603daf58cc5464ccc517fc23653a503ee0d436

27 files changed:
SEP/SEP_133_profiling.odt [new file with mode: 0644]
scilab/CHANGES.md
scilab/modules/ast/includes/types/macro.hxx
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/coverage/Makefile.am
scilab/modules/coverage/Makefile.in
scilab/modules/coverage/coverage.vcxproj
scilab/modules/coverage/coverage.vcxproj.filters
scilab/modules/coverage/help/en_US/addchapter.sce
scilab/modules/coverage/help/en_US/profile.xml [new file with mode: 0644]
scilab/modules/coverage/help/en_US/profileDisable.xml [new file with mode: 0644]
scilab/modules/coverage/help/en_US/profileEnable.xml [new file with mode: 0644]
scilab/modules/coverage/help/en_US/profileGetInfo.xml [new file with mode: 0644]
scilab/modules/coverage/includes/Counter.hxx
scilab/modules/coverage/includes/CoverModule.hxx
scilab/modules/coverage/includes/CoverResult.hxx
scilab/modules/coverage/includes/coverage_gw.hxx
scilab/modules/coverage/sci_gateway/cpp/coverage_gw.cpp
scilab/modules/coverage/sci_gateway/cpp/sci_profileDisable.cpp [new file with mode: 0644]
scilab/modules/coverage/sci_gateway/cpp/sci_profileEnable.cpp [new file with mode: 0644]
scilab/modules/coverage/sci_gateway/cpp/sci_profileGetInfo.cpp [new file with mode: 0644]
scilab/modules/coverage/src/cpp/CoverModule.cpp
scilab/modules/coverage/src/cpp/CoverResult.cpp
scilab/modules/coverage/src/cpp/InstrumentVisitor.cpp
scilab/modules/coverage/tests/unit_tests/profileDisable.tst [new file with mode: 0644]
scilab/modules/coverage/tests/unit_tests/profileEnable.tst [new file with mode: 0644]
scilab/modules/coverage/tests/unit_tests/profileGetInfo.tst [new file with mode: 0644]

diff --git a/SEP/SEP_133_profiling.odt b/SEP/SEP_133_profiling.odt
new file mode 100644 (file)
index 0000000..876bdac
Binary files /dev/null and b/SEP/SEP_133_profiling.odt differ
index cc9d331..6600644 100644 (file)
@@ -26,7 +26,7 @@ For a high-level description of the main new features of this release, please co
 
 In summary, the main new features are:
 * Webtools utilities added for HTTP protocol, JSON data usage
-
+* Profiled values are available as Scilab values 
 
 Installation
 ------------
@@ -87,6 +87,7 @@ Feature changes and additions
   - For decimal numbers `x > 2^52`, querried bits below `%eps` (indices < log2(x)-52) now return `Nan` instead of 0.
   - Several bits can now be retrieved from each component of an input array.
 * `edit` now accepts a line number as text (like "23").
+* `profileEnable`, `profileDisable`, `profileGetInfo` could be used to instrument functions and gather execution information within Scilab.
 
 
 Help pages:
index 56c9b59..4b4b991 100644 (file)
@@ -79,7 +79,7 @@ public :
         return L"function";
     }
 
-    const std::wstring&         getFileName()
+    const std::wstring&         getFileName() const
     {
         return m_stPath;
     }
index cb67331..44cb87c 100644 (file)
@@ -1423,6 +1423,10 @@ void RunVisitorT<T>::visitprivate(const FunctionDec & e)
     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
                                             const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
     pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
+    if (e.getMacro())
+    {
+        pMacro->setFileName(e.getMacro()->getFileName());
+    }
 
     if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
     {
index 5869b83..2343f4d 100644 (file)
@@ -40,6 +40,9 @@ GATEWAY_CXX_SOURCES = \
     sci_gateway/cpp/sci_covWrite.cpp \
     sci_gateway/cpp/sci_covStop.cpp \
     sci_gateway/cpp/sci_covMerge.cpp \
+    sci_gateway/cpp/sci_profileGetInfo.cpp \
+    sci_gateway/cpp/sci_profileEnable.cpp \
+    sci_gateway/cpp/sci_profileDisable.cpp \
     sci_gateway/cpp/coverage_gw.cpp
 
 libscicoverage_la_CPPFLAGS = \
index 9d987e1..9864702 100644 (file)
@@ -199,6 +199,9 @@ am__objects_2 = sci_gateway/cpp/libscicoverage_la-sci_covStart.lo \
        sci_gateway/cpp/libscicoverage_la-sci_covWrite.lo \
        sci_gateway/cpp/libscicoverage_la-sci_covStop.lo \
        sci_gateway/cpp/libscicoverage_la-sci_covMerge.lo \
+       sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo \
+       sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo \
+       sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo \
        sci_gateway/cpp/libscicoverage_la-coverage_gw.lo
 am_libscicoverage_la_OBJECTS = $(am__objects_2)
 libscicoverage_la_OBJECTS = $(am_libscicoverage_la_OBJECTS)
@@ -664,6 +667,9 @@ GATEWAY_CXX_SOURCES = \
     sci_gateway/cpp/sci_covWrite.cpp \
     sci_gateway/cpp/sci_covStop.cpp \
     sci_gateway/cpp/sci_covMerge.cpp \
+    sci_gateway/cpp/sci_profileGetInfo.cpp \
+    sci_gateway/cpp/sci_profileEnable.cpp \
+    sci_gateway/cpp/sci_profileDisable.cpp \
     sci_gateway/cpp/coverage_gw.cpp
 
 libscicoverage_la_CPPFLAGS = \
@@ -832,6 +838,15 @@ sci_gateway/cpp/libscicoverage_la-sci_covStop.lo:  \
 sci_gateway/cpp/libscicoverage_la-sci_covMerge.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
+sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo:  \
+       sci_gateway/cpp/$(am__dirstamp) \
+       sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
+sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo:  \
+       sci_gateway/cpp/$(am__dirstamp) \
+       sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
+sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo:  \
+       sci_gateway/cpp/$(am__dirstamp) \
+       sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
 sci_gateway/cpp/libscicoverage_la-coverage_gw.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
@@ -854,6 +869,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_covStart.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_covStop.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_covWrite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileDisable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileEnable.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileGetInfo.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicoverage_algo_la-CodePrinterVisitor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicoverage_algo_la-CovHTMLCodePrinter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/$(DEPDIR)/libscicoverage_algo_la-CoverMacroInfo.Plo@am__quote@
@@ -971,6 +989,27 @@ sci_gateway/cpp/libscicoverage_la-sci_covMerge.lo: sci_gateway/cpp/sci_covMerge.
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicoverage_la-sci_covMerge.lo `test -f 'sci_gateway/cpp/sci_covMerge.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_covMerge.cpp
 
+sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo: sci_gateway/cpp/sci_profileGetInfo.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileGetInfo.Tpo -c -o sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo `test -f 'sci_gateway/cpp/sci_profileGetInfo.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileGetInfo.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileGetInfo.Tpo sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileGetInfo.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_profileGetInfo.cpp' object='sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicoverage_la-sci_profileGetInfo.lo `test -f 'sci_gateway/cpp/sci_profileGetInfo.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileGetInfo.cpp
+
+sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo: sci_gateway/cpp/sci_profileEnable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileEnable.Tpo -c -o sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo `test -f 'sci_gateway/cpp/sci_profileEnable.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileEnable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileEnable.Tpo sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileEnable.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_profileEnable.cpp' object='sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicoverage_la-sci_profileEnable.lo `test -f 'sci_gateway/cpp/sci_profileEnable.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileEnable.cpp
+
+sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo: sci_gateway/cpp/sci_profileDisable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileDisable.Tpo -c -o sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo `test -f 'sci_gateway/cpp/sci_profileDisable.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileDisable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileDisable.Tpo sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-sci_profileDisable.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_profileDisable.cpp' object='sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicoverage_la-sci_profileDisable.lo `test -f 'sci_gateway/cpp/sci_profileDisable.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_profileDisable.cpp
+
 sci_gateway/cpp/libscicoverage_la-coverage_gw.lo: sci_gateway/cpp/coverage_gw.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicoverage_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicoverage_la-coverage_gw.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-coverage_gw.Tpo -c -o sci_gateway/cpp/libscicoverage_la-coverage_gw.lo `test -f 'sci_gateway/cpp/coverage_gw.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/coverage_gw.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-coverage_gw.Tpo sci_gateway/cpp/$(DEPDIR)/libscicoverage_la-coverage_gw.Plo
index f7854c7..9234005 100644 (file)
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.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="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{B150E4A2-2EC1-4BE0-B416-95CFEB13E2FF}</ProjectGuid>
-    <RootNamespace>coverage</RootNamespace>
-    <Keyword>Win32Proj</Keyword>
-    <ProjectName>coverage</ProjectName>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>MultiByte</CharacterSet>
-    <WholeProgramOptimization>false</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>MultiByte</CharacterSet>
-    <WholeProgramOptimization>false</WholeProgramOptimization>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <CharacterSet>MultiByte</CharacterSet>
-    <PlatformToolset>v141</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup>
-    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
-    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)$(Configuration)\</IntDir>
-    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-    </ClCompile>
-    <PreLinkEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreLinkEvent>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>
-      <TargetMachine>MachineX86</TargetMachine>
-      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-    </Link>
-    <PreBuildEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <ClCompile>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-    </ClCompile>
-    <PreLinkEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreLinkEvent>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-    </Link>
-    <PreBuildEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>false</WholeProgramOptimization>
-      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <StringPooling>true</StringPooling>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <PreLinkEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreLinkEvent>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>
-      <TargetMachine>MachineX86</TargetMachine>
-      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-    </Link>
-    <PreBuildEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <Midl>
-      <TargetEnvironment>X64</TargetEnvironment>
-    </Midl>
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>false</WholeProgramOptimization>
-      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <StringPooling>true</StringPooling>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <PreLinkEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreLinkEvent>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Windows</SubSystem>
-      <OptimizeReferences>true</OptimizeReferences>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>
-      <TargetMachine>MachineX64</TargetMachine>
-      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>
-      <RandomizedBaseAddress>false</RandomizedBaseAddress>
-    </Link>
-    <PreBuildEvent>
-      <Message>
-      </Message>
-      <Command>
-      </Command>
-    </PreBuildEvent>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="sci_gateway\cpp\coverage_gw.cpp" />
-    <ClCompile Include="sci_gateway\cpp\sci_covMerge.cpp" />
-    <ClCompile Include="sci_gateway\cpp\sci_covStart.cpp" />
-    <ClCompile Include="sci_gateway\cpp\sci_covStop.cpp" />
-    <ClCompile Include="sci_gateway\cpp\sci_covWrite.cpp" />
-    <ClCompile Include="src\cpp\CodePrinterVisitor.cpp" />
-    <ClCompile Include="src\cpp\CoverMacroInfo.cpp" />
-    <ClCompile Include="src\cpp\CoverModule.cpp" />
-    <ClCompile Include="src\cpp\CoverModule_interface.cpp" />
-    <ClCompile Include="src\cpp\CoverResult.cpp" />
-    <ClCompile Include="src\cpp\CovHTMLCodePrinter.cpp" />
-    <ClCompile Include="src\cpp\InstrumentVisitor.cpp" />
-    <ClCompile Include="src\cpp\URLEncoder.cpp" />
-    <ClCompile Include="src\c\DllmainCoverage.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="coverage.rc" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="includes\CodePrinter.hxx" />
-    <ClInclude Include="includes\CodePrinterVisitor.hxx" />
-    <ClInclude Include="includes\Counter.hxx" />
-    <ClInclude Include="includes\CoverAction.hxx" />
-    <ClInclude Include="includes\coverage_gw.hxx" />
-    <ClInclude Include="includes\CoverMacroInfo.hxx" />
-    <ClInclude Include="includes\CoverModule.hxx" />
-    <ClInclude Include="includes\CoverModule_interface.h" />
-    <ClInclude Include="includes\CoverResult.hxx" />
-    <ClInclude Include="includes\cover_tools.hxx" />
-    <ClInclude Include="includes\CovHTMLCodePrinter.hxx" />
-    <ClInclude Include="includes\dynlib_coverage.h" />
-    <ClInclude Include="includes\InstrumentVisitor.hxx" />
-    <ClInclude Include="includes\MacroLoc.hxx" />
-    <ClInclude Include="includes\URLEncoder.hxx" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ast\ast.vcxproj">
-      <Project>{0d3fa25b-8116-44ec-a45e-260789daa3d9}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\core\src\c\core.vcxproj">
-      <Project>{c6e2bc17-34d8-46e4-85f3-6293cb21adcd}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\fileio\fileio.vcxproj">
-      <Project>{4fc72d4a-80ee-4b1a-8724-0201c1a35621}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\localization\src\localization.vcxproj">
-      <Project>{ecffeb0c-1eda-45ee-9a10-b18143852e17}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\output_stream\src\c\output_stream.vcxproj">
-      <Project>{a5911cd7-f8e8-440c-a23e-4843a0636f3a}</Project>
-    </ProjectReference>
-    <ProjectReference Include="..\string\src\c\string.vcxproj">
-      <Project>{8d45767a-9b03-4905-97f6-d2f3f79141ea}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Library Include="..\..\bin\libintl.lib" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{B150E4A2-2EC1-4BE0-B416-95CFEB13E2FF}</ProjectGuid>\r
+    <RootNamespace>coverage</RootNamespace>\r
+    <Keyword>Win32Proj</Keyword>\r
+    <ProjectName>coverage</ProjectName>\r
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>false</WholeProgramOptimization>\r
+    <PlatformToolset>v141</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <PlatformToolset>v141</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>false</WholeProgramOptimization>\r
+    <PlatformToolset>v141</PlatformToolset>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+    <PlatformToolset>v141</PlatformToolset>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup>\r
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\</OutDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)$(Configuration)\</IntDir>\r
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
+  </PropertyGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <WarningLevel>Level3</WarningLevel>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;_DEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
+      <WarningLevel>Level3</WarningLevel>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <SubSystem>Windows</SubSystem>\r
+      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
+      <WholeProgramOptimization>false</WholeProgramOptimization>\r
+      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>\r
+      <GenerateDebugInformation>false</GenerateDebugInformation>\r
+      <SubSystem>Windows</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>\r
+      <TargetMachine>MachineX86</TargetMachine>\r
+      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <Midl>\r
+      <TargetEnvironment>X64</TargetEnvironment>\r
+    </Midl>\r
+    <ClCompile>\r
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
+      <WholeProgramOptimization>false</WholeProgramOptimization>\r
+      <AdditionalIncludeDirectories>includes;../../libs/intl;../../libs/libxml2;..\threads\includes;..\ast\includes\types;..\ast\includes\ast;..\ast\includes\analysis;..\ast\includes\exps;..\ast\includes\operations;..\ast\includes\symbol;..\ast\includes\system_env;..\ast\includes\parse;../core/includes;../localization/includes;../dynamic_link/includes;../output_stream/includes;../string/includes;../console/includes;../fileio/includes;../fileio/src/c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;FORDLL;NDEBUG;_WINDOWS;_USRDLL;COVERAGE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+      <StringPooling>true</StringPooling>\r
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>\r
+    </ClCompile>\r
+    <PreLinkEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreLinkEvent>\r
+    <Link>\r
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
+      <OutputFile>$(SolutionDir)bin\$(ProjectName).dll</OutputFile>\r
+      <GenerateDebugInformation>false</GenerateDebugInformation>\r
+      <SubSystem>Windows</SubSystem>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <ImportLibrary>$(SolutionDir)bin\$(ProjectName).lib</ImportLibrary>\r
+      <TargetMachine>MachineX64</TargetMachine>\r
+      <CLRUnmanagedCodeCheck>true</CLRUnmanagedCodeCheck>\r
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
+    </Link>\r
+    <PreBuildEvent>\r
+      <Message>\r
+      </Message>\r
+      <Command>\r
+      </Command>\r
+    </PreBuildEvent>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="sci_gateway\cpp\coverage_gw.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_covMerge.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_covStart.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_covStop.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_covWrite.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileDisable.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileEnable.cpp" />\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileGetInfo.cpp" />\r
+    <ClCompile Include="src\cpp\CodePrinterVisitor.cpp" />\r
+    <ClCompile Include="src\cpp\CoverMacroInfo.cpp" />\r
+    <ClCompile Include="src\cpp\CoverModule.cpp" />\r
+    <ClCompile Include="src\cpp\CoverModule_interface.cpp" />\r
+    <ClCompile Include="src\cpp\CoverResult.cpp" />\r
+    <ClCompile Include="src\cpp\CovHTMLCodePrinter.cpp" />\r
+    <ClCompile Include="src\cpp\InstrumentVisitor.cpp" />\r
+    <ClCompile Include="src\cpp\URLEncoder.cpp" />\r
+    <ClCompile Include="src\c\DllmainCoverage.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="coverage.rc" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="includes\CodePrinter.hxx" />\r
+    <ClInclude Include="includes\CodePrinterVisitor.hxx" />\r
+    <ClInclude Include="includes\Counter.hxx" />\r
+    <ClInclude Include="includes\CoverAction.hxx" />\r
+    <ClInclude Include="includes\coverage_gw.hxx" />\r
+    <ClInclude Include="includes\CoverMacroInfo.hxx" />\r
+    <ClInclude Include="includes\CoverModule.hxx" />\r
+    <ClInclude Include="includes\CoverModule_interface.h" />\r
+    <ClInclude Include="includes\CoverResult.hxx" />\r
+    <ClInclude Include="includes\cover_tools.hxx" />\r
+    <ClInclude Include="includes\CovHTMLCodePrinter.hxx" />\r
+    <ClInclude Include="includes\dynlib_coverage.h" />\r
+    <ClInclude Include="includes\InstrumentVisitor.hxx" />\r
+    <ClInclude Include="includes\MacroLoc.hxx" />\r
+    <ClInclude Include="includes\URLEncoder.hxx" />\r
+    <ClInclude Include="sci_gateway\cpp\sci_profile.h" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="..\ast\ast.vcxproj">\r
+      <Project>{0d3fa25b-8116-44ec-a45e-260789daa3d9}</Project>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\core\src\c\core.vcxproj">\r
+      <Project>{c6e2bc17-34d8-46e4-85f3-6293cb21adcd}</Project>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\fileio\fileio.vcxproj">\r
+      <Project>{4fc72d4a-80ee-4b1a-8724-0201c1a35621}</Project>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\localization\src\localization.vcxproj">\r
+      <Project>{ecffeb0c-1eda-45ee-9a10-b18143852e17}</Project>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\output_stream\src\c\output_stream.vcxproj">\r
+      <Project>{a5911cd7-f8e8-440c-a23e-4843a0636f3a}</Project>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\string\src\c\string.vcxproj">\r
+      <Project>{8d45767a-9b03-4905-97f6-d2f3f79141ea}</Project>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Library Include="..\..\bin\libintl.lib" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
 </Project>
\ No newline at end of file
index 2b6fd87..02f6736 100644 (file)
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{d9bf83dd-1baf-45e6-9879-66f1fbeb65c1}</UniqueIdentifier>
-      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{d8fc54b8-74ed-4b17-9b4b-760058549a64}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl</Extensions>
-    </Filter>
-    <Filter Include="localization">
-      <UniqueIdentifier>{8f6c9d89-6623-4ca0-82a0-1b3f216e71bd}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{d3d6fc04-eeff-42c8-9ac1-f20fb74b6b26}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="coverage.rc">
-      <Filter>Resource Files</Filter>
-    </ResourceCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\cpp\CodePrinterVisitor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\CoverMacroInfo.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\CoverModule.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\CoverResult.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\CovHTMLCodePrinter.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\InstrumentVisitor.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\URLEncoder.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="sci_gateway\cpp\sci_covMerge.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="sci_gateway\cpp\sci_covStart.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="sci_gateway\cpp\sci_covStop.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="sci_gateway\cpp\sci_covWrite.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\cpp\CoverModule_interface.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="src\c\DllmainCoverage.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="sci_gateway\cpp\coverage_gw.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="includes\CodePrinter.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CodePrinterVisitor.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\Counter.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\cover_tools.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CoverAction.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\coverage_gw.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CoverMacroInfo.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CoverModule.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CoverResult.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CovHTMLCodePrinter.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\dynlib_coverage.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\InstrumentVisitor.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\MacroLoc.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\URLEncoder.hxx">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="includes\CoverModule_interface.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <Library Include="..\..\bin\libintl.lib" />
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{d9bf83dd-1baf-45e6-9879-66f1fbeb65c1}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{d8fc54b8-74ed-4b17-9b4b-760058549a64}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl</Extensions>\r
+    </Filter>\r
+    <Filter Include="localization">\r
+      <UniqueIdentifier>{8f6c9d89-6623-4ca0-82a0-1b3f216e71bd}</UniqueIdentifier>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{d3d6fc04-eeff-42c8-9ac1-f20fb74b6b26}</UniqueIdentifier>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ResourceCompile Include="coverage.rc">\r
+      <Filter>Resource Files</Filter>\r
+    </ResourceCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="src\cpp\CodePrinterVisitor.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\CoverMacroInfo.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\CoverModule.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\CoverResult.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\CovHTMLCodePrinter.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\InstrumentVisitor.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\URLEncoder.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_covMerge.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_covStart.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_covStop.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_covWrite.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\cpp\CoverModule_interface.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\c\DllmainCoverage.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\coverage_gw.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileDisable.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileEnable.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="sci_gateway\cpp\sci_profileGetInfo.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="includes\CodePrinter.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CodePrinterVisitor.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\Counter.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\cover_tools.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CoverAction.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\coverage_gw.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CoverMacroInfo.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CoverModule.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CoverResult.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CovHTMLCodePrinter.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\dynlib_coverage.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\InstrumentVisitor.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\MacroLoc.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\URLEncoder.hxx">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="includes\CoverModule_interface.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="sci_gateway\cpp\sci_profile.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Library Include="..\..\bin\libintl.lib" />\r
+  </ItemGroup>\r
 </Project>
\ No newline at end of file
index a1f7c2e..6e78b77 100644 (file)
@@ -8,5 +8,5 @@
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-add_help_chapter("Scilab code coverage",SCI+"/modules/coverage/help/en_US",%T);
+add_help_chapter("Scilab code instrumentation",SCI+"/modules/coverage/help/en_US",%T);
 
diff --git a/scilab/modules/coverage/help/en_US/profile.xml b/scilab/modules/coverage/help/en_US/profile.xml
new file mode 100644 (file)
index 0000000..2faad66
--- /dev/null
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="profile">
+    <refnamediv>
+        <refname>profile</refname>
+        <refpurpose>General information about instrumentation capabilities</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>
+          profileEnable(function)
+          profileDisable(function)
+          prof = profileGetInfo()
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>function</term>
+                <listitem>
+                    <para>A Scilab function.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>prof</term>
+                <listitem>
+                    <para>The execution information of <literal>function</literal>.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            These commands are used to profile a specific function within Scilab and get some execution information as Scilab values for further manipulation. Any Scilab function could be instrumented and function informations (static and after execution) are generated for each instrumented function independently. For more information on the <literal>prof</literal> value, see <link linkend="profileGetInfo">profileGetInfo</link>.
+        </para>
+        <para>
+            The commands are used to setup and retrieve execution information. As the instrumentation information are accessible within Scilab you could define specific computation to report these numbers.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Basic example</title>
+        <programlisting role="example"><![CDATA[
+// Function to be profiled
+function x=foo(n)
+  if n > 0 then
+    x = 0;
+    for k = 1:n
+      s = svd(rand(n, n));
+      x = x + s(1);
+    end
+  else
+    x = [];
+  end
+endfunction
+
+// Enables the profiling of the function
+profileEnable(foo)
+
+// Executes the function
+foo(200);
+
+// Returns the function profiling results
+prof = profileGetInfo()
+    ]]></programlisting>
+    </refsection>
+    <refsection>
+        <title>Basic example with a Scilab function</title>
+        <programlisting role="example"><![CDATA[
+profileEnable(isempty)                 // instrument isempty()
+
+isempty(1)                             // execute the function
+
+prof = profileGetInfo()                // retrieve execution information
+
+profileDisable(isempty)                // de-instrument isempty()
+    ]]></programlisting>
+    </refsection>
+    <refsection>
+        <title>Display the 5th most executed lines</title>
+        <programlisting role="example"><![CDATA[
+// instrument and execute as before
+profileEnable(isempty);
+for i=1:1e5; isempty(i); end
+prof = profileGetInfo();
+profileDisable(isempty);
+
+// retrieve the function text
+txt = mgetl(part(prof.FunctionTable.FileName, 1:($-3)) + "sci");
+txt = txt(prof.FunctionTable.FirstLine:$);
+
+// sort per execution time and display the corresponding lines
+[B, k] = gsort(prof.LineCoverage(1)(:,2));
+[string(k(1:5)) string(prof.LineCoverage(1)(k(1:5),2)), txt(k(1:5))]
+    ]]></programlisting>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="profileEnable">profileEnable</link>
+            </member>
+            <member>
+                <link linkend="profileDisable">profileDisable</link>
+            </member>
+            <member>
+                <link linkend="profileGetInfo">profileGetInfo</link>
+            </member>
+        </simplelist>
+    </refsection>
+</refentry>
+
diff --git a/scilab/modules/coverage/help/en_US/profileDisable.xml b/scilab/modules/coverage/help/en_US/profileDisable.xml
new file mode 100644 (file)
index 0000000..35046f6
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="profileDisable">
+    <refnamediv>
+        <refname>profileDisable</refname>
+        <refpurpose>Remove instrumentation from a function, a library or remove all instrumentation</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>
+          profileDisable()
+          profileDisable(function)
+          profileDisable(library)
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>function</term>
+                <listitem>
+                    <para>A Scilab function.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>library</term>
+                <listitem>
+                    <para>A Scilab library.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            This command is used to remove instrumentation from functions and discard all existing information.
+        </para>
+        <para>
+            A function or library could also be passed as an argument to only de-instrument and remove some specific functions.
+        </para>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="profile">profile</link>
+            </member>
+            <member>
+                <link linkend="profileDisable">profileEnable</link>
+            </member>
+            <member>
+                <link linkend="profileGetInfo">profileGetInfo</link>
+            </member>
+        </simplelist>
+    </refsection>
+</refentry>
+
diff --git a/scilab/modules/coverage/help/en_US/profileEnable.xml b/scilab/modules/coverage/help/en_US/profileEnable.xml
new file mode 100644 (file)
index 0000000..688b375
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="profileEnable">
+    <refnamediv>
+        <refname>profileEnable</refname>
+        <refpurpose>Add instrumentation to a function, a library or all available functions</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>
+          profileEnable(function)
+          profileEnable(library)
+          profileEnable()
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>function</term>
+                <listitem>
+                    <para>A Scilab function.</para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>library</term>
+                <listitem>
+                    <para>A Scilab library.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            This command is used to add instrumentation to functions with execution counters incremented on a future function call. Each Scilab statement is instrumented independently by both an independent counter and a timer.
+        </para>
+        <para>
+            A library could also be instrumented to handle all of its functions.
+        </para>
+        <para>
+            Without argument, this command instrument all loaded libraries.
+        </para>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="profile">profile</link>
+            </member>
+            <member>
+                <link linkend="profileDisable">profileDisable</link>
+            </member>
+            <member>
+                <link linkend="profileGetInfo">profileGetInfo</link>
+            </member>
+        </simplelist>
+    </refsection>
+</refentry>
+
diff --git a/scilab/modules/coverage/help/en_US/profileGetInfo.xml b/scilab/modules/coverage/help/en_US/profileGetInfo.xml
new file mode 100644 (file)
index 0000000..827de14
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="profileGetInfo">
+    <refnamediv>
+        <refname>profileGetInfo</refname>
+        <refpurpose>Retrieve instrumentation information as a Scilab value</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>
+          prof = profileGetInfo()
+        </synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>prof</term>
+                <listitem>
+                    <para>A Scilab <literal>ProfilerStatistics</literal> tlist with fields :
+            <code>FunctionTable</code> containing functions description, <code>FunctionCoverage</code> containing functions runtime statistics and <code>LineCoverage</code> containing line coverage per function.</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+            This command retrieve the profiled information as a Scilab data-structure which contains function information, function statistics and line coverage.
+        </para>
+        <para>The tlist <literal>ProfilerStatistics</literal> contains:
+        <variablelist>
+        <varlistentry><term>FunctionTable</term><listitem><para>a struct of profiled functions information containing:
+        <variablelist>
+                   <varlistentry><term>FunctionName</term><listitem><para>the function name.</para></listitem></varlistentry>
+                   <varlistentry><term>FileName</term><listitem><para>the macro <literal>.bin</literal> file used to defined the function.</para></listitem></varlistentry>
+                       <varlistentry><term>FirstLine</term><listitem><para>the number of the first executed line of the macro.</para></listitem></varlistentry>
+                       <varlistentry><term>LibraryName</term><listitem><para>the library name (with its lib suffix) containing the function.</para></listitem></varlistentry>
+                       <varlistentry><term>ParentIndex</term><listitem><para>index to the parent function for inner functions.</para></listitem></varlistentry>
+        </variablelist></para></listitem></varlistentry>
+               
+               <varlistentry><term>FunctionCoverage</term><listitem><para>a struct of profiled functions information containing:
+        <variablelist>
+                   <varlistentry><term>NumCalls</term><listitem><para>the number of call to this function.</para></listitem></varlistentry>
+               <varlistentry><term>TotalTime</term><listitem><para>the time spent in seconds within this function.</para></listitem></varlistentry>
+               <varlistentry><term>InstructionsCount</term><listitem><para>a vector <code>2xN</code> of <code>uint64</code>, where <code>N</code> is the executed lines count, containing the number of executed instructions and the number of non-executed instructions.</para></listitem></varlistentry>
+               <varlistentry><term>BranchesCount</term><listitem><para>a vector <code>2xN</code> of <code>uint64</code>, where <code>N</code> is the executed lines count, containing the number of executed branches and the number of non-executed branches.</para></listitem></varlistentry>
+               <varlistentry><term>PathsCount</term><listitem><para>a vector <code>1xN</code> of <code>uint64</code>, where <code>N</code> is the executed lines count, containing the number of executed paths.</para></listitem></varlistentry>
+        </variablelist></para></listitem></varlistentry>
+    <varlistentry><term>LineCoverage</term><listitem><para>a list of <code>M</code> vectors of <code>double</code>, where <code>M</code> the number of instrumented functions, storing execution counters per function with:
+        <variablelist>
+                   <varlistentry><term>LineCoverage(i)(1,j)</term><listitem><para>the number of times the line <literal>j</literal> of the function <literal>j</literal> has been executed or containing <literal>-1</literal> if this is not an executable line.</para></listitem></varlistentry>
+                   <varlistentry><term>LineCoverage(i)(2,j)</term><listitem><para>cumulated CPU time [in seconds] spent to execute the line <literal>j</literal> of the function <literal>j</literal>.</para></listitem></varlistentry>
+        </variablelist></para></listitem></varlistentry></variablelist></para>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="profile">profile</link>
+            </member>
+            <member>
+                <link linkend="profileEnable">profileEnable</link>
+            </member>
+            <member>
+                <link linkend="profileDisable">profileDisable</link>
+            </member>
+        </simplelist>
+    </refsection>
+</refentry>
+
index 61a78fa..162163e 100644 (file)
 #include <chrono>
 
 #include "allexp.hxx"
-#include "allvar.hxx"
 #include "alltypes.hxx"
+#include "allvar.hxx"
+
+#include "MacroLoc.hxx"
 
 namespace coverage
 {
@@ -32,12 +34,11 @@ class Counter
     uint64_t cumTime;
     std::chrono::steady_clock::time_point start;
     bool isRunning;
-    types::Macro * macro;
-    ast::Exp * e;
-
-public:
+    types::Macro* macro;
+    ast::Exp* e;
 
-    Counter(types::Macro * _macro, ast::Exp * _e) : counter(0), cumTime(0), macro(_macro), e(_e), isRunning(false) { }
+  public:
+    Counter(types::Macro* _macro, ast::Exp* _e) : counter(0), cumTime(0), macro(_macro), e(_e), isRunning(false) {}
 
     inline void inc()
     {
@@ -49,22 +50,22 @@ public:
         return counter;
     }
 
-    inline types::Macro * getMacro()
+    inline types::Macro* getMacro()
     {
         return macro;
     }
 
-    inline ast::Exp * getExp()
+    inline ast::Exp* getExp()
     {
         return e;
     }
 
-    inline types::Macro * getMacro() const
+    inline types::Macro* getMacro() const
     {
         return macro;
     }
 
-    inline ast::Exp * getExp() const
+    inline ast::Exp* getExp() const
     {
         return e;
     }
@@ -94,9 +95,8 @@ class CallCounter
 {
     uint64_t counter;
 
-public:
-
-    CallCounter() : counter(0) { }
+  public:
+    CallCounter() : counter(0) {}
 
     inline void inc()
     {
@@ -114,6 +114,73 @@ public:
     }
 };
 
+struct CounterPredicate
+{
+    struct by_file_and_location
+    {
+        bool operator()(const Location& o1, const Location& o2) const
+        {
+            return o1.first_line < o2.first_line || (o1.first_line == o2.first_line && o2.last_line < o1.last_line);
+        };
+
+        bool operator()(const Counter& o1, const Counter& o2) const
+        {
+            bool file = o1.getMacro()->getFileName() < o2.getMacro()->getFileName();
+            if (!file && o1.getMacro()->getFileName() == o2.getMacro()->getFileName())
+            {
+                const Location& l1 = o1.getExp()->getLocation();
+                const Location& l2 = o2.getExp()->getLocation();
+                return this->operator()(l1, l2);
+            }
+            return file;
+        };
+
+        bool operator()(types::Macro* o1, const Counter& o2) const
+        {
+            bool file = o1->getFileName() < o2.getMacro()->getFileName();
+            if (!file && o1->getFileName() == o2.getMacro()->getFileName())
+            {
+                const Location& l1 = o1->getBody()->getLocation();
+                const Location& l2 = o2.getExp()->getLocation();
+                return this->operator()(l1, l2);
+            }
+
+            return file;
+        };
+
+        bool operator()(const Counter& o1, types::Macro* o2) const
+        {
+            bool file = o1.getMacro()->getFileName() < o2->getFileName();
+            if (!file && o1.getMacro()->getFileName() == o2->getFileName())
+            {
+                const Location& l1 = o1.getExp()->getLocation();
+                const Location& l2 = o2->getBody()->getLocation();
+                return this->operator()(l1, l2);
+            }
+
+            return file;
+        };
+
+        bool operator()(const Counter& o1, const MacroLoc& o2) const
+        {
+            if (o1.getMacro()->getName() == o2.name)
+            {
+                return this->operator()(o1.getExp()->getLocation(), o2.loc);
+            }
+            return o1.getMacro()->getName() < o2.name;
+        };
+
+        bool operator()(const MacroLoc& o1, const Counter& o2) const
+        {
+            if (o1.name == o2.getMacro()->getName())
+            {
+                return this->operator()(o1.loc, o2.getExp()->getLocation());
+            }
+            return o1.name < o2.getMacro()->getName();
+        };
+    };
+};
+
 } // namespace coverage
 
 #endif // __COUNTER_HXX__
index 6938078..cc0aa90 100644 (file)
 
 #include <cstring>
 #include <iostream>
-#include <string>
-#include <memory>
 #include <map>
+#include <memory>
+#include <string>
 #include <tuple>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
 
 #include "Counter.hxx"
-#include "InstrumentVisitor.hxx"
 #include "CoverMacroInfo.hxx"
 #include "CoverResult.hxx"
+#include "InstrumentVisitor.hxx"
 #include "MacroLoc.hxx"
-#include "dynlib_coverage.h"
 #include "UTF8.hxx"
+#include "dynlib_coverage.h"
 
 namespace coverage
 {
@@ -41,11 +41,11 @@ class COVERAGE_IMPEXP CoverModule
 {
 
     std::vector<Counter> counters;
-    std::unordered_map<types::Callable *, CallCounter> callCounters;
-    std::unordered_map<types::Macro *, CoverMacroInfo> macros;
+    std::unordered_map<types::Callable*, CallCounter> callCounters;
+    std::unordered_map<types::Macro*, CoverMacroInfo> macros;
 
     // { moduleName => functions }
-    std::unordered_multimap<std::wstring, types::Callable *> functions;
+    std::unordered_multimap<std::wstring, types::Callable*> functions;
 
     // { moduleName => { macroFilename => { macroName => CoverResult } } }
     std::unordered_map<std::wstring, std::unordered_map<std::wstring, std::map<MacroLoc, CoverResult>>> results;
@@ -54,38 +54,37 @@ class COVERAGE_IMPEXP CoverModule
 
     InstrumentVisitor visitor;
 
-    static CoverModule * instance;
+    static CoverModule* instance;
 
-    CoverModule(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods);
-    CoverModule(const std::vector<std::wstring> & moduleNames);
+    CoverModule(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods);
+    CoverModule(const std::vector<std::wstring>& moduleNames);
     CoverModule();
 
     ~CoverModule();
 
-public:
-
-    inline static CoverModule * createInstance(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods)
+  public:
+    inline static CoverModule* createInstance(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods)
     {
         delete instance;
         instance = new CoverModule(paths_mods);
         return instance;
     }
 
-    inline static CoverModule * createInstance(const std::vector<std::wstring> & moduleNames)
+    inline static CoverModule* createInstance(const std::vector<std::wstring>& moduleNames)
     {
         delete instance;
         instance = new CoverModule(moduleNames);
         return instance;
     }
 
-    inline static CoverModule * createInstance()
+    inline static CoverModule* createInstance()
     {
         delete instance;
         instance = new CoverModule();
         return instance;
     }
 
-    inline static CoverModule * getInstance()
+    inline static CoverModule* getInstance()
     {
         return instance;
     }
@@ -96,22 +95,22 @@ public:
         instance = nullptr;
     }
 
-    void add(types::Macro * macro, ast::Exp * e);
-    void invoke(types::Callable * f);
+    void add(types::Macro* macro, ast::Exp* e);
+    void invoke(types::Callable* f);
     void invoke(const uint64_t id);
     void print();
     void collect();
-    void toHTML(const std::wstring & outputDir);
-    void toBin(std::fstream & out) const;
-    void save(const std::wstring & path) const;
-    void load(const std::wstring & path);
+    void toHTML(const std::wstring& outputDir);
+    void toBin(std::fstream& out) const;
+    void save(const std::wstring& path) const;
+    void load(const std::wstring& path);
 
-    void fromBin(std::fstream & in);
-    static void fromBin(CoverModule & cm, std::fstream & in);
-    static void merge(const std::vector<std::wstring> & paths, const std::wstring & out);
-    static void toHTML(const std::wstring & inBin, const std::wstring & outDir);
+    void fromBin(std::fstream& in);
+    static void fromBin(CoverModule& cm, std::fstream& in);
+    static void merge(const std::vector<std::wstring>& paths, const std::wstring& out);
+    static void toHTML(const std::wstring& inBin, const std::wstring& outDir);
 
-    inline bool isCovered(types::Callable * f) const
+    inline bool isCovered(types::Callable* f) const
     {
         return callCounters.find(f) != callCounters.end();
     }
@@ -126,7 +125,7 @@ public:
         counters[id - 2].stopChrono();
     }
 
-    inline static void invoke(const ast::Exp & e)
+    inline static void invoke(const ast::Exp& e)
     {
         if (instance && e.getCoverId())
         {
@@ -134,7 +133,7 @@ public:
         }
     }
 
-    inline static void invokeAndStartChrono(const ast::Exp & e)
+    inline static void invokeAndStartChrono(const ast::Exp& e)
     {
         if (instance && e.getCoverId())
         {
@@ -143,7 +142,7 @@ public:
         }
     }
 
-    inline static void startChrono(const ast::Exp & e)
+    inline static void startChrono(const ast::Exp& e)
     {
         if (instance && e.getCoverId())
         {
@@ -151,7 +150,7 @@ public:
         }
     }
 
-    inline static void stopChrono(const ast::Exp & e)
+    inline static void stopChrono(const ast::Exp& e)
     {
         if (instance && e.getCoverId())
         {
@@ -159,30 +158,30 @@ public:
         }
     }
 
-    inline static void write(std::fstream & out, const std::wstring & str)
+    inline static void write(std::fstream& out, const std::wstring& str)
     {
         const std::string _str = scilab::UTF8::toUTF8(str);
-        uint32_t n = _str.size();
-        out.write((char *)&n, sizeof(uint32_t));
+        uint32_t n = static_cast<uint32_t>(_str.size());
+        out.write((char*)&n, sizeof(uint32_t));
         out.write(_str.c_str(), sizeof(char) * n);
     }
 
-    inline static void write(std::fstream & out, const uint64_t n)
+    inline static void write(std::fstream& out, const uint64_t n)
     {
-        out.write((char *)&n, sizeof(uint64_t));
+        out.write((char*)&n, sizeof(uint64_t));
     }
 
-    inline static void write(std::fstream & out, const int32_t n)
+    inline static void write(std::fstream& out, const int32_t n)
     {
-        out.write((char *)&n, sizeof(int32_t));
+        out.write((char*)&n, sizeof(int32_t));
     }
 
-    inline static void write(std::fstream & out, const bool n)
+    inline static void write(std::fstream& out, const bool n)
     {
-        out.write((char *)&n, sizeof(bool));
+        out.write((char*)&n, sizeof(bool));
     }
 
-    inline static void write(std::fstream & out, const Location & loc)
+    inline static void write(std::fstream& out, const Location& loc)
     {
         write(out, loc.first_line);
         write(out, loc.first_column);
@@ -190,14 +189,14 @@ public:
         write(out, loc.last_column);
     }
 
-    inline static std::wstring readWstring(std::fstream & in)
+    inline static std::wstring readWstring(std::fstream& in)
     {
         uint32_t n;
         in.read((char*)&n, sizeof(uint32_t));
-        char * buf = new char[n + 1];
+        char* buf = new char[n + 1];
         buf[n] = '\0';
         in.read(buf, n * sizeof(char));
-        wchar_t * wstr = to_wide_string(buf);
+        wchar_t* wstr = to_wide_string(buf);
         std::wstring str(wstr);
         delete[] buf;
         FREE(wstr);
@@ -205,31 +204,31 @@ public:
         return str;
     }
 
-    inline static uint64_t readUint64_t(std::fstream & in)
+    inline static uint64_t readUint64_t(std::fstream& in)
     {
         uint64_t n;
-        in.read((char *)&n, sizeof(uint64_t));
+        in.read((char*)&n, sizeof(uint64_t));
 
         return n;
     }
 
-    inline static int32_t readInt32_t(std::fstream & in)
+    inline static int32_t readInt32_t(std::fstream& in)
     {
         int32_t n;
-        in.read((char *)&n, sizeof(int32_t));
+        in.read((char*)&n, sizeof(int32_t));
 
         return n;
     }
 
-    inline static bool readBool(std::fstream & in)
+    inline static bool readBool(std::fstream& in)
     {
         bool n;
-        in.read((char *)&n, sizeof(bool));
+        in.read((char*)&n, sizeof(bool));
 
         return n;
     }
 
-    inline static Location readLocation(std::fstream & in)
+    inline static Location readLocation(std::fstream& in)
     {
         const int32_t fl = readInt32_t(in);
         const int32_t fc = readInt32_t(in);
@@ -239,51 +238,87 @@ public:
         return Location(fl, ll, fc, lc);
     }
 
+    void instrumentSingleMacro(const std::wstring& module, const std::wstring& path, types::Macro* macro, bool instrumentInners);
+    inline const std::vector<Counter>& getCounters() const
+    {
+        return counters;
+    }
+    inline std::vector<Counter>& getCounters()
+    {
+        return counters;
+    }
+    std::vector<Counter>::const_iterator lower_bound(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last, types::Macro* value);
+    std::vector<Counter>::const_iterator upper_bound(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last, types::Macro* value);
+    inline const std::unordered_map<types::Callable*, CallCounter>& getCallCounters() const
+    {
+        return callCounters;
+    }
+    inline std::unordered_map<types::Callable*, CallCounter>& getCallCounters()
+    {
+        return callCounters;
+    }
+    inline const std::unordered_map<types::Macro*, CoverMacroInfo>& getMacros() const
+    {
+        return macros;
+    }
+    inline std::unordered_map<types::Macro*, CoverMacroInfo>& getMacros()
+    {
+        return macros;
+    }
+    inline const std::unordered_multimap<std::wstring, types::Callable*>& getFunctions() const
+    {
+        return functions;
+    }
+    inline std::unordered_multimap<std::wstring, types::Callable*>& getFunctions()
+    {
+        return functions;
+    }
+    inline const std::unordered_map<std::wstring, std::unordered_map<std::wstring, std::map<MacroLoc, CoverResult>>>& getResults() const
+    {
+        return results;
+    }
 
-    void instrumentSingleMacro(const std::wstring & module, const std::wstring & path, types::Macro * macro, bool instrumentInners);
-
-private:
-
-    void getMacros(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods);
-    void getMacros(const std::wstring & path, const std::wstring & module);
-    void getMacrosFromDir(const std::wstring & path, const std::wstring & module);
-    void getBuiltins(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods);
-    void instrumentMacro(const std::wstring & module, const std::wstring & path, types::Macro * macro);
-
-    static bool getStringFromXPath(char * filePath, const char * xpquery, std::unordered_set<std::wstring> & set);
-    static void copyDataFiles(const std::wstring & outputDir);
-    static void copyFile(const std::wstring & inDir, const std::wstring & outDir, const std::wstring & filename);
-    static void writeFile(const std::wostringstream & out, const std::wstring & outputDir, const std::wstring & filename);
-    static ast::Exp * getTree(const std::wstring & path);
-    static const std::wstring getName(const std::wstring & path);
-    static void writeMacroHTMLReport(ast::Exp * tree, const std::wstring & filename, const std::wstring & path, const std::wstring & moduleName, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir);
-    static bool writeMacroHTMLReport(const std::wstring & path, const std::wstring & moduleName, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir);
-    static void writeMacroHTMLReport(types::Macro * macro, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir);
-    static std::wstring encodeFilename(const std::wstring & name);
-    static const std::vector<std::pair<std::wstring, std::wstring>> getModule(const std::vector<std::wstring> & moduleNames);
-
-    typedef std::tuple<const CoverResult *, const std::wstring *, const std::wstring *, const Location *> __Res1;
+  private:
+    void getMacros(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods);
+    void getMacros(const std::wstring& path, const std::wstring& module);
+    void getMacrosFromDir(const std::wstring& path, const std::wstring& module);
+    void getBuiltins(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods);
+    void instrumentMacro(const std::wstring& module, const std::wstring& path, types::Macro* macro);
+
+    void collect(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last);
+    static bool getStringFromXPath(char* filePath, const char* xpquery, std::unordered_set<std::wstring>& set);
+    static void copyDataFiles(const std::wstring& outputDir);
+    static void copyFile(const std::wstring& inDir, const std::wstring& outDir, const std::wstring& filename);
+    static void writeFile(const std::wostringstream& out, const std::wstring& outputDir, const std::wstring& filename);
+    static ast::Exp* getTree(const std::wstring& path);
+    static const std::wstring getName(const std::wstring& path);
+    static void writeMacroHTMLReport(ast::Exp* tree, const std::wstring& filename, const std::wstring& path, const std::wstring& moduleName, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir);
+    static bool writeMacroHTMLReport(const std::wstring& path, const std::wstring& moduleName, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir);
+    static void writeMacroHTMLReport(types::Macro* macro, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir);
+    static std::wstring encodeFilename(const std::wstring& name);
+    static const std::vector<std::pair<std::wstring, std::wstring>> getModule(const std::vector<std::wstring>& moduleNames);
+
+    typedef std::tuple<const CoverResult*, const std::wstring*, const std::wstring*, const Location*> __Res1;
     struct __Compare1
     {
-        inline bool operator()(const __Res1 & l, const __Res1 & r) const
+        inline bool operator()(const __Res1& l, const __Res1& r) const
         {
             return std::get<0>(l)->counter < std::get<0>(r)->counter || (std::get<0>(l)->counter == std::get<0>(r)->counter && (std::get<2>(l) < std::get<2>(r) || (std::get<2>(l) == std::get<2>(r) && std::get<3>(l) < std::get<3>(r))));
         }
     };
-    std::set<__Res1, __Compare1> getOrderedResults(const std::wstring & moduleName) const;
+    std::set<__Res1, __Compare1> getOrderedResults(const std::wstring& moduleName) const;
 
-    typedef std::pair<const std::wstring *, uint64_t> __Res2;
+    typedef std::pair<const std::wstring*, uint64_t> __Res2;
     struct __Compare2
     {
-        inline bool operator()(const __Res2 & l, const __Res2 & r) const
+        inline bool operator()(const __Res2& l, const __Res2& r) const
         {
             return l.second < r.second || (l.second == r.second && *l.first < *r.first);
         }
     };
-    std::set<__Res2, __Compare2> getBuiltinStats(const std::wstring & moduleName) const;
-
-    std::vector<std::pair<types::Callable *, uint64_t>> getFunctionCalls(const std::wstring & moduleName, const bool builtin) const;
+    std::set<__Res2, __Compare2> getBuiltinStats(const std::wstring& moduleName) const;
 
+    std::vector<std::pair<types::Callable*, uint64_t>> getFunctionCalls(const std::wstring& moduleName, const bool builtin) const;
 };
 
 } // namespace coverage
index 08bfd0e..641fb0a 100644 (file)
@@ -148,6 +148,11 @@ public:
         return std::round(x * 1000.) / 1000.;
     }
 
+    inline const std::wstring& getName() const
+    {
+        return name;
+    }
+
     inline const CoverMacroInfo & getInfo() const
     {
         return info;
@@ -155,12 +160,12 @@ public:
 
     inline unsigned int getCovInstrsPercent() const
     {
-        return info.instrsCount ? std::round(100. * (1. - (double)uncoveredInstrs / (double)info.instrsCount)) : 100.;
+        return info.instrsCount ? static_cast<unsigned int>(std::round(100. * (1. - (double)uncoveredInstrs / (double)info.instrsCount))) : 100;
     }
 
     inline unsigned int getCovBranchesPercent() const
     {
-        return info.branchesCount ? std::round(100. * (1. - (double)uncoveredBranches / (double)info.branchesCount)) : 100.;
+        return info.branchesCount ? static_cast<unsigned int>(std::round(100. * (1. - (double)uncoveredBranches / (double)info.branchesCount))) : 100;
     }
 
     inline uint64_t getUncInstrs() const
index 506843c..537c9c7 100644 (file)
@@ -38,6 +38,9 @@ CPP_GATEWAY_PROTOTYPE_EXPORT(sci_covStart, COVERAGE_IMPEXP);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_covWrite, COVERAGE_IMPEXP);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_covStop, COVERAGE_IMPEXP);
 CPP_GATEWAY_PROTOTYPE_EXPORT(sci_covMerge, COVERAGE_IMPEXP);
+CPP_GATEWAY_PROTOTYPE_EXPORT(sci_profileEnable, COVERAGE_IMPEXP);
+CPP_GATEWAY_PROTOTYPE_EXPORT(sci_profileDisable, COVERAGE_IMPEXP);
+CPP_GATEWAY_PROTOTYPE_EXPORT(sci_profileGetInfo, COVERAGE_IMPEXP);
 
 #endif /* __COVERAGE_GW_HXX__ */
 
index 7fb2006..04c0a02 100644 (file)
 
 int CoverageModule::Load()
 {
+    // Coverage functionality
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"covStart", &sci_covStart, NULL, MODULE_NAME));
-    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"covWrite", &sci_covWrite, NULL, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(
+                L"covWrite", &sci_covWrite, NULL, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"covStop", &sci_covStop, NULL, MODULE_NAME));
-    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"covMerge", &sci_covMerge, NULL, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(
+                L"covMerge", &sci_covMerge, NULL, MODULE_NAME));
+
+    // Profiling functionnality
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"profileEnable", &sci_profileEnable, NULL, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"profileDisable", &sci_profileDisable, NULL, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(
+        L"profileGetInfo", &sci_profileGetInfo, NULL, MODULE_NAME));
+
     return 1;
 }
diff --git a/scilab/modules/coverage/sci_gateway/cpp/sci_profileDisable.cpp b/scilab/modules/coverage/sci_gateway/cpp/sci_profileDisable.cpp
new file mode 100644 (file)
index 0000000..f031c4a
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2018 - ESI Group - Clement DAVID
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#include <string.h>
+
+#include "CoverModule.hxx"
+
+#include "configvariable.hxx"
+#include "context.hxx"
+#include "coverage_gw.hxx"
+#include "scilabWrite.hxx"
+#include "scilabexception.hxx"
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+extern "C"
+{
+#include "Scierror.h"
+#include "localization.h"
+}
+/*--------------------------------------------------------------------------*/
+using namespace coverage;
+/*--------------------------------------------------------------------------*/
+namespace
+{
+
+void addToProcess(CoverModule* cm, std::vector<types::Macro*>& macros, types::Macro* current)
+{
+    size_t macroLen = macros.size();
+    macros.push_back(current);
+
+    // clean sub functions (defined in the same file)
+    std::vector<types::Macro*> macrosStack{current};
+    for (types::Macro* m = macrosStack.back(); !macrosStack.empty(); m = macrosStack.back(), macrosStack.pop_back())
+    {
+        for (const auto& p : m->getSubMacros())
+        {
+            macros.push_back(p.second);
+            macrosStack.push_back(p.second);
+        }
+    }
+}
+
+} /* namespace */
+/*--------------------------------------------------------------------------*/
+types::Function::ReturnValue sci_profileDisable(types::typed_list& in, int _iRetCount, types::typed_list& out)
+{
+    CoverModule* cm = CoverModule::getInstance();
+       if (cm == nullptr && in.size() == 0)
+       {
+               // nothing to do, OK
+               return types::Function::ReturnValue::OK;
+       }
+
+    if (cm == nullptr)
+    {
+        Scierror(999, _("%s: profile is disabled.\n"), "profileDisable");
+        return types::Function::ReturnValue::Error;
+    }
+
+    // store macros arguments (stored into Library, MacroFile or self)
+    std::vector<types::Macro*> macrosToClean;
+    for (size_t idx = 0; idx < in.size(); idx++)
+    {
+        types::InternalType* pIT = in[idx];
+
+        // case Library
+        if (pIT->isLibrary())
+        {
+            types::Library* lib = pIT->getAs<types::Library>();
+            std::list<std::wstring> lst;
+            int sz = lib->getMacrosName(lst);
+            if (sz > 0)
+            {
+                const std::wstring& selectedModule(lib->get(lst.front())->getModule());
+                for (const std::wstring& macro : lst)
+                {
+                    types::MacroFile* macroFile = lib->get(macro);
+                    addToProcess(cm, macrosToClean, macroFile->getMacro());
+                }
+                continue;
+            }
+        }
+
+        // case MacroFile
+        if (pIT->isMacroFile())
+        {
+            types::MacroFile* macroFile = pIT->getAs<types::MacroFile>();
+            addToProcess(cm, macrosToClean, macroFile->getMacro());
+            continue;
+        }
+
+        // case Macro
+        if (pIT->isMacro())
+        {
+            addToProcess(cm, macrosToClean, pIT->getAs<types::Macro>());
+            continue;
+        }
+
+        // default
+        Scierror(999, _("%s: Wrong type for input argument #%d: A macro or library expected.\n"), "profileGetInfo", idx + 1);
+        return types::Function::ReturnValue::Error;
+    }
+
+    // Full cleanup
+    if (macrosToClean.empty())
+    {
+        coverage::CoverModule::clearInstance();
+        return types::Function::ReturnValue::OK;
+    }
+
+    // Clean only the selected macros and their inners/nested function
+    std::vector<Counter> counters(cm->getCounters());
+    std::sort(counters.begin(), counters.end(), CounterPredicate::by_file_and_location());
+
+    for (types::Macro* m : macrosToClean)
+    {
+        std::vector<Counter>::iterator found = std::lower_bound(counters.begin(), counters.end(), m, CounterPredicate::by_file_and_location());
+        if (found == counters.end())
+        {
+            continue;
+        }
+
+        while (found != counters.end() && found->getExp()->getLocation().last_line <= m->getBody()->getLocation().last_line)
+        {
+            found->getExp()->setCoverId(0);
+
+            found++;
+        }
+
+        cm->getCallCounters().erase(m);
+        m->DecreaseRef();
+
+        // FIXME cleanup previously collected CoverModule maps ?
+    }
+
+    // compact the retained Counters
+    std::vector<Counter>& refCounters = cm->getCounters();
+    uint64_t removed = 0;
+    std::vector<Counter>::iterator erased = std::remove_if(refCounters.begin(), refCounters.end(), [&](Counter& c) -> bool {
+        if (c.getExp()->getCoverId() == 0)
+        {
+            removed++;
+            return true;
+        }
+        else
+        {
+            c.getExp()->setCoverId(c.getExp()->getCoverId() - removed);
+            return false;
+        }
+    });
+    refCounters.erase(erased, refCounters.end());
+
+    return types::Function::OK;
+}
diff --git a/scilab/modules/coverage/sci_gateway/cpp/sci_profileEnable.cpp b/scilab/modules/coverage/sci_gateway/cpp/sci_profileEnable.cpp
new file mode 100644 (file)
index 0000000..0f5978a
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2018 - ESI Group - Clement DAVID
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#include <string.h>
+
+#include "CoverModule.hxx"
+
+#include "coverage_gw.hxx"
+#include "scilabWrite.hxx"
+#include "scilabexception.hxx"
+#include "configvariable.hxx"
+#include "context.hxx"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+extern "C"
+{
+#include "Scierror.h"
+#include "localization.h"
+}
+/*--------------------------------------------------------------------------*/
+using namespace coverage;
+/*--------------------------------------------------------------------------*/
+namespace
+{
+void addToProcess(CoverModule* cm, types::Macro* current)
+{
+    cm->instrumentSingleMacro(current->getModule(), current->getFileName(), current, true);
+};
+} /* namespace */
+/*--------------------------------------------------------------------------*/
+types::Function::ReturnValue sci_profileEnable(types::typed_list &in, int _iRetCount, types::typed_list &out)
+{
+       CoverModule* cm = CoverModule::getInstance();
+    if (cm == nullptr)
+    {
+        cm = CoverModule::createInstance();
+        if (cm == nullptr)
+        {
+                       Scierror(999, _("%s: No more memory.\n"), "profileEnable");
+                       return types::Function::ReturnValue::Error;
+               }
+    }
+
+       // instrument all
+       if (in.empty())
+       {
+        std::list<std::wstring> lst;
+        symbol::Context::getInstance()->getMacrosName(lst);
+
+               for (const std::wstring& macroName : lst)
+               {
+            types::InternalType* pIT = symbol::Context::getInstance()->get(symbol::Symbol(macroName));
+            if (pIT->isMacro())
+                       {
+                               addToProcess(cm, pIT->getAs<types::Macro>());
+                       }
+                       else if (pIT->isMacroFile())
+                       {
+                               types::MacroFile* macroFile = pIT->getAs<types::MacroFile>();
+                               addToProcess(cm, macroFile->getMacro());
+                       }
+               }
+       }
+
+    // handle macros arguments (stored into Library, MacroFile or self)
+    for (size_t idx = 0; idx < in.size(); idx++)
+    {
+        types::InternalType* pIT = in[idx];
+
+        // case Library
+        if (pIT->isLibrary())
+        {
+            types::Library* lib = pIT->getAs<types::Library>();
+            std::list<std::wstring> lst;
+            int sz = lib->getMacrosName(lst);
+            if (sz > 0)
+            {
+                for (const std::wstring& macro : lst)
+                {
+                    types::MacroFile* macroFile = lib->get(macro);
+                    addToProcess(cm, macroFile->getMacro());
+                }
+                continue;
+            }
+        }
+
+        // case MacroFile
+        if (pIT->isMacroFile())
+        {
+            types::MacroFile* macroFile = pIT->getAs<types::MacroFile>();
+            addToProcess(cm, macroFile->getMacro());
+            continue;
+        }
+
+        // case Macro
+        if (pIT->isMacro())
+        {
+            addToProcess(cm, pIT->getAs<types::Macro>());
+            continue;
+        }
+
+        // default
+        Scierror(999, _("%s: Wrong type for input argument #%d: A macro or library expected.\n"), "profileGetInfo", idx + 1);
+        return types::Function::ReturnValue::Error;
+    }
+
+    return types::Function::OK;
+}
diff --git a/scilab/modules/coverage/sci_gateway/cpp/sci_profileGetInfo.cpp b/scilab/modules/coverage/sci_gateway/cpp/sci_profileGetInfo.cpp
new file mode 100644 (file)
index 0000000..f34c2c6
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2018 - ESI Group - Clement DAVID
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
+ *
+ */
+
+#include <string.h>
+
+#include "CoverModule.hxx"
+
+#include "configvariable.hxx"
+#include "context.hxx"
+#include "coverage_gw.hxx"
+#include "double.hxx"
+#include "int.hxx"
+#include "scilabWrite.hxx"
+#include "scilabexception.hxx"
+#include "string.hxx"
+#include "struct.hxx"
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+extern "C"
+{
+#include "Scierror.h"
+#include "localization.h"
+}
+
+/*--------------------------------------------------------------------------*/
+using namespace coverage;
+/*--------------------------------------------------------------------------*/
+namespace
+{
+
+bool is_nested_function(const std::map<std::wstring, std::pair<int, int>>& fileDescription, const std::map<std::wstring, std::pair<int, int>>::const_iterator& found, types::Macro* macro)
+{
+    if (found != fileDescription.end() && found->first == macro->getFileName())
+    {
+        return macro->getLastLine() < found->second.second;
+    }
+    return false;
+}
+
+bool is_sub_function(const std::map<std::wstring, std::pair<int, int>>& fileDescription, const std::map<std::wstring, std::pair<int, int>>::const_iterator& found, types::Macro* macro)
+{
+    if (found != fileDescription.end() && found->first == macro->getFileName())
+    {
+        return macro->getLastLine() > found->second.second;
+    }
+    return false;
+}
+
+void populateFunctionTable(types::Struct* functionTable, const std::map<std::wstring, std::pair<int, int>>& fileDescription, types::Macro* macro)
+{
+    // first call
+    if (functionTable->getSize() == 0)
+    {
+        types::SingleStruct* functionTableStruct = new types::SingleStruct();
+
+        int i = 0;
+        auto& fields = functionTableStruct->getFields();
+        auto& data = functionTableStruct->getData();
+
+        fields.insert({L"FunctionName", i++});
+        data.push_back(new types::String(macro->getName().c_str()));
+
+        fields.insert({L"FileName", i++});
+        data.push_back(new types::String(macro->getFileName().c_str()));
+
+        fields.insert({L"FirstLine", i++});
+        data.push_back(new types::Double(macro->getFirstLine()));
+
+        fields.insert({L"LibraryName", i++});
+        data.push_back(new types::String(macro->getModule().c_str()));
+
+        fields.insert({L"ParentIndex", i++});
+        data.push_back(new types::Double(0));
+
+        functionTable->resize(1, 1);
+        functionTable->set(0, 0, functionTableStruct);
+        return;
+    }
+
+    // append some information to an existing types::SingleStruct
+    int i = 0;
+    auto& fields = functionTable->get(0, 0)->getFields();
+    auto& data = functionTable->get(0, 0)->getData();
+
+    const auto& found = fileDescription.lower_bound(macro->getFileName());
+    int previousSize = data[0]->getAs<types::String>()->getSize();
+
+    types::String* functionName = data[i++]->getAs<types::String>();
+    functionName->resize(previousSize + 1, 1);
+    functionName->set(previousSize, 0, macro->getName().c_str());
+
+    types::String* fileName = data[i++]->getAs<types::String>();
+    fileName->resize(previousSize + 1, 1);
+    fileName->set(previousSize, 0, macro->getFileName().c_str());
+
+    types::Double* firstLine = data[i++]->getAs<types::Double>();
+    firstLine->resize(previousSize + 1, 1);
+    if (is_nested_function(fileDescription, found, macro))
+    {
+        firstLine->set(previousSize, 0, found->second.first);
+    }
+    else
+    {
+        firstLine->set(previousSize, 0, macro->getFirstLine());
+    }
+
+    types::String* libraryName = data[i++]->getAs<types::String>();
+    libraryName->resize(previousSize + 1, 1);
+    libraryName->set(previousSize, 0, macro->getModule().c_str());
+
+    types::Double* parentIndex = data[i++]->getAs<types::Double>();
+    parentIndex->resize(previousSize + 1, 1);
+    if (is_nested_function(fileDescription, found, macro))
+    {
+        for (int i = 0; i < fileName->getSize() - 1; i++)
+        {
+            bool sameFileName = wcscmp(fileName->get(i), macro->getFileName().c_str()) == 0;
+            bool samefirstLine = firstLine->get(i) == found->second.first;
+            if (sameFileName && samefirstLine)
+            {
+                parentIndex->set(previousSize, 0, i + 1);
+                break;
+            }
+        }
+    }
+    else
+    {
+        parentIndex->set(previousSize, 0, 0);
+    }
+
+}
+
+void populateFunctionCoverage(types::Struct* functionCoverage, CoverModule* cm, types::Macro* macro)
+{
+    const CoverResult empty = CoverResult(L"", CoverMacroInfo(L"", L"", 0, 0, 0));
+
+    // retrieve the function coverage information
+    const auto& results = cm->getResults();
+    const CoverResult* coverResultPtr = nullptr;
+    const auto& map1 = results.find(macro->getModule());
+    if (map1 != results.end())
+    {
+        const auto& map2 = map1->second.find(macro->getFileName());
+        if (map2 != map1->second.end())
+        {
+            MacroLoc ml(macro->getName(), macro->getBody()->getLocation());
+            const auto& found = map2->second.find(ml);
+            if (found != map2->second.end())
+            {
+                coverResultPtr = &(found->second);
+            }
+        }
+    }
+    if (coverResultPtr == nullptr)
+    {
+        coverResultPtr = &empty;
+    }
+    const CoverResult& result = *coverResultPtr;
+
+    // first call
+    if (functionCoverage->getSize() == 0)
+    {
+        types::SingleStruct* functionCoverageStruct = new types::SingleStruct();
+
+        int i = 0;
+        auto& fields = functionCoverageStruct->getFields();
+        auto& data = functionCoverageStruct->getData();
+
+        fields.insert({L"NumCalls", i++});
+        data.push_back(new types::UInt64(result.getCounter()));
+
+        fields.insert({L"TotalTime", i++});
+        data.push_back(new types::Double(std::pow(10, std::log10(result.getNanoTime()) - 9)));
+
+        fields.insert({L"InstructionsCount", i++});
+        types::UInt64* instrsCount = new types::UInt64(1, 2);
+        instrsCount->set(0, 0, result.getInfo().instrsCount);
+        instrsCount->set(0, 1, result.getUncInstrs());
+        data.push_back(instrsCount);
+
+        fields.insert({L"BranchesCount", i++});
+        types::UInt64* branchesCount = new types::UInt64(1, 2);
+        branchesCount->set(0, 0, result.getInfo().branchesCount);
+        branchesCount->set(0, 1, result.getUncBranches());
+        data.push_back(branchesCount);
+
+        fields.insert({L"PathsCount", i++});
+        data.push_back(new types::UInt64(result.getInfo().pathsCount));
+
+        functionCoverage->resize(1, 1);
+        functionCoverage->set(0, 0, functionCoverageStruct);
+        return;
+    }
+
+    // append some information to an existing types::SingleStruct
+    int i = 0;
+    auto& fields = functionCoverage->get(0, 0)->getFields();
+    auto& data = functionCoverage->get(0, 0)->getData();
+
+    int previousSize = data[0]->getAs<types::String>()->getSize();
+
+    types::UInt64* numCalls = data[i++]->getAs<types::UInt64>();
+    numCalls->resize(previousSize + 1, 1);
+    numCalls->set(previousSize, 0, result.getCounter());
+
+    types::Double* totalTime = data[i++]->getAs<types::Double>();
+    totalTime->resize(previousSize + 1, 1);
+    totalTime->set(previousSize, 0, std::pow(10, std::log10(result.getNanoTime()) - 9));
+
+    types::UInt64* instrsCount = data[i++]->getAs<types::UInt64>();
+    instrsCount->resize(previousSize + 1, 2);
+    instrsCount->set(previousSize, 0, result.getInfo().instrsCount);
+    instrsCount->set(previousSize, 1, result.getUncInstrs());
+
+    types::UInt64* branchesCount = data[i++]->getAs<types::UInt64>();
+    branchesCount->resize(previousSize + 1, 2);
+    branchesCount->set(previousSize, 0, result.getInfo().branchesCount);
+    branchesCount->set(previousSize, 1, result.getUncBranches());
+
+    types::UInt64* pathsCount = data[i++]->getAs<types::UInt64>();
+    pathsCount->resize(previousSize + 1, 1);
+    pathsCount->set(previousSize, 0, result.getInfo().pathsCount);
+}
+
+void populateLineCoverage(types::List* lineCoverage, std::map<std::wstring, std::pair<int, int>>& fileDescription, std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last)
+{
+    types::Macro* macro = first->getMacro();
+
+    // firstLine and lastLine are stored into the fileDescription set
+    //
+    // As the macros are in order of their definitions, nested-functions are
+    // populated after their parent functions. The initial (eg. from parent
+    // functions) firstLine and lastLine are re-used for their nesteds.
+    int macroFirstLine = macro->getFirstLine();
+    int macroLastLine = macro->getLastLine();
+    const auto& found = fileDescription.lower_bound(macro->getFileName());
+    if (is_nested_function(fileDescription, found, macro))
+    {
+        // nested functions are merged within their parents
+        macroFirstLine = found->second.first;
+        macroLastLine = found->second.second;
+    }
+    else if (is_sub_function(fileDescription, found, macro))
+    {
+        // sub functions are independant
+        found->second.first = macroFirstLine;
+        found->second.second = macroLastLine;
+    }
+    else
+    {
+        // this is a note parsed function, store for later use
+        fileDescription.insert(found, {macro->getFileName(), std::make_pair(macroFirstLine, macroLastLine)});
+    }
+
+    // initialize with "not executable" flags
+    types::Double* coverage = new types::Double(macroLastLine - macroFirstLine + 1, 2);
+    for (int i = 0; i < coverage->getRows(); i++)
+    {
+        coverage->set(i, 0, -1.);
+        coverage->set(i, 1, 0.);
+    }
+
+    // store counters
+    for (std::vector<Counter>::const_iterator it = first; it < last; ++it)
+    {
+        // filter out function declaration timings, this is not clear for the end-user
+        if (it->getExp()->isFunctionDec())
+        {
+            continue;
+        }
+
+        const Location& line = it->getExp()->getLocation();
+        // multi-lines Exp (such as IfExp) only display its counter on its first
+        // line (with the if keyword).
+        //
+        // Multiple Exp might be present on the same line, in that case the usual
+        // way to report is to have the counter of the first Exp and the
+        // cumulated time displayed.
+        int l = line.first_line;
+        if (coverage->get(l - macroFirstLine, 0) <= 0.)
+        {
+            coverage->set(l - macroFirstLine, 0, double(it->get()));
+        }
+        double seconds = std::pow(10, std::log10(it->getNanoTime()) - 9);
+        coverage->set(l - macroFirstLine, 1, coverage->get(l - macroFirstLine, 1) + seconds);
+    }
+
+    lineCoverage->set(lineCoverage->getSize(), coverage);
+}
+
+void populate(CoverModule* cm, types::Struct* functionTable, types::Struct* functionCoverage, types::List* lineCoverage)
+{
+    const std::vector<Counter>& counters = cm->getCounters();
+
+    // store firstLine, lastLine information per filename
+    std::map<std::wstring, std::pair<int, int>> fileDescription;
+
+    // at least, one macro is instrumented
+    std::vector<Counter>::const_iterator first = counters.begin();
+    std::vector<Counter>::const_iterator last = cm->upper_bound(first, counters.end(), first->getMacro());
+
+    populateFunctionTable(functionTable, fileDescription, first->getMacro());
+    populateFunctionCoverage(functionCoverage, cm, first->getMacro());
+    populateLineCoverage(lineCoverage, fileDescription, first, last);
+
+    while (last != counters.end())
+    {
+        first = last;
+        last = cm->upper_bound(first, counters.end(), first->getMacro());
+
+        populateFunctionTable(functionTable, fileDescription, first->getMacro());
+        populateFunctionCoverage(functionCoverage, cm, first->getMacro());
+        populateLineCoverage(lineCoverage, fileDescription, first, last);
+    }
+}
+
+} /* namespace */
+/*--------------------------------------------------------------------------*/
+types::Function::ReturnValue sci_profileGetInfo(types::typed_list& in, int _iRetCount, types::typed_list& out)
+{
+    if (in.size() != 0)
+    {
+        Scierror(999, _("%s: Wrong number of input arguments: %d expected.\n"), "profileGetInfo", 0);
+        return types::Function::ReturnValue::Error;
+    }
+    if (_iRetCount > 1)
+    {
+        Scierror(999, _("%s: Wrong number of output arguments: %d expected.\n"), "profileGetInfo", 1);
+        return types::Function::ReturnValue::Error;
+    }
+
+    CoverModule* cm = CoverModule::getInstance();
+    if (cm == nullptr)
+    {
+        Scierror(999, _("%s: profile is disabled.\n"), "profileGetInfo");
+        return types::Function::ReturnValue::Error;
+    }
+    cm->collect();
+
+    types::Struct* functionTable = new types::Struct();
+    types::Struct* functionCoverage = new types::Struct();
+    types::List* lineCoverage = new types::List();
+
+    if (!cm->getCounters().empty())
+    {
+        populate(cm, functionTable, functionCoverage, lineCoverage);
+    }
+
+    int i = 0;
+    types::String* header = new types::String(4, 1);
+    header->set(i++, "ProfilerStatistics");
+    header->set(i++, "FunctionTable");
+    header->set(i++, "FunctionCoverage");
+    header->set(i++, "LineCoverage");
+
+    types::TList* tlist = new types::TList();
+    tlist->append(header);
+    tlist->append(functionTable);
+    tlist->append(functionCoverage);
+    tlist->append(lineCoverage);
+    out.push_back(tlist);
+
+    return types::Function::OK;
+}
index 6da30a4..6e748ec 100644 (file)
 #pragma comment(lib, "../../bin/libxml2.lib")
 #endif
 
-#include <libxml/xpath.h>
 #include <libxml/xmlreader.h>
+#include <libxml/xpath.h>
 
-#include "CoverModule.hxx"
 #include "CovHTMLCodePrinter.hxx"
-#include "cover_tools.hxx"
+#include "CoverModule.hxx"
 #include "allexp.hxx"
-#include "allvar.hxx"
 #include "alltypes.hxx"
+#include "allvar.hxx"
+#include "cover_tools.hxx"
 #include "coverage_instance.hxx"
 
 extern "C"
 {
-#include "sci_malloc.h"
-#include "os_string.h"
-#include "expandPathVariable.h"
-#include "createdirectory.h"
 #include "copyfile.h"
-#include "isdir.h"
+#include "createdirectory.h"
+#include "expandPathVariable.h"
 #include "findfiles.h"
 #include "freeArrayOfString.h"
+#include "isdir.h"
+#include "os_string.h"
+#include "sci_malloc.h"
 }
 
 #ifdef _MSC_VER
@@ -49,16 +49,16 @@ extern "C"
 namespace coverage
 {
 
-CoverModule * CoverModule::instance = nullptr;
+CoverModule* CoverModule::instance = nullptr;
 
-CoverModule::CoverModule(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods) : visitor(*this)
+CoverModule::CoverModule(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods) : visitor(*this)
 {
     getMacros(paths_mods);
     getBuiltins(paths_mods);
     ast::CoverageInstance::setCoverage(this);
 }
 
-CoverModule::CoverModule(const std::vector<std::wstring> & moduleNames) : CoverModule(getModule(moduleNames))
+CoverModule::CoverModule(const std::vector<std::wstring>& moduleNames) : CoverModule(getModule(moduleNames))
 {
     ast::CoverageInstance::setCoverage(this);
 }
@@ -70,11 +70,11 @@ CoverModule::CoverModule() : visitor(*this)
 
 CoverModule::~CoverModule()
 {
-    for (auto & counter : counters)
+    for (auto& counter : counters)
     {
         counter.getExp()->setCoverId(0);
     }
-    for (auto & p : callCounters)
+    for (auto& p : callCounters)
     {
         p.first->DecreaseRef();
         //p.first->killMe();
@@ -83,17 +83,17 @@ CoverModule::~CoverModule()
     ast::CoverageInstance::setCoverage(nullptr);
 }
 
-const std::vector<std::pair<std::wstring, std::wstring>> CoverModule::getModule(const std::vector<std::wstring> & moduleNames)
+const std::vector<std::pair<std::wstring, std::wstring>> CoverModule::getModule(const std::vector<std::wstring>& moduleNames)
 {
     const std::wstring _path = std::wstring(L"SCI") + DIR_SEPARATORW + L"modules" + DIR_SEPARATORW;
-    wchar_t * __path = expandPathVariableW((wchar_t *)_path.c_str());
+    wchar_t* __path = expandPathVariableW((wchar_t*)_path.c_str());
     const std::wstring path(__path);
     FREE(__path);
 
     if (moduleNames.size() == 1 && moduleNames.back() == L"all")
     {
         int size = -1;
-        wchar_t ** files = findfilesW(path.c_str(), DEFAULT_FILESPEC, &size, FALSE);
+        wchar_t** files = findfilesW(path.c_str(), DEFAULT_FILESPEC, &size, FALSE);
         if (size > 0 && files)
         {
             std::vector<std::pair<std::wstring, std::wstring>> paths;
@@ -109,12 +109,12 @@ const std::vector<std::pair<std::wstring, std::wstring>> CoverModule::getModule(
             return paths;
         }
 
-        return{};
+        return {};
     }
     else
     {
         std::vector<std::pair<std::wstring, std::wstring>> paths;
-        for (const auto & name : moduleNames)
+        for (const auto& name : moduleNames)
         {
             paths.emplace_back(path + name, name);
         }
@@ -122,16 +122,16 @@ const std::vector<std::pair<std::wstring, std::wstring>> CoverModule::getModule(
     }
 }
 
-void CoverModule::getMacros(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods)
+void CoverModule::getMacros(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods)
 {
-    for (const auto & p : paths_mods)
+    for (const auto& p : paths_mods)
     {
         std::wstring _path = p.first + DIR_SEPARATORW + L"macros";
         getMacrosFromDir(_path, p.second);
     }
 }
 
-void CoverModule::getMacrosFromDir(const std::wstring & path, const std::wstring & module)
+void CoverModule::getMacrosFromDir(const std::wstring& path, const std::wstring& module)
 {
     std::wstring _path = path + DIR_SEPARATORW + L"lib";
     getMacros(_path, module);
@@ -139,7 +139,7 @@ void CoverModule::getMacrosFromDir(const std::wstring & path, const std::wstring
     int size = -1;
     _path = path + DIR_SEPARATORW;
 
-    wchar_t ** files = findfilesW(_path.c_str(), DEFAULT_FILESPEC, &size, FALSE);
+    wchar_t** files = findfilesW(_path.c_str(), DEFAULT_FILESPEC, &size, FALSE);
     if (size > 0 && files)
     {
         for (int i = 0; i < size; ++i)
@@ -154,26 +154,26 @@ void CoverModule::getMacrosFromDir(const std::wstring & path, const std::wstring
     }
 }
 
-void CoverModule::getMacros(const std::wstring & path, const std::wstring & module)
+void CoverModule::getMacros(const std::wstring& path, const std::wstring& module)
 {
     std::unordered_set<std::wstring> _macros;
-    wchar_t * pwstPathLib = expandPathVariableW((wchar_t *)path.c_str());
+    wchar_t* pwstPathLib = expandPathVariableW((wchar_t*)path.c_str());
     std::wstring libPath(pwstPathLib);
     FREE(pwstPathLib);
 
-    char * libFile = wide_string_to_UTF8(libPath.c_str());
+    char* libFile = wide_string_to_UTF8(libPath.c_str());
 
     if (getStringFromXPath(libFile, "//scilablib/macro/@name", _macros))
     {
-        for (const auto & name : _macros)
+        for (const auto& name : _macros)
         {
-            types::InternalType * pIT = symbol::Context::getInstance()->get(symbol::Symbol(name));
+            types::InternalType* pIT = symbol::Context::getInstance()->get(symbol::Symbol(name));
             if (pIT && pIT->isMacroFile())
             {
-                types::MacroFile * pMF = static_cast<types::MacroFile *>(pIT);
-                if (types::Macro * macro = pMF->getMacro())
+                types::MacroFile* pMF = static_cast<types::MacroFile*>(pIT);
+                if (types::Macro* macro = pMF->getMacro())
                 {
-                    const std::wstring & file = pMF->getPath();
+                    const std::wstring& file = pMF->getPath();
                     std::size_t pos = file.find_last_of(L'.');
                     if (pos != std::string::npos)
                     {
@@ -190,11 +190,11 @@ void CoverModule::getMacros(const std::wstring & path, const std::wstring & modu
     FREE(libFile);
 }
 
-void CoverModule::getBuiltins(const std::vector<std::pair<std::wstring, std::wstring>> & paths_mods)
+void CoverModule::getBuiltins(const std::vector<std::pair<std::wstring, std::wstring>>& paths_mods)
 {
-    for (const auto & p : paths_mods)
+    for (const auto& p : paths_mods)
     {
-        std::list<types::Callable *> lst;
+        std::list<types::Callable*> lst;
         if (symbol::Context::getInstance()->getFunctionList(lst, p.second))
         {
             for (auto pCall : lst)
@@ -202,7 +202,7 @@ void CoverModule::getBuiltins(const std::vector<std::pair<std::wstring, std::wst
                 if (pCall->isFunction())
                 {
                     pCall->IncreaseRef();
-                    functions.emplace(p.second, static_cast<types::Function *>(pCall));
+                    functions.emplace(p.second, static_cast<types::Function*>(pCall));
                     callCounters.emplace(pCall, CallCounter());
                 }
             }
@@ -210,10 +210,10 @@ void CoverModule::getBuiltins(const std::vector<std::pair<std::wstring, std::wst
     }
 }
 
-void CoverModule::instrumentMacro(const std::wstring & module, const std::wstring & path, types::Macro * macro)
+void CoverModule::instrumentMacro(const std::wstring& module, const std::wstring& path, types::Macro* macro)
 {
-    const std::map<symbol::Variable *, types::Macro *> & submacros = macro->getSubMacros();
-    for (const auto & p : submacros)
+    const std::map<symbol::Variable*, types::Macro*>& submacros = macro->getSubMacros();
+    for (const auto& p : submacros)
     {
         instrumentSingleMacro(module, path, p.second, true);
     }
@@ -221,19 +221,19 @@ void CoverModule::instrumentMacro(const std::wstring & module, const std::wstrin
     instrumentSingleMacro(module, path, macro, true);
 }
 
-void CoverModule::instrumentSingleMacro(const std::wstring & module, const std::wstring & path, types::Macro * macro, bool instrumentInners)
+void CoverModule::instrumentSingleMacro(const std::wstring& module, const std::wstring& path, types::Macro* macro, bool instrumentInners)
 {
     macro->IncreaseRef();
     visitor.setMacro(macro);
     macro->getBody()->accept(visitor);
     macros.emplace(macro, CoverMacroInfo(module, path, visitor.getInstrsCount(), visitor.getBranchesCount(), visitor.getPathsCount()));
-    callCounters.emplace(static_cast<types::Callable *>(macro), CallCounter());
-    functions.emplace(module, static_cast<types::Callable *>(macro));
+    callCounters.emplace(static_cast<types::Callable*>(macro), CallCounter());
+    functions.emplace(module, static_cast<types::Callable*>(macro));
 
     if (instrumentInners)
     {
         // We make a copy since the call to instrumentSingleMacro will modify visitor.getInnerMacros()
-        const std::vector<types::Macro *> inners = visitor.getInnerMacros();
+        const std::vector<types::Macro*> inners = visitor.getInnerMacros();
         for (auto inner : inners)
         {
             instrumentSingleMacro(module, path, inner, true);
@@ -241,7 +241,7 @@ void CoverModule::instrumentSingleMacro(const std::wstring & module, const std::
     }
 }
 
-void CoverModule::add(types::Macro * macro, ast::Exp * e)
+void CoverModule::add(types::Macro* macro, ast::Exp* e)
 {
     if (e)
     {
@@ -251,11 +251,11 @@ void CoverModule::add(types::Macro * macro, ast::Exp * e)
     }
 }
 
-void CoverModule::invoke(types::Callable * f)
+void CoverModule::invoke(types::Callable* f)
 {
     if (f->isMacroFile())
     {
-        f = static_cast<types::MacroFile *>(f)->getMacro();
+        f = static_cast<types::MacroFile*>(f)->getMacro();
     }
     auto i = callCounters.find(f);
     if (i != callCounters.end())
@@ -269,7 +269,7 @@ void CoverModule::invoke(const uint64_t id)
     counters[id - 2].inc();
 }
 
-bool CoverModule::getStringFromXPath(char * filePath, const char * xpquery, std::unordered_set<std::wstring> & set)
+bool CoverModule::getStringFromXPath(char* filePath, const char* xpquery, std::unordered_set<std::wstring>& set)
 {
     xmlDocPtr doc = xmlReadFile(filePath, "utf-8", XML_PARSE_NOWARNING);
     if (!doc)
@@ -277,23 +277,23 @@ bool CoverModule::getStringFromXPath(char * filePath, const char * xpquery, std:
         return false;
     }
 
-    if (!doc->encoding || stricmp((const char *)doc->encoding, "utf-8") != 0)
+    if (!doc->encoding || stricmp((const char*)doc->encoding, "utf-8") != 0)
     {
         xmlFreeDoc(doc);
         return false;
     }
 
     xmlXPathContextPtr ctxt = xmlXPathNewContext(doc);
-    xmlXPathObjectPtr xp = xmlXPathEval((const xmlChar *)xpquery, ctxt);
+    xmlXPathObjectPtr xp = xmlXPathEval((const xmlChar*)xpquery, ctxt);
     xmlNodeSetPtr nodeSet = xp->nodesetval;
 
     if (nodeSet)
     {
         for (unsigned int i = 0; i < nodeSet->nodeNr; ++i)
         {
-            const char * content = (const char *)xmlNodeGetContent(nodeSet->nodeTab[i]);
-            wchar_t * ws = to_wide_string(content);
-            xmlFree(const_cast<char *>(content));
+            const char* content = (const char*)xmlNodeGetContent(nodeSet->nodeTab[i]);
+            wchar_t* ws = to_wide_string(content);
+            xmlFree(const_cast<char*>(content));
             set.emplace(ws);
             FREE(ws);
         }
@@ -306,44 +306,45 @@ bool CoverModule::getStringFromXPath(char * filePath, const char * xpquery, std:
     return nodeSet;
 }
 
+std::vector<Counter>::const_iterator CoverModule::lower_bound(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last, types::Macro* value)
+{
+    // binary search could not be performed as the counters are not sorted, linear lookup is OK
+    for (auto it = first; it < last; it++)
+    {
+        if (it->getMacro() == value)
+            return it;
+    }
+
+    return last;
+}
+
+std::vector<Counter>::const_iterator CoverModule::upper_bound(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last, types::Macro* value)
+{
+    // binary search could not be performed as the counters are not sorted, linear lookup is OK
+    for (auto it = lower_bound(first, last, value); it < last; it++)
+    {
+        if (it->getMacro() != value)
+            return it;
+    }
+
+    return last;
+}
+
 void CoverModule::collect()
 {
     if (!counters.empty())
     {
-        std::vector<Counter>::const_iterator b = counters.begin();
-        types::Macro * current = counters.front().getMacro();
-        for (std::vector<Counter>::const_iterator i = b, e = counters.end(); i != e; ++i)
+        std::vector<Counter>::const_iterator first = counters.begin();
+        std::vector<Counter>::const_iterator last = upper_bound(first, counters.end(), first->getMacro());
+        collect(first, last);
+        while (last != counters.end())
         {
-            if (i->getMacro() != current || std::next(i) == e)
-            {
-                const std::wstring & name = current->getName();
-                CoverMacroInfo & info = macros.find(current)->second;
-                const uint64_t counter = callCounters[current].get();
-                auto & map1 = results[info.macroModule];
-                auto & map2 = map1[info.macroFilePath];
-                MacroLoc ml(name, current->getBody()->getLocation());
-                auto j = map2.find(ml);
-                if (j == map2.end())
-                {
-                    CoverResult & result = map2.emplace(ml, CoverResult(name, info)).first->second;
-                    result.setCounter(counter);
-
-                    if (std::next(i) == e)
-                    {
-                        result.populate(b, e);
-                    }
-                    else
-                    {
-                        result.populate(b, i);
-                        b = i;
-                        current = i->getMacro();
-                    }
-                }
-                allCounters[info.macroModule][name] = std::pair<bool, uint64_t>(true, counter);
-            }
+            first = last;
+            last = upper_bound(first, counters.end(), first->getMacro());
+            collect(first, last);
         }
 
-        for (const auto & p : functions)
+        for (const auto& p : functions)
         {
             if (p.second->isFunction())
             {
@@ -353,6 +354,27 @@ void CoverModule::collect()
     }
 }
 
+void CoverModule::collect(const std::vector<Counter>::const_iterator& first, const std::vector<Counter>::const_iterator& last)
+{
+    types::Macro* current = first->getMacro();
+
+    const std::wstring& name = current->getName();
+    CoverMacroInfo& info = macros.find(current)->second;
+    const uint64_t counter = callCounters[current].get();
+    auto& map1 = results[info.macroModule];
+    auto& map2 = map1[info.macroFilePath];
+    MacroLoc ml(name, current->getBody()->getLocation());
+    auto j = map2.find(ml);
+    if (j == map2.end())
+    {
+        CoverResult& result = map2.emplace(ml, CoverResult(name, info)).first->second;
+        result.setCounter(counter);
+
+        result.populate(first, last);
+    }
+    allCounters[info.macroModule][name] = std::pair<bool, uint64_t>(true, counter);
+}
+
 void CoverModule::print()
 {
     /*std::wcerr << L"Builtin calls" << std::endl << tools::getUnderline(L"Builtin calls") << std::endl;
@@ -383,15 +405,15 @@ void CoverModule::print()
     //collect();
 }
 
-void CoverModule::toHTML(const std::wstring & outputDir)
+void CoverModule::toHTML(const std::wstring& outputDir)
 {
     bool nomodules = false;
-    wchar_t * _outputDir = expandPathVariableW((wchar_t *)outputDir.c_str());
+    wchar_t* _outputDir = expandPathVariableW((wchar_t*)outputDir.c_str());
     createdirectoryW(_outputDir);
 
     if (results.size() == 1 && results.begin()->first == L"" && results.begin()->second.size() == 1 && results.begin()->second.begin()->first == L"")
     {
-        for (const auto & p : macros)
+        for (const auto& p : macros)
         {
             writeMacroHTMLReport(p.first, results.begin()->second.begin()->second, _outputDir);
         }
@@ -403,16 +425,16 @@ void CoverModule::toHTML(const std::wstring & outputDir)
         std::map<std::wstring, std::pair<uint64_t, double>> modulesStats;
 
         // We make all the reports for the macros
-        for (auto & p1 : results)
+        for (auto& p1 : results)
         {
-            const std::wstring & moduleName = p1.first;
+            const std::wstring& moduleName = p1.first;
             const std::wstring __outputDir = std::wstring(_outputDir) + DIR_SEPARATORW + moduleName;
-            createdirectoryW((wchar_t *)__outputDir.c_str());
+            createdirectoryW((wchar_t*)__outputDir.c_str());
             uint64_t totalCalls = 0;
             uint64_t totalInstrs = 0;
             uint64_t uncoveredInstrs = 0;
 
-            for (auto & p2 : p1.second)
+            for (auto& p2 : p1.second)
             {
                 writeMacroHTMLReport(p2.first, moduleName, p2.second, __outputDir);
             }
@@ -442,11 +464,11 @@ void CoverModule::toHTML(const std::wstring & outputDir)
                 << L"<div class=\'macros_cell\'><table id=\'table" << tableid << L"\'>\n"
                 << L"<tr class=\'col_name\'><td>Name&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid, 0, false) << L"</td><td>File</td><td>Calls&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid + 1, 2, true) << L"</td><td>Covered&nbsp" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid + 2, 3, false) << L"</td></tr>\n";
 
-            for (const auto & t : getOrderedResults(moduleName))
+            for (const auto& t : getOrderedResults(moduleName))
             {
-                const CoverResult & res = *std::get<0>(t);
-                const std::wstring & macroFilename = *std::get<1>(t);
-                const std::wstring & macroName = *std::get<2>(t);
+                const CoverResult& res = *std::get<0>(t);
+                const std::wstring& macroFilename = *std::get<1>(t);
+                const std::wstring& macroName = *std::get<2>(t);
 
                 totalInstrs += res.getInfo().instrsCount;
                 uncoveredInstrs += res.getUncInstrs();
@@ -489,7 +511,7 @@ void CoverModule::toHTML(const std::wstring & outputDir)
                 << L"<div class=\'builtins_cell\'><table id=\'table" << tableid << L"\'>\n"
                 << L"<tr class=\'col_name\'><td>Name&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid, 0, false) << L"</td><td class=\'col_name\'>Calls&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid + 1, 1, true) << L"</td></tr>\n";
 
-            for (const auto & p : getBuiltinStats(moduleName))
+            for (const auto& p : getBuiltinStats(moduleName))
             {
                 const std::wstring countercls = p.second == 0 ? L"null_stats" : L"stats";
                 const std::wstring trcls = altern ? L"altern1" : L"altern2";
@@ -537,9 +559,9 @@ void CoverModule::toHTML(const std::wstring & outputDir)
             << L"<div class=\'macros_cell\'><table id=\'table" << tableid << L"\'>\n"
             << L"<tr class=\'col_name\'><td>Name&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid, 0, false) << L"</td><td>Builtin calls&nbsp;" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid + 1, 1, true) << L"</td><td>Covered&nbsp" << CovHTMLCodePrinter::getOrderButton(tableid, buttonid + 2, 2, false) << L"</td></tr>\n";
 
-        for (const auto & p : modulesStats)
+        for (const auto& p : modulesStats)
         {
-            const std::wstring & moduleName = p.first;
+            const std::wstring& moduleName = p.first;
             const uint64_t builtinCalls = p.second.first;
             const double percent = p.second.second;
             const std::wstring countercls = builtinCalls ? L"stats" : L"null_stats";
@@ -568,7 +590,7 @@ void CoverModule::toHTML(const std::wstring & outputDir)
     copyDataFiles(outputDir);
 }
 
-void CoverModule::copyDataFiles(const std::wstring & outputDir)
+void CoverModule::copyDataFiles(const std::wstring& outputDir)
 {
     const std::wstring _outputDir = outputDir + DIR_SEPARATORW;
     const std::wstring _inputDir = std::wstring(L"SCI") + DIR_SEPARATORW + L"modules" + DIR_SEPARATORW + L"coverage" + DIR_SEPARATORW + L"data";
@@ -579,18 +601,18 @@ void CoverModule::copyDataFiles(const std::wstring & outputDir)
     copyFile(_inputDir, _outputDir, L"module.js");
 }
 
-void CoverModule::copyFile(const std::wstring & inDir, const std::wstring & outDir, const std::wstring & filename)
+void CoverModule::copyFile(const std::wstring& inDir, const std::wstring& outDir, const std::wstring& filename)
 {
     const std::wstring in = inDir + DIR_SEPARATORW + filename;
     const std::wstring out = outDir + DIR_SEPARATORW + filename;
-    wchar_t * _input = expandPathVariableW((wchar_t *)in.c_str());
-    wchar_t * _output = expandPathVariableW((wchar_t *)out.c_str());
+    wchar_t* _input = expandPathVariableW((wchar_t*)in.c_str());
+    wchar_t* _output = expandPathVariableW((wchar_t*)out.c_str());
     CopyFileFunction(_output, _input);
     FREE(_input);
     FREE(_output);
 }
 
-void CoverModule::writeFile(const std::wostringstream & out, const std::wstring & outputDir, const std::wstring & filename)
+void CoverModule::writeFile(const std::wostringstream& out, const std::wstring& outputDir, const std::wstring& filename)
 {
     const std::string code = scilab::UTF8::toUTF8(out.str().c_str());
     const std::string _filename = scilab::UTF8::toUTF8(outputDir + DIR_SEPARATORW + filename);
@@ -599,20 +621,20 @@ void CoverModule::writeFile(const std::wostringstream & out, const std::wstring
     file.close();
 }
 
-std::set<CoverModule::__Res1, CoverModule::__Compare1> CoverModule::getOrderedResults(const std::wstring & moduleName) const
+std::set<CoverModule::__Res1, CoverModule::__Compare1> CoverModule::getOrderedResults(const std::wstring& moduleName) const
 {
     std::set<__Res1, __Compare1> set;
     auto i = results.find(moduleName);
     if (i != results.end())
     {
-        for (const auto & p : i->second)
+        for (const auto& p : i->second)
         {
-            const std::wstring & macroFilename = p.first;
-            for (const auto & pp : p.second)
+            const std::wstring& macroFilename = p.first;
+            for (const auto& pp : p.second)
             {
-                const std::wstring & macroName = pp.first.name;
-                const Location & macroLoc = pp.first.loc;
-                const CoverResult & res = pp.second;
+                const std::wstring& macroName = pp.first.name;
+                const Location& macroLoc = pp.first.loc;
+                const CoverResult& res = pp.second;
                 set.emplace(__Res1(&res, &macroFilename, &macroName, &macroLoc));
             }
         }
@@ -621,13 +643,13 @@ std::set<CoverModule::__Res1, CoverModule::__Compare1> CoverModule::getOrderedRe
     return set;
 }
 
-std::set<CoverModule::__Res2, CoverModule::__Compare2> CoverModule::getBuiltinStats(const std::wstring & moduleName) const
+std::set<CoverModule::__Res2, CoverModule::__Compare2> CoverModule::getBuiltinStats(const std::wstring& moduleName) const
 {
     std::set<__Res2, __Compare2> set;
     auto i = allCounters.find(moduleName);
     if (i != allCounters.end())
     {
-        for (const auto & p : i->second)
+        for (const auto& p : i->second)
         {
             if (!p.second.first)
             {
@@ -639,27 +661,27 @@ std::set<CoverModule::__Res2, CoverModule::__Compare2> CoverModule::getBuiltinSt
     return set;
 }
 
-std::vector<std::pair<types::Callable *, uint64_t>> CoverModule::getFunctionCalls(const std::wstring & moduleName, const bool builtin) const
+std::vector<std::pair<types::Callable*, uint64_t>> CoverModule::getFunctionCalls(const std::wstring& moduleName, const bool builtin) const
 {
     struct _Res
     {
-        types::Callable * const fptr;
+        types::Callable* const fptr;
         const uint64_t counter;
 
-        _Res(types::Callable * const _fptr, const uint64_t _counter) : fptr(_fptr), counter(_counter) { }
-        inline bool operator<(const _Res & res) const
+        _Res(types::Callable* const _fptr, const uint64_t _counter) : fptr(_fptr), counter(_counter) {}
+        inline bool operator<(const _Res& res) const
         {
             return (counter < res.counter) || (counter == res.counter && fptr->getName() < res.fptr->getName());
         }
     };
     std::set<_Res> set;
-    std::vector<std::pair<types::Callable *, uint64_t>> calls;
+    std::vector<std::pair<types::Callable*, uint64_t>> calls;
     auto range = functions.equal_range(moduleName);
     for (auto fptr = range.first; fptr != range.second; ++fptr)
     {
         if ((builtin && fptr->second->isFunction()) || (!builtin && fptr->second->isMacro()))
         {
-            auto i = callCounters.find(static_cast<types::Callable *>(fptr->second));
+            auto i = callCounters.find(static_cast<types::Callable*>(fptr->second));
             if (i != callCounters.end())
             {
                 set.emplace(fptr->second, i->second.get());
@@ -676,7 +698,7 @@ std::vector<std::pair<types::Callable *, uint64_t>> CoverModule::getFunctionCall
     return calls;
 }
 
-ast::Exp * CoverModule::getTree(const std::wstring & path)
+ast::Exp* CoverModule::getTree(const std::wstring& path)
 {
     if (!path.empty())
     {
@@ -686,12 +708,12 @@ ast::Exp * CoverModule::getTree(const std::wstring & path)
             src.seekg(0, src.end);
             int len = src.tellg();
             src.seekg(0, src.beg);
-            char * buffer = new char[len + 1];
+            char* buffer = new char[len + 1];
             buffer[len] = '\0';
             src.read(buffer, len);
             src.close();
 
-            wchar_t * _wstr = to_wide_string(buffer);
+            wchar_t* _wstr = to_wide_string(buffer);
             delete[] buffer;
             Parser parser;
             parser.parse(_wstr);
@@ -703,7 +725,7 @@ ast::Exp * CoverModule::getTree(const std::wstring & path)
     return nullptr;
 }
 
-const std::wstring CoverModule::getName(const std::wstring & path)
+const std::wstring CoverModule::getName(const std::wstring& path)
 {
     std::size_t pos = path.find_last_of(L'.');
     std::wstring name = path.substr(0, pos);
@@ -715,14 +737,14 @@ const std::wstring CoverModule::getName(const std::wstring & path)
     return name;
 }
 
-void CoverModule::writeMacroHTMLReport(types::Macro * macro, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir)
+void CoverModule::writeMacroHTMLReport(types::Macro* macro, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir)
 {
-    std::list<symbol::Variable *> * in = macro->getInputs();
-    std::list<symbol::Variable *> * out = macro->getOutputs();
-    ast::SeqExp & body = *macro->getBody()->clone();
+    std::list<symbol::Variable*>* in = macro->getInputs();
+    std::list<symbol::Variable*>* out = macro->getOutputs();
+    ast::SeqExp& body = *macro->getBody()->clone();
 
-    ast::exps_t & _in = *new ast::exps_t();
-    ast::exps_t & _out = *new ast::exps_t();
+    ast::exps_t& _in = *new ast::exps_t();
+    ast::exps_t& _out = *new ast::exps_t();
     for (const auto i : *in)
     {
         _in.emplace_back(new ast::SimpleVar(Location(), i->getSymbol()));
@@ -731,12 +753,12 @@ void CoverModule::writeMacroHTMLReport(types::Macro * macro, std::map<MacroLoc,
     {
         _out.emplace_back(new ast::SimpleVar(Location(), o->getSymbol()));
     }
-    ast::FunctionDec * fdec = new ast::FunctionDec(Location(), symbol::Symbol(macro->getName()), *new ast::ArrayListVar(Location(), _in), *new ast::ArrayListVar(Location(), _out), body);
+    ast::FunctionDec* fdec = new ast::FunctionDec(Location(), symbol::Symbol(macro->getName()), *new ast::ArrayListVar(Location(), _in), *new ast::ArrayListVar(Location(), _out), body);
 
     writeMacroHTMLReport(fdec, macro->getName() + L".html", L"", L"", results, outputDir);
 }
 
-void CoverModule::writeMacroHTMLReport(ast::Exp * tree, const std::wstring & filename, const std::wstring & path, const std::wstring & moduleName, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir)
+void CoverModule::writeMacroHTMLReport(ast::Exp* tree, const std::wstring& filename, const std::wstring& path, const std::wstring& moduleName, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir)
 {
     std::wostringstream out;
     std::wstring mod, prev;
@@ -785,7 +807,7 @@ void CoverModule::writeMacroHTMLReport(ast::Exp * tree, const std::wstring & fil
     }
     if (!results.empty())
     {
-        for (const auto & p : results)
+        for (const auto& p : results)
         {
             out << L"<tr><td><div class=\'allmacstats\'>\n";
             CovHTMLCodePrinter::getFunctionStats(out, p.first, p.second);
@@ -812,9 +834,9 @@ void CoverModule::writeMacroHTMLReport(ast::Exp * tree, const std::wstring & fil
     writeFile(out, outputDir, filename);
 }
 
-bool CoverModule::writeMacroHTMLReport(const std::wstring & path, const std::wstring & moduleName, std::map<MacroLoc, CoverResult> & results, const std::wstring & outputDir)
+bool CoverModule::writeMacroHTMLReport(const std::wstring& path, const std::wstring& moduleName, std::map<MacroLoc, CoverResult>& results, const std::wstring& outputDir)
 {
-    if (ast::Exp * tree = getTree(path))
+    if (ast::Exp* tree = getTree(path))
     {
         writeMacroHTMLReport(tree, getName(path) + L".html", path, moduleName, results, outputDir);
         return true;
@@ -823,7 +845,7 @@ bool CoverModule::writeMacroHTMLReport(const std::wstring & path, const std::wst
     return false;
 }
 
-std::wstring CoverModule::encodeFilename(const std::wstring & name)
+std::wstring CoverModule::encodeFilename(const std::wstring& name)
 {
     std::wostringstream wos;
     for (const auto c : name)
@@ -833,7 +855,7 @@ std::wstring CoverModule::encodeFilename(const std::wstring & name)
     return wos.str();
 }
 
-void CoverModule::merge(const std::vector<std::wstring> & paths, const std::wstring & out)
+void CoverModule::merge(const std::vector<std::wstring>& paths, const std::wstring& out)
 {
     CoverModule cm;
     for (const auto path : paths)
@@ -843,14 +865,14 @@ void CoverModule::merge(const std::vector<std::wstring> & paths, const std::wstr
     cm.save(out);
 }
 
-void CoverModule::toHTML(const std::wstring & inBin, const std::wstring & outDir)
+void CoverModule::toHTML(const std::wstring& inBin, const std::wstring& outDir)
 {
     CoverModule cm;
     cm.load(inBin);
     cm.toHTML(outDir);
 }
 
-void CoverModule::save(const std::wstring & path) const
+void CoverModule::save(const std::wstring& path) const
 {
     if (!path.empty())
     {
@@ -863,7 +885,7 @@ void CoverModule::save(const std::wstring & path) const
     }
 }
 
-void CoverModule::load(const std::wstring & path)
+void CoverModule::load(const std::wstring& path)
 {
     if (!path.empty())
     {
@@ -876,19 +898,19 @@ void CoverModule::load(const std::wstring & path)
     }
 }
 
-void CoverModule::toBin(std::fstream & out) const
+void CoverModule::toBin(std::fstream& out) const
 {
     // Save results
     CoverModule::write(out, (uint64_t)results.size());
-    for (const auto & p : results)
+    for (const auto& p : results)
     {
         CoverModule::write(out, p.first);
         CoverModule::write(out, (uint64_t)p.second.size());
-        for (const auto & pp : p.second)
+        for (const auto& pp : p.second)
         {
             CoverModule::write(out, pp.first);
             CoverModule::write(out, (uint64_t)pp.second.size());
-            for (const auto & ppp : pp.second)
+            for (const auto& ppp : pp.second)
             {
                 CoverModule::write(out, ppp.first.name);
                 CoverModule::write(out, ppp.first.loc);
@@ -899,11 +921,11 @@ void CoverModule::toBin(std::fstream & out) const
 
     // Save allcounters
     CoverModule::write(out, (uint64_t)allCounters.size());
-    for (const auto & p : allCounters)
+    for (const auto& p : allCounters)
     {
         CoverModule::write(out, p.first);
         CoverModule::write(out, (uint64_t)p.second.size());
-        for (const auto & pp : p.second)
+        for (const auto& pp : p.second)
         {
             CoverModule::write(out, pp.first);
             CoverModule::write(out, pp.second.first);
@@ -912,12 +934,12 @@ void CoverModule::toBin(std::fstream & out) const
     }
 }
 
-void CoverModule::fromBin(std::fstream & in)
+void CoverModule::fromBin(std::fstream& in)
 {
     fromBin(*this, in);
 }
 
-void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
+void CoverModule::fromBin(CoverModule& cm, std::fstream& in)
 {
     // Load results
     uint64_t size = CoverModule::readUint64_t(in);
@@ -930,7 +952,7 @@ void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
         {
             it = cm.results.emplace(moduleName, std::unordered_map<std::wstring, std::map<MacroLoc, CoverResult>>()).first;
         }
-        auto & map = it->second;
+        auto& map = it->second;
         for (uint64_t j = 0; j < sizee; ++j)
         {
             const std::wstring macroFilename = CoverModule::readWstring(in);
@@ -940,7 +962,7 @@ void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
             {
                 it = map.emplace(macroFilename, std::map<MacroLoc, CoverResult>()).first;
             }
-            auto & mapp = it->second;
+            auto& mapp = it->second;
             for (uint64_t k = 0; k < sizeee; ++k)
             {
                 const std::wstring macroName = CoverModule::readWstring(in);
@@ -970,7 +992,7 @@ void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
         {
             it = cm.allCounters.emplace(moduleName, std::unordered_map<std::wstring, std::pair<bool, uint64_t>>()).first;
         }
-        auto & map = it->second;
+        auto& map = it->second;
         for (uint64_t j = 0; j < sizee; ++j)
         {
             const std::wstring funName = CoverModule::readWstring(in);
@@ -983,7 +1005,7 @@ void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
             }
             else
             {
-                auto & p = it->second;
+                auto& p = it->second;
                 if (p.first == ismacro)
                 {
                     p.second += counter;
@@ -993,4 +1015,4 @@ void CoverModule::fromBin(CoverModule & cm, std::fstream & in)
     }
 }
 
-}
+} // namespace coverage
index b01f78b..c3f95d9 100644 (file)
@@ -52,7 +52,7 @@ void CoverResult::populate(const std::vector<Counter>::const_iterator pos, const
             auto j = branches.find(parent->getLocation());
             if (j == branches.end())
             {
-                branches.emplace(parent->getLocation(), std::vector<uint64_t>(1, i->get()));
+                branches.emplace(parent->getLocation(), std::vector<uint64_t>({i->get(), 0}));
             }
             else
             {
index 9232295..f37d013 100644 (file)
@@ -115,6 +115,7 @@ void InstrumentVisitor::visit(ast::FunctionDec & e)
 
         pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList, static_cast<ast::SeqExp &>(e.getBody()), L"script");
         pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
+        pMacro->setFileName(macro->getFileName());
         //pMacro->setFirstLine(e.getLocation().first_line);
         e.setMacro(pMacro);
     }
diff --git a/scilab/modules/coverage/tests/unit_tests/profileDisable.tst b/scilab/modules/coverage/tests/unit_tests/profileDisable.tst
new file mode 100644 (file)
index 0000000..e4d44ec
--- /dev/null
@@ -0,0 +1,59 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - ESI Group - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+
+// helpers
+
+function simple()
+    2
+endfunction
+
+function with_inner()
+    2
+    function inner()
+        4
+    endfunction
+    6
+endfunction
+
+// API check
+profileEnable(simple)
+profileDisable(simple)
+assert_checkequal(size(profileGetInfo().LineCoverage), 0);
+assert_checkequal(size(profileGetInfo().FunctionCoverage), [0 0]);
+assert_checkequal(size(profileGetInfo().FunctionTable), [0 0]);
+
+profileEnable(with_inner)
+profileDisable(with_inner)
+assert_checkequal(size(profileGetInfo().LineCoverage), 0);
+assert_checkequal(size(profileGetInfo().FunctionCoverage), [0 0]);
+assert_checkequal(size(profileGetInfo().FunctionTable), [0 0]);
+
+profileEnable(iscolumn) // from elementary_functionslib
+profileDisable(iscolumn)
+assert_checkequal(size(profileGetInfo().LineCoverage), 0);
+assert_checkequal(size(profileGetInfo().FunctionCoverage), [0 0]);
+assert_checkequal(size(profileGetInfo().FunctionTable), [0 0]);
+
+profileEnable(whos) // from corelib with sub-macros
+profileDisable(whos)
+assert_checkequal(size(profileGetInfo().LineCoverage), 0);
+assert_checkequal(size(profileGetInfo().FunctionCoverage), [0 0]);
+assert_checkequal(size(profileGetInfo().FunctionTable), [0 0]);
+
+profileEnable(corelib)
+profileDisable(corelib)
+assert_checkequal(size(profileGetInfo().LineCoverage), 0);
+assert_checkequal(size(profileGetInfo().FunctionCoverage), [0 0]);
+assert_checkequal(size(profileGetInfo().FunctionTable), [0 0]);
+
+profileEnable()
+profileDisable()
+assert_checkerror("profileGetInfo", "profileGetInfo: profile is disabled.");
diff --git a/scilab/modules/coverage/tests/unit_tests/profileEnable.tst b/scilab/modules/coverage/tests/unit_tests/profileEnable.tst
new file mode 100644 (file)
index 0000000..21433fa
--- /dev/null
@@ -0,0 +1,65 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - ESI Group - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+
+//
+// nominal check using a user-defined function
+//
+
+function foo()
+    2
+endfunction
+profileEnable(foo)
+
+// Executes the function
+foo();
+
+prof = profileGetInfo();
+assert_checkequal(prof.FunctionTable.FunctionName, "foo");
+assert_checkequal(size(prof.LineCoverage), 1);
+assert_checkequal(prof.LineCoverage(1)(:,1), [-1;1;-1]);
+
+//
+// check with inner functions
+//
+
+function with_inner()
+    2
+    function inner()
+        4
+    endfunction
+    6
+endfunction
+profileEnable(with_inner)
+
+// execute
+with_inner()
+
+prof = profileGetInfo();
+assert_checkequal(prof.FunctionTable.FunctionName, ["foo" ; "with_inner" ; "inner"]);
+
+//
+// check API using Scilab functions
+//
+
+profileEnable(iscolumn) // from elementary_functionslib
+// check that foo, with_inner, inner and iscolumn are instrumented
+prof = profileGetInfo();
+assert_checkequal(prof.FunctionTable.FunctionName, ["foo" ; "with_inner" ; "inner" ; "iscolumn"]);
+
+profileEnable(corelib)
+// check that at least publicly visible function are instrumented (inner functions are not visible)
+assert_checktrue(size(profileGetInfo().LineCoverage) > 4 + size(libraryinfo("corelib"), "*"));
+
+profileEnable()
+// check that more than corelib and elementary_functionslib are instrumented
+assert_checktrue(size(profileGetInfo().LineCoverage) > 4 + size(libraryinfo("corelib"), "*") + size(libraryinfo("elementary_functionslib"), "*"));
+
+profileDisable()
diff --git a/scilab/modules/coverage/tests/unit_tests/profileGetInfo.tst b/scilab/modules/coverage/tests/unit_tests/profileGetInfo.tst
new file mode 100644 (file)
index 0000000..8de1a6d
--- /dev/null
@@ -0,0 +1,128 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - ESI Group - Clement DAVID
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+
+//
+// nominal check using a user-defined function
+//
+
+function foo()
+    2
+endfunction
+profileDisable();
+profileEnable(foo)
+
+prof = profileGetInfo();
+expectedProf = tlist(["ProfilerStatistics" ; "FunctionTable" ; "FunctionCoverage" ; "LineCoverage"], struct(), struct(), list());
+expectedProf.FunctionTable.FunctionName = "foo";
+expectedProf.FunctionTable.FileName = get_absolute_file_path("profileGetInfo.tst")+"profileGetInfo.tst";
+expectedProf.FunctionTable.FirstLine = 34; // FirstLine with test_run headers
+expectedProf.FunctionTable.LibraryName = "script";
+expectedProf.FunctionTable.ParentIndex = [0];
+
+expectedProf.FunctionCoverage.NumCalls = uint64(0);
+expectedProf.FunctionCoverage.TotalTime = 0;
+expectedProf.FunctionCoverage.InstructionsCount = uint64([1 1]);
+expectedProf.FunctionCoverage.BranchesCount = uint64([0 0]);
+expectedProf.FunctionCoverage.PathsCount = uint64(0);
+
+expectedProf.LineCoverage = list([-1 0 ; 0 0 ; -1 0]);
+
+assert_checkequal(prof.FunctionTable, expectedProf.FunctionTable);
+assert_checkequal(prof.FunctionCoverage, expectedProf.FunctionCoverage);
+assert_checkequal(prof.LineCoverage, expectedProf.LineCoverage);
+
+
+//
+// check with inner functions
+//
+
+function with_inner()
+    2
+    function inner()
+        4
+    endfunction
+    6
+endfunction
+profileEnable(with_inner)
+
+prof = profileGetInfo();
+expectedProf = tlist(["ProfilerStatistics" ; "FunctionTable" ; "FunctionCoverage" ; "LineCoverage"], struct(), struct(), list());
+
+expectedProf.FunctionTable.FunctionName = ["foo" ; "with_inner" ; "inner"];
+expectedProf.FunctionTable.FileName = emptystr(3,1) + get_absolute_file_path("profileGetInfo.tst")+"profileGetInfo.tst";
+expectedProf.FunctionTable.FirstLine = [34 ; 65 ; 65];
+expectedProf.FunctionTable.LibraryName = ["script" ; "script" ; "script"];
+expectedProf.FunctionTable.ParentIndex = [0 ; 0 ; 2];
+
+expectedProf.FunctionCoverage.NumCalls = uint64([0 ; 0 ; 0]);
+expectedProf.FunctionCoverage.TotalTime = [0 ; 0 ; 0];
+expectedProf.FunctionCoverage.InstructionsCount = uint64([1 1 ; 3 3 ; 1 1]);
+expectedProf.FunctionCoverage.BranchesCount = uint64([0 0 ; 0 0 ; 0 0]);
+expectedProf.FunctionCoverage.PathsCount = uint64([0 ; 0 ; 0]);
+
+expectedProf.LineCoverage = list()
+expectedProf.LineCoverage(1) = [-1 0 ; 0 0 ; -1 0];
+expectedProf.LineCoverage(2) = [-1 0 ; 0 0 ; -1 0 ; -1 0 ; -1 0 ; 0 0 ; -1 0];
+expectedProf.LineCoverage(3) = [-1 0 ; -1 0 ; -1 0 ; 0 0 ; -1 0 ; -1 0 ; -1 0];
+
+assert_checkequal(prof.FunctionTable, expectedProf.FunctionTable);
+assert_checkequal(prof.FunctionCoverage, expectedProf.FunctionCoverage);
+assert_checkequal(prof.LineCoverage, expectedProf.LineCoverage);
+profileDisable();
+
+//
+// Regular function profiling
+//
+
+profileEnable(iscolumn)
+iscolumn(1);
+prof = profileGetInfo()
+profileDisable();
+
+// assert property list
+assert_checkequal(fieldnames(prof.FunctionTable), ["FunctionName" ; "FileName" ; "FirstLine" ; "LibraryName" ; "ParentIndex"]);
+assert_checkequal(fieldnames(prof.FunctionCoverage), ["NumCalls" ; "TotalTime" ; "InstructionsCount" ; "BranchesCount" ; "PathsCount"]);
+
+// assert basic properties values, properties value that are tightly related to
+// the implementation are not listed on purpose.
+assert_checkequal(prof.FunctionTable.FunctionName, "iscolumn");
+assert_checkequal(part(prof.FunctionTable.FileName, ($-47):$), fullfile("modules", "elementary_functions", "macros", "iscolumn.bin"));
+assert_checkequal(prof.FunctionTable.LibraryName, "elementary_functionslib");
+assert_checkequal(prof.FunctionCoverage.NumCalls, uint64(1));
+
+// Display the executed "real" lines using the source file
+txt = mgetl(part(prof.FunctionTable.FileName, 1:($-3)) + "sci");
+assert_checkequal(size(txt(prof.FunctionTable.FirstLine:$), "r"), size(prof.LineCoverage(1), "r"));
+
+txt = txt(prof.FunctionTable.FirstLine:$);
+assert_checkequal(grep(txt(1), "/^function /", "r"), 1);
+assert_checkequal(txt($), "endfunction");
+
+// check the statistics
+assert_checktrue(sum(prof.LineCoverage(1)(:,1) > 0) <= double(prof.FunctionCoverage.InstructionsCount(1)));
+assert_checktrue(sum(prof.LineCoverage(1)(:,1) == 0) <= double(prof.FunctionCoverage.InstructionsCount(2)));
+
+//
+// Macro with sub-function defined
+//
+
+profileEnable(assert_checkequal)
+assert_checkequal(1, 1);
+prof = profileGetInfo()
+profileDisable();
+
+// there is one bin file containing 1 main function and 2 sub-functions
+assert_checkequal(prof.FunctionTable.FileName(1), prof.FunctionTable.FileName(2));
+assert_checkequal(prof.FunctionTable.FileName(1), prof.FunctionTable.FileName(3));
+assert_checkequal(prof.FunctionTable.FirstLine(1), prof.FunctionTable.FirstLine(2));
+assert_checkequal(prof.FunctionTable.FirstLine(1), prof.FunctionTable.FirstLine(3));
+assert_checkequal(prof.FunctionTable.ParentIndex, [0 ; 1 ; 1]);
+assert_checkequal(prof.FunctionTable.LibraryName, ["assertlib" ; "script" ; "script"]);