]> Kevux Git Server - fll/commitdiff
Update: Improve directory recursion and its documentation. development
authorKevin Day <Kevin@kevux.org>
Fri, 31 Jan 2025 03:45:53 +0000 (21:45 -0600)
committerKevin Day <Kevin@kevux.org>
Fri, 31 Jan 2025 03:45:53 +0000 (21:45 -0600)
Fix some problems in the `fl_directory_do()` documentation.
Extend the documentation adding more details of the process.

Remove redundant "is not error" status checks.

The checks like `if (flag_actions[j])` and `if (!flag_actions[j])` are now changed to respect the recently added `f_directory_recurse_do_flag_action_e` flag.

level_1/fl_directory/c/directory.h
level_1/fl_directory/c/private-directory.c

index fd0a45e261d4ad83aab23bf19a7b0865f407992a..da3e08e10a95dbde81f372e2f1c434a1a7f182f6 100644 (file)
@@ -91,21 +91,56 @@ extern "C" {
  * This is intended to be used as an alternative to functions like fl_directory_list(), giving more control over the recursion process.
  *
  * When recursing the directory, except for the top directory, handle() with the before and after flags set is called after the recurse.path is updated.
- * For the top directory, handle() is called with the before and after flags set when the path is not updated (that is, the path should be
+ * For the top directory, handle() is called with the before and after flags set when the path is not updated.
  *
  * This function is designed and intended to be used on directories.
  * If depth is 0, the operations callacks are still called but done at the top level.
  *
- * The action callback must set the error bit to ensure that the handle callbacks are called or not set the error bit to prevent this behavior.
+ * The action callback must set the error bit on recurse.state.status to ensure that the handle callbacks are called or not set the error bit to prevent this behavior.
  *
- * This exists on error if, after the handle callback is called, that the recurse.state.status still has the error bit set.
+ * This exits on error if, after the handle callback is called, that the recurse.state.status still has the error bit set.
  * This allows for the caller to inform this function to effectively ignore any errors.
  *
+ * General behavior flow:
+ *   1. Check recurse.action existence (if not _di_level_1_parameter_checking_), calling recurse.handle with (f_directory_recurse_do_flag_top_e) on error.
+ *   2. Check path.used, call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e) on error.
+ *   3. Prepare recurse.path, call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e) on error.
+ *   4. If recurse.flag has (f_directory_recurse_do_flag_top_e) or (f_directory_recurse_do_flag_before_e), call recurse.action with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_before_e).
+ *     - Call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_before_e) on error.
+ *   5. If recurse.depth_max > 0, perform recursion.
+ *     1. Load directory listing, call recurse.handle with (f_directory_recurse_do_flag_list_e | f_directory_recurse_do_flag_path_e) on error.
+ *     2. If recurse.flag has (f_directory_recurse_do_flag_list_e), call recurse.action with (f_directory_recurse_do_flag_list_e).
+ *       - Call recurse.handle with (f_directory_recurse_do_flag_list_e) on error.
+ *     3. For each file type, except directory (optionally calling recurse->state.interrupt() at the top of each loop):
+ *       1. Prepare list array, call recurse.handle with (f_directory_recurse_do_flag_directory_e) on error.
+ *       2. Call recurse.action with (f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_*_e, where * represents type).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_*_e, where * represents type) on error.
+ *       3. Call recurse.action with (f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_*_e, where * represents type).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_*_e, where * represents type) on error.
+ *       4. Call recurse.action with (f_directory_recurse_do_flag_after_e | f_directory_recurse_do_flag_*_e, where * represents type).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_after_e | f_directory_recurse_do_flag_*_e, where * represents type) on error.
+ *     4. For each directory (optionally calling recurse->state.interrupt() at the top of each loop):
+ *       1. Prepare list array, call recurse.handle with (f_directory_recurse_do_flag_directory_e) on error.
+ *       2. Call recurse.action with (f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_directory_e).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_before_e | f_directory_recurse_do_flag_directory_e) on error.
+ *       3. If depth max is not reached, perform recursion.
+ *       4. If depth max is reached, call recurse.action with (f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e) on error.
+ *       5. Call recurse.action with (f_directory_recurse_do_flag_after_e | f_directory_recurse_do_flag_directory_e).
+ *         - Call recurse.handle with (f_directory_recurse_do_flag_after_e | f_directory_recurse_do_flag_directory_e) on error.
+ *   6. Else if recurse.depth_max == 0, process directory, call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_directory_e) on error.
+ *     1. Call recurse.action with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_directory_e).
+ *       - Call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_directory_e) on error.
+ *     2. If recurse.flag has (f_directory_recurse_do_flag_top_e) or (f_directory_recurse_do_flag_after_e), call recurse.action with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_after_e).
+ *       - Call recurse.handle with (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_after_e) on error.
+ *
  * @param path
  *   The directory file path.
