Add several directory functions.
I still may need to add more, such as a rewind to handle rewinddir().
Change the directory recurse do flags from an enumeration to defines.
Add a type fo handling `DIR *` called `f_directory_stream_t`.
Get rid of the directory listing structure to reduce memory usage.
This is only possible by replacing the `scandir()` with custom direct processing.
This change reduces the number of looping and removes the sorting behavior.
The directory recurse do flags are now redesigned.
The `top` is now entirely removed because a depth of 0 can be used to test for top without needing a flag.
The `opendir()` still has a notable cost, especially during recursion.
I need to do more research into how to more efficiently call `opendir()` without consuming too much memory.
The documentation comments still needs to be reviewed following these changes.
Make sure the directory functions only update the id values if there is no error.
Explicitly check for `-1` as return error rather than `< 0` to be more consistent with the standards.
Use typedefs to define callbacks.
Tweak the `fl_directory_list()` design.
Tweak the `fl_directory_path_pop()` design.
Kevin Day [Sun, 13 Apr 2025 02:20:42 +0000 (21:20 -0500)]
Regression: Parent directory in recursion does not get processed properly.
The commit 8df0301badf6f38fcb4ddf73318e02708ad344f7 fixed a problem with the parent directory not being processed at all.
It failed to handle the situation where the child directory alters the path to append itself.
Save the parent directory path and then restore it after processing the child directory.
Many POSIX libc functions work on NULL termination where possible.
Make sure a NULL termination exists after restoring the path.
Kevin Day [Sun, 13 Apr 2025 01:54:37 +0000 (20:54 -0500)]
Update: Add recurse flag masks.
This adds `f_directory_recurse_do_flag_action_mask_e` and `f_directory_recurse_do_flag_top_mask_e`.
These are helper flags for existing flag sets as a convenience.
Kevin Day [Thu, 10 Apr 2025 03:51:18 +0000 (22:51 -0500)]
Bugfix: The fl_directory_do() needs to operate on the parent directory during recursion.
The parent directory must be processed after recursion during the recursion steps.
These should not have the `f_directory_recurse_do_flag_top_after_e` flags because these are not top level.
These must have action because the action is expected to be performed on the directory just like other file types.
Kevin Day [Wed, 9 Apr 2025 02:23:33 +0000 (21:23 -0500)]
Feature: Add fll_program_signal_check_loop() and fll_program_signal_check_simple().
These functions are already implemented in each of the level 3 programs.
The functions are pretty much identical.
Move the signal check logic into the `fll_program` project as `fll_program_signal_check_loop()` and `fll_program_signal_check_simple()`.
Update all of the programs, removing their variation and instead using one of these two.
Utilize a macro to call one or the other based on thread enabled state.
The fss_write payload is not calling the fss_write function and is instead using its own variation.
Replace that code with the macro as well.
Remove all stale and no longer needed signal check defines.
Kevin Day [Fri, 4 Apr 2025 00:46:57 +0000 (19:46 -0500)]
Bugfix: The fl_directory_do() needs to pass f_directory_recurse_do_flag_directory_e at the top.
At the top, before recursion, the path is known to be a directory.
The flag `f_directory_recurse_do_flag_directory_e` must be passed to the callbacks to let the callbacks know this is a directory.
Kevin Day [Mon, 31 Mar 2025 02:07:05 +0000 (21:07 -0500)]
Update: Switch to the global array for print messages for fll_program.
This migrates the string messages to a single array.
At this time the array as a whole is enabled/disabled via the macros.
This may result in more strings included that needed.
This provides a single location to manage the string messages.
This may help with different languages.
Kevin Day [Sun, 30 Mar 2025 23:03:03 +0000 (18:03 -0500)]
Cleanup: The FLL FSS Status String strings.
Remove the granular define wrapping structure that I am not using anymore.
Make sure to use the proper `_s_` naming strategy.
Simplify some of the names.
Kevin Day [Wed, 26 Mar 2025 01:16:27 +0000 (20:16 -0500)]
Feature: The standard input should be available in fll_program_data_t.
I am surprised that I hadn't ever gotten to standard input processing.
The functionality should exist but the programs haven't needed this as of yet.
This is most certainly going to be needed so add the support.
Kevin Day [Sun, 23 Mar 2025 00:34:20 +0000 (19:34 -0500)]
Bugfix: Trailing semi-colon added at the end of the macro for f_time_spec_t.
The semi-colons should not be auto-added like this.
When adding the define inside an array, the semi-colon will cause compile problems that are hard to debug.
Kevin Day [Sun, 9 Mar 2025 23:41:43 +0000 (18:41 -0500)]
Update: The top-level directory recursion actions should have more fine-tuned control.
Provide `f_directory_recurse_do_flag_top_after_e` and `f_directory_recurse_do_flag_top_before_e` flags.
This requires increasing the size of the flags from `uint16_t` to `uint32_t`.
Be sure to pass the `path` rather than `recurse->path` at the top-level.
Make sure the `action` flag is set for the top-level action.
Add additional documentation comment regarding the `top` flag and the `recurse.path`.
Even though it is a listing of the path, still pass the `recurse.path` to the error handler at the top of `private_fl_directory_do_recurse()`.
Try to make the flag usage be ordered alphabetically.
Always perform the directory listing loading.
If this is not desired, then the `fl_directory_do()` function is likely not needed and simpler functions may be better choices.
Do not include the top-level flag for the directory listing for consistency with the recursion.
The recursion doesn't know the top-level, so do not set the top flag in this case.
The directory exists check is no longer needed and might have been redundant anyway.
Update the documentation comments.
I appear to have missed updating this in some of the previous commits that introduced operational changes.
Add additional documentation about checking the recurse parameter for NULL.
The private_fl_directory_do_recurse() already checks the error status.
Remove extra error checking after the `private_fl_directory_do_recurse()` call.
This extra error checking is redundant.
The return on error and return on done must still be performed.
After every private_inline_fl_directory_do_handle() call, the F_done is not being processed.
The check for `F_done` must be done for every single error handler call.
The only exception would be the last one in the top-level function because the function will always return after the last call anyway.
Update Featureless Make to work with the latest changes.
Kevin Day [Sun, 9 Mar 2025 22:03:20 +0000 (17:03 -0500)]
Bugfix: Ensure that fl_directory_do() depth 0 may still list directory contents.
The caller may want to check if there are any files within the directory when the max depth is 0.
Load the directory listing if the list flag is passed even when max depth is 0.
Kevin Day [Sat, 8 Mar 2025 03:35:06 +0000 (21:35 -0600)]
Cleanup: Fix incorrect statement in documentation.
The statement of "This is different from code:"build_sources_object"" for the build_sources_object documentation makes no sense.
Remove that part of the statement.
There are no functional changes to the specification, so the version date is unchanged.
Kevin Day [Fri, 7 Mar 2025 06:05:05 +0000 (00:05 -0600)]
Feature: Add more fine tuned build_name options.
The build names should support shared, static, program, object, and library.
Some of these may not be directly used.
They should still be loaded.
This is done to make the project compliant with the standard while allowing extendability/hackability.
Kevin Day [Fri, 21 Feb 2025 03:03:57 +0000 (21:03 -0600)]
Update: Implement the static string array for the fll_error program.
This provides some centralization to the static strings to a single global array.
This uses an enumeration similar to the way the function strings in the programs are handled.
This enumeration does come with a cost.
However, adding all the strings together in a single location should have some technical benefits.
Kevin Day [Thu, 20 Feb 2025 05:12:08 +0000 (23:12 -0600)]
Cleanup: Reduce duplicate code in the fll_error print functions.
Populate the `type_name` via a nested ternary instead of an if else if blocks.
The if else if blocks are cleaner but I want to have the `type_name` be a constant variable.
This should help the compiler optimize the variable.
Replace a lot of the repeated styles with new private functions.
This reduces quite a bit of repeated lines of code based on common patterns.
I do intend to follow this up at a later date with a commit that moves all of the static strings into a global array.
Kevin Day [Thu, 20 Feb 2025 03:59:53 +0000 (21:59 -0600)]
Cleanup: Use the f_string_static_t macros for the f_string_dynamic_t macros.
The `macro_f_string_dynamic_t_initialize_1` and `macro_f_string_dynamic_t_initialize_2` should be using the word `string` rather than `array` for the first argument.
call the `f_string_static_t` macros for the respective `f_string_dynamic_t` macros.
Kevin Day [Wed, 12 Feb 2025 01:56:07 +0000 (19:56 -0600)]
Feature: Allow for the group and user functions to not require a write value.
Several of these functions can be used to just check the validity of an ID or name.
Use the NULL pointer case to support this rather than writing a completely new functions for this logic.
For example, the `f_account_group_id_by_name()` function can have NULL for the `id` parameter.
In this case, nothing is written for the `id` and the function does not error out on invalid parameter (for when `id` is NULL).
The same logic is applied for the `f_account_group_name_by_id()` for the `name` parameter.
The same logic is applied for both user functions.
The account by functions are not updated as this is not needed.
Update the documentation for the account by functions, documenting that NULL is not allowed.
Kevin Day [Sun, 9 Feb 2025 06:20:23 +0000 (00:20 -0600)]
Update: Callback changes and improvements.
The `void *(*)(void *)` function structure is being used so add that as a function callback type `f_void_pointer_call_t`.
Add `fl_print_call_t` function callback type.
Rename the console parameter callback from `callback` to `on_match`.
Add `f_console_parameters_call_t` function callback type.
Fix documentation comment where `length` should instead be `used`.
The `void_main` are now replaced with literal `main` type now that the typedef structure improvements are in place.
Shorten the `callback` name to `call`.
Use more typedefs for functions.
This better takes advantage of how functions are a "first class citizen" in C.
Kevin Day [Sun, 9 Feb 2025 05:08:51 +0000 (23:08 -0600)]
Bugfix: Individual build problems with incorrect settings and dependencies.
The `f_abstruse` is not being included in some cases.
The `individual_thread` is not being used in some cases and instead `individual-thread` is being used.
Make sure `individual_thread` is the only form used.
Remove `f_parse` inclusion where it is not needed.
Kevin Day [Sat, 8 Feb 2025 22:12:11 +0000 (16:12 -0600)]
Update: Add f_id_t, f_uid_t, and f_gid_t type helpers for uid_t and gid_t.
The `uid_t` and `gid_t` don't readily map to each other.
I would love to simplify the code and have a single function call in several cases when using both `uid_t` and `gid_t`.
This provides interchangeable types `f_id_t`, `f_uid_t`, and `f_gid_t`.
The standard behavior is that `f_uid_t` and `f_gid_t` are both sub-types of `f_id_t`.
The `f_id_t` is by default an unsigned 32-bit integer.
Kevin Day [Fri, 31 Jan 2025 03:45:53 +0000 (21:45 -0600)]
Update: Improve directory recursion and its documentation.
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.
Kevin Day [Tue, 28 Jan 2025 04:31:23 +0000 (22:31 -0600)]
Update: Improve signal handling code.
Add a new line before printing the standard "Received signal code" message to ensure that it is always reasonably separated from the output being interrupted.
Simplify the verbosity variable check to a less than because the verbosity list is an enumeration.
Move the `fll_program_print_signal_received()` calls to the main program to help ensure consistent printing at the end of the program.
- Note: I am not certain if I want this instead in the main() function or not and I opted not to do so for now.
Fix some cases where the manual signal checks are still being performed to use the function instead.
The `fll_program_standard_signal_received_wait()` is now added because a lot of this code is repeated forr every single FLL program.
The `fll_program_standard_signal_received()` is refactored to return a status code to match the newly added `ll_program_standard_signal_received_wait()`.
The `status_signal` can now be moved into the main program settings structure.
The `status_signal` is renamed to `signal_status` to keep the naming more consistent.
This also exposes and fixes a race condition in how the pre-existing threaded signal handling is being used.
The check for `program.signal.id` that then opens a signal via `f_signal_open()` in the thread is not necessary because the signal id from the parent thread is preserved.
The `f_signal_close()` in the thread ends up prematurely closing the signal because the parent thread signal id is passed to the child thread.
The `main->program.signal.id == -1` checks in the signal check functions end up preventing the interrupt cancel from being triggered because of the `f_signal_close()` being called in a separate thread that shares the same signal id.
Kevin Day [Mon, 20 Jan 2025 03:54:42 +0000 (21:54 -0600)]
Cleanup: Fix function alphabetic ordering in unit tests.
Several of the test files have the parameter_checking function out of order.
I also happened to notice that the work test in some cases are also out of order.
This out of order is likely a problem caused by early day mass test generation.
Kevin Day [Fri, 17 Jan 2025 05:04:47 +0000 (23:04 -0600)]
Feature: Add new function fl_directory_empty().
Simplify the process of determining if the directory is empty.
The entire list of directories do not need to be processed in this case.
Only check if the first child in the directory exists.
Kevin Day [Sat, 11 Jan 2025 16:38:02 +0000 (10:38 -0600)]
Bugfix: The IKI and EKI specifications do not require escaping inside of Content.
This is an oops on my part.
I thought I was correcting something that I missed and I ended up causing a problem.
I think this problem was introduced in this commit: e9621b09db34cfd9ac6264c77068c34afa5bfb17.
Kevin Day [Fri, 10 Jan 2025 05:30:01 +0000 (23:30 -0600)]
Bugfix: Specification files need proper escaping for example code.
The IKI/EKI need to be properly escaped inside the example so that when the specification file itself is processed, the examples do not get substituted.
The examples that have what would be valid FSS Basic Lists also need to be escaped for the same reason.
Kevin Day [Thu, 9 Jan 2025 04:40:37 +0000 (22:40 -0600)]
Update: Next micro version (0.7.1).
The following are the commands that I ran to make this change:
# find build/ level_? specifications/ documents/ licenses/ -type f -exec sed -i -e 's|0\.7\.0|0.7.1|g' '{}' ';'
# find build/ level_? specifications/ documents/ licenses/ -type f -exec sed -i -e 's|^version_micro 0|version_micro 1|g' '{}' ';'
# find level_3/ -name *.h -exec sed -i -e 's|_program_version_micro_s F_string_ascii_0_s|_program_version_micro_s F_string_ascii_1_s|g' '{}' ';'
# find level_3/ -name *.h -exec sed -i -e 's|_program_version_micro_s_length F_string_ascii_0_s_length|_program_version_micro_s_length F_string_ascii_1_s_length|g' '{}' ';'