Commits

Sepehr Taghdisian committed db72e63 Merge

merge

Comments (0)

Files changed (21)

include/efsw/efsw.h

 #ifndef ESFW_H
 #define ESFW_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if defined(_WIN32)
 	#ifdef EFSW_DYNAMIC
 		// Windows platforms
 		enum efsw_action action,
 		const char* old_filename,
         void* param
+		void* param
 );
 
 #ifdef __cplusplus
 /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option.
 /// For backwards compatibility.
 /// On error returns WatchID with Error type.
-EFSW_API efsw_watchid efsw_addwatch(efsw_watcher watcher, const char* directory, 
+EFSW_API efsw_watchid efsw_addwatch(efsw_watcher watcher, const char* directory,
 	efsw_pfn_fileaction_callback callback_fn, int recursive, void* param);
 
 /// Remove a directory watch. This is a brute force search O(nlogn).
 }
 #endif
 
-
 #endif
-function args_contains( element )
-  for _, value in pairs(_ARGS) do
-    if value == element then
-      return true
-    end
-  end
-  return false
-end
+newoption { trigger = "verbose", description = "Build efsw with verbose mode." }
+newoption { trigger = "strip-symbols", description = "Strip debugging symbols in other file ( only for relwithdbginfo configuration )." }
+
+efsw_major_version	= "1"
+efsw_minor_version	= "0"
+efsw_patch_version	= "0"
+efsw_version		= efsw_major_version .. "." .. efsw_minor_version .. "." .. efsw_patch_version
 
 function string.starts(String,Start)
 	if ( _ACTION ) then
 solution "efsw"
 	location("./make/" .. os.get() .. "/")
 	targetdir("./bin")
-	configurations { "debug", "release" }
+	configurations { "debug", "release", "relwithdbginfo" }
 
 	if os.is("windows") then
 		osfiles = "src/efsw/platform/win/*.cpp"
 	else
 		osfiles = "src/efsw/platform/posix/*.cpp"
 	end
-			
-	-- This is for testing in other platforms that don't support kqueue
-	if args_contains( "kqueue" ) then
-		links { "kqueue" }
-		defines { "EFSW_KQUEUE" }
-		printf("Forced Kqueue backend build.")
-	end
 	
 	-- Activates verbose mode
-	if args_contains( "verbose" ) then
+	if _OPTIONS["verbose"] then
 		defines { "EFSW_VERBOSE" }
 	end
 
 			targetname "efsw-static-release"
 			conf_warnings()
 	
+		configuration "relwithdbginfo"
+			defines { "NDEBUG" }
+			flags { "Optimize", "Symbols" }
+			targetname "efsw-static-reldbginfo"
+			conf_warnings()
+
 	project "efsw-test"
 		kind "ConsoleApp"
 		language "C++"
 			flags { "Optimize" }
 			targetname "efsw-test-release"
 			conf_warnings()
+			
+		configuration "relwithdbginfo"
+			defines { "NDEBUG" }
+			flags { "Optimize", "Symbols" }
+			targetname "efsw-test-reldbginfo"
+			conf_warnings()
 
 	project "efsw-shared-lib"
 		kind "SharedLib"
 			flags { "Optimize" }
 			targetname "efsw"
 			conf_warnings()
+
+		configuration "relwithdbginfo"
+			defines { "NDEBUG" }
+			flags { "Optimize", "Symbols" }
+			targetname "efsw"
+			conf_warnings()
+			
+			if os.is("linux") or os.is("bsd") or os.is("haiku") then
+				targetextension ( ".so." .. efsw_version )
+				postbuildcommands { "sh ../../project/build.reldbginfo.sh " .. efsw_major_version .. " " .. efsw_minor_version .. " " .. efsw_patch_version .. " " .. iif( _OPTIONS["strip-symbols"], "strip-symbols", "" ) }
+			end

project/build.reldbginfo.sh

