Progress: Continue working on completing the remove program.
authorKevin Day <Kevin@kevux.org>
Fri, 28 Mar 2025 22:38:06 +0000 (17:38 -0500)
committerKevin Day <Kevin@kevux.org>
Sat, 29 Mar 2025 02:09:43 +0000 (21:09 -0500)
Make sure the `--force` parameter is properly suppressing errors and warnings when a file is not found.
Do not print an error or error out when `--force` is used.
Utilize the `ignore` string and print the boolean state based on `--force` when a file is not found during simulation mode.

Remove the warning on file not found because an error is potentially printed later on.

Update the `--prompt` settings.

Update the program unit tests.
The program now properly returns non-zero on file not found when trying to remove.
The program unit tests are updated to match this expectation.

Update the readme documentation for the remove program.

Fix the standard parameters and properly use `f_console_standard_parameter_last_e`.

Begin adding the `rm` program.

43 files changed:
data/build/remove/fakefile
data/build/remove/settings.rm [new file with mode: 0644]
data/build/stand_alone/fakefile
data/build/stand_alone/settings/settings.remove
data/build/stand_alone/settings/settings.rm [new file with mode: 0644]
data/build/stand_alone/settings/settings.rmdir
data/build/stand_alone/settings/settings.tacocat
documents/readme.remove.txt
sources/c/program/kevux/tools/remove/main/common.c
sources/c/program/kevux/tools/remove/main/common/define.h
sources/c/program/kevux/tools/remove/main/common/enumeration.h
sources/c/program/kevux/tools/remove/main/common/string.c
sources/c/program/kevux/tools/remove/main/common/string.h
sources/c/program/kevux/tools/remove/main/operate.c
sources/c/program/kevux/tools/remove/main/preprocess.c
sources/c/program/kevux/tools/remove/main/print/message.c
sources/c/program/kevux/tools/remove/main/print/simulate.c
sources/c/program/kevux/tools/remove/main/print/simulate.h
sources/c/program/kevux/tools/remove/main/remove.c
sources/c/program/kevux/tools/remove/rm/config.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/config.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/enumeration.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/enumeration.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/main.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/main.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/print.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/print.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/rm.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/rm.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/string.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rm/string.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/rmdir/enumeration.h
sources/c/program/kevux/tools/remove/rmdir/main.h
sources/c/program/kevux/tools/remove/rmdir/print.h
sources/c/program/kevux/tools/remove/rmdir/rmdir.c
sources/c/program/kevux/tools/remove/rmdir/rmdir.h
sources/c/program/kevux/tools/remove/rmdir/string.h
sources/c/program/kevux/tools/remove/unlink/enumeration.h
sources/c/program/kevux/tools/remove/unlink/unlink.c
tests/unit/remove/c/test-remove-directory_no_args.c
tests/unit/remove/c/test-remove-force.c
tests/unit/remove/c/test-remove-regular_no_args.c
tests/unit/remove/c/test-remove.c

index 3e82472807323bfd3e4be810059bd3385d3cc57a..5c137c4caccee7ed991ab86e04408ef18d3a1f27 100644 (file)
@@ -10,6 +10,7 @@ settings:
 main:
   build settings
   build settings.remove
+  build settings.rm
   build settings.rmdir
   build settings.unlink
 
diff --git a/data/build/remove/settings.rm b/data/build/remove/settings.rm
new file mode 100644 (file)
index 0000000..be01a90
--- /dev/null
@@ -0,0 +1,93 @@
+# fss-0001
+#
+# Builds the rm program of the project.
+#
+# Modes:
+#   - android:           Compile on an android system (using Termux; may need modification depending on the android system).
+#   - clang:             Use CLang rather than the default, which is generally GCC.
+#   - coverage:          Compile for building coverage.
+#   - fanalyzer:         Compile using GCC's -fanalyzer compile time option.
+#   - gcc:               Use GCC specific settings.
+#   - gcc_13:            Use gcc version 13 or greater specific settings.
+#   - individual:        Compile using per project (individual) libraries, does not handle thread or threadless cases.
+#   - individual_thread: This is required when compiling in individual mode with "thread" mode.
+#   - level:             Compile using per level libraries.
+#   - monolithic:        Compile using per monolithic libraries.
+#   - test:              Compile for a test, such as unit testing.
+#   - thread:            Compile with thread support.
+#   - threadless:        Compile without thread support.
+#
+
+build_name rm
+stage rm
+
+version_major 0
+version_minor 7
+version_micro 1
+version_file micro
+version_target minor
+
+modes android clang coverage fanalyzer gcc gcc_13 individual individual_thread level monolithic test thread threadless
+modes_default monolithic thread gcc
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc -lremove
+build_libraries-individual -lfll_error -lfll_print -lfll_program
+build_libraries-individual -lfl_conversion -lfl_directory -lfl_print
+build_libraries-individual -lf_account -lf_color -lf_compare -lf_console -lf_conversion -lf_directory -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_rip -lf_signal -lf_string -lf_time -lf_type_array -lf_utf
+build_libraries-individual_thread -lf_thread
+build_libraries-level -lfll_2 -lfll_1 -lfll_0
+build_libraries-monolithic -lfll
+
+build_sources_program config.c enumeration.c main.c print.c string.c rm.c
+
+build_sources_headers enumeration.h print.h string.h rm.h
+
+build_sources_documentation man
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers program/kevux/tools/remove/rm
+path_sources sources/c/program/kevux/tools/remove/rm
+
+has_path_standard no
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+#defines -D_di_libcap_
+defines -D_libcap_legacy_only_
+defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_ -D_di_f_thread_cancel_state_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_
+defines-threadless -D_di_thread_support_
+defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
+
+# This is needed for glibc and strptime() usage.
+defines -D_GNU_SOURCE=1
+
+flags -O2 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces
+flags -fstack-clash-protection -fno-delete-null-pointer-checks
+flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
+flags-android -Wno-implicit-function-declaration -Wl,-z,norelro
+flags-clang -Wno-logical-op-parentheses
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+flags-fanalyzer -fanalyzer
+flags-gcc_13 -fstrict-flex-arrays=3
+flags-test -O0 -fstack-protector-strong -Wall
+flags-thread -pthread
+
+flags_library -fPIC
+flags_object -fPIC
+flags_program -fPIE
+flags_program-android -fPIE -Wl,-z,relro
index 4e990f4bac899cd26c0241bd5a64047af73f2174..51bef2b4d5a9a47957fb94b38ca95ada07df89c0 100644 (file)
@@ -21,6 +21,7 @@ settings:
 
 main:
   build settings/settings.remove
+  build settings/settings.rm
   build settings/settings.rmdir
   build settings/settings.tacocat
   build settings/settings.unlink
@@ -28,6 +29,9 @@ main:
 main_remove:
   build settings/settings.remove
 
+main_rm:
+  build settings/settings.rm
+
 main_rmdir:
   build settings/settings.rmdir
 
@@ -50,6 +54,7 @@ help:
   print "  - context:'notable'install:context:'reset'      A helper operation that calls the ./install.sh script for the programs."
   print "  - context:'notable'main:context:'reset'         Compilation using the build settings mode for the programs (default)."
   print "  - context:'notable'main_remove:context:'reset'  Compilation using the build settings mode for the remove program."
+  print "  - context:'notable'main_rm:context:'reset'      Compilation using the build settings mode for the rm program."
   print "  - context:'notable'main_rmdir:context:'reset'   Compilation using the build settings mode for the rmdir program."
   print "  - context:'notable'main_tacocat:context:'reset' Compilation using the build settings mode for the tacocat program."
   print "  - context:'notable'main_unlink:context:'reset'  Compilation using the build settings mode for the unlink program."
index 64cc6153470b6144089c81ddbdb17acaca6840e3..edde000075530411e4887ff5275270b2bbc76406 100644 (file)
@@ -82,15 +82,6 @@ build_shared yes
 build_static no
 
 path_headers
-path_library_script script
-path_library_shared shared
-path_library_static static
-path_object_script script
-path_object_shared shared
-path_object_static static
-path_program_script script
-path_program_shared shared
-path_program_static static
 
 has_path_standard yes
 preserve_path_headers yes
