99
1010#include "fs.h"
1111#include "index.h"
12- #include "je.h"
1312#include "log.h"
1413
15- #define SL_OVERRIDE
16- #define SLX_REALLOC je_realloc
17- #define SLX_FREE je_free
18- #define SLX_STRDUP je_strdup
19-
20- #define SL_IMPL
21- #include "sl.h"
22-
2314/// @struct deng_state_s
2415/// @brief Search state context provided to the diff engine as user data which
2516/// is passed to the file event hook functions.
2617struct deng_state_s {
27- slist_t dirqueue ; ///< Processing directory queue
2818 deng_filter_t ffn ; ///< File filter function
2919 const struct deng_hooks_s * hooks ;///< File event hook functions
3020 const struct index_s * lastmap ; ///< Previous index state
@@ -54,14 +44,14 @@ struct deng_state_s {
5444/// files are indexed. This function may trigger new (NEW), modified (MOD),
5545/// and unmodified (NOP) events for each file in the directory tree.
5646/// @param fp The file path to process
47+ /// @param st The file stat information
5748/// @param udata The diff engine state context
5849/// @return 0 if successful, otherwise a non-zero error code.
59- static int stagepre (const char * fp , void * udata ) {
50+ static int stagepre (const char * fp , const struct fsstat_s * st , void * udata ) {
6051 struct deng_state_s * mach = (struct deng_state_s * ) udata ;
61- if (mach -> ffn != NULL && mach -> ffn ( fp )) return 0 ;
52+ notifyhook (mach , DENG_NOTIF_FILE_FOUND ) ;
6253
63- struct fsstat_s st = {0 };
64- if (fsstat (fp , & st )) return -1 ;
54+ if (mach -> ffn != NULL && mach -> ffn (fp )) return 0 ;// skip filtered files
6555
6656 const uint64_t fphash = indexhash (fp );
6757
@@ -74,9 +64,8 @@ static int stagepre(const char* fp, void* udata) {
7464 if ((curr = indexput (mach -> thismap , fp , fphash , st )) == NULL ) return -1 ;
7565
7666 if (prev != NULL ) {
77- if (! fsstateql ( & prev -> st , & curr -> st )) {
67+ if (prev -> st . lmod != st -> lmod || prev -> st . fsze != st -> fsze )
7868 callevent (mach , DENG_FEVENT_MOD , curr );
79- }
8069 } else {
8170 callevent (mach , DENG_FEVENT_NEW , curr );
8271 }
@@ -88,67 +77,44 @@ static int stagepre(const char* fp, void* udata) {
8877/// files are indexed. This function may trigger new (NEW) and modified (MOD)
8978/// events for each file in the directory tree.
9079/// @param fp The file path to process
80+ /// @param st The file stat information
9181/// @param udata The diff engine state context
9282/// @return 0 if successful, otherwise a non-zero error code.
93- static int stagepost (const char * fp , void * udata ) {
83+ static int stagepost (const char * fp , const struct fsstat_s * st , void * udata ) {
9484 struct deng_state_s * mach = (struct deng_state_s * ) udata ;
95- if (mach -> ffn != NULL && mach -> ffn (fp )) return 0 ;
85+ notifyhook (mach , DENG_NOTIF_FILE_FOUND );
86+
87+ if (mach -> ffn != NULL && mach -> ffn (fp )) return 0 ;// skip filtered files
9688
9789 const uint64_t fphash = indexhash (fp );
9890
9991 struct inode_s * curr = indexfind (mach -> thismap , fp , fphash );
10092 if (curr != NULL ) {
101- // check if the file was modified during the command execution
102- struct fsstat_s mod = {0 };
103- if (fsstat (fp , & mod )) return -1 ;
104- curr -> st = mod ;// update the file info in the current index
93+ curr -> st = * st ;// update the file info in the current index
10594 return 0 ;
10695 }
10796
108- struct fsstat_s st = {0 };
109- if (fsstat (fp , & st )) return -1 ;
11097 if ((curr = indexput (mach -> thismap , fp , fphash , st )) == NULL ) return -1 ;
11198 callevent (mach , DENG_FEVENT_NEW , curr );
11299
113100 return 0 ;
114101}
115102
116- /// @brief Pushes a directory path onto the directory queue for processing.
117- /// @param fp The directory path to push
118- /// @param udata The diff engine state context
119- /// @return 0 if successful, otherwise a non-zero error code.
120- static int dqpush (const char * fp , void * udata ) {
121- struct deng_state_s * mach = (struct deng_state_s * ) udata ;
122- int err ;
123- if ((err = sladd (& mach -> dirqueue , fp )))
124- log_error ("error pushing directory `%s`" , fp );
125- return err ;
126- }
127-
128- /// @brief Resets the directory queue to the initial search path, and invokes
129- /// the `filefn` function for each file in the directory tree, recursively.
103+ /// @brief Walks the directory tree starting at \p sd and invokes the provided
104+ /// file function \p filefn for each file found. After the walk is complete,
105+ /// the stage done notification is triggered.
130106/// @param mach The diff engine state context
131107/// @param sd The initial search directory path
132108/// @param filefn The function to invoke for each file in the directory tree
133109/// @return 0 if successful, otherwise a non-zero error code.
134110static int execstage (struct deng_state_s * mach , const char * sd ,
135111 fswalkfn_t filefn ) {
136- slfree (& mach -> dirqueue );
137- mach -> dirqueue = (slist_t ){0 };
138- if (sladd (& mach -> dirqueue , sd )) return -1 ;
139-
140- char * dir ;
141- while ((dir = slpop (& mach -> dirqueue )) != NULL ) {
142- int err ;
143- if ((err = fswalk (dir , filefn , dqpush , (void * ) mach ))) {
144- log_error ("file func for `%s` returned %d" , dir , err );
145- return -1 ;
146- }
147- notifyhook (mach , DENG_NOTIF_DIR_DONE );
148- je_free (dir );
112+ int err ;
113+ if ((err = fswalk (sd , filefn , (void * ) mach ))) {
114+ log_error ("file func for `%s` returned %d" , sd , err );
115+ return -1 ;
149116 }
150117 notifyhook (mach , DENG_NOTIF_STAGE_DONE );
151-
152118 return 0 ;
153119}
154120
@@ -180,12 +146,11 @@ int dengsearch(const char* sd, deng_filter_t filter,
180146 assert (old != NULL );
181147 assert (new != NULL );
182148
183- struct deng_state_s mach = {{ 0 }, filter , hooks , old , new };
149+ struct deng_state_s mach = {filter , hooks , old , new };
184150 int err ;
185151 if ((err = execstage (& mach , sd , stagepre ))) goto ret ;
186152 if ((err = checkremoved (& mach ))) goto ret ;
187153 if ((err = execstage (& mach , sd , stagepost ))) goto ret ;
188154ret :
189- slfree (& mach .dirqueue );
190155 return err ;
191156}
0 commit comments