+#!/bin/sh
+cd ../../lib
+ln -s libefsw.so.$1.$2.$3 libefsw.so.$1
+ln -s libefsw.so.$1 libefsw.so
+
+if [ "$4" == "strip-symbols" ]; then
+	objcopy --only-keep-debug libefsw.so.$1.$2.$3 libefsw.debug
+	objcopy --strip-debug libefsw.so.$1.$2.$3
+fi

project/qtcreator-linux/efsw.creator.user

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 2.8.0, 2013-09-07T02:24:13. -->
+<!-- Written by QtCreator 2.8.1, 2013-12-19T03:02:54. -->
 <qtcreator>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
      <value type="QString" key="CurrentPreferences">CppGlobal</value>
     </valuemap>
    </valuemap>
-   <value type="int" key="EditorConfiguration.CodeStyle.Count">1</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QString" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
    <value type="QByteArray" key="EditorConfiguration.Codec">System</value>
    <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
    <value type="int" key="EditorConfiguration.IndentSize">4</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
-   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">2</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
-    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">/home/programming/efsw/make/linux</value>
+    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">../../make/linux</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">gmake</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}../../../</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
       <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4 -e config=release efsw-test</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4 -e config=release</value>
       <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
      </valuemap>
-     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
-    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">/home/programming/efsw/make/linux</value>
+    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">../../make/linux</value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
-      <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">gmake verbose</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--verbose gmake</value>
       <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
       <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}../../../</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
       <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4 efsw-test</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4</value>
       <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">debug</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
    </valuemap>
-   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">../../make/linux</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">gmake</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}../../../</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
+      <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4 -e config=relwithdbginfo</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+       <value type="QString">clean</value>
+      </valuelist>
+      <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=relwithdbginfo</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">relwithdbginfo</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
     <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">/home/programming/efsw/bin/efsw-test-debug</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">%{buildDir}../../../bin/efsw-test-debug</value>
     <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">true</value>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}../../../</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run /home/programming/efsw/bin/efsw-test-debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run %{buildDir}../../../bin/efsw-test-debug</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">debug</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
     <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
     <value type="int" key="PE.EnvironmentAspect.Base">2</value>
     <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">/home/programming/efsw/bin/efsw-test-release</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">%{buildDir}../../../bin/efsw-test-release</value>
     <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">true</value>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}../../../</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run /home/programming/efsw/bin/efsw-test-release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run %{buildDir}../../../bin/efsw-test-release</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">release</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
     <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
    </valuemap>
-   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.2">
+    <value type="bool" key="Analyzer.Project.UseGlobal">true</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">%{buildDir}../../../bin/efsw-test-dbginfo</value>
+    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">true</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}../../../</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run %{buildDir}../../../bin/efsw-test-dbginfo</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">reldbginfo</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">3</value>
   </valuemap>
  </data>
  <data>

project/qtcreator-win/efsw.config

File contents unchanged.

project/qtcreator-win/efsw.creator.user

 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by Qt Creator 2.6.0, 2013-06-30T14:44:00. -->
+<!-- Written by QtCreator 2.8.1, 2013-11-28T13:20:12. -->
 <qtcreator>
  <data>
   <variable>ProjectExplorer.Project.ActiveTarget</variable>
    <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
     <value type="QString" key="language">Cpp</value>
     <valuemap type="QVariantMap" key="value">
-     <value type="QString" key="CurrentPreferences">qt2</value>
+     <value type="QString" key="CurrentPreferences">CppGlobal</value>
     </valuemap>
    </valuemap>
    <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
   <valuemap type="QVariantMap">
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
-   <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">{f5f667a5-573a-4037-a489-01c5a58885ac}</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
    <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
    <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
-    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">C:/home/programming/efsw/make/windows</value>
+    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory"></value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--file=%{buildDir}\..\..\premake4.lua gmake verbose</value>
-      <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4.exe</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
       <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}/../../</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-      <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
      </valuemap>
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
-      <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
+      <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
+       <value type="QString">all</value>
+      </valuelist>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">efsw-test</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-C %{buildDir}\..\..\make\windows -j4</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">mingw32-make</value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-      <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
      </valuemap>
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-     <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
     </valuemap>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
        <value type="QString">clean</value>
       </valuelist>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-C %{buildDir}\..\..\make\windows</value>
       <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-      <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
      </valuemap>
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-     <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
     </valuemap>
     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
     <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
     <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName"></value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">debug</value>
