Skip to content

Commit

Permalink
Fixes issue #181.
Browse files Browse the repository at this point in the history
  • Loading branch information
SpartanJ committed Sep 3, 2024
1 parent aae269e commit 8d9db3c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 34 deletions.
48 changes: 21 additions & 27 deletions project/qtcreator-osx/efsw.creator.user
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 7.0.2, 2022-06-19T12:14:51. -->
<!-- Written by QtCreator 12.0.1, 2024-09-03T01:51:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{1e2eacf3-3fa1-45d9-bcd5-871df4d12ee9}</value>
<value type="QByteArray">{49267ae2-f136-4b84-8041-cf11a20f6a32}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
Expand Down Expand Up @@ -37,6 +37,7 @@
<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="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
Expand All @@ -54,6 +55,7 @@
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
Expand All @@ -77,6 +79,7 @@
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">4</value>
<value type="bool" key="ClangTools.PreferConfigFile">false</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
Expand All @@ -88,9 +91,9 @@
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{03ce7d1a-f943-45a1-9d10-661febc7fb89}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop (arm-darwin-generic-mach_o-64bit)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop (arm-darwin-generic-mach_o-64bit)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{6d6b6d62-1e99-4e76-b5e2-cf731a0dbd92}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
Expand All @@ -99,13 +102,12 @@
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--file=../../premake4.lua --thread-sanitizer gmake</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--file=../../premake4.lua --thread-sanitizer --verbose gmake</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">/usr/local/bin/premake4</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
Expand Down Expand Up @@ -147,7 +149,6 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets"/>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments">-j4 config=release</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
Expand Down Expand Up @@ -194,49 +195,42 @@
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<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>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">0</value>
<value type="qlonglong" key="Analyzer.QmlProfiler.FlushInterval">0</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">efsw-test-debug</value>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">/Users/prognoz/programming/efsw/bin/efsw-test-debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">true</value>
<value type="int" key="RunConfiguration.UseCppDebugger">0</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="int" key="RunConfiguration.UseQmlDebugger">1</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">false</value>
<value type="bool" key="RunConfiguration.UseTerminal">false</value>
<value type="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}/../../bin/</value>
<value type="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}/../../bin</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
<value type="QString">cpu-cycles</value>
</valuelist>
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">0</value>
<value type="qlonglong" key="Analyzer.QmlProfiler.FlushInterval">0</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">efsw-test</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="int" key="RunConfiguration.UseCppDebugger">1</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseTerminal">false</value>
<value type="QString" key="RunConfiguration.WorkingDirectory">%{buildDir}/../../bin/</value>
Expand Down
1 change: 0 additions & 1 deletion src/efsw/FileSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <efsw/FileInfo.hpp>
#include <efsw/base.hpp>
#include <map>