diff --git a/data/build/stand_alone/settings/settings.rm b/data/build/stand_alone/settings/settings.rm
new file mode 100644 (file)
index 0000000..24d214e
--- /dev/null
@@ -0,0 +1,120 @@
+# fss-0001
+#
+# See the fakefile for details about the stand alone build.
+#
+# This can be built directly via:
+#   fake -s data/build/stand_alone/settings/settings.rm clean build
+#
+# Modes:
+#   - android:    Compile on an android system (using Termux; may need modification depending on the android system).
+#   - clang:      Use CLang rather than the default, which is generally GCC.
+#   - coverage:   Compile for building coverage.
+#   - fanalyzer:  Compile using GCC's -fanalyzer compile time option.
+#   - gcc:        Use GCC specific settings.
+#   - gcc_13:     Use gcc version 13 or greater specific settings.
+#   - test:       Compile for a test, such as unit testing.
+#   - thread:     Compile with thread support.
+#   - threadless: Compile without thread support.
+#
+
+build_name rm
+stage stand_alone
+
+version_major 0
+version_minor 7
+version_micro 1
+version_file micro
+version_target minor
+
+modes android clang coverage fanalyzer gcc gcc_13 test thread threadless
+modes_default thread gcc
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+
+build_sources_program fll/level_0/account.c fll/level_0/private-account.c fll/level_0/account/accounts.c
+build_sources_program fll/level_0/color.c fll/level_0/private-color.c fll/level_0/color/common.c
+build_sources_program fll/level_0/compare.c fll/level_0/compare/utf.c fll/level_0/private-compare.c fll/level_0/compare/private-utf.c
+build_sources_program fll/level_0/console.c fll/level_0/console/common.c fll/level_0/private-console.c
+build_sources_program fll/level_0/conversion.c fll/level_0/private-conversion.c fll/level_0/conversion/common.c
+build_sources_program fll/level_0/directory.c fll/level_0/directory/common.c fll/level_0/directory/listing.c fll/level_0/directory/recurse_do.c fll/level_0/directory/status.c
+build_sources_program fll/level_0/private-directory.c
+build_sources_program fll/level_0/file.c fll/level_0/private-file.c fll/level_0/file/common.c fll/level_0/file/stream.c
+build_sources_program fll/level_0/memory.c fll/level_0/memory/array.c fll/level_0/memory/arrays.c
+build_sources_program fll/level_0/private-memory.c fll/level_0/memory/private-array.c
+build_sources_program fll/level_0/path.c fll/level_0/private-path.c fll/level_0/path/common.c
+build_sources_program fll/level_0/pipe.c
+build_sources_program fll/level_0/print.c fll/level_0/private-print.c fll/level_0/print/common.c fll/level_0/print/to.c fll/level_0/print/private-to.c
+build_sources_program fll/level_0/rip.c fll/level_0/rip/utf.c fll/level_0/private-rip.c fll/level_0/rip/private-utf.c
+build_sources_program fll/level_0/signal.c
+build_sources_program fll/level_0/string.c fll/level_0/private-string.c fll/level_0/string/common.c
+build_sources_program fll/level_0/string/dynamic.c fll/level_0/string/dynamics.c fll/level_0/string/dynamicss.c fll/level_0/string/map.c fll/level_0/string/maps.c fll/level_0/string/mapss.c fll/level_0/string/map_multi.c fll/level_0/string/map_multis.c fll/level_0/string/map_multiss.c fll/level_0/string/static.c fll/level_0/string/statics.c fll/level_0/string/staticss.c fll/level_0/string/triple.c fll/level_0/string/triples.c fll/level_0/string/tripless.c
+build_sources_program fll/level_0/time.c
+build_sources_program fll/level_0/type_array/cell.c fll/level_0/type_array/file.c fll/level_0/type_array/fll_id.c fll/level_0/type_array/int8.c fll/level_0/type_array/int16.c fll/level_0/type_array/int32.c fll/level_0/type_array/int64.c fll/level_0/type_array/int128.c fll/level_0/type_array/number_signed.c fll/level_0/type_array/number_unsigned.c fll/level_0/type_array/poll.c fll/level_0/type_array/quantity.c  fll/level_0/type_array/quantitys.c fll/level_0/type_array/quantityss.c fll/level_0/type_array/range.c  fll/level_0/type_array/ranges.c fll/level_0/type_array/rangess.c fll/level_0/type_array/state.c fll/level_0/type_array/status.c fll/level_0/type_array/uint8.c fll/level_0/type_array/uint16.c fll/level_0/type_array/uint32.c fll/level_0/type_array/uint64.c fll/level_0/type_array/uint128.c
+build_sources_program fll/level_0/utf.c fll/level_0/private-utf.c fll/level_0/private-utf_alphabetic.c fll/level_0/private-utf_combining.c fll/level_0/private-utf_control.c fll/level_0/private-utf_digit.c fll/level_0/private-utf_emoji.c fll/level_0/private-utf_numeric.c fll/level_0/private-utf_phonetic.c fll/level_0/private-utf_private.c fll/level_0/private-utf_punctuation.c fll/level_0/private-utf_subscript.c fll/level_0/private-utf_superscript.c fll/level_0/private-utf_symbol.c fll/level_0/private-utf_unassigned.c fll/level_0/private-utf_valid.c fll/level_0/private-utf_whitespace.c fll/level_0/private-utf_wide.c fll/level_0/private-utf_word.c fll/level_0/private-utf_zero_width.c
+build_sources_program fll/level_0/utf/common.c fll/level_0/utf/convert.c fll/level_0/utf/dynamic.c fll/level_0/utf/dynamics.c fll/level_0/utf/dynamicss.c fll/level_0/utf/is.c fll/level_0/utf/is_character.c fll/level_0/utf/map.c fll/level_0/utf/maps.c fll/level_0/utf/mapss.c fll/level_0/utf/map_multi.c fll/level_0/utf/map_multis.c fll/level_0/utf/map_multiss.c fll/level_0/utf/static.c fll/level_0/utf/statics.c fll/level_0/utf/staticss.c fll/level_0/utf/string.c fll/level_0/utf/triple.c fll/level_0/utf/triples.c fll/level_0/utf/tripless.c
+build_sources_program fll/level_0/utf/private-dynamics.c fll/level_0/utf/private-maps.c fll/level_0/utf/private-map_multis.c fll/level_0/utf/private-string.c fll/level_0/utf/private-triples.c
+
+build_sources_program-thread fll/level_0/thread.c fll/level_0/thread/attribute.c fll/level_0/thread/barrier.c fll/level_0/thread/barrier_attribute.c fll/level_0/thread/condition.c fll/level_0/thread/condition_attribute.c fll/level_0/thread/id.c fll/level_0/thread/key.c fll/level_0/thread/lock.c fll/level_0/thread/lock_attribute.c fll/level_0/thread/mutex.c fll/level_0/thread/mutex_attribute.c fll/level_0/thread/once.c fll/level_0/thread/semaphore.c fll/level_0/thread/set.c fll/level_0/thread/spin.c
+
+build_sources_program fll/level_1/conversion.c fll/level_1/private-conversion.c fll/level_1/conversion/common.c
+build_sources_program fll/level_1/directory.c fll/level_1/private-directory.c
+build_sources_program fll/level_1/path.c
+build_sources_program fll/level_1/print.c fll/level_1/private-print.c fll/level_1/print/common.c
+
+build_sources_program fll/level_2/error.c fll/level_2/private-error.c fll/level_2/error/common.c fll/level_2/error/string.c
+build_sources_program fll/level_2/print.c
+build_sources_program fll/level_2/program.c fll/level_2/program/common.c fll/level_2/program/print.c fll/level_2/private-program.c
+
+build_sources_program program/kevux/tools/remove/main/common.c program/kevux/tools/remove/main/common/define.c program/kevux/tools/remove/main/common/enumeration.c program/kevux/tools/remove/main/common/print.c program/kevux/tools/remove/main/common/string.c program/kevux/tools/remove/main/common/type.c program/kevux/tools/remove/main/convert.c program/kevux/tools/remove/main/operate.c program/kevux/tools/remove/main/preprocess.c program/kevux/tools/remove/main/print/debug.c program/kevux/tools/remove/main/print/error.c program/kevux/tools/remove/main/print/message.c program/kevux/tools/remove/main/print/simulate.c program/kevux/tools/remove/main/print/verbose.c program/kevux/tools/remove/main/print/warning.c program/kevux/tools/remove/main/remove.c program/kevux/tools/remove/main/signal.c program/kevux/tools/remove/main/thread.c
+
+build_sources_program program/kevux/tools/remove/rm/config.c program/kevux/tools/remove/rm/enumeration.c program/kevux/tools/remove/rm/main.c program/kevux/tools/remove/rm/print.c program/kevux/tools/remove/rm/string.c program/kevux/tools/remove/rm/rm.c
+
+build_sources_documentation man
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+defines -include sources/c/remove-config.h -I sources/c/
+#defines -D_di_libcap_
+defines -D_libcap_legacy_only_
+defines-android -D_di_f_thread_attribute_affinity_get_ -D_di_f_thread_attribute_affinity_set_ -D_di_f_thread_attribute_concurrency_get_ -D_di_f_thread_attribute_concurrency_set_ -D_di_f_thread_attribute_default_get_ -D_di_f_thread_attribute_default_set_ -D_di_f_thread_cancel_ -D_di_f_thread_cancel_state_set_ -D_di_f_thread_cancel_test_ -D_di_f_thread_join_try_ -D_di_f_thread_join_timed_ -D_pthread_mutex_prioceiling_unsupported_ -D_di_f_thread_semaphore_file_close_ -D_di_f_thread_semaphore_file_open_ -D_di_f_thread_semaphore_file_delete_ -D_di_f_thread_cancel_type_set_
+defines-thread -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
+defines-threadless -D_di_thread_support_
+
+# This is needed for glibc and strptime() usage.
+defines -D_GNU_SOURCE=1
+
+flags -O2 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces
+flags -fstack-clash-protection -fno-delete-null-pointer-checks
+flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
+flags-android -Wno-implicit-function-declaration -Wl,-z,norelro
+flags-clang -Wno-logical-op-parentheses
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+flags-fanalyzer -fanalyzer
+flags-gcc_13 -fstrict-flex-arrays=3
+flags-test -O0 -fstack-protector-strong -Wall
+flags-thread -pthread
+
+flags_library -fPIC
+flags_object -fPIC
+flags_program -fPIE
+flags_program-android -fPIE -Wl,-z,relro
index 2c28be6fcf03394ea26317078952c82761e55576..ae9846bd2b0f39fdaa3bd2425d2c181af6857c07 100644 (file)
@@ -82,15 +82,6 @@ build_shared yes
 build_static no
 
 path_headers
-path_library_script script
-path_library_shared shared
-path_library_static static
-path_object_script script
-path_object_shared shared
-path_object_static static
-path_program_script script
-path_program_shared shared
-path_program_static static
 
 has_path_standard yes
 preserve_path_headers yes
index c4794c779d3eed7244f76e8957b4a1afb0a10cbe..3bfdf215369c007d2a35cc8941370aebeff506c8 100644 (file)
@@ -87,15 +87,6 @@ build_shared yes
 build_static no
 
 path_headers
-path_library_script script
-path_library_shared shared
-path_library_static static
-path_object_script script
-path_object_shared shared
-path_object_static static
-path_program_script script
-path_program_shared shared
-path_program_static static
 
 has_path_standard yes
 preserve_path_headers yes
index fde68a5e98e1580619fdcbdedfd327e46374663c..4f51a5d768cdded78ccc7cf5e3e9a3d247c39737 100644 (file)
@@ -1,7 +1,7 @@
 # fss-0002 iki-0000
 #
 # license: cc-by-sa-4.0
-# version 2024/07/30
+# version 2025/03/28
 #
 # This file (assumed to be named readme.remove.txt) can be more easily read using the following iki_read commands:
 #   iki_read readme.remove.txt +Q -w -W code '"' '"'
@@ -24,32 +24,58 @@ Remove Readme Documentation:
 
   The bold:"remove" program has the following arguments\:
 
+    The code:"--accessed" (code:"-A") parameter filters by accessed date and time and accepts two additional parameters, see below for details.
     The code:"--block" (code:"-b") parameter is a file type parameter that restricts removal to block device files.
+    The code:"--changed" (code:"-C") parameter filters by changed date and time and accepts two additional parameters, see below for details.
     The code:"--character" (code:"-c") parameter is a file type parameter that restricts removal to character device files.
-    The code:"--date" (code:"-D") parameter accepts three additional parameters and restricts removal based on the relationship to some date.
     The code:"--different" (code:"-O") parameter restricts removal of files whose owner is not the user of the caller of the program.
     The code:"--directory" (code:"-d") parameter is a file type parameter that restricts removal to directory files.
-    The code:"--empty" (code:"-e") parameter to remove empty directories.
-    The code:"--empty_fail" (code:"-y") parameter to fail on empty directories.
-    The code:"--empty_fail_not" (code:"-Y") parameter to fail on not empty directories.
-    The code:"--empty_not" (code:"-E") parameter to fail on not-empty directories.
-    The code:"--follow" (code:"-F") parameter alters removal to remove the files pointed to by a symbolic link rather than the link itself.
-    The code:"--force" (code:"-f") parameter to never prompt and ignore non-existent files and arguments.
+    The code:"--empty" (code:"-e") parameter to remove empty directories, see below for details.
+    The code:"--follow" (code:"-F") parameter alters removal to remove the file pointed to by a symbolic link rather than the link itself (opposite of --stay).
+    The code:"--force" (code:"-f") parameter to ignore non-existent files and never prompt.
     The code:"--group" (code:"-g") parameter accepts two additional parameters that restrict removal to the given group identifier.
     The code:"--link" (code:"-l") parameter is a file type parameter that restricts removal to a symbolic link file.