-    <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
    </valuemap>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
-    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory">C:/home/programming/efsw/make/windows</value>
+    <value type="QString" key="GenericProjectManager.GenericBuildConfiguration.BuildDirectory"></value>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--file=%{buildDir}\..\..\premake4.lua gmake verbose</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.Command">premake4</value>
+      <value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}/../../</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
       <valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
        <value type="QString">all</value>
       </valuelist>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-C %{buildDir}\..\..\make\windows -j4 config=release</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand">mingw32-make</value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-      <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
      </valuemap>
-     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-     <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
     </valuemap>
     <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
      <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
        <value type="QString">clean</value>
       </valuelist>
       <value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
-      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-e config=release</value>
+      <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-C %{buildDir}\..\..\make\windows config=release</value>
       <value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
       <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
       <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-      <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
      </valuemap>
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-     <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
     </valuemap>
     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
     <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
     <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName"></value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">release</value>
-    <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
      <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-     <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
     </valuemap>
     <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">No deployment</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
-    <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
    </valuemap>
    <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
    <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
     <value type="bool" key="Analyzer.Project.UseGlobal">true</value>
     <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
-    <value type="int" key="ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase">2</value>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">C:/home/programming/efsw/bin/efsw-test-debug.exe</value>
-    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">true</value>
-    <valuelist type="QVariantList" key="ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges"/>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">C:/home/programming/efsw/bin</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run C:\home\programming\efsw\bin\efsw-test-debug.exe</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">efsw-test-debug.exe</value>
+    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}/../../bin/</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run efsw-test-debug.exe</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">debug</value>
-    <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
     <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
      <value type="int">13</value>
      <value type="int">14</value>
     </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
     <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
-    <value type="int" key="ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase">2</value>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">C:/home/programming/efsw/bin/efsw-test-release.exe</value>
-    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">true</value>
-    <valuelist type="QVariantList" key="ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges"/>
-    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">C:/home/programming/efsw/bin</value>
-    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run C:\home\programming\efsw\bin\efsw-test-release.exe</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">efsw-test-release.exe</value>
+    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}/../../bin/</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run efsw-test-release.exe</value>
     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">release</value>
-    <value type="QByteArray" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
     <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
     <value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
     <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
     <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
-  <value type="QString">{70d9cc57-eb22-4b34-bb11-95840d3c1fdb}</value>
+  <value type="QByteArray">{b6114084-39c2-4cd0-b9e2-d8803dc6b446}</value>
  </data>
  <data>
   <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
-  <value type="int">12</value>
+  <value type="int">14</value>
  </data>
 </qtcreator>

project/qtcreator-win/efsw.files

 ../../src/efsw/DirectorySnapshotDiff.cpp
 ../../src/efsw/DirectorySnapshot.cpp
 ../../src/efsw/Debug.cpp
+../../include/efsw/efsw.h
+../../src/efsw/FileWatcherCWrapper.cpp

project/qtcreator-win/efsw.includes

-src 
-include
+../../src
+../../include

src/efsw/FileSystem.cpp

 
 #include <sys/stat.h>
 
+#if EFSW_OS == EFSW_OS_MACOSX
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
 namespace efsw {
 
 bool FileSystem::isDirectory( const std::string& path )
 	return "";
 }
 
+std::string FileSystem::precomposeFileName(const std::string& name)
+{
+	#if EFSW_OS == EFSW_OS_MACOSX
+	CFStringRef cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8);
+	CFMutableStringRef cfMutable = CFStringCreateMutableCopy(NULL, 0, cfStringRef);
+
+	CFStringNormalize(cfMutable,kCFStringNormalizationFormC);
+
+	char c_str[255 + 1];
+	CFStringGetCString(cfMutable, c_str, sizeof(c_str)-1, kCFStringEncodingUTF8);
+
+	CFRelease(cfStringRef);
+	CFRelease(cfMutable);
+
+	return std::string(c_str);
+	#else
+	return name;
+	#endif
 }