namespace efsw {

Expand Down
43 changes: 41 additions & 2 deletions src/efsw/FileWatcherFSEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ bool FileWatcherFSEvents::isGranular() {
return getOSXReleaseNumber() >= 11;
}

static std::string convertCFStringToStdString( CFStringRef cfString ) {
// Try to get the C string pointer directly
const char* cStr = CFStringGetCStringPtr( cfString, kCFStringEncodingUTF8 );

if ( cStr ) {
// If the pointer is valid, directly return a std::string from it
return std::string( cStr );
} else {
// If not, manually convert it
CFIndex length = CFStringGetLength( cfString );
CFIndex maxSize = CFStringGetMaximumSizeForEncoding( length, kCFStringEncodingUTF8 ) +
1; // +1 for null terminator

char* buffer = new char[maxSize];

if ( CFStringGetCString( cfString, buffer, maxSize, kCFStringEncodingUTF8 ) ) {
std::string result( buffer );
delete[] buffer;
return result;
} else {
delete[] buffer;
return "";
}
}
}

void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef streamRef, void* userData,
size_t numEvents, void* eventPaths,
const FSEventStreamEventFlags eventFlags[],
Expand All @@ -51,8 +77,21 @@ void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef streamRef, void
events.reserve( numEvents );

for ( size_t i = 0; i < numEvents; i++ ) {
events.push_back( FSEvent( std::string( ( (char**)eventPaths )[i] ), (long)eventFlags[i],
(Uint64)eventIds[i] ) );
if ( isGranular() ) {
CFDictionaryRef pathInfoDict =
static_cast<CFDictionaryRef>( CFArrayGetValueAtIndex( (CFArrayRef)eventPaths, i ) );
CFStringRef path = static_cast<CFStringRef>(
CFDictionaryGetValue( pathInfoDict, kFSEventStreamEventExtendedDataPathKey ) );
CFNumberRef cfInode = static_cast<CFNumberRef>(
CFDictionaryGetValue( pathInfoDict, kFSEventStreamEventExtendedFileIDKey ) );
unsigned long inode = 0;
CFNumberGetValue( cfInode, kCFNumberLongType, &inode );
events.push_back( FSEvent( convertCFStringToStdString( path ), (long)eventFlags[i],
(Uint64)eventIds[i], inode ) );
} else {
events.push_back( FSEvent( std::string( ( (char**)eventPaths )[i] ),
(long)eventFlags[i], (Uint64)eventIds[i] ) );
}
}

watcher->handleActions( events );
Expand Down
2 changes: 2 additions & 0 deletions src/efsw/FileWatcherFSEvents.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ namespace efsw {
/* OSX < 10.7 has no file events */
/* So i declare the events constants */
enum FSEventEvents {
efswFSEventStreamCreateFlagUseCFTypes = 0x00000001,
efswFSEventStreamCreateFlagNoDefer = 0x00000002,
efswFSEventStreamCreateFlagFileEvents = 0x00000010,
efswFSEventStreamCreateFlagUseExtendedData = 0x00000040,
efswFSEventStreamEventFlagItemCreated = 0x00000100,
efswFSEventStreamEventFlagItemRemoved = 0x00000200,
efswFSEventStreamEventFlagItemInodeMetaMod = 0x00000400,
Expand Down
8 changes: 5 additions & 3 deletions src/efsw/WatcherFSEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ void WatcherFSEvents::init() {
Uint32 streamFlags = kFSEventStreamCreateFlagNone;

if ( FileWatcherFSEvents::isGranular() ) {
streamFlags = efswFSEventStreamCreateFlagFileEvents | efswFSEventStreamCreateFlagNoDefer;
streamFlags = efswFSEventStreamCreateFlagFileEvents | efswFSEventStreamCreateFlagNoDefer |
efswFSEventStreamCreateFlagUseExtendedData |
efswFSEventStreamCreateFlagUseCFTypes;
} else {
WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher.load(), Recursive );
}
Expand Down Expand Up @@ -128,12 +130,12 @@ void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) {
// been added modified and erased, but i can't know if first was erased and then added
// and modified, or added, then modified and then erased. I don't know what they were
// thinking by doing this...
efDEBUG( "Event in: %s - flags: %ld\n", event.Path.c_str(), event.Flags );
efDEBUG( "Event in: %s - flags: 0x%x\n", event.Path.c_str(), event.Flags );

if ( event.Flags & efswFSEventStreamEventFlagItemRenamed ) {
if ( ( i + 1 < esize ) &&
( events[i + 1].Flags & efswFSEventStreamEventFlagItemRenamed ) &&
( events[i + 1].Id == event.Id + 1 ) ) {
( events[i + 1].inode == event.inode ) ) {
FSEvent& nEvent = events[i + 1];
std::string newDir( FileSystem::pathRemoveFileName( nEvent.Path ) );
std::string newFilepath( FileSystem::fileNameFromPath( nEvent.Path ) );
Expand Down
4 changes: 3 additions & 1 deletion src/efsw/WatcherFSEvents.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ class FileWatcherFSEvents;

class FSEvent {
public:
FSEvent( std::string path, long flags, Uint64 id ) : Path( path ), Flags( flags ), Id( id ) {}
FSEvent( std::string path, long flags, Uint64 id, Uint64 inode = 0 ) :
Path( path ), Flags( flags ), Id( id ), inode( inode ) {}

std::string Path;
long Flags;
Uint64 Id;
Uint64 inode{ 0 };
};

class WatcherFSEvents : public Watcher {
Expand Down

0 comments on commit 8d9db3c

Please sign in to comment.