-    The code:"--mode" (code:"-m") parameter accepts two additional parameters that restrict removal to the given file mode.
-    The code:"--prompt" (code:"-p") parameter accepts one additional parameter that designates operating in interactive mode and prompts the user for input.
+    The code:"--mode" (code:"-m") parameter accepts two additional parameters that restrict removal to the given file mode, see below for details.
+    The code:"--prompt" (code:"-p") parameter accepts one additional parameter that designates operating in interactive mode and prompts the user for input, see below for details.
     The code:"--recurse" (code:"-g") parameter remove directories and their contents recursively.
     The code:"--regular" (code:"-R") parameter is a file type parameter that restricts removal to regular files (commonly referred to as just bold:"file").
     The code:"--remember" parameter to remember paths of files already deleted so as to not potentially error out on already removed path.
     The code:"--same" (code:"-s") parameter restricts removal of files whose owner is the user of the caller of the program.
     The code:"--simulate" (code:"-S") parameter designates that the program operates in simulation mode, never removing anything and instead printing what would have been mode (unless in quiet mode).
     The code:"--socket" (code:"-k") parameter is a file type parameter that restricts removal to socket files.
+    The code:"--stay" (code:"-Y") parameter designating to operate on any symbolic links directly rather than what they are pointing to (opposite of --follow).
     The code:"--tree" (code:"-t") parameter designates that the specified directory tree is also deleted (may require --force and --recurse if directory tree is not empty).
+    The code:"--updated" (code:"-U") parameter filters by updated date and time and accepts two additional parameters, see below for details.
     The code:"--user" (code:"-u") parameter accepts two additional parameters that restrict removal to the given group identifier.
 
-  The code:"--date" (code:"-d") parameter's arguments three are (and in this order)\:
+  The code:"--accessed" (code:"-A"), code:"--changed" (code:"-C"), and code:"--updated" (code:"-U") parameters' two arguments are (in this order)\:
 