+
+}

src/efsw/FileSystem.hpp

 		static void realPath( std::string curdir, std::string& path );
 
 		static std::string getLinkRealPath( std::string dir, std::string& curPath );
+
+		static std::string precomposeFileName(const std::string& name);
 };
 
 }

src/efsw/FileWatcher.cpp

 	mImpl->watch();
 }
 
+std::list<std::string> FileWatcher::directories()
+{
+	return mImpl->directories();
+}
+
 void FileWatcher::followSymlinks( bool follow )
 {
 	mFollowSymlinks = follow;

src/efsw/FileWatcherCWrapper.cpp

 	{
 		mWatcher = watcher;
 		mFn = fn;
-        mParam = param;
+		mParam = param;
 	}
 
 	void handleFileAction(efsw::WatchID watchid, const std::string& dir, const std::string& filename,
 	return log_str.c_str();
 }
 
-efsw_watchid efsw_addwatch(efsw_watcher watcher, const char* directory, 
+efsw_watchid efsw_addwatch(efsw_watcher watcher, const char* directory,
 	efsw_pfn_fileaction_callback callback_fn, int recursive, void* param)
 {
 	Watcher_CAPI* callback = find_callback(watcher, callback_fn);

src/efsw/FileWatcherInotify.cpp

 		}
 	}
 
+	efDEBUG( "Added watch %s with id: %d\n", dir.c_str(), wd );
+
 	WatcherInotify * pWatch	= new WatcherInotify();
 	pWatch->Listener	= watcher;
 	pWatch->ID			= wd;
 	return wd;
 }
 
-void FileWatcherInotify::removeWatch(const std::string& directory)
+void FileWatcherInotify::removeWatchLocked(WatchID watchid)
 {
-	mWatchesLock.lock();
-
-	WatchMap::iterator iter = mWatches.begin();
-
-	for(; iter != mWatches.end(); ++iter)
-	{
-		if( directory == iter->second->Directory )
-		{
-			WatcherInotify * watch = iter->second;
-
-			if ( watch->Recursive )
-			{
-				WatchMap::iterator it = mWatches.begin();
-				std::list<WatchID> eraseWatches;
-
-				for(; it != mWatches.end(); ++it)
-				{
-					if ( it->second->inParentTree( watch ) )
-					{
-						eraseWatches.push_back( it->second->ID );
-					}
-				}
-
-				for ( std::list<WatchID>::iterator eit = eraseWatches.begin(); eit != eraseWatches.end(); eit++ )
-				{
-					removeWatch( *eit );
-				}
-			}
-
-			mWatches.erase( iter );
-
-			if ( NULL == watch->Parent )
-			{
-				WatchMap::iterator eraseit = mRealWatches.find( watch->ID );
-
-				if ( eraseit != mRealWatches.end() )
-				{
-					mRealWatches.erase( eraseit );
-				}
-			}
-
-			inotify_rm_watch(mFD, watch->ID);
-
-			efSAFE_DELETE( watch );
-
-			return;
-		}
-	}
-
-	mWatchesLock.unlock();
-}
-
-void FileWatcherInotify::removeWatch( WatchID watchid )
-{
-	mWatchesLock.lock();
-
 	WatchMap::iterator iter = mWatches.find( watchid );
 
-	if( iter == mWatches.end() )
-		return;
-
 	WatcherInotify * watch = iter->second;
 
 	if ( watch->Recursive )
 		}
 	}
 
-	efDEBUG( "Removed watch %s\n", watch->Directory.c_str() );
+	int err = inotify_rm_watch(mFD, watchid);
 
-	inotify_rm_watch(mFD, watchid);
+	if ( err < 0 )
+	{
+		efDEBUG( "Error removing watch %d: %s\n", watchid, strerror(errno) );
+	}
+	else
+	{
+		efDEBUG( "Removed watch %s with id: %d\n", watch->Directory.c_str(), watchid );
+	}
 
 	efSAFE_DELETE( watch );