+ *
  *   Must be NULL terminated.
  * @param recurse
  *   The directory recurse data.
+ *
  *   This must not be NULL.
  *
  *   This alters recurse.state.status:
index 48677d5bc36110459e5db5a75a2de2a2450d65a4..42b9eac3c0421c362e0f7b030205b858d89b72b9 100644 (file)
@@ -55,7 +55,7 @@ extern "C" {
         if (F_status_is_error(recurse->state.status)) return;
       }
 
-      if (recurse->state.status != F_done && F_status_is_error_not(recurse->state.status)) {
+      if (recurse->state.status != F_done) {
         recurse->state.status = F_okay;
       }
     }
@@ -80,7 +80,7 @@ extern "C" {
       f_directory_recurse_do_flag_unknown_e,
     };
 
-    if (recurse->state.status != F_done && F_status_is_error_not(recurse->state.status)) {
+    if (recurse->state.status != F_done) {
       f_string_dynamics_t * const list[] = {
         &recurse->listing.block,
         &recurse->listing.character,
@@ -126,13 +126,13 @@ extern "C" {
           // Convenience and code simplification loop for processing before action, action, and after action.
           for (j = 0; j < 3; ++j) {
 
-            if (!flag_actions[j] || (recurse->flag & flag_actions[j])) {
+            if (flag_actions[j] & f_directory_recurse_do_flag_action_e || (recurse->flag & flag_actions[j])) {
               recurse->state.status = F_okay;
 
               recurse->action(recurse, list[k]->array[i], flag_actions[j] | flags[k]);
 
               if (F_status_is_error(recurse->state.status)) {
-                private_inline_fl_directory_do_handle(recurse, recurse->listing.directory.array[i], f_directory_recurse_do_flag_before_e | flags[k]);
+                private_inline_fl_directory_do_handle(recurse, recurse->listing.directory.array[i], flag_actions[j] | flags[k]);
                 if (F_status_is_error(recurse->state.status)) break;
               }
 
@@ -183,6 +183,7 @@ extern "C" {
 
         if (F_status_is_error(recurse->state.status)) {
           private_inline_fl_directory_do_handle(recurse, recurse->listing.directory.array[i], f_directory_recurse_do_flag_directory_e);
+
           if (F_status_is_error(recurse->state.status)) break;
           if (recurse->state.status == F_break || recurse->state.status == F_done) break;
           if (recurse->state.status == F_continue) continue;
@@ -191,17 +192,7 @@ extern "C" {
         // Convenience and code simplification loop for processing before action, action, and after action.
         for (j = 0; j < 3; ++j) {
 
-          if (flag_actions[j]) {
-            if (recurse->flag & flag_actions[j]) {
-              recurse->action(recurse, recurse->listing.directory.array[i], flag_actions[j] | f_directory_recurse_do_flag_directory_e);
-
-              if (F_status_is_error(recurse->state.status)) {
-                private_inline_fl_directory_do_handle(recurse, recurse->listing.directory.array[i], flag_actions[j] | f_directory_recurse_do_flag_directory_e);
-                if (F_status_is_error(recurse->state.status)) break;
-              }
-            }
-          }
-          else {
+          if (flag_actions[j] & f_directory_recurse_do_flag_action_e) {
             recurse->state.status = F_okay;
 
             if (recurse->depth < recurse->depth_max) {
@@ -225,6 +216,16 @@ extern "C" {
             // This loop is not considered a loop for breaking and continuing.
             if (recurse->state.status == F_break || recurse->state.status == F_done || recurse->state.status == F_continue) break;
           }
+          else {
+            if (recurse->flag & flag_actions[j]) {
+              recurse->action(recurse, recurse->listing.directory.array[i], flag_actions[j] | f_directory_recurse_do_flag_directory_e);
+
+              if (F_status_is_error(recurse->state.status)) {
+                private_inline_fl_directory_do_handle(recurse, recurse->listing.directory.array[i], flag_actions[j] | f_directory_recurse_do_flag_directory_e);
+                if (F_status_is_error(recurse->state.status)) break;
+              }
+            }
+          }
 
           if (F_status_is_error(recurse->state.status)) break;
           if (recurse->state.status == F_break || recurse->state.status == F_done) break;