-    1) Either bold:"create" or bold:"modify" to represent file created date or file modified date.
-    2) One of bold:"<", bold:"<=", bold:"==", bold:">=", and bold:">" to represent the relationship between the date in argument 3.
-    3) The date (can be in Time format, such as code:"2020:86.4 TT" and code:"2020:86400000000000" (copy the documentation from Featureless Make and/or Controller to describe this)).
+    1) One of bold:"<", bold:"<=", bold:"==", bold:">=", bold:">", bold:"<>", bold:"equal", bold:"less", bold:"less_equal", bold:"more", bold:"more_equal", and bold:"not" to represent the relationship between the data for the file as the left side and the second argument as the right side.
+    2) The date in any of the following formats\:
+
+      - One of these reserved words: bold:"now", bold:"today", bold:"tomorrow", and bold:"yesterday".
+      - The bold:"EpochTime format, such as code:"1234::5678".
+      - The bold:"Time" format, such as code:"1234:5678".
+      - The bold:"Unix Epoch" format, such as code:"1672639985".
+      - Various standard date time formats, such as bold:"2022/12/30 1:45:02 pm +0600".
+
+  The code:"--empty" (code:"-e") parameter supports the following values\:
+
+    - code:"not" for designating removing directories that are not empty.
+    - code:"not_fail" for designating to fail when attempting to remove directories that are not empty.
+    - code:"only' for designating to only remove directories that are empty.
+    - code:"only_fail" for desginating to fail when removing directoies that are empty.
+
+  The code:"--prompt" (code:"-p") parameter supports the following values\:
+
+    - code:"each" for designating operating in interactive mode, prompting for every file.
+    - code:"follow" for designating operating in interactive mode, prompting for every link that is being followed.
+    - code:"never" for designating to not operate in interactive mode.
+    - code:"once" for designating operating in interactive mode: prompting if removing 3 or more files while not in recursive mode.
+
+  The code:"--mode" (code:"-m") supports the following values\:
+
+    - code:"~~" and code:"different" designate matching different parts of each mode.
+    - code:"==" and code:"same" designate matching modes exactly.
+    - code:"~=" and code:"similar" designate matching the same parts of each mode.
+    - code:"<>" and code:"not" designate does not match modes exactly.
index 68976d241317b0646947dc95dd58f935bfa02468..679551e3b98bc653776687419f69bcde58e68a26 100644 (file)
@@ -28,7 +28,7 @@ extern "C" {
 
       // Identify and prioritize "color context" parameters.
       {
-        uint16_t choices_array[3] = { kt_remove_parameter_no_color_e, kt_remove_parameter_light_e, kt_remove_parameter_dark_e };
+        uint16_t choices_array[3] = { f_console_standard_parameter_no_color_e, f_console_standard_parameter_light_e, f_console_standard_parameter_dark_e };
         choices.array = choices_array;
         choices.used = 3;
 
@@ -45,7 +45,7 @@ extern "C" {
 
       // Identify and prioritize "verbosity" parameters.
       {
-        uint16_t choices_array[5] = { kt_remove_parameter_verbosity_quiet_e, kt_remove_parameter_verbosity_error_e, kt_remove_parameter_verbosity_verbose_e, kt_remove_parameter_verbosity_debug_e, kt_remove_parameter_verbosity_normal_e };
+        uint16_t choices_array[5] = { f_console_standard_parameter_verbosity_quiet_e, f_console_standard_parameter_verbosity_error_e, f_console_standard_parameter_verbosity_verbose_e, f_console_standard_parameter_verbosity_debug_e, f_console_standard_parameter_verbosity_normal_e };
         choices.array = choices_array;
         choices.used = 5;
 
@@ -71,15 +71,15 @@ extern "C" {
 
     main->setting.flag &= ~kt_remove_main_flag_version_copyright_help_d;
 
-    if (main->program.parameters.array[kt_remove_parameter_help_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_help_d;
     }
 
-    if (main->program.parameters.array[kt_remove_parameter_version_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_version_d;
     }
 
-    if (main->program.parameters.array[kt_remove_parameter_copyright_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_copyright_d;
     }
 
index 538cef3930bfd986b9c71bd0280583b6415204bf..379ccac61e9bcba05d34ed6a455f17ecb2b4206a 100644 (file)
@@ -220,9 +220,9 @@ extern "C" {
  *   - accessed:                 Remove by last accessed datetime.
  *   - accessed_changed_updated: A helper flag representing accessed, changed, and updated flag bits being set.
  *   - block:                    Remove by file type: block.
+ *   - changed:                  Remove by changed datetime.
  *   - character:                Remove by file type: character.
  *   - copyright:                Print copyright.
- *   - changed:                  Remove by changed datetime.
  *   - different:                Remove by user different from caller.
  *   - directory:                Remove by file type: directory.
  *   - empty_all:                Helper flag representing all empty flag bits.
@@ -233,6 +233,7 @@ extern "C" {
  *   - fifo:                     Remove by file type: FIFO.
  *   - follow:                   Follow symbolic links for deleting the file being pointed to rather than the link itself (when not set the link itself is deleted).
  *   - force:                    Forcibly delete.
+ *   - force_simulate:           A helper flag representing force and simulate flag bits being set.
  *   - group:                    Remove by GID.
  *   - help:                     Print help.
  *   - link:                     Remove by file type: link.
@@ -242,7 +243,7 @@ extern "C" {
  *   - prompt_each:              Operate in interactive mode, prompting for every file.
  *   - prompt_follow:            Operate in interactive mode: prompting for every link that is being followed.
  *   - prompt_never:             Do not operate in interactive mode.
- *   - prompt_once:              Operate in interactive mode: prompting if removing 3 or more files.
+ *   - prompt_once:              Operate in interactive mode: prompting once if removing 3 or more files or when operating recursively.
  *   - recurse:                  Recurse directories.
  *   - regular:                  Remove by file type: regular.
  *   - remember:                 Enable remembering paths already processed.
@@ -260,11 +261,11 @@ extern "C" {
 #ifndef _di_kt_remove_main_flag_d_
   #define kt_remove_main_flag_none_d                     0x0
   #define kt_remove_main_flag_accessed_d                 0x1
-  #define kt_remove_main_flag_accessed_changed_updated_d 0x40000011
+  #define kt_remove_main_flag_accessed_changed_updated_d 0x40000005
   #define kt_remove_main_flag_block_d                    0x2
-  #define kt_remove_main_flag_character_d                0x4
-  #define kt_remove_main_flag_copyright_d                0x8
-  #define kt_remove_main_flag_changed_d                  0x10
+  #define kt_remove_main_flag_changed_d                  0x4
+  #define kt_remove_main_flag_character_d                0x8
+  #define kt_remove_main_flag_copyright_d                0x10
   #define kt_remove_main_flag_different_d                0x20
   #define kt_remove_main_flag_directory_d                0x40
   #define kt_remove_main_flag_empty_all_d                0x780
@@ -275,6 +276,7 @@ extern "C" {
   #define kt_remove_main_flag_fifo_d                     0x800
   #define kt_remove_main_flag_follow_d                   0x1000
   #define kt_remove_main_flag_force_d                    0x2000
+  #define kt_remove_main_flag_force_simulate_d           0x8002000
   #define kt_remove_main_flag_group_d                    0x4000
   #define kt_remove_main_flag_help_d                     0x8000
   #define kt_remove_main_flag_link_d                     0x10000
@@ -297,7 +299,7 @@ extern "C" {
   #define kt_remove_main_flag_unknown_d                  0x100000000
   #define kt_remove_main_flag_utc_d                      0x200000000
   #define kt_remove_main_flag_version_d                  0x400000000
-  #define kt_remove_main_flag_version_copyright_help_d   0x400008008
+  #define kt_remove_main_flag_version_copyright_help_d   0x400008010
 #endif // _di_kt_remove_main_flag_e_
 
 /**
index 6b8e11703b743944ecaa573b970f1e56c3e9b41f..3387966e44fcddbde5e7f4ce06565f768a9ffc57 100644 (file)
@@ -21,22 +21,10 @@ extern "C" {
  */
 #ifndef _di_kt_remove_parameter_e_
   enum {
-    kt_remove_parameter_help_e,
-    kt_remove_parameter_copyright_e,
-    kt_remove_parameter_light_e,
-    kt_remove_parameter_dark_e,
-    kt_remove_parameter_no_color_e,
-    kt_remove_parameter_verbosity_quiet_e,
-    kt_remove_parameter_verbosity_error_e,
-    kt_remove_parameter_verbosity_normal_e,
-    kt_remove_parameter_verbosity_verbose_e,
-    kt_remove_parameter_verbosity_debug_e,
-    kt_remove_parameter_version_e,
-
-    kt_remove_parameter_accessed_e,
+    kt_remove_parameter_accessed_e = f_console_standard_parameter_last_e,
     kt_remove_parameter_block_e,
-    kt_remove_parameter_character_e,
     kt_remove_parameter_changed_e,
+    kt_remove_parameter_character_e,
     kt_remove_parameter_different_e,
     kt_remove_parameter_directory_e,
     kt_remove_parameter_empty_e,
@@ -68,8 +56,8 @@ extern "C" {
       \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_accessed_s,  kt_remove_long_accessed_s,  2, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_block_s,     kt_remove_long_block_s,     0, f_console_flag_normal_e), \
-      macro_f_console_parameter_t_initialize_3(kt_remove_short_character_s, kt_remove_long_character_s, 0, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_changed_s,   kt_remove_long_changed_s,   2, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(kt_remove_short_character_s, kt_remove_long_character_s, 0, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_different_s, kt_remove_long_different_s, 0, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_directory_s, kt_remove_long_directory_s, 0, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_remove_short_empty_s,     kt_remove_long_empty_s,     1, f_console_flag_normal_e), \
index ec2c70ff2333f4a22da992b821c373f99f6c6ca9..62dca4c8f7ded6d02077df8e7bb92109325b9042 100644 (file)
@@ -110,8 +110,8 @@ extern "C" {
 #ifndef _di_kt_remove_parameter_s_
   const f_string_static_t kt_remove_short_accessed_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_accessed_s, 0, KT_REMOVE_short_accessed_s_length);
   const f_string_static_t kt_remove_short_block_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_block_s, 0, KT_REMOVE_short_block_s_length);
-  const f_string_static_t kt_remove_short_character_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_character_s, 0, KT_REMOVE_short_character_s_length);
   const f_string_static_t kt_remove_short_changed_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_changed_s, 0, KT_REMOVE_short_changed_s_length);
+  const f_string_static_t kt_remove_short_character_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_character_s, 0, KT_REMOVE_short_character_s_length);
   const f_string_static_t kt_remove_short_different_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_different_s, 0, KT_REMOVE_short_different_s_length);
   const f_string_static_t kt_remove_short_directory_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_directory_s, 0, KT_REMOVE_short_directory_s_length);
   const f_string_static_t kt_remove_short_empty_s = macro_f_string_static_t_initialize_1(KT_REMOVE_short_empty_s, 0, KT_REMOVE_short_empty_s_length);
@@ -134,8 +134,8 @@ extern "C" {
 
   const f_string_static_t kt_remove_long_accessed_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_accessed_s, 0, KT_REMOVE_long_accessed_s_length);
   const f_string_static_t kt_remove_long_block_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_block_s, 0, KT_REMOVE_long_block_s_length);
-  const f_string_static_t kt_remove_long_character_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_character_s, 0, KT_REMOVE_long_character_s_length);
   const f_string_static_t kt_remove_long_changed_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_changed_s, 0, KT_REMOVE_long_changed_s_length);
+  const f_string_static_t kt_remove_long_character_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_character_s, 0, KT_REMOVE_long_character_s_length);
   const f_string_static_t kt_remove_long_different_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_different_s, 0, KT_REMOVE_long_different_s_length);
   const f_string_static_t kt_remove_long_directory_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_directory_s, 0, KT_REMOVE_long_directory_s_length);
   const f_string_static_t kt_remove_long_empty_s = macro_f_string_static_t_initialize_1(KT_REMOVE_long_empty_s, 0, KT_REMOVE_long_empty_s_length);
index e3f52842f8379bd4799f24df0f187c3bd2da65ca..899cfe3f92da30872084464764df621c67dc503c 100644 (file)
@@ -509,8 +509,8 @@ extern "C" {
 
   extern const f_string_static_t kt_remove_short_accessed_s;
   extern const f_string_static_t kt_remove_short_block_s;
-  extern const f_string_static_t kt_remove_short_character_s;
   extern const f_string_static_t kt_remove_short_changed_s;
+  extern const f_string_static_t kt_remove_short_character_s;
   extern const f_string_static_t kt_remove_short_different_s;
   extern const f_string_static_t kt_remove_short_directory_s;
   extern const f_string_static_t kt_remove_short_empty_s;
@@ -533,8 +533,8 @@ extern "C" {
 
   extern const f_string_static_t kt_remove_long_accessed_s;
   extern const f_string_static_t kt_remove_long_block_s;
-  extern const f_string_static_t kt_remove_long_character_s;
   extern const f_string_static_t kt_remove_long_changed_s;
+  extern const f_string_static_t kt_remove_long_character_s;
   extern const f_string_static_t kt_remove_long_different_s;
   extern const f_string_static_t kt_remove_long_directory_s;
   extern const f_string_static_t kt_remove_long_empty_s;
index 87bc396e1b27eca342299f253972423d627d3341..5be8e65e2df44c972c80a4523c8daa362e133222 100644 (file)
@@ -22,31 +22,38 @@ extern "C" {
 
     if (F_status_is_error_not(main->setting.state.status) && !(flag_operate & kt_remove_flag_file_operate_processed_d)) {
       if (flag_operate & kt_remove_flag_file_operate_missing_d) {
-        main->setting.state.status = F_status_set_error(F_file_found_not);
+        if (main->setting.flag & kt_remove_main_flag_force_simulate_d) {
+          status = main->setting.state.status = F_no;
+        }
+        else {
+          main->setting.state.status = F_status_set_error(F_file_found_not);
 
-        kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(f_file_exists), path, f_file_operation_delete_s, fll_error_file_type_file_e);
+          kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(f_file_exists), path, f_file_operation_delete_s, fll_error_file_type_file_e);
+        }
       }
-      else if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) {
+      else {
         kt_remove_operate_file_prompt(main, path, flag_operate);
 
-        if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_skip) {
-          main->setting.state.status = F_okay;
+        if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) {
+          if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_skip) {
+            main->setting.state.status = F_okay;
 
-          if (flag_operate & kt_remove_flag_file_operate_directory_d) {
-            if (main->call.process_operate_directory) {
-              status = main->setting.state.status = main->call.process_operate_directory(main, path, flag_operate);
+            if (flag_operate & kt_remove_flag_file_operate_directory_d) {
+              if (main->call.process_operate_directory) {
+                status = main->setting.state.status = main->call.process_operate_directory(main, path, flag_operate);
+              }
             }
-          }
-          else {
-            if (main->call.process_operate_file) {
-              status = main->setting.state.status = main->call.process_operate_file(main, path, flag_operate);
+            else {
+              if (main->call.process_operate_file) {
+                status = main->setting.state.status = main->call.process_operate_file(main, path, flag_operate);
+              }
             }
-          }
 
-          if (status == F_done) {
-            main->setting.state.status = F_okay;
+            if (status == F_done) {
+              main->setting.state.status = F_okay;
 
-            return;
+              return;
+            }
           }
         }
       }
@@ -205,6 +212,8 @@ extern "C" {
       if (!(flag_operate & kt_remove_flag_file_operate_link_d)) return;
     }
 
+    if (main->setting.flag & kt_remove_main_flag_simulate_d) return;
+
     main->cache.input.used = 0;
 
     kt_remove_print_message_remove_confirm(&main->program.message, path);
index fdd8b5e839140b293801f8528d9591ea8f79bc1a..602ca714d7723a4e441aeecd18be3e91cba8db58 100644 (file)
@@ -47,8 +47,15 @@ extern "C" {
     kt_remove_print_simulate_operate_file_exists(&main->program.output, path, flag_out);
 
     if (main->setting.state.status == F_false) {
-      if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) {
-        remove_print_warning_file_reason(&main->program.warning, path, kt_remove_print_reason_not_found_s);
+      if (main->setting.flag & kt_remove_main_flag_force_d) {
+        if (main->setting.flag & kt_remove_main_flag_simulate_d) {
+          kt_remove_print_simulate_operate_boolean(&main->program.output, kt_remove_ignore_s, F_true);
+        }
+      }
+      else {
+        if (main->setting.flag & kt_remove_main_flag_simulate_d) {
+          kt_remove_print_simulate_operate_boolean(&main->program.output, kt_remove_ignore_s, F_false);
+        }
       }
 
       return kt_remove_flag_file_operate_missing_d;
@@ -314,8 +321,8 @@ extern "C" {
       else if (main->setting.flag & kt_remove_main_flag_prompt_follow_d) {
         kt_remove_print_simulate_operate_boolean(&main->program.output, kt_remove_prompt_s, (main->setting.flag & kt_remove_main_flag_follow_d) && (flag_out & kt_remove_flag_file_operate_link_d));
       }
-      else {
-        kt_remove_print_simulate_operate_prompt_once(&main->program.output, main->setting.files.used > 2 || main->setting.flag & kt_remove_main_flag_recurse_d);
+      else if (main->setting.flag & kt_remove_main_flag_prompt_once_d) {
+        kt_remove_print_simulate_operate_boolean(&main->program.output, kt_remove_prompt_s, !(main->setting.prompt));
       }
     }
 
index adc11de13def8b5d69bebe6116c9401ecb3b6015..5deb8ba408f4e3582c2a5ec5ac487320607c9956 100644 (file)
@@ -27,8 +27,8 @@ extern "C" {
 
     fll_program_print_help_option(print, kt_remove_short_accessed_s, kt_remove_long_accessed_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Remove by file last accessed date and time.");
     fll_program_print_help_option(print, kt_remove_short_block_s, kt_remove_long_block_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "    Remove by file type of block.");
-    fll_program_print_help_option(print, kt_remove_short_character_s, kt_remove_long_character_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Remove by file type of character.");
     fll_program_print_help_option(print, kt_remove_short_changed_s, kt_remove_long_changed_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "  Remove by file changed on date and time.");
+    fll_program_print_help_option(print, kt_remove_short_character_s, kt_remove_long_character_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Remove by file type of character.");
     fll_program_print_help_option(print, kt_remove_short_different_s, kt_remove_long_different_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Remove by file owner by a user different from the current calling user.");
     fll_program_print_help_option(print, kt_remove_short_directory_s, kt_remove_long_directory_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Remove by file type of directory.");
     fll_program_print_help_option(print, kt_remove_short_empty_s, kt_remove_long_empty_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "    Remove directory by a specific empty or not empty state.");
index e56b07c0f0a67922d6b1cf9c2d3b2ba779470e59..537c999466ed41eb328018b3e26333fd86a1a4c0 100644 (file)
@@ -170,22 +170,6 @@ extern "C" {
     return F_okay;
   }
 #endif // _di_kt_remove_print_simulate_operate_mode_
-
-#ifndef _di_kt_remove_print_simulate_operate_prompt_once_
-  f_status_t kt_remove_print_simulate_operate_prompt_once(fl_print_t * const print, const bool yes) {
-
-    if (!print || !print->custom) return F_status_set_error(F_output_not);
-
-    kt_remove_main_t * const main = (kt_remove_main_t *) print->custom;
-
-    if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) return F_output_not;
-
-    fll_print_format("  %r %r%r", print->to, kt_remove_prompt_s, yes ? kt_remove_once_s : kt_remove_no_s, f_string_eol_s);
-
-    return F_okay;
-  }
-#endif // _di_kt_remove_print_simulate_operate_prompt_once_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index c84100ed86e3c75c5067212321d6a4623be399a0..b0e2bd45c1ec6ae00f4ba60c3b066f4ff74cc926 100644 (file)
@@ -220,33 +220,6 @@ extern "C" {
   extern f_status_t kt_remove_print_simulate_operate_mode(fl_print_t * const print, const f_number_unsigned_t mode, const f_string_static_t match);
 #endif // _di_kt_remove_print_simulate_operate_mode_
 
-/**
- * Print a message for some prompt parameter is set to once regarding the simulation.
- *
- * This does nothing if the simulate flag (kt_remove_flag_simulate_d) is not set.
- *
- * @param print
- *   The output structure to print to.
- *
- *   This locks, uses, and unlocks the file stream.
- *
- *   Must not be NULL.
- *
- *   This does not alter print.custom.setting.state.status.
- * @param yes
- *   If TRUE, then print "once".
- *   If FALSE, then print "no".
- *
- * @return
- *   F_okay on success.
- *   F_output_not on success, but no printing is performed.
- *
- *   F_output_not (with error bit) if setting is NULL.
- */
-#ifndef _di_kt_remove_print_simulate_operate_prompt_once_
-  extern f_status_t kt_remove_print_simulate_operate_prompt_once(fl_print_t * const print, const bool yes);
-#endif // _di_kt_remove_print_simulate_operate_prompt_once_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 0e3b4999fcc0741e428441f4b377ffd40a4a9d1c..ef4ad100486af89fbfc005bbbe109c7f61a78321 100644 (file)
@@ -52,6 +52,13 @@ extern "C" {
       return;
     }
 
+    // Disable once prompt if fewer than three files passed in non-recursive mode.
+    if (main->setting.flag & kt_remove_main_flag_prompt_once_d) {
+      if (main->setting.files.used < 3 && !(main->setting.flag & kt_remove_main_flag_recurse_d)) {
+        main->setting.prompt = 1;
+      }
+    }
+
     kt_remove_print_simulate_operate(&main->program.output);
 
     main->setting.state.status = F_okay;
diff --git a/sources/c/program/kevux/tools/remove/rm/config.c b/sources/c/program/kevux/tools/remove/rm/config.c
new file mode 100644 (file)
index 0000000..1ac2545
--- /dev/null
@@ -0,0 +1 @@
+#include "config.h"
diff --git a/sources/c/program/kevux/tools/remove/rm/config.h b/sources/c/program/kevux/tools/remove/rm/config.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sources/c/program/kevux/tools/remove/rm/enumeration.c b/sources/c/program/kevux/tools/remove/rm/enumeration.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sources/c/program/kevux/tools/remove/rm/enumeration.h b/sources/c/program/kevux/tools/remove/rm/enumeration.h
new file mode 100644 (file)
index 0000000..8b22930
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * Kevux Tools - Remove (rm)
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common enumeration types.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_remove_rm_enumeration_h
+#define _kt_remove_rm_enumeration_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The rm program parameters.
+ */
+#ifndef _di_kt_remove_rm_parameter_e_
+  enum {
+    kt_remove_rm_parameter_directory_e = f_console_standard_parameter_last_e,
+    kt_remove_rm_parameter_each_e, // -i
+    kt_remove_rm_parameter_force_e,
+    kt_remove_rm_parameter_once_e, // -I
+    kt_remove_rm_parameter_one_filesystem_e,
+    kt_remove_rm_parameter_recursive_e, // -r, --recursive
+    kt_remove_rm_parameter_recursive_alt_e, // -R
+    kt_remove_rm_parameter_simulate_e,
+    kt_remove_rm_parameter_verbose_alt_e,
+    kt_remove_rm_parameter_version_alt_e,
+  }; // enum
+
+  #define kt_remove_rm_console_parameter_t_initialize \
+    { \
+      macro_fll_program_console_parameter_standard_initialize, \
+      \
+      macro_f_console_parameter_t_initialize_3(kt_remove_short_directory_s,        kt_remove_long_directory_s,              0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_6(                                    kt_remove_rm_short_each_s,               0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(kt_remove_short_force_s,            kt_remove_long_force_s,                  0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_6(                                    kt_remove_rm_short_once_s,               0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_5(                                    kt_remove_rm_long_one_filesystem_s,      0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(kt_remove_short_recursive_s,        kt_remove_long_recursive_s,              0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_6(                                    kt_remove_rm_short_recursive_alt_s,      0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(kt_remove_short_simulate_s,         kt_remove_long_simulate_s,               0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(f_console_standard_short_verbose_s, f_console_standard_long_verbose_s,       0, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_5(                                    f_console_standard_long_version_s,       0, f_console_flag_normal_e), \
+    }
+
+  #define kt_remove_rm_total_parameters_d (f_console_parameter_state_type_total_d + 10)
+#endif // _di_kt_remove_rm_parameter_e_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_rm_enumeration_h
diff --git a/sources/c/program/kevux/tools/remove/rm/main.c b/sources/c/program/kevux/tools/remove/rm/main.c
new file mode 100644 (file)
index 0000000..1c2f32b
--- /dev/null
@@ -0,0 +1,93 @@
+#include "rm.h"
+#include "main.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
+
+  kt_remove_main_t data = kt_remove_main_t_initialize;
+
+  data.program.debug.flag |= kt_remove_print_flag_debug_d | kt_remove_print_flag_out_d;
+  data.program.error.flag |= kt_remove_print_flag_error_d | kt_remove_print_flag_out_d;
+  data.program.message.flag |= kt_remove_print_flag_message_d | kt_remove_print_flag_out_d;
+  data.program.output.flag |= kt_remove_print_flag_out_d;
+  data.program.warning.flag |= kt_remove_print_flag_warning_d | kt_remove_print_flag_out_d;
+  data.program.message.custom = (void *) &data;
+  data.program.output.custom = (void *) &data;
+  data.program.error.custom = (void *) &data;
+  data.program.warning.custom = (void *) &data;
+  data.program.debug.custom = (void *) &data;
+
+  data.setting.state.data = (void *) &data;
+  data.setting.program_name = &kt_remove_program_name_s;
+  data.setting.program_name_long = &kt_remove_program_name_long_s;
+
+  data.call.print_help = &kt_remove_rm_print_message_help;
+  data.call.process_normal = &kt_remove_process_normal_operate;
+  data.call.process_operate_directory = &kt_remove_rm_operate_file_remove;
+  data.call.process_operate_file = &kt_remove_rm_operate_file_remove;
+
+  #ifdef _en_kt_default_to_utc_
+    data.setting.flag |= kt_remove_flag_utc_d;
+  #endif // _en_kt_default_to_utc_
+
+  f_console_parameter_t parameters[] = kt_remove_rm_console_parameter_t_initialize;
+
+  data.program.parameters.array = parameters;
+  data.program.parameters.used = kt_remove_rm_total_parameters_d;
+  data.program.environment = envp;
+
+  if (f_pipe_input_exists()) {
+    data.program.pipe = fll_program_data_pipe_input_e;
+  }
+
+  fll_program_standard_set_up(&data.program);
+
+  #ifdef _di_thread_support_
+    {
+      const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
+
+      kt_remove_rm_setting_load(arguments, &data);
+    }
+
+    kt_remove_main(&data);
+  #else
+    {
+      f_thread_id_t id_signal;
+
+      memset(&id_signal, 0, sizeof(f_thread_id_t));
+
+      data.setting.state.status = f_thread_create(0, &id_signal, &kt_remove_thread_signal, (void *) &data);
+
+      if (F_status_is_error(data.setting.state.status)) {
+        kt_remove_print_error(&data.program.error, macro_kt_remove_f(f_thread_create));
+      }
+      else {
+        {
+          const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize_1(argc, argv, envp);
+
+          kt_remove_rm_setting_load(arguments, &data);
+        }
+
+        if (!kt_remove_signal_check(&data)) {
+          kt_remove_main(&data);
+        }
+
+        f_thread_cancel(id_signal);
+        f_thread_join(id_signal, 0);
+      }
+    }
+  #endif // _di_thread_support_
+
+  kt_remove_main_delete(&data);
+
+  fll_program_standard_set_down(&data.program);
+
+  return (F_status_is_error(data.setting.state.status) || data.setting.state.status == F_false) ? 1 : 0;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/rm/main.h b/sources/c/program/kevux/tools/remove/rm/main.h
new file mode 100644 (file)
index 0000000..3feafc5
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Kevux Tools - Remove (rm)
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * This file is only ever included by main.c and should not normally be included anywhere else.
+ * Anything that wants to include this should be providing the "rm" program functionality in some manner.
+ */
+#ifndef _kt_remove_rm_main_h
+#define _kt_remove_rm_main_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Standard program entry point.
+ *
+ * @param argc
+ *   The number of arguments.
+ * @param argv
+ *   The array of arguments.
+ * @param envp
+ *   The array of all environment variables on program start.
+ *
+ * @return
+ *   0 on success.
+ *   1 on error.
+ */
+extern int main(const int argc, const f_string_t *argv, const f_string_t *envp);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_rm_main_h
diff --git a/sources/c/program/kevux/tools/remove/rm/print.c b/sources/c/program/kevux/tools/remove/rm/print.c
new file mode 100644 (file)
index 0000000..45a6e57
--- /dev/null
@@ -0,0 +1,71 @@
+#include "rm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_remove_rm_print_error_directory_not_
+  f_status_t kt_remove_rm_print_error_directory_not(fl_print_t * const print, const f_string_static_t path) {
+
+    if (!print) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QCannot remove directory '%]", print->to, print->set->error, print->prefix, print->set->error);
+    fl_print_format("%[%Q%]", print->to, print->set->notable, path, print->set->notable);
+    fl_print_format("%[', file is not a directory.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_kt_remove_rm_print_error_directory_not_
+
+#ifndef _di_kt_remove_rm_print_message_help_
+  f_status_t kt_remove_rm_print_message_help(fl_print_t * const print, const f_color_context_t context) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+
+    kt_remove_main_t * const main = (kt_remove_main_t *) print->custom;
+
+    f_file_stream_lock(print->to);
+
+    fll_program_print_help_header(
+      print,
+      main->setting.program_name_long
+        ? *main->setting.program_name_long
+        : kt_remove_program_name_long_s,
+      kt_remove_program_version_s
+    );
+
+    fll_program_print_help_option_standard(print);
+
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_option(print, kt_remove_rm_short_parents_s, kt_remove_rm_long_parents_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "                 Remove directory and the parent directories in the path provided.");
+    fll_program_print_help_option(print, kt_remove_short_simulate_s, kt_remove_long_simulate_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "                Simulate removal rather than actually rming.");
+
+    fll_program_print_help_option_long(print, kt_remove_rm_long_ignore_empty_not_s, f_console_symbol_long_normal_s, "Ignore directories that are not empty rather than fail on error.");
+    fll_program_print_help_option_long(print, f_console_standard_long_version_s, f_console_symbol_long_normal_s, "                 Print this help message.");
+
+    f_print_dynamic_raw(f_string_eol_s, print->to);
+
+    fll_program_print_help_usage(
+      print,
+      main->setting.program_name
+        ? *main->setting.program_name
+        : kt_remove_program_name_s,
+      kt_remove_program_help_parameters_s
+    );
+
+    f_file_stream_flush(print->to);
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_kt_remove_rm_print_message_help_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/rm/print.h b/sources/c/program/kevux/tools/remove/rm/print.h
new file mode 100644 (file)
index 0000000..0b4c74f
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * Kevux Tools - Remove (rm)
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the print message functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_remove_rm_print_h
+#define _kt_remove_rm_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print error message about not being able to delete a file because that file is not a directory.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   Must not be NULL.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param path
+ *   The file that cannot be deleted.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_kt_remove_rm_print_error_directory_not_
+  extern f_status_t kt_remove_rm_print_error_directory_not(fl_print_t * const print, const f_string_static_t path);
+#endif // _di_kt_remove_rm_print_error_directory_not_
+
+/**
+ * Print help.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This locks, uses, and unlocks the file stream.
+ *
+ *   Must not be NULL.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param context
+ *   The color context settings.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ */
+#ifndef _di_kt_remove_rm_print_message_help_
+  extern f_status_t kt_remove_rm_print_message_help(fl_print_t * const print, const f_color_context_t context);
+#endif // _di_kt_remove_rm_print_message_help_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_rm_print_h
diff --git a/sources/c/program/kevux/tools/remove/rm/rm.c b/sources/c/program/kevux/tools/remove/rm/rm.c
new file mode 100644 (file)
index 0000000..e2c438c
--- /dev/null
@@ -0,0 +1,157 @@
+#include "rm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_remove_rm_operate_file_remove_
+  f_status_t kt_remove_rm_operate_file_remove(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate) {
+
+    if (!main) return F_status_set_error(F_parameter);
+
+    if (!flag_operate) return F_status_set_error(F_parameter);
+
+    if (flag_operate & kt_remove_flag_file_operate_directory_d) {
+      return kt_remove_operate_file_remove(main, path, flag_operate);
+    }
+
+    kt_remove_rm_print_error_directory_not(&main->program.error, path);
+
+    return F_status_set_error(F_no);
+  }
+#endif // _di_kt_remove_rm_operate_file_remove_
+
+#ifndef _di_kt_remove_rm_setting_load_
+  void kt_remove_rm_setting_load(const f_console_arguments_t arguments, kt_remove_main_t * const main) {
+
+    if (!main) return;
+
+    main->setting.flag &= ~kt_remove_main_flag_option_used_d;
+
+    main->setting.state.step_small = kt_remove_allocation_console_d;
+
+    f_console_parameter_process(arguments, &main->program.parameters, &main->setting.state, 0);
+
+    main->setting.state.step_small = kt_remove_allocation_small_d;
+
+    if (F_status_is_error(main->setting.state.status)) {
+      kt_remove_print_error(&main->program.error, macro_kt_remove_f(f_console_parameter_process));
+
+      return;
+    }
+
+    {
+      f_uint16s_t choices = f_uint16s_t_initialize;
+
+      // Identify and prioritize "color context" parameters.
+      {
+        uint16_t choices_array[3] = { kt_remove_rm_parameter_no_color_e, kt_remove_rm_parameter_light_e, kt_remove_rm_parameter_dark_e };
+        choices.array = choices_array;
+        choices.used = 3;
+
+        const uint8_t modes[3] = { f_color_mode_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+        main->setting.state.status = fll_program_parameter_process_context(choices, modes, F_true, &main->program);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          kt_remove_print_error(&main->program.error, macro_kt_remove_f(fll_program_parameter_process_context));
+
+          return;
+        }
+      }
+
+      // Identify and prioritize "verbosity" parameters.
+      {
+        if (main->program.parameters.array[kt_remove_rm_parameter_verbose_alt_e].result & f_console_result_found_e) {
+          main->program.warning.verbosity
+            = main->program.error.verbosity
+            = main->program.output.verbosity
+            = main->program.message.verbosity
+              = f_console_verbosity_verbose_e;
+        }
+        else {
+          uint16_t choices_array[5] = { kt_remove_rm_parameter_verbosity_quiet_e, kt_remove_rm_parameter_verbosity_error_e, kt_remove_rm_parameter_verbosity_verbose_e, kt_remove_rm_parameter_verbosity_debug_e, kt_remove_rm_parameter_verbosity_normal_e };
+          choices.array = choices_array;
+          choices.used = 5;
+
+          const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+          main->setting.state.status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, &main->program);
+
+          if (F_status_is_error(main->setting.state.status)) {
+            kt_remove_print_error(&main->program.error, macro_kt_remove_f(fll_program_parameter_process_verbosity));
+
+            return;
+          }
+        }
+      }
+    }
+
+    f_number_unsigned_t i = 0;
+    f_number_unsigned_t index = 0;
+    f_number_unsigned_t index2 = 0;
+    f_number_unsigned_t total_locations = 0;
+    f_number_unsigned_t total_arguments = 0;
+
+    uint8_t j = 0;
+
+    main->setting.flag &= ~kt_remove_main_flag_version_copyright_help_d;
+
+    if (main->program.parameters.array[kt_remove_rm_parameter_help_e].result & f_console_result_found_e) {
+      main->setting.flag |= kt_remove_main_flag_help_d;
+    }
+
+    if ((main->program.parameters.array[kt_remove_rm_parameter_version_e].result & f_console_result_found_e) || (main->program.parameters.array[kt_remove_rm_parameter_version_alt_e].result & f_console_result_found_e)) {
+      main->setting.flag |= kt_remove_main_flag_version_d;
+    }
+
+    if (main->program.parameters.array[kt_remove_rm_parameter_copyright_e].result & f_console_result_found_e) {
+      main->setting.flag |= kt_remove_main_flag_copyright_d;
+    }
+
+    if (main->program.parameters.array[kt_remove_rm_parameter_ignore_empty_not_e].result & f_console_result_found_e) {
+      main->setting.flag |= kt_remove_main_flag_empty_only_d;
+    }
+
+    if (main->program.parameters.array[kt_remove_rm_parameter_parents_e].result & f_console_result_found_e) {
+      main->setting.flag |= kt_remove_main_flag_tree_d;
+    }
+
+    if (main->program.parameters.array[kt_remove_rm_parameter_simulate_e].result & f_console_result_found_e) {
+      main->setting.flag |= kt_remove_main_flag_simulate_d;
+    }
+
+    // Load all remaining files as static strings (setting size to 0).
+    if (main->program.parameters.remaining.used) {
+      main->setting.state.status = f_memory_array_increase_by(main->program.parameters.remaining.used, sizeof(f_string_dynamic_t), (void **) &main->setting.files.array, &main->setting.files.used, &main->setting.files.size);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        kt_remove_print_error(&main->program.error, macro_kt_remove_f(f_memory_array_increase_by));
+
+        return;
+      }
+
+      for (i = 0; i < main->program.parameters.remaining.used; ++i, ++main->setting.files.used) {
+
+        index = main->program.parameters.remaining.array[i];
+
+        main->setting.files.array[main->setting.files.used].used = 0;
+
+        fl_path_clean(main->program.parameters.arguments.array[index], &main->setting.files.array[main->setting.files.used]);
+
+        if (F_status_is_error(main->setting.state.status)) {
+          kt_remove_print_error_file(&main->program.error, macro_kt_remove_f(fl_path_clean), main->program.parameters.arguments.array[index], f_file_operation_process_s, fll_error_file_type_path_e);
+
+          return;
+        }
+      } // for
+    }
+
+    // Make sure only directoreis are deleted.
+    main->setting.flag |= kt_remove_main_flag_directory_d | kt_remove_main_flag_option_used_d;
+  }
+#endif // _di_kt_remove_rm_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/rm/rm.h b/sources/c/program/kevux/tools/remove/rm/rm.h
new file mode 100644 (file)
index 0000000..01b68d7
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * Kevux Tools - Remove (rm)
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * This program provides the base include for the rm program.
+ */
+#ifndef _kt_remove_rm_rm_h
+#define _kt_remove_rm_rm_h
+
+// Unlink includes.
+#include <program/kevux/tools/remove/main/remove.h>
+#include <program/kevux/tools/remove/rm/enumeration.h>
+#include <program/kevux/tools/remove/rm/print.h>
+#include <program/kevux/tools/remove/rm/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform rm program file operation.
+ *
+ * This prints error messages as appropriate.
+ *
+ * @param main
+ *   The main program and settings data.
+ *
+ *   The setting.flag has kt_remove_flag_option_used_d forcibly cleared on the start of this function.
+ *
+ *   Must not be NULL.
+ *
+ *   This alters setting.status:
+ *     Success from: kt_remove_operate_file_remove().
+ *
+ *     F_no (with error bit) on failure and file is not to be removed or cannot be removed.
+ *
+ *     Errors (with error bit) from: kt_remove_operate_file_remove().
+ *
+ *     F_parameter (with error bit) on parameter error.
+ * @param path
+ *   The file being processed.
+ * @param flag_operate
+ *   The operate file specific flags from kt_remove_flag_file_operate_*_e.
+ *
+ * @return
+ *   Success from: kt_remove_operate_file_remove().
+ *
+ *   F_no (with error bit) on failure and file is not to be removed or cannot be removed.
+ *
+ *   Errors (with error bit) from: kt_remove_operate_file_remove().
+ *
+ *   F_parameter (with error bit) on parameter error.
+ *
+ * @see kt_remove_operate_file_remove()
+ */
+#ifndef _di_kt_remove_rm_operate_file_remove_
+  extern f_status_t kt_remove_rm_operate_file_remove(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
+#endif // _di_kt_remove_rm_operate_file_remove_
+
+/**
+ * Perform the rm program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * @param arguments
+ *   The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ *   The main program and settings data.
+ *
+ *   The setting.flag has kt_remove_flag_option_used_d forcibly cleared on the start of this function.
+ *
+ *   Must not be NULL.
+ *
+ *   This alters setting.status:
+ *     F_okay on success.
+ *     F_data_not on success but nothing was provided to operate with.
+ *
+ *     F_parameter (with error bit) on parameter error.
+ *
+ *     Errors (with error bit) from: f_console_parameter_process().
+ *     Errors (with error bit) from: f_file_stream_open().
+ *     Errors (with error bit) from: f_memory_array_increase_by().
+ *
+ * @see f_console_parameter_process()
+ * @see f_file_stream_open()
+ * @see f_memory_array_increase_by()
+ */
+#ifndef _di_kt_remove_rm_setting_load_
+  extern void kt_remove_rm_setting_load(const f_console_arguments_t arguments, kt_remove_main_t * const main);
+#endif // _di_kt_remove_rm_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_rm_rm_h
diff --git a/sources/c/program/kevux/tools/remove/rm/string.c b/sources/c/program/kevux/tools/remove/rm/string.c
new file mode 100644 (file)
index 0000000..5ffdac8
--- /dev/null
@@ -0,0 +1,21 @@
+#include "rm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_remove_program_name_s_
+  const f_string_static_t kt_remove_program_name_s = macro_f_string_static_t_initialize_1(KT_REMOVE_program_name_s, 0, KT_REMOVE_program_name_s_length);
+  const f_string_static_t kt_remove_program_name_long_s = macro_f_string_static_t_initialize_1(KT_REMOVE_program_name_long_s, 0, KT_REMOVE_program_name_long_s_length);
+#endif // _di_remove_program_name_s_
+
+#ifndef _di_kt_remove_rm_parameter_s_
+  const f_string_static_t kt_remove_rm_short_parents_s = macro_f_string_static_t_initialize_1(KT_REMOVE_rm_short_parents_s, 0, KT_REMOVE_rm_short_parents_s_length);
+
+  const f_string_static_t kt_remove_rm_long_ignore_empty_not_s = macro_f_string_static_t_initialize_1(KT_REMOVE_rm_long_ignore_empty_not_s, 0, KT_REMOVE_rm_long_ignore_empty_not_s_length);
+  const f_string_static_t kt_remove_rm_long_parents_s = macro_f_string_static_t_initialize_1(KT_REMOVE_rm_long_parents_s, 0, KT_REMOVE_rm_long_parents_s_length);
+#endif // _di_kt_remove_rm_parameter_s_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/rm/string.h b/sources/c/program/kevux/tools/remove/rm/string.h
new file mode 100644 (file)
index 0000000..a43b9ea
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Kevux Tools - Remove (rm)
+ *
+ * Project: Kevux Tools
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides the common string structures for the remove program.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _kt_remove_rm_string_h
+#define _kt_remove_rm_string_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The program name.
+ */
+#ifndef _di_kt_remove_program_name_s_
+  #define KT_REMOVE_program_name_s      "rm"
+  #define KT_REMOVE_program_name_long_s "Remove Directory"
+
+  #define KT_REMOVE_program_name_s_length      5
+  #define KT_REMOVE_program_name_long_s_length 16
+#endif // _di_kt_remove_program_name_s_
+
+/**
+ * Additional strings used for various purposes for the rm program.
+ *
+ * kt_remove_rm_parameter_*_s: Parameter related strings.
+ */
+#ifndef _di_kt_remove_rm_parameter_s_
+  #define KT_REMOVE_rm_short_parents_s "p"
+
+  #define KT_REMOVE_rm_long_ignore_empty_not_s "ignore-fail-on-non-empty"
+  #define KT_REMOVE_rm_long_parents_s          "parents"
+
+  #define KT_REMOVE_rm_short_parents_s_length 1
+
+  #define KT_REMOVE_rm_long_ignore_empty_not_s_length 24
+  #define KT_REMOVE_rm_long_parents_s_length          7
+
+  extern const f_string_static_t kt_remove_rm_short_parents_s;
+
+  extern const f_string_static_t kt_remove_rm_long_ignore_empty_not_s;
+  extern const f_string_static_t kt_remove_rm_long_parents_s;
+#endif // _di_kt_remove_rm_parameter_s_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_rm_string_h
index b5f2a9635a7f6e925efb3e313d1526860851f88b..393f939d54809e01895fbcd54ba82bc929cd4b54 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Kevux Tools - Rmdir
+ * Kevux Tools - Remove Directory
  *
  * Project: Kevux Tools
  * API Version: 0.7
@@ -21,19 +21,7 @@ extern "C" {
  */
 #ifndef _di_kt_remove_rmdir_parameter_e_
   enum {
-    kt_remove_rmdir_parameter_help_e,
-    kt_remove_rmdir_parameter_copyright_e,
-    kt_remove_rmdir_parameter_light_e,
-    kt_remove_rmdir_parameter_dark_e,
-    kt_remove_rmdir_parameter_no_color_e,
-    kt_remove_rmdir_parameter_verbosity_quiet_e,
-    kt_remove_rmdir_parameter_verbosity_error_e,
-    kt_remove_rmdir_parameter_verbosity_normal_e,
-    kt_remove_rmdir_parameter_verbosity_verbose_e,
-    kt_remove_rmdir_parameter_verbosity_debug_e,
-    kt_remove_rmdir_parameter_version_e,
-
-    kt_remove_rmdir_parameter_ignore_empty_not_e,
+    kt_remove_rmdir_parameter_ignore_empty_not_e = f_console_standard_parameter_last_e,
     kt_remove_rmdir_parameter_parents_e,
     kt_remove_rmdir_parameter_simulate_e,
     kt_remove_rmdir_parameter_verbose_alt_e,
index 1ef53496426f589a929cff5e470dfae1c6be2eb9..371127d2d7a0191a6160cc829833feb7d2dd6938 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Kevux Tools - Rmdir
+ * Kevux Tools - Remove Directory
  *
  * Project: Kevux Tools
  * API Version: 0.7
index 6c751d8cf4d04a2e28ca26fb3cbd1431ace947fe..52e0a6d66ef572fcfe31d40fcee3ec02b0bca10b 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Kevux Tools - Rmdir
+ * Kevux Tools - Remove Directory
  *
  * Project: Kevux Tools
  * API Version: 0.7
index e95583010dad376b23f6432cc35562239660d6ee..e32203524fcf17f7e7b29f0b5fe416e1b6b33d70 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
 
       // Identify and prioritize "color context" parameters.
       {
-        uint16_t choices_array[3] = { kt_remove_rmdir_parameter_no_color_e, kt_remove_rmdir_parameter_light_e, kt_remove_rmdir_parameter_dark_e };
+        uint16_t choices_array[3] = { f_console_standard_parameter_no_color_e, f_console_standard_parameter_light_e, f_console_standard_parameter_dark_e };
         choices.array = choices_array;
         choices.used = 3;
 
@@ -70,7 +70,7 @@ extern "C" {
               = f_console_verbosity_verbose_e;
         }
         else {
-          uint16_t choices_array[5] = { kt_remove_rmdir_parameter_verbosity_quiet_e, kt_remove_rmdir_parameter_verbosity_error_e, kt_remove_rmdir_parameter_verbosity_verbose_e, kt_remove_rmdir_parameter_verbosity_debug_e, kt_remove_rmdir_parameter_verbosity_normal_e };
+          uint16_t choices_array[5] = { f_console_standard_parameter_verbosity_quiet_e, f_console_standard_parameter_verbosity_error_e, f_console_standard_parameter_verbosity_verbose_e, f_console_standard_parameter_verbosity_debug_e, f_console_standard_parameter_verbosity_normal_e };
           choices.array = choices_array;
           choices.used = 5;
 
@@ -97,15 +97,15 @@ extern "C" {
 
     main->setting.flag &= ~kt_remove_main_flag_version_copyright_help_d;
 
-    if (main->program.parameters.array[kt_remove_rmdir_parameter_help_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_help_d;
     }
 
-    if ((main->program.parameters.array[kt_remove_rmdir_parameter_version_e].result & f_console_result_found_e) || (main->program.parameters.array[kt_remove_rmdir_parameter_version_alt_e].result & f_console_result_found_e)) {
+    if ((main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) || (main->program.parameters.array[kt_remove_rmdir_parameter_version_alt_e].result & f_console_result_found_e)) {
       main->setting.flag |= kt_remove_main_flag_version_d;
     }
 
-    if (main->program.parameters.array[kt_remove_rmdir_parameter_copyright_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_copyright_d;
     }
 
index ea34686773b618a02a13fbb7e50454d426866137..7878b47f53f8176a3e5aa17631440dfd4e47aa01 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Kevux Tools - Rmdir
+ * Kevux Tools - Remove Directory
  *
  * Project: Kevux Tools
  * API Version: 0.7
index 846b7805343cd6a39772395d453a206745f13e23..492c8c0516f35d68b97bf58e11be49537831c6cc 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Kevux Tools - Rmdir
+ * Kevux Tools - Remove Directory
  *
  * Project: Kevux Tools
  * API Version: 0.7
index c6c759ece7c4afc9b03bf276a42b9b23095c950e..2fafd1f310c237d86d73a2603666d7e1d704b049 100644 (file)
@@ -21,19 +21,7 @@ extern "C" {
  */
 #ifndef _di_kt_remove_unlink_parameter_e_
   enum {
-    kt_remove_unlink_parameter_help_e,
-    kt_remove_unlink_parameter_copyright_e,
-    kt_remove_unlink_parameter_light_e,
-    kt_remove_unlink_parameter_dark_e,
-    kt_remove_unlink_parameter_no_color_e,
-    kt_remove_unlink_parameter_verbosity_quiet_e,
-    kt_remove_unlink_parameter_verbosity_error_e,
-    kt_remove_unlink_parameter_verbosity_normal_e,
-    kt_remove_unlink_parameter_verbosity_verbose_e,
-    kt_remove_unlink_parameter_verbosity_debug_e,
-    kt_remove_unlink_parameter_version_e,
-
-    kt_remove_unlink_parameter_simulate_e,
+    kt_remove_unlink_parameter_simulate_e = f_console_standard_parameter_last_e,
     kt_remove_unlink_parameter_version_alt_e,
   }; // enum
 
index 0bc8e13756a5288d61471f3b4e20b749c852311f..c323e4dd678246a7a6b8274668e166bfb36a4aff 100644 (file)
@@ -45,7 +45,7 @@ extern "C" {
 
       // Identify and prioritize "color context" parameters.
       {
-        uint16_t choices_array[3] = { kt_remove_unlink_parameter_no_color_e, kt_remove_unlink_parameter_light_e, kt_remove_unlink_parameter_dark_e };
+        uint16_t choices_array[3] = { f_console_standard_parameter_no_color_e, f_console_standard_parameter_light_e, f_console_standard_parameter_dark_e };
         choices.array = choices_array;
         choices.used = 3;
 
@@ -62,7 +62,7 @@ extern "C" {
 
       // Identify and prioritize "verbosity" parameters.
       {
-        uint16_t choices_array[5] = { kt_remove_unlink_parameter_verbosity_quiet_e, kt_remove_unlink_parameter_verbosity_error_e, kt_remove_unlink_parameter_verbosity_verbose_e, kt_remove_unlink_parameter_verbosity_debug_e, kt_remove_unlink_parameter_verbosity_normal_e };
+        uint16_t choices_array[5] = { f_console_standard_parameter_verbosity_quiet_e, f_console_standard_parameter_verbosity_error_e, f_console_standard_parameter_verbosity_verbose_e, f_console_standard_parameter_verbosity_debug_e, f_console_standard_parameter_verbosity_normal_e };
         choices.array = choices_array;
         choices.used = 5;
 
@@ -88,15 +88,15 @@ extern "C" {
 
     main->setting.flag &= ~kt_remove_main_flag_version_copyright_help_d;
 
-    if (main->program.parameters.array[kt_remove_unlink_parameter_help_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_help_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_help_d;
     }
 
-    if ((main->program.parameters.array[kt_remove_unlink_parameter_version_e].result & f_console_result_found_e) || (main->program.parameters.array[kt_remove_unlink_parameter_version_alt_e].result & f_console_result_found_e)) {
+    if ((main->program.parameters.array[f_console_standard_parameter_version_e].result & f_console_result_found_e) || (main->program.parameters.array[kt_remove_unlink_parameter_version_alt_e].result & f_console_result_found_e)) {
       main->setting.flag |= kt_remove_main_flag_version_d;
     }
 
-    if (main->program.parameters.array[kt_remove_unlink_parameter_copyright_e].result & f_console_result_found_e) {
+    if (main->program.parameters.array[f_console_standard_parameter_copyright_e].result & f_console_result_found_e) {
       main->setting.flag |= kt_remove_main_flag_copyright_d;
     }
 
index e76ea6c34ac9fbe4c4a7b008fca5655a22bd211b..23cdef59f99b76fbeb5a6076c5a8a3e1e888c87e 100644 (file)
@@ -203,7 +203,7 @@ void test__kt_remove__directory_no_args__one_empty_exists_not(void **state) {
 
     const int result = kt_main_test__remove(2, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -213,7 +213,7 @@ void test__kt_remove__directory_no_args__one_empty_exists_not(void **state) {
 
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -223,7 +223,7 @@ void test__kt_remove__directory_no_args__one_empty_exists_not(void **state) {
 
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
@@ -435,11 +435,12 @@ void test__kt_remove__directory_no_args__two_empty_exists_and_not(void **state)
   mock_unwrap_f_time_clock_get = 1;
 
   const f_string_static_t file = macro_f_string_static_t_initialize_1("to_remove", 0, 9);
+  const f_string_static_t file_also = macro_f_string_static_t_initialize_1("also/remove", 0, 11);
 
   struct stat statistics;
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -447,29 +448,13 @@ void test__kt_remove__directory_no_args__two_empty_exists_and_not(void **state)
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // Directory processing.
-    will_return(__wrap_f_directory_empty, F_true);
-    will_return(__wrap_fl_directory_do, 1);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e | f_directory_recurse_do_flag_top_after_e);
-
-    // This will fail if f_directory_remove() is not called, therefore success here means f_directory_remove has been called.
-    will_return(__wrap_f_directory_remove, F_okay);
-
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_verbose_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_verbose_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -477,29 +462,13 @@ void test__kt_remove__directory_no_args__two_empty_exists_and_not(void **state)
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // Directory processing.
-    will_return(__wrap_f_directory_empty, F_true);
-    will_return(__wrap_fl_directory_do, 1);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e | f_directory_recurse_do_flag_top_after_e);
-
-    // This will fail if f_directory_remove() is not called, therefore success here means f_directory_remove has been called.
-    will_return(__wrap_f_directory_remove, F_okay);
-
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_debug_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_debug_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -507,25 +476,9 @@ void test__kt_remove__directory_no_args__two_empty_exists_and_not(void **state)
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // Directory processing.
-    will_return(__wrap_f_directory_empty, F_true);
-    will_return(__wrap_fl_directory_do, 1);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, &file);
-    will_return(__wrap_fl_directory_do, f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e | f_directory_recurse_do_flag_top_after_e);
-
-    // This will fail if f_directory_remove() is not called, therefore success here means f_directory_remove has been called.
-    will_return(__wrap_f_directory_remove, F_okay);
-
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
@@ -535,11 +488,12 @@ void test__kt_remove__directory_no_args__two_empty_exists_link(void **state) {
   mock_unwrap_f_time_clock_get = 1;
 
   const f_string_static_t file = macro_f_string_static_t_initialize_1("to_remove", 0, 9);
+  const f_string_static_t file_also = macro_f_string_static_t_initialize_1("also/remove", 0, 11);
 
   struct stat statistics;
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -582,7 +536,7 @@ void test__kt_remove__directory_no_args__two_empty_exists_link(void **state) {
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_verbose_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_verbose_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -625,7 +579,7 @@ void test__kt_remove__directory_no_args__two_empty_exists_link(void **state) {
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_debug_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_debug_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -674,11 +628,12 @@ void test__kt_remove__directory_no_args__two_empty_exists_link_not(void **state)
   mock_unwrap_f_time_clock_get = 1;
 
   const f_string_static_t file = macro_f_string_static_t_initialize_1("to_remove", 0, 9);
+  const f_string_static_t file_also = macro_f_string_static_t_initialize_1("also/remove", 0, 11);
 
   struct stat statistics;
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -721,7 +676,7 @@ void test__kt_remove__directory_no_args__two_empty_exists_link_not(void **state)
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_verbose_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_verbose_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -764,7 +719,7 @@ void test__kt_remove__directory_no_args__two_empty_exists_link_not(void **state)
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_debug_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_debug_s, 0 };
 
     memset(&statistics, 0, sizeof(struct stat));
     statistics.st_mode = F_file_mode_all_d | F_file_type_directory_d; // Should result in kt_remove_flag_file_operate_remove_d.
@@ -813,38 +768,36 @@ void test__kt_remove__directory_no_args__two_empty_exists_not(void **state) {
   mock_unwrap_f_time_clock_get = 1;
 
   const f_string_static_t file = macro_f_string_static_t_initialize_1("to_remove", 0, 9);
+  const f_string_static_t file_also = macro_f_string_static_t_initialize_1("also/remove", 0, 11);
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_verbose_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_verbose_s, 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
-    const f_string_t argv[] = { "mocked_main", file.string, "also/remove", "+" F_console_standard_short_debug_s, 0 };
+    const f_string_t argv[] = { "mocked_main", file.string, file_also.string, "+" F_console_standard_short_debug_s, 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
index 4d2c528a6db7083ff2b216621092ba70332346d1..19cfbe94ea860d1f5b3726c09913966bbd222d33 100644 (file)
@@ -29,17 +29,6 @@ void test__kt_remove__force__works(void **state) {
   stats[6].st_mode = F_file_mode_all_d | F_file_type_socket_d;
   stats[7].st_mode = F_file_mode_all_d & ~S_IFMT;
 
-  const f_string_t types[] = {
-    "-" KT_REMOVE_short_block_s,
-    "-" KT_REMOVE_short_character_s,
-    "-" KT_REMOVE_short_directory_s,
-    "-" KT_REMOVE_short_fifo_s,
-    "-" KT_REMOVE_short_link_s,
-    "-" KT_REMOVE_short_regular_s,
-    "-" KT_REMOVE_short_socket_s,
-    "--" KT_REMOVE_long_unknown_s,
-  };
-
   {
     uint8_t i = 0;
     uint8_t type = 0;
index 013d9f499482d6ae51174265a24e7d6d53582957..ad74fead76c8b09502c35ab50499d14d5772064e 100644 (file)
@@ -155,7 +155,7 @@ void test__kt_remove__regular_no_args__one_exists_not(void **state) {
 
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -165,7 +165,7 @@ void test__kt_remove__regular_no_args__one_exists_not(void **state) {
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -175,7 +175,7 @@ void test__kt_remove__regular_no_args__one_exists_not(void **state) {
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
@@ -195,18 +195,9 @@ void test__kt_remove__regular_no_args__two_exists_and_not(void **state) {
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // This will fail if f_file_remove() is not called, therefore success here means f_file_remove has been called.
-    will_return(__wrap_f_file_remove, F_okay);
-
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -218,18 +209,9 @@ void test__kt_remove__regular_no_args__two_exists_and_not(void **state) {
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // This will fail if f_file_remove() is not called, therefore success here means f_file_remove has been called.
-    will_return(__wrap_f_file_remove, F_okay);
-
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
@@ -241,18 +223,9 @@ void test__kt_remove__regular_no_args__two_exists_and_not(void **state) {
     // Pre-process file 1.
     will_return(__wrap_f_file_exists, F_false);
 
-    // Pre-process file 2.
-    will_return(__wrap_f_file_exists, F_true);
-    will_return(__wrap_f_file_is, F_false); // Not a link, kt_remove_flag_file_operate_link_d is not set.
-    will_return(__wrap_f_file_stat, &statistics);
-    will_return(__wrap_f_file_stat, F_okay);
-
-    // This will fail if f_file_remove() is not called, therefore success here means f_file_remove has been called.
-    will_return(__wrap_f_file_remove, F_okay);
-
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
@@ -455,33 +428,30 @@ void test__kt_remove__regular_no_args__two_exists_not(void **state) {
     const f_string_t argv[] = { "mocked_main", "to_remove", "also/remove", 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(3, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
     const f_string_t argv[] = { "mocked_main", "to_remove", "also/remove", "+" F_console_standard_short_verbose_s, 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 
   {
     const f_string_t argv[] = { "mocked_main", "to_remove", "also/remove", "+" F_console_standard_short_debug_s, 0 };
 
     will_return(__wrap_f_file_exists, F_false);
-    will_return(__wrap_f_file_exists, F_false);
 
     const int result = kt_main_test__remove(4, argv, 0);
 
-    assert_int_equal(result, 0);
+    assert_int_equal(result, 1);
   }
 }
 
index 193f40f29f713dd0b5a7eb3e7cbb70448f137d64..d37e40f2e677c77ae457c8226cb26de0655429e3 100644 (file)
@@ -40,17 +40,16 @@ int main(void) {
     cmocka_unit_test(test__kt_remove__date_updated__tomorrow_works),
     cmocka_unit_test(test__kt_remove__date_updated__yesterday_works),
 
-    // @todo temporarily disabled, I need to rethink the design for the --empty options and how rmdir --ignore-fail-on-non-empty is intended to work.
-    //cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_link),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_link_not),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_not),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_not_exists_link),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_not_exists_link_not),
-    //
-    //cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_and_not),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_link),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_link_not),
-    //cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_not),
+    cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_link),
+    cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_link_not),
+    cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_exists_not),
+    cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_not_exists_link),
+    cmocka_unit_test(test__kt_remove__directory_no_args__one_empty_not_exists_link_not),
+
+    cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_and_not),
+    cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_link),
+    cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_link_not),
+    cmocka_unit_test(test__kt_remove__directory_no_args__two_empty_exists_not),
 
     cmocka_unit_test(test__kt_remove__directory_recurse_simple__one_child_one_exists_link),
     cmocka_unit_test(test__kt_remove__directory_recurse_simple__one_child_one_exists_link_not),
@@ -73,20 +72,18 @@ int main(void) {
 
     cmocka_unit_test(test__kt_remove__file_type__works),
 
-    // @fixme this test is incorrect, it didn't even hae the --force parameter passed to it.
-    //cmocka_unit_test(test__kt_remove__force__works),
+    cmocka_unit_test(test__kt_remove__force__works),
 
     cmocka_unit_test(test__kt_remove__group__name_works),
 
-    // @todo temporarily disabled, I need to rethink the design for the --empty options and how rmdir --ignore-fail-on-non-empty is intended to work.
-    //cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_link),
-    //cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_link_not),
-    //cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_not),
-    //
-    //cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_and_not),
-    //cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_link),
-    //cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_link_not),
-    //cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_not),
+    cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_link),
+    cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_link_not),
+    cmocka_unit_test(test__kt_remove__regular_no_args__one_exists_not),
+
+    cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_and_not),
+    cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_link),
+    cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_link_not),
+    cmocka_unit_test(test__kt_remove__regular_no_args__two_exists_not),
 
     cmocka_unit_test(test__kt_remove__time__accessed_works),
     cmocka_unit_test(test__kt_remove__time__changed_works),