+}
+
+void FileWatcherInotify::removeWatch(const std::string& directory)
+{
+	mWatchesLock.lock();
+
+	WatchMap::iterator iter = mWatches.begin();
+
+	for(; iter != mWatches.end(); ++iter)
+	{
+		if( directory == iter->second->Directory )
+		{
+			WatcherInotify * watch = iter->second;
+
+			if ( watch->Recursive )
+			{
+				WatchMap::iterator it = mWatches.begin();
+				std::list<WatchID> eraseWatches;
+
+				for(; it != mWatches.end(); ++it)
+				{
+					if ( it->second->inParentTree( watch ) )
+					{
+						eraseWatches.push_back( it->second->ID );
+					}
+				}
+
+				for ( std::list<WatchID>::iterator eit = eraseWatches.begin(); eit != eraseWatches.end(); eit++ )
+				{
+					removeWatchLocked( *eit );
+				}
+			}
+
+			mWatches.erase( iter );
+
+			if ( NULL == watch->Parent )
+			{
+				WatchMap::iterator eraseit = mRealWatches.find( watch->ID );
+
+				if ( eraseit != mRealWatches.end() )
+				{
+					mRealWatches.erase( eraseit );
+				}
+			}
+
+			int err = inotify_rm_watch(mFD, watch->ID);
+
+			if ( err < 0 )
+			{
+				efDEBUG( "Error removing watch %d: %s\n", watch->ID, strerror(errno) );
+			}
+			else
+			{
+				efDEBUG( "Removed watch %s with id: %d\n", watch->Directory.c_str(), watch->ID );
+			}
+
+			efSAFE_DELETE( watch );
+
+			break;
+		}
+	}
+
+	mWatchesLock.unlock();
+}
+
+void FileWatcherInotify::removeWatch( WatchID watchid )
+{
+	mWatchesLock.lock();
+
+	WatchMap::iterator iter = mWatches.find( watchid );
+
+	if( iter == mWatches.end() )
+	{
+		mWatchesLock.unlock();
+
+		return;
+	}
+
+	removeWatchLocked( watchid );
 
 	mWatchesLock.unlock();
 }
 
 void FileWatcherInotify::run()
 {
+	static char buff[BUFF_SIZE] = {0};
 	WatchMap::iterator wit;
 	std::list<WatcherInotify*> movedOutsideWatches;
 
 	do
 	{
 		ssize_t len, i = 0;
-		static char buff[BUFF_SIZE] = {0};
 
 		len = read (mFD, buff, BUFF_SIZE);
 
 	} while( mFD > 0 );
 }
 
