* 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:
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;
}
}
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,
// 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;
}
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;
// 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) {
// 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;