watch 1 folder only

This commit is contained in:
jason 2025-12-29 20:29:50 +00:00
commit 556a9081aa
18 changed files with 3843 additions and 3242 deletions

18
.clang-format Normal file
View File

@ -0,0 +1,18 @@
---
AlignEscapedNewlines: Left
AllowAllConstructorInitializersOnNextLine: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortFunctionsOnASingleLine: Inline
BreakConstructorInitializers: AfterColon
ColumnLimit: '100'
CompactNamespaces: 'true'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
ContinuationIndentWidth: '4'
IndentCaseLabels: 'true'
IndentWidth: '4'
PointerAlignment: Left
SpacesInParentheses: 'true'
TabWidth: '4'
UseTab: Always
...

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
bin/
build/
obj/
make/
lib/
CMakeFiles/
/cmake
/CMakeCache.txt
/cmake_install.cmake
/Makefile
*.DS_Store
.qtc_clangd
.cmake
.vscode/
*.so
*.a
*.dylib
*.lib
/.cache
/efsw-test
/efsw-test-stdc

View File

@ -42,13 +42,15 @@ Run **x64 Native Tools Command Prompt for VS 2022**
```
mkdir learndir
cd learndir
git clone https://git.indoodle.com/jason/joomer-ftxui-file-monitoring.git
cd joomer-ftxui-file-monitoring
git clone https://git.indoodle.com/jason/joomer-efsw-file-monitoring.git
premake5 vs2022
cd joomer-ftxui-file-monitoring/make/windows
msbuild joomer-ftxui-file-monitoring.vcxproj /t:Build /p:Configuration=Debug /p:Platform=x64
cd ../..
bin\Debug\joomer-ftxui-file-monitoring.exe
```
For a prototype app we can just dump the stb headers right into the helloworld dir for simplicity
For a prototype app we can just dump the stb headers right into the joomer-efsw-file-monitoring/src dir for simplicity
```
curl -LO https://raw.githubusercontent.com/nothings/stb/master/stb_image.h
curl -LO https://raw.githubusercontent.com/nothings/stb/master/stb_image_write.h

View File

@ -1,267 +1,267 @@
/**
@author Martín Lucas Golini
Copyright (c) 2024 Martín Lucas Golini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com)
http://code.google.com/p/simplefilewatcher/ also MIT licensed.
*/
#ifndef ESFW_HPP
#define ESFW_HPP
#include <string>
#include <vector>
#if defined( _WIN32 )
#ifdef EFSW_DYNAMIC
// Windows platforms
#ifdef EFSW_EXPORTS
// From DLL side, we must export
#define EFSW_API __declspec( dllexport )
#else
// From client application side, we must import
#define EFSW_API __declspec( dllimport )
#endif
#else
// No specific directive needed for static build
#ifndef EFSW_API
#define EFSW_API
#endif
#endif
#else
#if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
#ifndef EFSW_API
#define EFSW_API __attribute__( ( visibility( "default" ) ) )
#endif
#endif
// Other platforms don't need to define anything
#ifndef EFSW_API
#define EFSW_API
#endif
#endif
namespace efsw {
/// Type for a watch id
typedef long WatchID;
// forward declarations
class FileWatcherImpl;
class FileWatchListener;
class WatcherOption;
/// Actions to listen for. Rename will send two events, one for
/// the deletion of the old file, and one for the creation of the
/// new file.
namespace Actions {
enum Action {
/// Sent when a file is created or renamed
Add = 1,
/// Sent when a file is deleted or renamed
Delete = 2,
/// Sent when a file is modified
Modified = 3,
/// Sent when a file is moved
Moved = 4
};
}
typedef Actions::Action Action;
/// Errors log namespace
namespace Errors {
enum Error {
NoError = 0,
FileNotFound = -1,
FileRepeated = -2,
FileOutOfScope = -3,
FileNotReadable = -4,
/// Directory in remote file system
/// ( create a generic FileWatcher instance to watch this directory ).
FileRemote = -5,
/// File system watcher failed to watch for changes.
WatcherFailed = -6,
Unspecified = -7
};
class EFSW_API Log {
public:
/// @return The last error logged
static std::string getLastErrorLog();
/// @return The code of the last error logged
static Error getLastErrorCode();
/// Reset last error
static void clearLastError();
/// Creates an error of the type specified
static Error createLastError( Error err, std::string log );
};
} // namespace Errors
typedef Errors::Error Error;
/// Optional file watcher settings.
namespace Options {
enum Option {
/// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and
/// file system events may be dropped. For that, using a different (bigger) buffer size
/// can be defined here, but note that this does not work for network drives,
/// because a buffer larger than 64K will fail the folder being watched, see
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx)
WinBufferSize = 1,
/// For Windows, per default all events are captured but we might only be interested
/// in a subset; the value of the option should be set to a bitwise or'ed set of
/// FILE_NOTIFY_CHANGE_* flags.
WinNotifyFilter = 2,
/// For macOS (FSEvents backend), per default all modified event types are capture but we might
/// only be interested in a subset; the value of the option should be set to a set of bitwise
/// from:
/// kFSEventStreamEventFlagItemFinderInfoMod
/// kFSEventStreamEventFlagItemModified
/// kFSEventStreamEventFlagItemInodeMetaMod
/// Default configuration will set the 3 flags
MacModifiedFilter = 3,
/// macOS sometimes informs incorrect or old file states that may confuse the consumer
/// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing
/// the number of events reported. This will have an small performance and memory impact as a
/// consequence.
MacSanitizeEvents = 4,
/// Linux does not support natively recursive watchers. This means that when using recursive
/// watches efsw registers new watchers for each directory. If new file are created between
/// the time efsw takes to register the new directory those events might be missed. To avoid
/// missing new file notifications efsw will trigger synthetic created file events for existing
/// files in the new directroy watched. This might have the unintended consequence of sending
/// duplicated created events due to the system also emitting this event.
LinuxProduceSyntheticEvents = 5,
};
}
typedef Options::Option Option;
/// Listens to files and directories and dispatches events
/// to notify the listener of files and directories changes.
/// @class FileWatcher
class EFSW_API FileWatcher {
public:
/// Default constructor, will use the default platform file watcher
FileWatcher();
/// Constructor that lets you force the use of the Generic File Watcher
explicit FileWatcher( bool useGenericFileWatcher );
virtual ~FileWatcher();
/// 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.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher );
/// Add a directory watch
/// On error returns WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive );
/// Add a directory watch, allowing customization with options
/// @param directory The folder to be watched
/// @param watcher The listener to receive events
/// @param recursive Set this to true to include subdirectories
/// @param options Allows customization of a watcher
/// @return Returns the watch id for the directory or, on error, a WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
const std::vector<WatcherOption>& options );
/// Remove a directory watch. This is a brute force search O(nlogn).
void removeWatch( const std::string& directory );
/// Remove a directory watch. This is a map lookup O(logn).
void removeWatch( WatchID watchid );
/// Starts watching ( in other thread )
void watch();
/// @return Returns a list of the directories that are being watched
std::vector<std::string> directories();
/** Allow recursive watchers to follow symbolic links to other directories
* followSymlinks is disabled by default
*/
void followSymlinks( bool follow );
/** @return If can follow symbolic links to directorioes */
const bool& followSymlinks() const;
/** When enable this it will allow symlinks to watch recursively out of the pointed directory.
* follorSymlinks must be enabled to this work.
* For example, added symlink to /home/folder, and the symlink points to /, this by default is
* not allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid
* great levels of recursion. Enabling this could lead in infinite recursion, and crash the
* watcher ( it will try not to avoid this ). Buy enabling out of scope links, it will allow
* this behavior. allowOutOfScopeLinks are disabled by default.
*/
void allowOutOfScopeLinks( bool allow );
/// @return Returns if out of scope links are allowed
const bool& allowOutOfScopeLinks() const;
private:
/// The implementation
FileWatcherImpl* mImpl;
bool mFollowSymlinks;
bool mOutOfScopeLinks;
};
/// Basic interface for listening for file events.
/// @class FileWatchListener
class FileWatchListener {
public:
virtual ~FileWatchListener() {}
/// Handles the action file action
/// @param watchid The watch id for the directory
/// @param dir The directory
/// @param filename The filename that was accessed (not full path)
/// @param action Action that was performed
/// @param oldFilename The name of the file or directory moved
virtual void handleFileAction( WatchID watchid, const std::string& dir,
const std::string& filename, Action action,
std::string oldFilename = "" ) = 0;
/// Handles that have missed file actions
/// @param watchid The watch id for the directory
/// @param dir The directory
virtual void handleMissedFileActions( WatchID /*watchid*/,
const std::string& /*dir*/ ) {}
};
/// Optional, typically platform specific parameter for customization of a watcher.
/// @class WatcherOption
class WatcherOption {
public:
WatcherOption( Option option, int value ) : mOption( option ), mValue( value ){};
Option mOption;
int mValue;
};
} // namespace efsw
#endif
/**
@author Martín Lucas Golini
Copyright (c) 2024 Martín Lucas Golini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com)
http://code.google.com/p/simplefilewatcher/ also MIT licensed.
*/
#ifndef ESFW_HPP
#define ESFW_HPP
#include <string>
#include <vector>
#if defined( _WIN32 )
#ifdef EFSW_DYNAMIC
// Windows platforms
#ifdef EFSW_EXPORTS
// From DLL side, we must export
#define EFSW_API __declspec( dllexport )
#else
// From client application side, we must import
#define EFSW_API __declspec( dllimport )
#endif
#else
// No specific directive needed for static build
#ifndef EFSW_API
#define EFSW_API
#endif
#endif
#else
#if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
#ifndef EFSW_API
#define EFSW_API __attribute__( ( visibility( "default" ) ) )
#endif
#endif
// Other platforms don't need to define anything
#ifndef EFSW_API
#define EFSW_API
#endif
#endif
namespace efsw {
/// Type for a watch id
typedef long WatchID;
// forward declarations
class FileWatcherImpl;
class FileWatchListener;
class WatcherOption;
/// Actions to listen for. Rename will send two events, one for
/// the deletion of the old file, and one for the creation of the
/// new file.
namespace Actions {
enum Action {
/// Sent when a file is created or renamed
Add = 1,
/// Sent when a file is deleted or renamed
Delete = 2,
/// Sent when a file is modified
Modified = 3,
/// Sent when a file is moved
Moved = 4
};
}
typedef Actions::Action Action;
/// Errors log namespace
namespace Errors {
enum Error {
NoError = 0,
FileNotFound = -1,
FileRepeated = -2,
FileOutOfScope = -3,
FileNotReadable = -4,
/// Directory in remote file system
/// ( create a generic FileWatcher instance to watch this directory ).
FileRemote = -5,
/// File system watcher failed to watch for changes.
WatcherFailed = -6,
Unspecified = -7
};
class EFSW_API Log {
public:
/// @return The last error logged
static std::string getLastErrorLog();
/// @return The code of the last error logged
static Error getLastErrorCode();
/// Reset last error
static void clearLastError();
/// Creates an error of the type specified
static Error createLastError( Error err, std::string log );
};
} // namespace Errors
typedef Errors::Error Error;
/// Optional file watcher settings.
namespace Options {
enum Option {
/// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and
/// file system events may be dropped. For that, using a different (bigger) buffer size
/// can be defined here, but note that this does not work for network drives,
/// because a buffer larger than 64K will fail the folder being watched, see
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx)
WinBufferSize = 1,
/// For Windows, per default all events are captured but we might only be interested
/// in a subset; the value of the option should be set to a bitwise or'ed set of
/// FILE_NOTIFY_CHANGE_* flags.
WinNotifyFilter = 2,
/// For macOS (FSEvents backend), per default all modified event types are capture but we might
/// only be interested in a subset; the value of the option should be set to a set of bitwise
/// from:
/// kFSEventStreamEventFlagItemFinderInfoMod
/// kFSEventStreamEventFlagItemModified
/// kFSEventStreamEventFlagItemInodeMetaMod
/// Default configuration will set the 3 flags
MacModifiedFilter = 3,
/// macOS sometimes informs incorrect or old file states that may confuse the consumer
/// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing
/// the number of events reported. This will have an small performance and memory impact as a
/// consequence.
MacSanitizeEvents = 4,
/// Linux does not support natively recursive watchers. This means that when using recursive
/// watches efsw registers new watchers for each directory. If new file are created between
/// the time efsw takes to register the new directory those events might be missed. To avoid
/// missing new file notifications efsw will trigger synthetic created file events for existing
/// files in the new directroy watched. This might have the unintended consequence of sending
/// duplicated created events due to the system also emitting this event.
LinuxProduceSyntheticEvents = 5,
};
}
typedef Options::Option Option;
/// Listens to files and directories and dispatches events
/// to notify the listener of files and directories changes.
/// @class FileWatcher
class EFSW_API FileWatcher {
public:
/// Default constructor, will use the default platform file watcher
FileWatcher();
/// Constructor that lets you force the use of the Generic File Watcher
explicit FileWatcher( bool useGenericFileWatcher );
virtual ~FileWatcher();
/// 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.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher );
/// Add a directory watch
/// On error returns WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive );
/// Add a directory watch, allowing customization with options
/// @param directory The folder to be watched
/// @param watcher The listener to receive events
/// @param recursive Set this to true to include subdirectories
/// @param options Allows customization of a watcher
/// @return Returns the watch id for the directory or, on error, a WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
const std::vector<WatcherOption>& options );
/// Remove a directory watch. This is a brute force search O(nlogn).
void removeWatch( const std::string& directory );
/// Remove a directory watch. This is a map lookup O(logn).
void removeWatch( WatchID watchid );
/// Starts watching ( in other thread )
void watch();
/// @return Returns a list of the directories that are being watched
std::vector<std::string> directories();
/** Allow recursive watchers to follow symbolic links to other directories
* followSymlinks is disabled by default
*/
void followSymlinks( bool follow );
/** @return If can follow symbolic links to directorioes */
const bool& followSymlinks() const;
/** When enable this it will allow symlinks to watch recursively out of the pointed directory.
* follorSymlinks must be enabled to this work.
* For example, added symlink to /home/folder, and the symlink points to /, this by default is
* not allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid
* great levels of recursion. Enabling this could lead in infinite recursion, and crash the
* watcher ( it will try not to avoid this ). Buy enabling out of scope links, it will allow
* this behavior. allowOutOfScopeLinks are disabled by default.
*/
void allowOutOfScopeLinks( bool allow );
/// @return Returns if out of scope links are allowed
const bool& allowOutOfScopeLinks() const;
private:
/// The implementation
FileWatcherImpl* mImpl;
bool mFollowSymlinks;
bool mOutOfScopeLinks;
};
/// Basic interface for listening for file events.
/// @class FileWatchListener
class FileWatchListener {
public:
virtual ~FileWatchListener() {}
/// Handles the action file action
/// @param watchid The watch id for the directory
/// @param dir The directory
/// @param filename The filename that was accessed (not full path)
/// @param action Action that was performed
/// @param oldFilename The name of the file or directory moved
virtual void handleFileAction( WatchID watchid, const std::string& dir,
const std::string& filename, Action action,
std::string oldFilename = "" ) = 0;
/// Handles that have missed file actions
/// @param watchid The watch id for the directory
/// @param dir The directory
virtual void handleMissedFileActions( WatchID /*watchid*/,
const std::string& /*dir*/ ) {}
};
/// Optional, typically platform specific parameter for customization of a watcher.
/// @class WatcherOption
class WatcherOption {
public:
WatcherOption( Option option, int value ) : mOption( option ), mValue( value ){};
Option mOption;
int mValue;
};
} // namespace efsw
#endif

View File

@ -1,261 +1,261 @@
newoption { trigger = "verbose", description = "Build efsw with verbose mode." }
newoption { trigger = "strip-symbols", description = "Strip debugging symbols in other file ( only for relwithdbginfo configuration )." }
newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer." }
efsw_major_version = "1"
efsw_minor_version = "5"
efsw_patch_version = "0"
efsw_version = efsw_major_version .. "." .. efsw_minor_version .. "." .. efsw_patch_version
function get_include_paths()
local function _insert_include_paths( file )
local function _trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local paths = { }
local lines = file:read('*all')
for line in string.gmatch(lines, '([^\n]+)')
do
table.insert( paths, _trim( line ) )
end
file:close()
return paths
end
local file = io.popen( "echo | gcc -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/'", 'r' )
local include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
file = io.popen( "echo | clang++ -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/' | grep -v 'nonexistent'", 'r' )
include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
table.insert( include_paths, "/usr/include" )
table.insert( include_paths, "/usr/local/include" )
end
end
return include_paths
end
function inotify_header_exists()
local efsw_include_paths = get_include_paths()
for _,v in pairs( efsw_include_paths )
do
local cur_path = v .. "/sys/inotify.h"
if os.isfile( cur_path ) then
return true
end
end
return false
end
function string.starts(String,Start)
if ( _ACTION ) then
return string.sub(String,1,string.len(Start))==Start
end
return false
end
function is_vs()
return ( string.starts(_ACTION,"vs") )
end
function conf_warnings()
if not is_vs() then
buildoptions{ "-Wall -Wno-long-long" }
if not os.is("windows") then
buildoptions{ "-fPIC" }
end
else
defines { "_SCL_SECURE_NO_WARNINGS" }
end
if _OPTIONS["thread-sanitizer"] then
buildoptions { "-fsanitize=thread" }
linkoptions { "-fsanitize=thread" }
if not os.is("macosx") then
links { "tsan" }
end
end
end
function conf_links()
if not os.is("windows") and not os.is("haiku") then
links { "pthread" }
end
if os.is("macosx") then
links { "CoreFoundation.framework", "CoreServices.framework" }
end
end
function conf_excludes()
if os.is("windows") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherInotify.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.is("linux") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.is("macosx") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp" }
elseif os.is("freebsd") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
end
if os.is("linux") and not inotify_header_exists() then
defines { "EFSW_INOTIFY_NOSYS" }
end
end
solution "efsw"
location("./make/" .. os.get() .. "/")
targetdir("./bin")
configurations { "debug", "release", "relwithdbginfo" }
if os.is("windows") then
osfiles = "src/efsw/platform/win/*.cpp"
else
osfiles = "src/efsw/platform/posix/*.cpp"
end
-- Activates verbose mode
if _OPTIONS["verbose"] then
defines { "EFSW_VERBOSE" }
end
if not is_vs() then
buildoptions { "-std=c++11" }
end
if os.is("macosx") then
-- Premake 4.4 needed for this
if not string.match(_PREMAKE_VERSION, "^4.[123]") then
local ver = os.getversion();
if not ( ver.majorversion >= 10 and ver.minorversion >= 5 ) then
defines { "EFSW_FSEVENTS_NOT_SUPPORTED" }
end
end
end
objdir("obj/" .. os.get() .. "/")
project "efsw-static-lib"
kind "StaticLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
conf_excludes()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-static-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
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++"
links { "efsw-static-lib" }
files { "src/test/*.cpp" }
includedirs { "include", "src" }
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-test-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
targetname "efsw-test-release"
conf_warnings()
configuration "relwithdbginfo"
defines { "NDEBUG" }
flags { "Optimize", "Symbols" }
targetname "efsw-test-reldbginfo"
conf_warnings()
project "efsw-test-stdc"
kind "ConsoleApp"
language "C"
links { "efsw-shared-lib" }
files { "src/test/*.c" }
includedirs { "include", "src" }
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-test-stdc-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
targetname "efsw-test-stdc-release"
conf_warnings()
configuration "relwithdbginfo"
defines { "NDEBUG" }
flags { "Optimize", "Symbols" }
targetname "efsw-test-stdc-reldbginfo"
conf_warnings()
project "efsw-shared-lib"
kind "SharedLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
defines { "EFSW_DYNAMIC", "EFSW_EXPORTS" }
conf_excludes()
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
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
newoption { trigger = "verbose", description = "Build efsw with verbose mode." }
newoption { trigger = "strip-symbols", description = "Strip debugging symbols in other file ( only for relwithdbginfo configuration )." }
newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer." }
efsw_major_version = "1"
efsw_minor_version = "5"
efsw_patch_version = "0"
efsw_version = efsw_major_version .. "." .. efsw_minor_version .. "." .. efsw_patch_version
function get_include_paths()
local function _insert_include_paths( file )
local function _trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local paths = { }
local lines = file:read('*all')
for line in string.gmatch(lines, '([^\n]+)')
do
table.insert( paths, _trim( line ) )
end
file:close()
return paths
end
local file = io.popen( "echo | gcc -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/'", 'r' )
local include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
file = io.popen( "echo | clang++ -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/' | grep -v 'nonexistent'", 'r' )
include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
table.insert( include_paths, "/usr/include" )
table.insert( include_paths, "/usr/local/include" )
end
end
return include_paths
end
function inotify_header_exists()
local efsw_include_paths = get_include_paths()
for _,v in pairs( efsw_include_paths )
do
local cur_path = v .. "/sys/inotify.h"
if os.isfile( cur_path ) then
return true
end
end
return false
end
function string.starts(String,Start)
if ( _ACTION ) then
return string.sub(String,1,string.len(Start))==Start
end
return false
end
function is_vs()
return ( string.starts(_ACTION,"vs") )
end
function conf_warnings()
if not is_vs() then
buildoptions{ "-Wall -Wno-long-long" }
if not os.is("windows") then
buildoptions{ "-fPIC" }
end
else
defines { "_SCL_SECURE_NO_WARNINGS" }
end
if _OPTIONS["thread-sanitizer"] then
buildoptions { "-fsanitize=thread" }
linkoptions { "-fsanitize=thread" }
if not os.is("macosx") then
links { "tsan" }
end
end
end
function conf_links()
if not os.is("windows") and not os.is("haiku") then
links { "pthread" }
end
if os.is("macosx") then
links { "CoreFoundation.framework", "CoreServices.framework" }
end
end
function conf_excludes()
if os.is("windows") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherInotify.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.is("linux") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.is("macosx") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp" }
elseif os.is("freebsd") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
end
if os.is("linux") and not inotify_header_exists() then
defines { "EFSW_INOTIFY_NOSYS" }
end
end
solution "efsw"
location("./make/" .. os.get() .. "/")
targetdir("./bin")
configurations { "debug", "release", "relwithdbginfo" }
if os.is("windows") then
osfiles = "src/efsw/platform/win/*.cpp"
else
osfiles = "src/efsw/platform/posix/*.cpp"
end
-- Activates verbose mode
if _OPTIONS["verbose"] then
defines { "EFSW_VERBOSE" }
end
if not is_vs() then
buildoptions { "-std=c++11" }
end
if os.is("macosx") then
-- Premake 4.4 needed for this
if not string.match(_PREMAKE_VERSION, "^4.[123]") then
local ver = os.getversion();
if not ( ver.majorversion >= 10 and ver.minorversion >= 5 ) then
defines { "EFSW_FSEVENTS_NOT_SUPPORTED" }
end
end
end
objdir("obj/" .. os.get() .. "/")
project "efsw-static-lib"
kind "StaticLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
conf_excludes()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-static-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
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++"
links { "efsw-static-lib" }
files { "src/test/*.cpp" }
includedirs { "include", "src" }
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-test-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
targetname "efsw-test-release"
conf_warnings()
configuration "relwithdbginfo"
defines { "NDEBUG" }
flags { "Optimize", "Symbols" }
targetname "efsw-test-reldbginfo"
conf_warnings()
project "efsw-test-stdc"
kind "ConsoleApp"
language "C"
links { "efsw-shared-lib" }
files { "src/test/*.c" }
includedirs { "include", "src" }
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-test-stdc-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
flags { "Optimize" }
targetname "efsw-test-stdc-release"
conf_warnings()
configuration "relwithdbginfo"
defines { "NDEBUG" }
flags { "Optimize", "Symbols" }
targetname "efsw-test-stdc-reldbginfo"
conf_warnings()
project "efsw-shared-lib"
kind "SharedLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
defines { "EFSW_DYNAMIC", "EFSW_EXPORTS" }
conf_excludes()
conf_links()
configuration "debug"
defines { "DEBUG" }
flags { "Symbols" }
targetname "efsw-debug"
conf_warnings()
configuration "release"
defines { "NDEBUG" }
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

View File

@ -1,273 +1,273 @@
newoption { trigger = "verbose", description = "Build efsw with verbose mode." }
newoption { trigger = "strip-symbols", description = "Strip debugging symbols in other file ( only for relwithdbginfo configuration )." }
newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer" }
efsw_major_version = "1"
efsw_minor_version = "5"
efsw_patch_version = "0"
efsw_version = efsw_major_version .. "." .. efsw_minor_version .. "." .. efsw_patch_version
function get_include_paths()
local function _insert_include_paths( file )
local function _trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local paths = { }
local lines = file:read('*all')
for line in string.gmatch(lines, '([^\n]+)')
do
table.insert( paths, _trim( line ) )
end
file:close()
return paths
end
local file = io.popen( "echo | gcc -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/'", 'r' )
local include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
file = io.popen( "echo | clang++ -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/' | grep -v 'nonexistent'", 'r' )
include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
table.insert( include_paths, "/usr/include" )
table.insert( include_paths, "/usr/local/include" )
end
end
return include_paths
end
function inotify_header_exists()
local efsw_include_paths = get_include_paths()
for _,v in pairs( efsw_include_paths )
do
local cur_path = v .. "/sys/inotify.h"
if os.isfile( cur_path ) then
return true
end
end
return false
end
function string.starts(String,Start)
if ( _ACTION ) then
return string.sub(String,1,string.len(Start))==Start
end
return false
end
function is_vs()
return ( string.starts(_ACTION,"vs") )
end
function conf_warnings()
if not is_vs() then
buildoptions{ "-Wall -Wno-long-long" }
if not os.istarget("windows") then
buildoptions{ "-fPIC" }
end
else
defines { "_SCL_SECURE_NO_WARNINGS" }
end
if _OPTIONS["thread-sanitizer"] then
buildoptions { "-fsanitize=thread" }
linkoptions { "-fsanitize=thread" }
if not os.istarget("macosx") then
links { "tsan" }
end
end
end
function conf_links()
if not os.istarget("windows") and not os.istarget("haiku") then
links { "pthread" }
end
if os.istarget("macosx") then
links { "CoreFoundation.framework", "CoreServices.framework" }
end
end
function conf_excludes()
if os.istarget("windows") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherInotify.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.istarget("linux") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.istarget("macosx") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp" }
elseif os.istarget("bsd") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
end
if os.istarget("linux") and not inotify_header_exists() then
defines { "EFSW_INOTIFY_NOSYS" }
end
end
workspace "efsw"
location("./make/" .. os.target() .. "/")
targetdir("./bin")
configurations { "debug", "release", "relwithdbginfo" }
platforms { "x86_64", "x86", "ARM", "ARM64" }
if os.istarget("windows") then
osfiles = "src/efsw/platform/win/*.cpp"
else
osfiles = "src/efsw/platform/posix/*.cpp"
end
-- Activates verbose mode
if _OPTIONS["verbose"] then
defines { "EFSW_VERBOSE" }
end
cppdialect "C++11"
objdir("obj/" .. os.target() .. "/")
filter "platforms:x86"
architecture "x86"
filter "platforms:x86_64"
architecture "x86_64"
filter "platforms:arm"
architecture "ARM"
filter "platforms:arm64"
architecture "ARM64"
project "efsw-static-lib"
kind "StaticLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
conf_excludes()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-static-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-static-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-static-reldbginfo"
conf_warnings()
project "efsw-test"
kind "ConsoleApp"
language "C++"
links { "efsw-static-lib" }
files { "src/test/efsw-test.cpp" }
includedirs { "include", "src" }
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-test-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-test-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-test-reldbginfo"
conf_warnings()
project "joomer-efsw-file-monitoring"
kind "ConsoleApp"
language "C++"
links { "efsw-static-lib" }
files { "src/joomer-efsw-file-monitoring.cpp" }
includedirs { "include", "src" }
conf_links()
project "efsw-test-stdc"
kind "ConsoleApp"
language "C"
links { "efsw-shared-lib" }
files { "src/test/*.c" }
includedirs { "include", "src" }
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-test-stdc-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-test-stdc-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-test-stdc-reldbginfo"
conf_warnings()
project "efsw-shared-lib"
kind "SharedLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
defines { "EFSW_DYNAMIC", "EFSW_EXPORTS" }
conf_excludes()
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw"
conf_warnings()
if os.istarget("linux") or os.istarget("bsd") or os.istarget("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
newoption { trigger = "verbose", description = "Build efsw with verbose mode." }
newoption { trigger = "strip-symbols", description = "Strip debugging symbols in other file ( only for relwithdbginfo configuration )." }
newoption { trigger = "thread-sanitizer", description ="Compile with ThreadSanitizer" }
efsw_major_version = "1"
efsw_minor_version = "5"
efsw_patch_version = "0"
efsw_version = efsw_major_version .. "." .. efsw_minor_version .. "." .. efsw_patch_version
function get_include_paths()
local function _insert_include_paths( file )
local function _trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local paths = { }
local lines = file:read('*all')
for line in string.gmatch(lines, '([^\n]+)')
do
table.insert( paths, _trim( line ) )
end
file:close()
return paths
end
local file = io.popen( "echo | gcc -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/'", 'r' )
local include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
file = io.popen( "echo | clang++ -Wp,-v -x c++ - -fsyntax-only 2>&1 | grep -v '#' | grep '/' | grep -v 'nonexistent'", 'r' )
include_paths = _insert_include_paths( file )
if next(include_paths) == nil then
table.insert( include_paths, "/usr/include" )
table.insert( include_paths, "/usr/local/include" )
end
end
return include_paths
end
function inotify_header_exists()
local efsw_include_paths = get_include_paths()
for _,v in pairs( efsw_include_paths )
do
local cur_path = v .. "/sys/inotify.h"
if os.isfile( cur_path ) then
return true
end
end
return false
end
function string.starts(String,Start)
if ( _ACTION ) then
return string.sub(String,1,string.len(Start))==Start
end
return false
end
function is_vs()
return ( string.starts(_ACTION,"vs") )
end
function conf_warnings()
if not is_vs() then
buildoptions{ "-Wall -Wno-long-long" }
if not os.istarget("windows") then
buildoptions{ "-fPIC" }
end
else
defines { "_SCL_SECURE_NO_WARNINGS" }
end
if _OPTIONS["thread-sanitizer"] then
buildoptions { "-fsanitize=thread" }
linkoptions { "-fsanitize=thread" }
if not os.istarget("macosx") then
links { "tsan" }
end
end
end
function conf_links()
if not os.istarget("windows") and not os.istarget("haiku") then
links { "pthread" }
end
if os.istarget("macosx") then
links { "CoreFoundation.framework", "CoreServices.framework" }
end
end
function conf_excludes()
if os.istarget("windows") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherInotify.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.istarget("linux") then
excludes { "src/efsw/WatcherKqueue.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherKqueue.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
elseif os.istarget("macosx") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp" }
elseif os.istarget("bsd") then
excludes { "src/efsw/WatcherInotify.cpp", "src/efsw/WatcherWin32.cpp", "src/efsw/WatcherFSEvents.cpp", "src/efsw/FileWatcherInotify.cpp", "src/efsw/FileWatcherWin32.cpp", "src/efsw/FileWatcherFSEvents.cpp" }
end
if os.istarget("linux") and not inotify_header_exists() then
defines { "EFSW_INOTIFY_NOSYS" }
end
end
workspace "efsw"
location("./make/" .. os.target() .. "/")
targetdir("./bin")
configurations { "debug", "release", "relwithdbginfo" }
platforms { "x86_64", "x86", "ARM", "ARM64" }
if os.istarget("windows") then
osfiles = "src/efsw/platform/win/*.cpp"
else
osfiles = "src/efsw/platform/posix/*.cpp"
end
-- Activates verbose mode
if _OPTIONS["verbose"] then
defines { "EFSW_VERBOSE" }
end
cppdialect "C++11"
objdir("obj/" .. os.target() .. "/")
filter "platforms:x86"
architecture "x86"
filter "platforms:x86_64"
architecture "x86_64"
filter "platforms:arm"
architecture "ARM"
filter "platforms:arm64"
architecture "ARM64"
project "efsw-static-lib"
kind "StaticLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
conf_excludes()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-static-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-static-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-static-reldbginfo"
conf_warnings()
project "efsw-test"
kind "ConsoleApp"
language "C++"
links { "efsw-static-lib" }
files { "src/test/efsw-test.cpp" }
includedirs { "include", "src" }
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-test-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-test-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-test-reldbginfo"
conf_warnings()
project "joomer-efsw-file-monitoring"
kind "ConsoleApp"
language "C++"
links { "efsw-static-lib" }
files { "src/joomer-efsw-file-monitoring.cpp" }
includedirs { "include", "src" }
conf_links()
project "efsw-test-stdc"
kind "ConsoleApp"
language "C"
links { "efsw-shared-lib" }
files { "src/test/*.c" }
includedirs { "include", "src" }
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-test-stdc-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw-test-stdc-release"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw-test-stdc-reldbginfo"
conf_warnings()
project "efsw-shared-lib"
kind "SharedLib"
language "C++"
targetdir("./lib")
includedirs { "include", "src" }
files { "src/efsw/*.cpp", osfiles }
defines { "EFSW_DYNAMIC", "EFSW_EXPORTS" }
conf_excludes()
conf_links()
filter "configurations:debug"
defines { "DEBUG" }
symbols "On"
targetname "efsw-debug"
conf_warnings()
filter "configurations:release"
defines { "NDEBUG" }
optimize "On"
targetname "efsw"
conf_warnings()
filter "configurations:relwithdbginfo"
defines { "NDEBUG" }
symbols "On"
optimize "On"
targetname "efsw"
conf_warnings()
if os.istarget("linux") or os.istarget("bsd") or os.istarget("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

View File

@ -1,211 +1,425 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.2, 2019-11-10T01:12:11. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{55fc4913-4acc-49e6-b0d5-ebf25d4d498e}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<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">{eb5b6178-a7a7-439e-ab01-e63b057196a1}</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="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\programming\efsw\make\windows</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</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="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">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="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<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.Executable">%{buildDir}\..\..\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run C:\programming\efsw\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</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="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>
<<<<<<< HEAD
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.2, 2019-11-10T01:12:11. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{55fc4913-4acc-49e6-b0d5-ebf25d4d498e}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<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">{eb5b6178-a7a7-439e-ab01-e63b057196a1}</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="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\programming\efsw\make\windows</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</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="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">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="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<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.Executable">%{buildDir}\..\..\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run C:\programming\efsw\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</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="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>
=======
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.2, 2019-11-10T01:12:11. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{55fc4913-4acc-49e6-b0d5-ebf25d4d498e}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<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">{eb5b6178-a7a7-439e-ab01-e63b057196a1}</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="ProjectExplorer.BuildConfiguration.BuildDirectory">C:\programming\efsw\make\windows</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">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"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</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">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</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="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></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="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
<value type="int" key="Analyzer.Perf.Frequency">250</value>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">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="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<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.Executable">%{buildDir}\..\..\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run C:\programming\efsw\bin\efsw-test-debug.exe</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</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="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>
>>>>>>> 0adf96dcdb6ba38e789d409ca1bf1fc149e60808

View File

@ -1,215 +1,433 @@
../../include/efsw/efsw.hpp
../../premake5.lua
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/System.cpp
../../src/efsw/platform/platformimpl.hpp
../../src/efsw/platform/posix/ThreadImpl.hpp
../../src/efsw/platform/posix/MutexImpl.hpp
../../src/efsw/platform/posix/SystemImpl.hpp
../../src/efsw/platform/posix/ThreadImpl.cpp
../../src/efsw/platform/posix/MutexImpl.cpp
../../src/efsw/platform/posix/SystemImpl.cpp
../../src/efsw/platform/win/ThreadImpl.hpp
../../src/efsw/platform/win/MutexImpl.hpp
../../src/efsw/platform/win/SystemImpl.hpp
../../src/efsw/platform/win/ThreadImpl.cpp
../../src/efsw/platform/win/MutexImpl.cpp
../../src/efsw/platform/win/SystemImpl.cpp
../../src/efsw/base.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/platform/posix/FileSystemImpl.hpp
../../src/efsw/platform/posix/FileSystemImpl.cpp
../../src/efsw/platform/win/FileSystemImpl.hpp
../../src/efsw/platform/win/FileSystemImpl.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/base.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/sophist.h
../../src/efsw/base.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Utf.inl
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/test/efsw-test.cpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/sophist.h
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../premake4.lua
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../src/efsw/WatcherWin32.hpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/WatcherFSEvents.hpp
../../src/efsw/Watcher.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherFSEvents.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/DirectorySnapshotDiff.hpp
../../src/efsw/DirectorySnapshot.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherWin32.cpp
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/WatcherFSEvents.cpp
../../src/efsw/Watcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcherFSEvents.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/DirectorySnapshotDiff.cpp
../../src/efsw/DirectorySnapshot.cpp
../../src/efsw/Debug.cpp
../../include/efsw/efsw.h
../../src/efsw/FileWatcherCWrapper.cpp
<<<<<<< HEAD
../../include/efsw/efsw.hpp
../../premake5.lua
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/System.cpp
../../src/efsw/platform/platformimpl.hpp
../../src/efsw/platform/posix/ThreadImpl.hpp
../../src/efsw/platform/posix/MutexImpl.hpp
../../src/efsw/platform/posix/SystemImpl.hpp
../../src/efsw/platform/posix/ThreadImpl.cpp
../../src/efsw/platform/posix/MutexImpl.cpp
../../src/efsw/platform/posix/SystemImpl.cpp
../../src/efsw/platform/win/ThreadImpl.hpp
../../src/efsw/platform/win/MutexImpl.hpp
../../src/efsw/platform/win/SystemImpl.hpp
../../src/efsw/platform/win/ThreadImpl.cpp
../../src/efsw/platform/win/MutexImpl.cpp
../../src/efsw/platform/win/SystemImpl.cpp
../../src/efsw/base.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/platform/posix/FileSystemImpl.hpp
../../src/efsw/platform/posix/FileSystemImpl.cpp
../../src/efsw/platform/win/FileSystemImpl.hpp
../../src/efsw/platform/win/FileSystemImpl.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/base.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/sophist.h
../../src/efsw/base.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Utf.inl
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/test/efsw-test.cpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/sophist.h
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../premake4.lua
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../src/efsw/WatcherWin32.hpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/WatcherFSEvents.hpp
../../src/efsw/Watcher.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherFSEvents.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/DirectorySnapshotDiff.hpp
../../src/efsw/DirectorySnapshot.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherWin32.cpp
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/WatcherFSEvents.cpp
../../src/efsw/Watcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcherFSEvents.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/DirectorySnapshotDiff.cpp
../../src/efsw/DirectorySnapshot.cpp
../../src/efsw/Debug.cpp
../../include/efsw/efsw.h
../../src/efsw/FileWatcherCWrapper.cpp
=======
../../include/efsw/efsw.hpp
../../premake5.lua
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/System.cpp
../../src/efsw/platform/platformimpl.hpp
../../src/efsw/platform/posix/ThreadImpl.hpp
../../src/efsw/platform/posix/MutexImpl.hpp
../../src/efsw/platform/posix/SystemImpl.hpp
../../src/efsw/platform/posix/ThreadImpl.cpp
../../src/efsw/platform/posix/MutexImpl.cpp
../../src/efsw/platform/posix/SystemImpl.cpp
../../src/efsw/platform/win/ThreadImpl.hpp
../../src/efsw/platform/win/MutexImpl.hpp
../../src/efsw/platform/win/SystemImpl.hpp
../../src/efsw/platform/win/ThreadImpl.cpp
../../src/efsw/platform/win/MutexImpl.cpp
../../src/efsw/platform/win/SystemImpl.cpp
../../src/efsw/base.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/platform/posix/FileSystemImpl.hpp
../../src/efsw/platform/posix/FileSystemImpl.cpp
../../src/efsw/platform/win/FileSystemImpl.hpp
../../src/efsw/platform/win/FileSystemImpl.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/base.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/sophist.h
../../src/efsw/base.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/Utf.inl
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/test/efsw-test.cpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/sophist.h
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../premake4.lua
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/Debug.cpp
../../src/efsw/WatcherWin32.hpp
../../src/efsw/WatcherKqueue.hpp
../../src/efsw/WatcherInotify.hpp
../../src/efsw/WatcherGeneric.hpp
../../src/efsw/WatcherFSEvents.hpp
../../src/efsw/Watcher.hpp
../../src/efsw/Utf.hpp
../../src/efsw/Thread.hpp
../../src/efsw/System.hpp
../../src/efsw/String.hpp
../../src/efsw/sophist.h
../../src/efsw/Mutex.hpp
../../src/efsw/FileWatcherWin32.hpp
../../src/efsw/FileWatcherKqueue.hpp
../../src/efsw/FileWatcherInotify.hpp
../../src/efsw/FileWatcherImpl.hpp
../../src/efsw/FileWatcherGeneric.hpp
../../src/efsw/FileWatcherFSEvents.hpp
../../src/efsw/FileSystem.hpp
../../src/efsw/FileInfo.hpp
../../src/efsw/DirWatcherGeneric.hpp
../../src/efsw/DirectorySnapshotDiff.hpp
../../src/efsw/DirectorySnapshot.hpp
../../src/efsw/Debug.hpp
../../src/efsw/base.hpp
../../src/efsw/Utf.inl
../../src/efsw/WatcherWin32.cpp
../../src/efsw/WatcherKqueue.cpp
../../src/efsw/WatcherInotify.cpp
../../src/efsw/WatcherGeneric.cpp
../../src/efsw/WatcherFSEvents.cpp
../../src/efsw/Watcher.cpp
../../src/efsw/Thread.cpp
../../src/efsw/System.cpp
../../src/efsw/String.cpp
../../src/efsw/Mutex.cpp
../../src/efsw/Log.cpp
../../src/efsw/FileWatcherWin32.cpp
../../src/efsw/FileWatcherKqueue.cpp
../../src/efsw/FileWatcherInotify.cpp
../../src/efsw/FileWatcherImpl.cpp
../../src/efsw/FileWatcherGeneric.cpp
../../src/efsw/FileWatcherFSEvents.cpp
../../src/efsw/FileWatcher.cpp
../../src/efsw/FileSystem.cpp
../../src/efsw/FileInfo.cpp
../../src/efsw/DirWatcherGeneric.cpp
../../src/efsw/DirectorySnapshotDiff.cpp
../../src/efsw/DirectorySnapshot.cpp
../../src/efsw/Debug.cpp
../../include/efsw/efsw.h
../../src/efsw/FileWatcherCWrapper.cpp
>>>>>>> 0adf96dcdb6ba38e789d409ca1bf1fc149e60808

View File

@ -1,120 +1,120 @@
#include <efsw/FileSystem.hpp>
#include <efsw/FileWatcherGeneric.hpp>
#include <efsw/FileWatcherImpl.hpp>
#include <efsw/efsw.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <efsw/FileWatcherWin32.hpp>
#define FILEWATCHER_IMPL FileWatcherWin32
#define BACKEND_NAME "Win32"
#elif EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY
#include <efsw/FileWatcherInotify.hpp>
#define FILEWATCHER_IMPL FileWatcherInotify
#define BACKEND_NAME "Inotify"
#elif EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE
#include <efsw/FileWatcherKqueue.hpp>
#define FILEWATCHER_IMPL FileWatcherKqueue
#define BACKEND_NAME "Kqueue"
#elif EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
#include <efsw/FileWatcherFSEvents.hpp>
#define FILEWATCHER_IMPL FileWatcherFSEvents
#define BACKEND_NAME "FSEvents"
#else
#define FILEWATCHER_IMPL FileWatcherGeneric
#define BACKEND_NAME "Generic"
#endif
#include <efsw/Debug.hpp>
namespace efsw {
FileWatcher::FileWatcher() : mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
mImpl = new FileWatcherGeneric( this );
}
}
FileWatcher::FileWatcher( bool useGenericFileWatcher ) :
mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
if ( useGenericFileWatcher ) {
efDEBUG( "Using backend: Generic\n" );
mImpl = new FileWatcherGeneric( this );
} else {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
mImpl = new FileWatcherGeneric( this );
}
}
}
FileWatcher::~FileWatcher() {
efSAFE_DELETE( mImpl );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher ) {
return addWatch( directory, watcher, false, {} );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive ) {
return addWatch( directory, watcher, recursive, {} );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption>& options ) {
if ( mImpl->mIsGeneric || !FileSystem::isRemoteFS( directory ) ) {
return mImpl->addWatch( directory, watcher, recursive, options );
} else {
return Errors::Log::createLastError( Errors::FileRemote, directory );
}
}
void FileWatcher::removeWatch( const std::string& directory ) {
mImpl->removeWatch( directory );
}
void FileWatcher::removeWatch( WatchID watchid ) {
mImpl->removeWatch( watchid );
}
void FileWatcher::watch() {
mImpl->watch();
}
std::vector<std::string> FileWatcher::directories() {
return mImpl->directories();
}
void FileWatcher::followSymlinks( bool follow ) {
mFollowSymlinks = follow;
}
const bool& FileWatcher::followSymlinks() const {
return mFollowSymlinks;
}
void FileWatcher::allowOutOfScopeLinks( bool allow ) {
mOutOfScopeLinks = allow;
}
const bool& FileWatcher::allowOutOfScopeLinks() const {
return mOutOfScopeLinks;
}
} // namespace efsw
#include <efsw/FileSystem.hpp>
#include <efsw/FileWatcherGeneric.hpp>
#include <efsw/FileWatcherImpl.hpp>
#include <efsw/efsw.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <efsw/FileWatcherWin32.hpp>
#define FILEWATCHER_IMPL FileWatcherWin32
#define BACKEND_NAME "Win32"
#elif EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY
#include <efsw/FileWatcherInotify.hpp>
#define FILEWATCHER_IMPL FileWatcherInotify
#define BACKEND_NAME "Inotify"
#elif EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE
#include <efsw/FileWatcherKqueue.hpp>
#define FILEWATCHER_IMPL FileWatcherKqueue
#define BACKEND_NAME "Kqueue"
#elif EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
#include <efsw/FileWatcherFSEvents.hpp>
#define FILEWATCHER_IMPL FileWatcherFSEvents
#define BACKEND_NAME "FSEvents"
#else
#define FILEWATCHER_IMPL FileWatcherGeneric
#define BACKEND_NAME "Generic"
#endif
#include <efsw/Debug.hpp>
namespace efsw {
FileWatcher::FileWatcher() : mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
mImpl = new FileWatcherGeneric( this );
}
}
FileWatcher::FileWatcher( bool useGenericFileWatcher ) :
mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
if ( useGenericFileWatcher ) {
efDEBUG( "Using backend: Generic\n" );
mImpl = new FileWatcherGeneric( this );
} else {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
mImpl = new FileWatcherGeneric( this );
}
}
}
FileWatcher::~FileWatcher() {
efSAFE_DELETE( mImpl );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher ) {
return addWatch( directory, watcher, false, {} );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive ) {
return addWatch( directory, watcher, recursive, {} );
}
WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption>& options ) {
if ( mImpl->mIsGeneric || !FileSystem::isRemoteFS( directory ) ) {
return mImpl->addWatch( directory, watcher, recursive, options );
} else {
return Errors::Log::createLastError( Errors::FileRemote, directory );
}
}
void FileWatcher::removeWatch( const std::string& directory ) {
mImpl->removeWatch( directory );
}
void FileWatcher::removeWatch( WatchID watchid ) {
mImpl->removeWatch( watchid );
}
void FileWatcher::watch() {
mImpl->watch();
}
std::vector<std::string> FileWatcher::directories() {
return mImpl->directories();
}
void FileWatcher::followSymlinks( bool follow ) {
mFollowSymlinks = follow;
}
const bool& FileWatcher::followSymlinks() const {
return mFollowSymlinks;
}
void FileWatcher::allowOutOfScopeLinks( bool allow ) {
mOutOfScopeLinks = allow;
}
const bool& FileWatcher::allowOutOfScopeLinks() const {
return mOutOfScopeLinks;
}
} // namespace efsw

View File

@ -1,34 +1,34 @@
#include <efsw/FileWatcherImpl.hpp>
#include <efsw/String.hpp>
#include <efsw/System.hpp>
namespace efsw {
FileWatcherImpl::FileWatcherImpl( FileWatcher* parent ) :
mFileWatcher( parent ), mInitOK( false ), mIsGeneric( false ) {
System::maxFD();
}
FileWatcherImpl::~FileWatcherImpl() {}
bool FileWatcherImpl::initOK() {
return static_cast<bool>( mInitOK );
}
bool FileWatcherImpl::linkAllowed( const std::string& curPath, const std::string& link ) {
return ( mFileWatcher->followSymlinks() && mFileWatcher->allowOutOfScopeLinks() ) ||
-1 != String::strStartsWith( curPath, link );
}
int FileWatcherImpl::getOptionValue( const std::vector<WatcherOption>& options, Option option,
int defaultValue ) {
for ( size_t i = 0; i < options.size(); i++ ) {
if ( options[i].mOption == option ) {
return options[i].mValue;
}
}
return defaultValue;
}
} // namespace efsw
#include <efsw/FileWatcherImpl.hpp>
#include <efsw/String.hpp>
#include <efsw/System.hpp>
namespace efsw {
FileWatcherImpl::FileWatcherImpl( FileWatcher* parent ) :
mFileWatcher( parent ), mInitOK( false ), mIsGeneric( false ) {
System::maxFD();
}
FileWatcherImpl::~FileWatcherImpl() {}
bool FileWatcherImpl::initOK() {
return static_cast<bool>( mInitOK );
}
bool FileWatcherImpl::linkAllowed( const std::string& curPath, const std::string& link ) {
return ( mFileWatcher->followSymlinks() && mFileWatcher->allowOutOfScopeLinks() ) ||
-1 != String::strStartsWith( curPath, link );
}
int FileWatcherImpl::getOptionValue( const std::vector<WatcherOption>& options, Option option,
int defaultValue ) {
for ( size_t i = 0; i < options.size(); i++ ) {
if ( options[i].mOption == option ) {
return options[i].mValue;
}
}
return defaultValue;
}
} // namespace efsw

View File

@ -1,64 +1,64 @@
#ifndef EFSW_FILEWATCHERIMPL_HPP
#define EFSW_FILEWATCHERIMPL_HPP
#include <efsw/Atomic.hpp>
#include <efsw/Mutex.hpp>
#include <efsw/Thread.hpp>
#include <efsw/Watcher.hpp>
#include <efsw/base.hpp>
#include <efsw/efsw.hpp>
namespace efsw {
class FileWatcherImpl {
public:
FileWatcherImpl( FileWatcher* parent );
virtual ~FileWatcherImpl();
/// Add a directory watch
/// On error returns WatchID with Error type.
virtual WatchID addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption>& options = {} ) = 0;
/// Remove a directory watch. This is a brute force lazy search O(nlogn).
virtual void removeWatch( const std::string& directory ) = 0;
/// Remove a directory watch. This is a map lookup O(logn).
virtual void removeWatch( WatchID watchid ) = 0;
/// Updates the watcher. Must be called often.
virtual void watch() = 0;
/// Handles the action
virtual void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
std::string oldFilename = "" ) = 0;
/// @return Returns a list of the directories that are being watched
virtual std::vector<std::string> directories() = 0;
/// @return true if the backend init successfully
virtual bool initOK();
/// @return If the link is allowed according to the current path and the state of out scope
/// links
virtual bool linkAllowed( const std::string& curPath, const std::string& link );
/// Search if a directory already exists in the watches
virtual bool pathInWatches( const std::string& path ) = 0;
protected:
friend class FileWatcher;
friend class DirWatcherGeneric;
FileWatcher* mFileWatcher;
Atomic<bool> mInitOK;
bool mIsGeneric;
int getOptionValue( const std::vector<WatcherOption>& options, Option option,
int defaultValue );
};
} // namespace efsw
#endif
#ifndef EFSW_FILEWATCHERIMPL_HPP
#define EFSW_FILEWATCHERIMPL_HPP
#include <efsw/Atomic.hpp>
#include <efsw/Mutex.hpp>
#include <efsw/Thread.hpp>
#include <efsw/Watcher.hpp>
#include <efsw/base.hpp>
#include <efsw/efsw.hpp>
namespace efsw {
class FileWatcherImpl {
public:
FileWatcherImpl( FileWatcher* parent );
virtual ~FileWatcherImpl();
/// Add a directory watch
/// On error returns WatchID with Error type.
virtual WatchID addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption>& options = {} ) = 0;
/// Remove a directory watch. This is a brute force lazy search O(nlogn).
virtual void removeWatch( const std::string& directory ) = 0;
/// Remove a directory watch. This is a map lookup O(logn).
virtual void removeWatch( WatchID watchid ) = 0;
/// Updates the watcher. Must be called often.
virtual void watch() = 0;
/// Handles the action
virtual void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
std::string oldFilename = "" ) = 0;
/// @return Returns a list of the directories that are being watched
virtual std::vector<std::string> directories() = 0;
/// @return true if the backend init successfully
virtual bool initOK();
/// @return If the link is allowed according to the current path and the state of out scope
/// links
virtual bool linkAllowed( const std::string& curPath, const std::string& link );
/// Search if a directory already exists in the watches
virtual bool pathInWatches( const std::string& path ) = 0;
protected:
friend class FileWatcher;
friend class DirWatcherGeneric;
FileWatcher* mFileWatcher;
Atomic<bool> mInitOK;
bool mIsGeneric;
int getOptionValue( const std::vector<WatcherOption>& options, Option option,
int defaultValue );
};
} // namespace efsw
#endif

View File

@ -1,267 +1,267 @@
#include <efsw/FileSystem.hpp>
#include <efsw/FileWatcherWin32.hpp>
#include <efsw/Lock.hpp>
#include <efsw/String.hpp>
#include <efsw/System.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
namespace efsw {
FileWatcherWin32::FileWatcherWin32( FileWatcher* parent ) :
FileWatcherImpl( parent ), mLastWatchID( 0 ), mThread( NULL ) {
mIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 );
if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE )
mInitOK = true;
}
FileWatcherWin32::~FileWatcherWin32() {
mInitOK = false;
if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE ) {
PostQueuedCompletionStatus( mIOCP, 0, reinterpret_cast<ULONG_PTR>( this ), NULL );
}
efSAFE_DELETE( mThread );
removeAllWatches();
if ( mIOCP )
CloseHandle( mIOCP );
}
WatchID FileWatcherWin32::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption> &options ) {
std::string dir( directory );
FileInfo fi( dir );
if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
} else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
}
FileSystem::dirAddSlashAtEnd( dir );
Lock lock( mWatchesLock );
if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, dir );
}
WatchID watchid = ++mLastWatchID;
DWORD bufferSize = static_cast<DWORD>( getOptionValue(options, Option::WinBufferSize, 63 * 1024) );
DWORD notifyFilter = static_cast<DWORD>( getOptionValue(options, Option::WinNotifyFilter,
FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_SIZE) );
WatcherStructWin32* watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(),
recursive, bufferSize, notifyFilter, mIOCP );
if ( NULL == watch ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
}
// Add the handle to the handles vector
watch->Watch->ID = watchid;
watch->Watch->Watch = this;
watch->Watch->Listener = watcher;
watch->Watch->DirName = new char[dir.length() + 1];
strcpy( watch->Watch->DirName, dir.c_str() );
mWatches.insert( watch );
return watchid;
}
void FileWatcherWin32::removeWatch( const std::string& directory ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
if ( directory == ( *iter )->Watch->DirName ) {
removeWatch( *iter );
break;
}
}
}
void FileWatcherWin32::removeWatch( WatchID watchid ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
// Find the watch ID
if ( ( *iter )->Watch->ID == watchid ) {
removeWatch( *iter );
return;
}
}
}
void FileWatcherWin32::removeWatch( WatcherStructWin32* watch ) {
Lock lock( mWatchesLock );
DestroyWatch( watch );
mWatches.erase( watch );
}
void FileWatcherWin32::watch() {
if ( NULL == mThread ) {
mThread = new Thread([this]{run();});
mThread->launch();
}
}
void FileWatcherWin32::removeAllWatches() {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
DestroyWatch( ( *iter ) );
}
mWatches.clear();
}
void FileWatcherWin32::run() {
do {
if ( mInitOK && !mWatches.empty() ) {
DWORD numOfBytes = 0;
OVERLAPPED* ov = NULL;
ULONG_PTR compKey = 0;
BOOL res = FALSE;
while ( ( res = GetQueuedCompletionStatus( mIOCP, &numOfBytes, &compKey, &ov,
INFINITE ) ) != FALSE ) {
if ( compKey != 0 && compKey == reinterpret_cast<ULONG_PTR>( this ) ) {
break;
} else {
Lock lock( mWatchesLock );
if (mWatches.find( (WatcherStructWin32*)ov ) != mWatches.end())
WatchCallback( numOfBytes, ov );
}
}
} else {
System::sleep( 10 );
}
} while ( mInitOK );
removeAllWatches();
}
void FileWatcherWin32::handleAction( Watcher* watch, const std::string& filename,
unsigned long action, std::string /*oldFilename*/ ) {
Action fwAction;
switch ( action ) {
case FILE_ACTION_RENAMED_OLD_NAME:
watch->OldFileName = filename;
return;
case FILE_ACTION_ADDED:
fwAction = Actions::Add;
break;
case FILE_ACTION_RENAMED_NEW_NAME: {
fwAction = Actions::Moved;
std::string fpath( watch->Directory + filename );
// Update the directory path
if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) {
// Update the new directory path
std::string opath( watch->Directory + watch->OldFileName );
FileSystem::dirAddSlashAtEnd( opath );
FileSystem::dirAddSlashAtEnd( fpath );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
if ( ( *it )->Watch->Directory == opath ) {
( *it )->Watch->Directory = fpath;
break;
}
}
}
std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
std::string realFilename = filename;
std::size_t sepPos = filename.find_last_of( "/\\" );
std::string oldFolderPath =
static_cast<WatcherWin32*>( watch )->DirName +
watch->OldFileName.substr( 0, watch->OldFileName.find_last_of( "/\\" ) );
if ( sepPos != std::string::npos ) {
folderPath +=
filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
realFilename = filename.substr( sepPos + 1 );
}
if ( folderPath == oldFolderPath ) {
watch->Listener->handleFileAction(
watch->ID, folderPath, realFilename, fwAction,
FileSystem::fileNameFromPath( watch->OldFileName ) );
} else {
watch->Listener->handleFileAction( watch->ID,
static_cast<WatcherWin32*>( watch )->DirName,
filename, fwAction, watch->OldFileName );
}
return;
}
case FILE_ACTION_REMOVED:
fwAction = Actions::Delete;
break;
case FILE_ACTION_MODIFIED:
fwAction = Actions::Modified;
break;
default:
return;
};
std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
std::string realFilename = filename;
std::size_t sepPos = filename.find_last_of( "/\\" );
if ( sepPos != std::string::npos ) {
folderPath += filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
realFilename = filename.substr( sepPos + 1 );
}
FileSystem::dirAddSlashAtEnd( folderPath );
watch->Listener->handleFileAction( watch->ID, folderPath, realFilename, fwAction );
}
std::vector<std::string> FileWatcherWin32::directories() {
std::vector<std::string> dirs;
Lock lock( mWatchesLock );
dirs.reserve( mWatches.size() );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
dirs.push_back( std::string( ( *it )->Watch->DirName ) );
}
return dirs;
}
bool FileWatcherWin32::pathInWatches( const std::string& path ) {
Lock lock( mWatchesLock );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
if ( ( *it )->Watch->DirName == path ) {
return true;
}
}
return false;
}
} // namespace efsw
#endif
#include <efsw/FileSystem.hpp>
#include <efsw/FileWatcherWin32.hpp>
#include <efsw/Lock.hpp>
#include <efsw/String.hpp>
#include <efsw/System.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
namespace efsw {
FileWatcherWin32::FileWatcherWin32( FileWatcher* parent ) :
FileWatcherImpl( parent ), mLastWatchID( 0 ), mThread( NULL ) {
mIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 );
if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE )
mInitOK = true;
}
FileWatcherWin32::~FileWatcherWin32() {
mInitOK = false;
if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE ) {
PostQueuedCompletionStatus( mIOCP, 0, reinterpret_cast<ULONG_PTR>( this ), NULL );
}
efSAFE_DELETE( mThread );
removeAllWatches();
if ( mIOCP )
CloseHandle( mIOCP );
}
WatchID FileWatcherWin32::addWatch( const std::string& directory, FileWatchListener* watcher,
bool recursive, const std::vector<WatcherOption> &options ) {
std::string dir( directory );
FileInfo fi( dir );
if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
} else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
}
FileSystem::dirAddSlashAtEnd( dir );
Lock lock( mWatchesLock );
if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, dir );
}
WatchID watchid = ++mLastWatchID;
DWORD bufferSize = static_cast<DWORD>( getOptionValue(options, Option::WinBufferSize, 63 * 1024) );
DWORD notifyFilter = static_cast<DWORD>( getOptionValue(options, Option::WinNotifyFilter,
FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_SIZE) );
WatcherStructWin32* watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(),
recursive, bufferSize, notifyFilter, mIOCP );
if ( NULL == watch ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
}
// Add the handle to the handles vector
watch->Watch->ID = watchid;
watch->Watch->Watch = this;
watch->Watch->Listener = watcher;
watch->Watch->DirName = new char[dir.length() + 1];
strcpy( watch->Watch->DirName, dir.c_str() );
mWatches.insert( watch );
return watchid;
}
void FileWatcherWin32::removeWatch( const std::string& directory ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
if ( directory == ( *iter )->Watch->DirName ) {
removeWatch( *iter );
break;
}
}
}
void FileWatcherWin32::removeWatch( WatchID watchid ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
// Find the watch ID
if ( ( *iter )->Watch->ID == watchid ) {
removeWatch( *iter );
return;
}
}
}
void FileWatcherWin32::removeWatch( WatcherStructWin32* watch ) {
Lock lock( mWatchesLock );
DestroyWatch( watch );
mWatches.erase( watch );
}
void FileWatcherWin32::watch() {
if ( NULL == mThread ) {
mThread = new Thread([this]{run();});
mThread->launch();
}
}
void FileWatcherWin32::removeAllWatches() {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
for ( ; iter != mWatches.end(); ++iter ) {
DestroyWatch( ( *iter ) );
}
mWatches.clear();
}
void FileWatcherWin32::run() {
do {
if ( mInitOK && !mWatches.empty() ) {
DWORD numOfBytes = 0;
OVERLAPPED* ov = NULL;
ULONG_PTR compKey = 0;
BOOL res = FALSE;
while ( ( res = GetQueuedCompletionStatus( mIOCP, &numOfBytes, &compKey, &ov,
INFINITE ) ) != FALSE ) {
if ( compKey != 0 && compKey == reinterpret_cast<ULONG_PTR>( this ) ) {
break;
} else {
Lock lock( mWatchesLock );
if (mWatches.find( (WatcherStructWin32*)ov ) != mWatches.end())
WatchCallback( numOfBytes, ov );
}
}
} else {
System::sleep( 10 );
}
} while ( mInitOK );
removeAllWatches();
}
void FileWatcherWin32::handleAction( Watcher* watch, const std::string& filename,
unsigned long action, std::string /*oldFilename*/ ) {
Action fwAction;
switch ( action ) {
case FILE_ACTION_RENAMED_OLD_NAME:
watch->OldFileName = filename;
return;
case FILE_ACTION_ADDED:
fwAction = Actions::Add;
break;
case FILE_ACTION_RENAMED_NEW_NAME: {
fwAction = Actions::Moved;
std::string fpath( watch->Directory + filename );
// Update the directory path
if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) {
// Update the new directory path
std::string opath( watch->Directory + watch->OldFileName );
FileSystem::dirAddSlashAtEnd( opath );
FileSystem::dirAddSlashAtEnd( fpath );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
if ( ( *it )->Watch->Directory == opath ) {
( *it )->Watch->Directory = fpath;
break;
}
}
}
std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
std::string realFilename = filename;
std::size_t sepPos = filename.find_last_of( "/\\" );
std::string oldFolderPath =
static_cast<WatcherWin32*>( watch )->DirName +
watch->OldFileName.substr( 0, watch->OldFileName.find_last_of( "/\\" ) );
if ( sepPos != std::string::npos ) {
folderPath +=
filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
realFilename = filename.substr( sepPos + 1 );
}
if ( folderPath == oldFolderPath ) {
watch->Listener->handleFileAction(
watch->ID, folderPath, realFilename, fwAction,
FileSystem::fileNameFromPath( watch->OldFileName ) );
} else {
watch->Listener->handleFileAction( watch->ID,
static_cast<WatcherWin32*>( watch )->DirName,
filename, fwAction, watch->OldFileName );
}
return;
}
case FILE_ACTION_REMOVED:
fwAction = Actions::Delete;
break;
case FILE_ACTION_MODIFIED:
fwAction = Actions::Modified;
break;
default:
return;
};
std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
std::string realFilename = filename;
std::size_t sepPos = filename.find_last_of( "/\\" );
if ( sepPos != std::string::npos ) {
folderPath += filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
realFilename = filename.substr( sepPos + 1 );
}
FileSystem::dirAddSlashAtEnd( folderPath );
watch->Listener->handleFileAction( watch->ID, folderPath, realFilename, fwAction );
}
std::vector<std::string> FileWatcherWin32::directories() {
std::vector<std::string> dirs;
Lock lock( mWatchesLock );
dirs.reserve( mWatches.size() );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
dirs.push_back( std::string( ( *it )->Watch->DirName ) );
}
return dirs;
}
bool FileWatcherWin32::pathInWatches( const std::string& path ) {
Lock lock( mWatchesLock );
for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
if ( ( *it )->Watch->DirName == path ) {
return true;
}
}
return false;
}
} // namespace efsw
#endif

View File

@ -1,71 +1,71 @@
#ifndef EFSW_FILEWATCHERWIN32_HPP
#define EFSW_FILEWATCHERWIN32_HPP
#include <efsw/base.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <efsw/WatcherWin32.hpp>
#include <map>
#include <unordered_set>
#include <vector>
namespace efsw {
/// Implementation for Win32 based on ReadDirectoryChangesW.
/// @class FileWatcherWin32
class FileWatcherWin32 : public FileWatcherImpl {
public:
/// type for a map from WatchID to WatcherWin32 pointer
typedef std::unordered_set<WatcherStructWin32*> Watches;
FileWatcherWin32( FileWatcher* parent );
virtual ~FileWatcherWin32();
/// Add a directory watch
/// On error returns WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
const std::vector<WatcherOption> &options ) override;
/// Remove a directory watch. This is a brute force lazy search O(nlogn).
void removeWatch( const std::string& directory ) override;
/// Remove a directory watch. This is a map lookup O(logn).
void removeWatch( WatchID watchid ) override;
/// Updates the watcher. Must be called often.
void watch() override;
/// Handles the action
void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
std::string oldFilename = "" ) override;
/// @return Returns a list of the directories that are being watched
std::vector<std::string> directories() override;
protected:
HANDLE mIOCP;
Watches mWatches;
/// The last watchid
WatchID mLastWatchID;
Thread* mThread;
Mutex mWatchesLock;
bool pathInWatches( const std::string& path ) override;
/// Remove all directory watches.
void removeAllWatches();
void removeWatch( WatcherStructWin32* watch );
private:
void run();
};
} // namespace efsw
#endif
#endif
#ifndef EFSW_FILEWATCHERWIN32_HPP
#define EFSW_FILEWATCHERWIN32_HPP
#include <efsw/base.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <efsw/WatcherWin32.hpp>
#include <map>
#include <unordered_set>
#include <vector>
namespace efsw {
/// Implementation for Win32 based on ReadDirectoryChangesW.
/// @class FileWatcherWin32
class FileWatcherWin32 : public FileWatcherImpl {
public:
/// type for a map from WatchID to WatcherWin32 pointer
typedef std::unordered_set<WatcherStructWin32*> Watches;
FileWatcherWin32( FileWatcher* parent );
virtual ~FileWatcherWin32();
/// Add a directory watch
/// On error returns WatchID with Error type.
WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
const std::vector<WatcherOption> &options ) override;
/// Remove a directory watch. This is a brute force lazy search O(nlogn).
void removeWatch( const std::string& directory ) override;
/// Remove a directory watch. This is a map lookup O(logn).
void removeWatch( WatchID watchid ) override;
/// Updates the watcher. Must be called often.
void watch() override;
/// Handles the action
void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
std::string oldFilename = "" ) override;
/// @return Returns a list of the directories that are being watched
std::vector<std::string> directories() override;
protected:
HANDLE mIOCP;
Watches mWatches;
/// The last watchid
WatchID mLastWatchID;
Thread* mThread;
Mutex mWatchesLock;
bool pathInWatches( const std::string& path ) override;
/// Remove all directory watches.
void removeAllWatches();
void removeWatch( WatcherStructWin32* watch );
private:
void run();
};
} // namespace efsw
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +1,147 @@
/* sophist.h - 0.3 - public domain - Sean Barrett 2010
** Knowledge drawn from Brian Hook's posh.h and http://predef.sourceforge.net
** Sophist provides portable types; you typedef/#define them to your own names
**
** defines:
** - SOPHIST_endian - either SOPHIST_little_endian or SOPHIST_big_endian
** - SOPHIST_has_64 - either 0 or 1; if 0, int64 types aren't defined
** - SOPHIST_pointer64 - either 0 or 1; if 1, pointer is 64-bit
**
** - SOPHIST_intptr, SOPHIST_uintptr - integer same size as pointer
** - SOPHIST_int8, SOPHIST_uint8, SOPHIST_int16, SOPHIST_uint16
** - SOPHIST_int32, SOPHIST_uint32, SOPHIST_int64, SOPHIST_uint64
** - SOPHIST_int64_constant(number) - macros for creating 64-bit
** - SOPHIST_uint64_constant(number) integer constants
** - SOPHIST_printf_format64 - string for printf format for int64
*/
#ifndef __INCLUDE_SOPHIST_H__
#define __INCLUDE_SOPHIST_H__
#define SOPHIST_compiletime_assert(name,val) \
typedef int SOPHIST__assert##name[(val) ? 1 : -1]
/* define a couple synthetic rules to make code more readable */
#if (defined(__sparc__) || defined(__sparc)) && \
(defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__))
#define SOPHIST_sparc64
#endif
#if (defined(linux) || defined(__linux__)) && \
(defined(__alpha)||defined(__alpha__)||defined(__x86_64__)||defined(_M_X64))
#define SOPHIST_linux64
#endif
/* basic types */
typedef signed char SOPHIST_int8;
typedef unsigned char SOPHIST_uint8;
typedef signed short SOPHIST_int16;
typedef unsigned short SOPHIST_uint16;
#ifdef __palmos__
typedef signed long SOPHIST_int32;
typedef unsigned long SOPHIST_uint32;
#else
typedef signed int SOPHIST_int32;
typedef unsigned int SOPHIST_uint32;
#endif
#ifndef SOPHIST_NO_64
#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) \
|| (defined(__alpha) && defined(__DECC))
typedef signed __int64 SOPHIST_int64;
typedef unsigned __int64 SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) (x##i64)
#define SOPHIST_uint64_constant(x) (x##ui64)
#define SOPHIST_printf_format64 "I64"
#elif defined(__LP64__) || defined(__powerpc64__) || defined(SOPHIST_sparc64)
typedef signed long SOPHIST_int64;
typedef unsigned long SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) ((SOPHIST_int64) x)
#define SOPHIST_uint64_constant(x) ((SOPHIST_uint64) x)
#define SOPHIST_printf_format64 "l"
#elif defined(_LONG_LONG) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) \
|| defined(__GNUC__) || defined(__MWERKS__) || defined(__APPLE_CC__) \
|| defined(sgi) || defined (__sgi) || defined(__sgi__) \
|| defined(_CRAYC)
typedef signed long long SOPHIST_int64;
typedef unsigned long long SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) (x##LL)
#define SOPHIST_uint64_constant(x) (x##ULL)
#define SOPHIST_printf_format64 "ll"
#endif
#endif
#ifndef SOPHIST_has_64
#define SOPHIST_has_64 0
#endif
SOPHIST_compiletime_assert( int8 , sizeof(SOPHIST_int8 ) == 1);
SOPHIST_compiletime_assert(uint16, sizeof(SOPHIST_int16) == 2);
SOPHIST_compiletime_assert( int32, sizeof(SOPHIST_int32 ) == 4);
SOPHIST_compiletime_assert(uint32, sizeof(SOPHIST_uint32) == 4);
#if SOPHIST_has_64
SOPHIST_compiletime_assert( int64, sizeof(SOPHIST_int64 ) == 8);
SOPHIST_compiletime_assert(uint64, sizeof(SOPHIST_uint64) == 8);
#endif
/* determine whether pointers are 64-bit */
#if defined(SOPHIST_linux64) || defined(SOPHIST_sparc64) \
|| defined(__osf__) || (defined(_WIN64) && !defined(_XBOX)) \
|| defined(__64BIT__) \
|| defined(__LP64) || defined(__LP64__) || defined(_LP64) \
|| defined(_ADDR64) || defined(_CRAYC) \
#define SOPHIST_pointer64 1
SOPHIST_compiletime_assert(pointer64, sizeof(void*) == 8);
typedef SOPHIST_int64 SOPHIST_intptr;
typedef SOPHIST_uint64 SOPHIST_uintptr;
#else
#define SOPHIST_pointer64 0
SOPHIST_compiletime_assert(pointer64, sizeof(void*) <= 4);
/* do we care about pointers that are only 16-bit? */
typedef SOPHIST_int32 SOPHIST_intptr;
typedef SOPHIST_uint32 SOPHIST_uintptr;
#endif
SOPHIST_compiletime_assert(intptr, sizeof(SOPHIST_intptr) == sizeof(char *));
/* enumerate known little endian cases; fallback to big-endian */
#define SOPHIST_little_endian 1
#define SOPHIST_big_endian 2
#if defined(__386__) || defined(i386) || defined(__i386__) \
|| defined(__X86) || defined(_M_IX86) \
|| defined(_M_X64) || defined(__x86_64__) \
|| defined(alpha) || defined(__alpha) || defined(__alpha__) \
|| defined(_M_ALPHA) \
|| defined(ARM) || defined(_ARM) || defined(__arm__) \
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(_WIN32_WCE) || defined(__NT__) \
|| defined(__MIPSEL__)
#define SOPHIST_endian SOPHIST_little_endian
#else
#define SOPHIST_endian SOPHIST_big_endian
#endif
#endif /* __INCLUDE_SOPHIST_H__ */
/* sophist.h - 0.3 - public domain - Sean Barrett 2010
** Knowledge drawn from Brian Hook's posh.h and http://predef.sourceforge.net
** Sophist provides portable types; you typedef/#define them to your own names
**
** defines:
** - SOPHIST_endian - either SOPHIST_little_endian or SOPHIST_big_endian
** - SOPHIST_has_64 - either 0 or 1; if 0, int64 types aren't defined
** - SOPHIST_pointer64 - either 0 or 1; if 1, pointer is 64-bit
**
** - SOPHIST_intptr, SOPHIST_uintptr - integer same size as pointer
** - SOPHIST_int8, SOPHIST_uint8, SOPHIST_int16, SOPHIST_uint16
** - SOPHIST_int32, SOPHIST_uint32, SOPHIST_int64, SOPHIST_uint64
** - SOPHIST_int64_constant(number) - macros for creating 64-bit
** - SOPHIST_uint64_constant(number) integer constants
** - SOPHIST_printf_format64 - string for printf format for int64
*/
#ifndef __INCLUDE_SOPHIST_H__
#define __INCLUDE_SOPHIST_H__
#define SOPHIST_compiletime_assert(name,val) \
typedef int SOPHIST__assert##name[(val) ? 1 : -1]
/* define a couple synthetic rules to make code more readable */
#if (defined(__sparc__) || defined(__sparc)) && \
(defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__))
#define SOPHIST_sparc64
#endif
#if (defined(linux) || defined(__linux__)) && \
(defined(__alpha)||defined(__alpha__)||defined(__x86_64__)||defined(_M_X64))
#define SOPHIST_linux64
#endif
/* basic types */
typedef signed char SOPHIST_int8;
typedef unsigned char SOPHIST_uint8;
typedef signed short SOPHIST_int16;
typedef unsigned short SOPHIST_uint16;
#ifdef __palmos__
typedef signed long SOPHIST_int32;
typedef unsigned long SOPHIST_uint32;
#else
typedef signed int SOPHIST_int32;
typedef unsigned int SOPHIST_uint32;
#endif
#ifndef SOPHIST_NO_64
#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) \
|| (defined(__alpha) && defined(__DECC))
typedef signed __int64 SOPHIST_int64;
typedef unsigned __int64 SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) (x##i64)
#define SOPHIST_uint64_constant(x) (x##ui64)
#define SOPHIST_printf_format64 "I64"
#elif defined(__LP64__) || defined(__powerpc64__) || defined(SOPHIST_sparc64)
typedef signed long SOPHIST_int64;
typedef unsigned long SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) ((SOPHIST_int64) x)
#define SOPHIST_uint64_constant(x) ((SOPHIST_uint64) x)
#define SOPHIST_printf_format64 "l"
#elif defined(_LONG_LONG) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) \
|| defined(__GNUC__) || defined(__MWERKS__) || defined(__APPLE_CC__) \
|| defined(sgi) || defined (__sgi) || defined(__sgi__) \
|| defined(_CRAYC)
typedef signed long long SOPHIST_int64;
typedef unsigned long long SOPHIST_uint64;
#define SOPHIST_has_64 1
#define SOPHIST_int64_constant(x) (x##LL)
#define SOPHIST_uint64_constant(x) (x##ULL)
#define SOPHIST_printf_format64 "ll"
#endif
#endif
#ifndef SOPHIST_has_64
#define SOPHIST_has_64 0
#endif
SOPHIST_compiletime_assert( int8 , sizeof(SOPHIST_int8 ) == 1);
SOPHIST_compiletime_assert(uint16, sizeof(SOPHIST_int16) == 2);
SOPHIST_compiletime_assert( int32, sizeof(SOPHIST_int32 ) == 4);
SOPHIST_compiletime_assert(uint32, sizeof(SOPHIST_uint32) == 4);
#if SOPHIST_has_64
SOPHIST_compiletime_assert( int64, sizeof(SOPHIST_int64 ) == 8);
SOPHIST_compiletime_assert(uint64, sizeof(SOPHIST_uint64) == 8);
#endif
/* determine whether pointers are 64-bit */
#if defined(SOPHIST_linux64) || defined(SOPHIST_sparc64) \
|| defined(__osf__) || (defined(_WIN64) && !defined(_XBOX)) \
|| defined(__64BIT__) \
|| defined(__LP64) || defined(__LP64__) || defined(_LP64) \
|| defined(_ADDR64) || defined(_CRAYC) \
#define SOPHIST_pointer64 1
SOPHIST_compiletime_assert(pointer64, sizeof(void*) == 8);
typedef SOPHIST_int64 SOPHIST_intptr;
typedef SOPHIST_uint64 SOPHIST_uintptr;
#else
#define SOPHIST_pointer64 0
SOPHIST_compiletime_assert(pointer64, sizeof(void*) <= 4);
/* do we care about pointers that are only 16-bit? */
typedef SOPHIST_int32 SOPHIST_intptr;
typedef SOPHIST_uint32 SOPHIST_uintptr;
#endif
SOPHIST_compiletime_assert(intptr, sizeof(SOPHIST_intptr) == sizeof(char *));
/* enumerate known little endian cases; fallback to big-endian */
#define SOPHIST_little_endian 1
#define SOPHIST_big_endian 2
#if defined(__386__) || defined(i386) || defined(__i386__) \
|| defined(__X86) || defined(_M_IX86) \
|| defined(_M_X64) || defined(__x86_64__) \
|| defined(alpha) || defined(__alpha) || defined(__alpha__) \
|| defined(_M_ALPHA) \
|| defined(ARM) || defined(_ARM) || defined(__arm__) \
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(_WIN32_WCE) || defined(__NT__) \
|| defined(__MIPSEL__)
#define SOPHIST_endian SOPHIST_little_endian
#else
#define SOPHIST_endian SOPHIST_big_endian
#endif
#endif /* __INCLUDE_SOPHIST_H__ */

View File

@ -156,18 +156,7 @@ int main( int argc, char** argv ) {
/// add a watch to the system
handleWatchID( fileWatcher.addWatch( CurPath + "test", ul, true ) );
/// adds another watch after started watching...
/*efsw::System::sleep( 100 );
efsw::WatchID watchID =
handleWatchID( fileWatcher.addWatch( CurPath + "test2", ul, true ) );
/// delete the watch
if ( watchID > 0 ) {
efsw::System::sleep( 1000 );
fileWatcher.removeWatch( watchID );
}*/
} else {
if ( fileWatcher.addWatch( path, ul, true ) > 0 ) {
fileWatcher.watch();

View File

@ -0,0 +1,139 @@
#include <efsw/FileSystem.hpp>
#include <efsw/System.hpp>
#include <efsw/efsw.hpp>
#include <iostream>
#include <signal.h>
bool STOP = false;
void sigend( int ) {
std::cout << std::endl << "Bye bye" << std::endl;
STOP = true;
}
/// Processes a file action
class UpdateListener : public efsw::FileWatchListener {
public:
UpdateListener() {}
std::string getActionName( efsw::Action action ) {
switch ( action ) {
case efsw::Actions::Add:
return "Add";
case efsw::Actions::Modified:
return "Modified";
case efsw::Actions::Delete:
return "Delete";
case efsw::Actions::Moved:
return "Moved";
default:
return "Bad Action";
}
}
void handleFileAction( efsw::WatchID watchid, const std::string& dir,
const std::string& filename, efsw::Action action,
std::string oldFilename = "" ) override {
std::cout << "Watch ID " << watchid << " DIR ("
<< dir + ") FILE (" +
( oldFilename.empty() ? "" : "from file " + oldFilename + " to " ) +
filename + ") has event "
<< getActionName( action ) << std::endl;
}
};
efsw::WatchID handleWatchID( efsw::WatchID watchid ) {
switch ( watchid ) {
case efsw::Errors::FileNotFound:
case efsw::Errors::FileRepeated:
case efsw::Errors::FileOutOfScope:
case efsw::Errors::FileRemote:
case efsw::Errors::WatcherFailed:
case efsw::Errors::Unspecified: {
std::cout << efsw::Errors::Log::getLastErrorLog().c_str() << std::endl;
break;
}
default: {
std::cout << "Added WatchID: " << watchid << std::endl;
}
}
return watchid;
}
int main( int argc, char** argv ) {
signal( SIGABRT, sigend );
signal( SIGINT, sigend );
signal( SIGTERM, sigend );
std::cout << "Press ^C to exit demo" << std::endl;
bool commonTest = true;
bool useGeneric = false;
std::string path;
if ( argc >= 2 ) {
path = std::string( argv[1] );
if ( efsw::FileSystem::isDirectory( path ) ) {
commonTest = false;
}
if ( argc >= 3 ) {
if ( std::string( argv[2] ) == "true" ) {
useGeneric = true;
}
}
}
UpdateListener* ul = new UpdateListener();
/// create the file watcher object
efsw::FileWatcher fileWatcher( useGeneric );
fileWatcher.followSymlinks( false );
fileWatcher.allowOutOfScopeLinks( false );
if ( commonTest ) {
std::string CurPath( efsw::System::getProcessPath() );
std::cout << "CurPath: " << CurPath.c_str() << std::endl;
/// starts watching
fileWatcher.watch();
/// add a watch to the system
handleWatchID( fileWatcher.addWatch( CurPath + "test", ul, true ) );
/// adds another watch after started watching...
efsw::System::sleep( 100 );
efsw::WatchID watchID =
handleWatchID( fileWatcher.addWatch( CurPath + "test2", ul, true ) );
/// delete the watch
if ( watchID > 0 ) {
efsw::System::sleep( 1000 );
fileWatcher.removeWatch( watchID );
}
} else {
if ( fileWatcher.addWatch( path, ul, true ) > 0 ) {
fileWatcher.watch();
std::cout << "Watching directory: " << path.c_str() << std::endl;
if ( useGeneric ) {
std::cout << "Using generic backend watcher" << std::endl;
}
} else {
std::cout << "Error trying to watch directory: " << path.c_str() << std::endl;
std::cout << efsw::Errors::Log::getLastErrorLog().c_str() << std::endl;
}
}
while ( !STOP ) {
efsw::System::sleep( 100 );
}
return 0;
}