+void FileWatcherInotify::checkForNewWatcher( Watcher* watch, std::string fpath )
+{
+	FileSystem::dirAddSlashAtEnd( fpath );
+
+	/// If the watcher is recursive, checks if the new file is a folder, and creates a watcher
+	if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
+	{
+		bool found = false;
+
+		/// First check if exists
+		for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
+		{
+			if ( it->second->Directory == fpath )
+			{
+				found = true;
+				break;
+			}
+		}
+
+		if ( !found )
+		{
+			addWatch( fpath, watch->Listener, watch->Recursive, static_cast<WatcherInotify*>( watch ) );
+		}
+	}
+}
+
 void FileWatcherInotify::handleAction( Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename )
 {
 	if ( !watch || !watch->Listener )
 		if ( watch->OldFileName.empty() )
 		{
 			watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Add );
+
+			checkForNewWatcher( watch, fpath );
 		}
 		else
 		{
 
 			for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
 			{
-				if ( it->second->Directory == opath )
+				if ( it->second->Directory == opath && it->second->DirInfo.Inode == FileInfo( opath ).Inode )
 				{
-					it->second->Directory = fpath;
+					it->second->Directory	= fpath;
+					it->second->DirInfo		= FileInfo( fpath );
 
 					break;
 				}
 	{
 		watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Add );
 
-		/// If the watcher is recursive, checks if the new file is a folder, and creates a watcher
-		if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
-		{
-			bool found = false;
-
-			/// First check if exists
-			for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
-			{
-				if ( it->second->Directory == fpath )
-				{
-					found = true;
-					break;
-				}
-			}
-
-			if ( !found )
-			{
-				addWatch( fpath, watch->Listener, watch->Recursive, static_cast<WatcherInotify*>( watch ) );
-			}
-		}
+		checkForNewWatcher( watch, fpath );
 	}
 	else if ( IN_MOVED_FROM & action )
 	{
 	{
 		watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Delete );
 
+		FileSystem::dirAddSlashAtEnd( fpath );
+
 		/// If the file erased is a directory and recursive is enabled, removes the directory erased
-		if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
+		if ( watch->Recursive )
 		{
 			for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
 			{

src/efsw/FileWatcherInotify.hpp

 		bool pathInWatches( const std::string& path );
 	private:
 		void run();
+
+		void removeWatchLocked(WatchID watchid);
+
+		void checkForNewWatcher( Watcher* watch, std::string fpath );
 };
 
 }

src/efsw/FileWatcherWin32.cpp

 
 	WatchID watchid = ++mLastWatchID;
 
-	WatcherStructWin32 * watch = CreateWatch( dir.c_str(), recursive,	FILE_NOTIFY_CHANGE_CREATION |
-																		FILE_NOTIFY_CHANGE_SIZE |
-																		FILE_NOTIFY_CHANGE_FILE_NAME |
-																		FILE_NOTIFY_CHANGE_DIR_NAME |
-																		FILE_NOTIFY_CHANGE_SIZE |
-																		FILE_NOTIFY_CHANGE_FILE_NAME |
-																		FILE_NOTIFY_CHANGE_DIR_NAME);
+	WatcherStructWin32 * watch = CreateWatch( dir.c_str(), recursive, FILE_NOTIFY_CHANGE_CREATION |
+		FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME);
 
 	if( NULL == watch )
 	{
 
 	do
 	{
-        /* due to a bug when mHandles is empty and program tries to call WaitForMultipleObjectsEx */
-        if (mHandles.empty())
-            return;
+		if ( !mHandles.empty() )
+		{
+			DWORD wait_result = WaitForMultipleObjectsEx( mHandles.size(), &mHandles[0], FALSE, 1000, FALSE );
 
-		DWORD wait_result = WaitForMultipleObjectsEx( mHandles.size(), &mHandles[0], FALSE, 1000, FALSE );
+			switch ( wait_result )
+			{
+				case WAIT_ABANDONED_0:
+				case WAIT_ABANDONED_0 + 1:
+					//"Wait abandoned."
+					break;
+				case WAIT_TIMEOUT:
+					break;
+				case WAIT_FAILED:
+					//"Wait failed."
+					break;
+				default:
+				{
+					mWatchesLock.lock();
 
-		switch ( wait_result )
-		{
-			case WAIT_ABANDONED_0:
-			case WAIT_ABANDONED_0 + 1:
-				//"Wait abandoned."
-				break;
-			case WAIT_TIMEOUT:
-				break;
-			case WAIT_FAILED:
-				//"Wait failed."
-				break;
-			default:
-			{
-				mWatchesLock.lock();
+					// Don't trust the result - multiple objects may be signalled during a single call.
+					if ( wait_result >=  WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + mWatches.size() )
+					{
+						WatcherStructWin32 * watch = mWatches[ wait_result ];
 
-				// Don't trust the result - multiple objects may be signalled during a single call.
-				if ( wait_result >=  WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + mWatches.size() )
-				{
-					WatcherStructWin32 * watch = mWatches[ wait_result ];
+						// First ensure that the handle is the same, this means that the watch was not removed.
+						if ( mHandles[ wait_result ] == watch->Watch->DirHandle && HasOverlappedIoCompleted( &watch->Overlapped ) )
+						{
+							DWORD bytes;
 
-					// First ensure that the handle is the same, this means that the watch was not removed.
-					if ( mHandles[ wait_result ] == watch->Watch->DirHandle && HasOverlappedIoCompleted( &watch->Overlapped ) )
-					{
-						DWORD bytes;
-
-						if ( GetOverlappedResult( watch->Watch->DirHandle, &watch->Overlapped, &bytes, FALSE ) )
-						{
-							WatchCallback( ERROR_SUCCESS, bytes, &watch->Overlapped );
-						}
-						else
-						{
-							//"GetOverlappedResult failed."
+							if ( GetOverlappedResult( watch->Watch->DirHandle, &watch->Overlapped, &bytes, FALSE ) )
+							{
+								WatchCallback( ERROR_SUCCESS, bytes, &watch->Overlapped );
+							}
+							else
+							{
+								//"GetOverlappedResult failed."
+							}
 						}
 					}
+					else
+					{
+						//"Unknown return value from WaitForMultipleObjectsEx."
+					}
+
+					mWatchesLock.unlock();
 				}
-				else
-				{
-					//"Unknown return value from WaitForMultipleObjectsEx."
-				}
-
-				mWatchesLock.unlock();
 			}
 		}
+		else
+		{
+			// Wait for a new handle to be added
+			System::sleep( 10 );
+		}
 	} while ( mInitOK );
 }
 

src/efsw/WatcherFSEvents.cpp

 	initializedAsync = true;
 }
 
+void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename )
+{
+	Listener->handleFileAction( watchid, FileSystem::precomposeFileName( dir ), FileSystem::precomposeFileName( filename ), action, oldFilename );
+}
+
 void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, std::string& dirPath, std::string& filePath )
 {
 	if ( flags & efswFSEventStreamEventFlagItemCreated )
 	{
 		if ( FileInfo::exists( path ) )
 		{
-			Listener->handleFileAction( ID, dirPath, filePath, Actions::Add );
+			sendFileAction( ID, dirPath, filePath, Actions::Add );
 		}
 	}
 
 	if ( flags & efswFSEventsModified )
 	{
-		Listener->handleFileAction( ID, dirPath, filePath, Actions::Modified );
+		sendFileAction( ID, dirPath, filePath, Actions::Modified );
 	}
 
 	if ( flags & efswFSEventStreamEventFlagItemRemoved )
 		// Since i don't know the order, at least i try to keep the data consistent with the real state
 		if ( !FileInfo::exists( path ) )
 		{
-			Listener->handleFileAction( ID, dirPath, filePath, Actions::Delete );
+			sendFileAction( ID, dirPath, filePath, Actions::Delete );
 		}
 	}
 }
 				efDEBUG( "Weird crap %s\n", tInfo.Filepath.c_str() );
 
 				if ( tInfo.exists() )
-					Listener->handleFileAction( ID, FileSystem::pathRemoveFileName( tInfo.Filepath ), FileSystem::fileNameFromPath( tInfo.Filepath ), Actions::Add );
+					sendFileAction( ID, FileSystem::pathRemoveFileName( tInfo.Filepath ), FileSystem::fileNameFromPath( tInfo.Filepath ), Actions::Add );
 				else
-					Listener->handleFileAction( ID, FileSystem::pathRemoveFileName( tInfo.Filepath ), FileSystem::fileNameFromPath( tInfo.Filepath ), Actions::Delete );
+					sendFileAction( ID, FileSystem::pathRemoveFileName( tInfo.Filepath ), FileSystem::fileNameFromPath( tInfo.Filepath ), Actions::Delete );
 			}
 		}
 
 					{
 						if ( !tFile.exists() )
 						{
-							Listener->handleFileAction( ID, dirPath, filePath, Actions::Moved, oldFilepath );
+							sendFileAction( ID, dirPath, filePath, Actions::Moved, oldFilepath );
 						}
 						else
 						{
-							Listener->handleFileAction( ID, dirPath, oldFilepath, Actions::Moved, filePath );
+							sendFileAction( ID, dirPath, oldFilepath, Actions::Moved, filePath );
 						}
 					}
 					else
 					{
-						Listener->handleFileAction( ID, oldDir, oldFilepath, Actions::Delete );
-						Listener->handleFileAction( ID, dirPath, filePath, Actions::Add );
+						sendFileAction( ID, oldDir, oldFilepath, Actions::Delete );
+						sendFileAction( ID, dirPath, filePath, Actions::Add );
 
 						if ( flags & efswFSEventsModified )
 						{
-							Listener->handleFileAction( ID, dirPath, filePath, Actions::Modified );
+							sendFileAction( ID, dirPath, filePath, Actions::Modified );
 						}
 					}
 				}
 		}
 		else
 		{
-			Listener->handleFileAction( ID, FileSystem::pathRemoveFileName( (*it) ), FileSystem::fileNameFromPath( (*it) ), Actions::Modified );
+			sendFileAction( ID, FileSystem::pathRemoveFileName( (*it) ), FileSystem::fileNameFromPath( (*it) ), Actions::Modified );
 		}
 	}
 

src/efsw/WatcherFSEvents.hpp

 		Uint64 mLastId;
 
 		void CheckLostEvents();
+
+		void sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename = "" );
 };
 
 }

src/efsw/WatcherInotify.cpp

 
 WatcherInotify::WatcherInotify( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherInotify * parent ) :
 	Watcher( id, directory, listener, recursive ),
-	Parent( parent )
+	Parent( parent ),
+	DirInfo( directory )
 {
 }
 

src/efsw/WatcherInotify.hpp

 #define EFSW_WATCHERINOTIFY_HPP
 
 #include <efsw/FileWatcherImpl.hpp>
+#include <efsw/FileInfo.hpp>
 
 namespace efsw {
 
 		
 		WatcherInotify( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherInotify * parent = NULL );
 
+		bool inParentTree( WatcherInotify * parent );
+
 		WatcherInotify * Parent;
 
-		bool inParentTree( WatcherInotify * parent );
+		FileInfo DirInfo;
 };
 
 }

src/efsw/WatcherWin32.cpp

 	{
 		do
 		{
+			bool skip = false;
+
 			pNotify = (PFILE_NOTIFY_INFORMATION) &pWatch->mBuffer[offset];
 			offset += pNotify->NextEntryOffset;
 
 			}
 #			endif
 
-			pWatch->Watch->handleAction(pWatch, szFile, pNotify->Action);
+			std::string nfile( szFile );
+
+			if ( FILE_ACTION_MODIFIED == pNotify->Action )
+			{
+				FileInfo fifile( std::string( pWatch->DirName ) + nfile );
+
+				if ( pWatch->LastModifiedEvent.file.ModificationTime == fifile.ModificationTime && pWatch->LastModifiedEvent.fileName == nfile )
+				{
+					skip = true;
+				}
+
+				pWatch->LastModifiedEvent.fileName	= nfile;
+				pWatch->LastModifiedEvent.file		= fifile;
+			}
+
+			if ( !skip )
+			{
+				pWatch->Watch->handleAction(pWatch, nfile, pNotify->Action);
+			}
 		} while (pNotify->NextEntryOffset != 0);
 	}
 

src/efsw/WatcherWin32.hpp

 #define EFSW_WATCHERWIN32_HPP
 
 #include <efsw/FileWatcherImpl.hpp>
+#include <efsw/FileInfo.hpp>
 
 #if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
 
 	WatcherWin32 *	Watch;
 };
 
+class cLastModifiedEvent
+{
+	public:
+		cLastModifiedEvent() {}
+		FileInfo	file;
+		std::string fileName;
+};
+
 bool RefreshWatch(WatcherStructWin32* pWatch, bool _clear = false);
 
 void CALLBACK WatchCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped);
 		bool StopNow;
 		FileWatcherImpl* Watch;
 		char* DirName;
+		cLastModifiedEvent LastModifiedEvent;
 };
 
 }