]> Kevux Git Server - kevux-tools/commitdiff
Progress: Continue working on completing the remove program.
authorKevin Day <Kevin@kevux.org>
Thu, 27 Mar 2025 03:34:00 +0000 (22:34 -0500)
committerKevin Day <Kevin@kevux.org>
Thu, 27 Mar 2025 04:00:27 +0000 (23:00 -0500)
Update the copyright year.

Add the `unlink` program.
Make sure all necessary callbacks are available to perform this.
Use a custom parameter processing to more closely match the standard Coreutils unlink argument.
I am still preserving some of the core parameters of the FLL/Kevux projects.
(This means that there is the `++version` and the `--version`.)

Fix bug where no error was being printed on non-existent file.
Make sure to also exit on error in this situation.

28 files changed:
data/build/fakefile
data/build/remove/fakefile
data/build/remove/settings
data/build/remove/settings.remove
data/build/remove/settings.unlink [new file with mode: 0644]
data/build/stand_alone/fakefile
data/build/stand_alone/settings/settings.unlink [new file with mode: 0644]
install.sh
sources/c/program/kevux/tools/remove/main/common/define.h
sources/c/program/kevux/tools/remove/main/common/print.c
sources/c/program/kevux/tools/remove/main/common/print.h
sources/c/program/kevux/tools/remove/main/common/type.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.h
sources/c/program/kevux/tools/remove/remove/main.c
sources/c/program/kevux/tools/remove/unlink/config.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/config.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/enumeration.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/enumeration.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/main.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/main.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/print.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/print.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/string.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/string.h [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/unlink.c [new file with mode: 0644]
sources/c/program/kevux/tools/remove/unlink/unlink.h [new file with mode: 0644]

index 255b8faf95511118a17ee4dd26cb569d4ac6cd76..ece49a3d9b07e66d4e529abb5141b77ab81583ef 100644 (file)
@@ -14,6 +14,7 @@ main:
 remove:
   build remove/settings
   build remove/settings.remove
+  build remove/settings.unlink
 
 tacocat:
   build tacocat/settings
index 60048dab4c723c33c6ea79e4f5771a5a021fc32a..c732f2d01bb27f42123961ef10a6419d928d8d1a 100644 (file)
@@ -10,6 +10,7 @@ settings:
 main:
   build settings
   build settings.remove
+  build settings.unlink
 
 install:
   shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color'
index 2ab1792693ec5a2fbb4a73163ae3087c66610b7b..2f82108621564af7b2251ab53ef6c8c505f4f972 100644 (file)
@@ -55,15 +55,6 @@ build_shared yes
 build_static no
 
 path_headers program/kevux/tools/remove/main
-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
 path_sources sources/c/program/kevux/tools/remove/main
 
 has_path_standard no
index 614479942ec013a27fe0cd1126ec69cbd4eb98a3..4d98b1bb880fe6ad1fdf864767ace0056238796c 100644 (file)
@@ -55,15 +55,6 @@ build_shared yes
 build_static no
 
 path_headers program/kevux/tools/remove/remove
-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
 path_sources sources/c/program/kevux/tools/remove/remove
 
 has_path_standard no
diff --git a/data/build/remove/settings.unlink b/data/build/remove/settings.unlink
new file mode 100644 (file)
index 0000000..65d977c
--- /dev/null
@@ -0,0 +1,93 @@
+# fss-0001
+#
+# Builds the unlink 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 unlink
+stage unlink
+
+version_major 0
+version_minor 5
+version_micro 0
+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 unlink.c
+
+build_sources_headers enumeration.h print.h string.h unlink.h
+
+build_sources_documentation man
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers program/kevux/tools/remove/unlink
+path_sources sources/c/program/kevux/tools/remove/unlink
+
+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 39e5b588a4833479e0df9323a6d0f672b068b988..801822646a98faff29b7fdf03707acd3ede0ddb9 100644 (file)
@@ -22,6 +22,7 @@ settings:
 main:
   build settings/settings.remove
   build settings/settings.tacocat
+  build settings/settings.unlink
 
 main_remove:
   build settings/settings.remove
@@ -29,6 +30,9 @@ main_remove:
 main_tacocat:
   build settings/settings.tacocat
 
+main_unlink:
+  build settings/settings.unlink
+
 install:
   shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/stand_alone/settings/settings.remove
   shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/stand_alone/settings/settings.tacocat
@@ -39,6 +43,9 @@ install_remove:
 install_tacocat:
   shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/stand_alone/settings/settings.tacocat
 
+install_unlink:
+  shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' -s data/build/stand_alone/settings/settings.unlink
+
 help:
   print
   print context:'title'Fakefile Options for the Kevux Tool Programs.context:'reset'
@@ -49,9 +56,11 @@ help:
   print "  - context:'notable'install:context:'reset'         A helper operation that calls the ./install.sh script for the programs."
   print "  - context:'notable'install_remove:context:'reset'  A helper operation that calls the ./install.sh script for the remove program."
   print "  - context:'notable'install_tacocat:context:'reset' A helper operation that calls the ./install.sh script for the tacocat program."
+  print "  - context:'notable'install_unlink:context:'reset'  A helper operation that calls the ./install.sh script for the unlink program."
   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_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."
 
   print
   print The context:'notable'install[context]:'reset' operation supports the context:'notable'work[context]:'reset', context:'notable'verbosity[context]:'reset', and context:'notable'color[context]:'reset' parameters.
diff --git a/data/build/stand_alone/settings/settings.unlink b/data/build/stand_alone/settings/settings.unlink
new file mode 100644 (file)
index 0000000..e3c5925
--- /dev/null
@@ -0,0 +1,129 @@
+# 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.unlink 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 unlink
+stage stand_alone
+
+version_major 0
+version_minor 5
+version_micro 0
+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_library 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/unlink/config.c program/kevux/tools/remove/unlink/enumeration.c program/kevux/tools/remove/unlink/main.c program/kevux/tools/remove/unlink/print.c program/kevux/tools/remove/unlink/string.c program/kevux/tools/remove/unlink/unlink.c
+
+build_sources_documentation man
+
+build_script yes
+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
+
+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 c820acfbc6831863bd9e7cbab79941a5613d855a..a47b4f1c67c7f87dca02e913c4d4ce630dc3370b 100755 (executable)
@@ -477,7 +477,7 @@ install_help() {
 
 install_copyright() {
 
-  echo "Copyright Â© 2007-2024 Kevin Day."
+  echo "Copyright Â© 2007-2025 Kevin Day."
   echo
   echo "Source code license lgpl-2.1-or-later."
   echo "Standard and specification license open-standard-license-1.0-or-later."
index 6ce49085d4245690c9412059d8f265b6c0fe3601..3bfe0715af97e99707c4e749f6959e52748c2ee3 100644 (file)
@@ -157,6 +157,7 @@ extern "C" {
  *   - empty:            Is an empty directory.
  *   - follow:           Follow the symbolic link.
  *   - link:             The file being operated on is a link or is a followed link.
+ *   - missing:          The file is not found.
  *   - parent:           This is a parent of a file for some other file tree operation process.
  *   - processed:        This path is already processed.
  *   - recurse:          Perform recursively (only on directories).
@@ -169,17 +170,18 @@ extern "C" {
   #define kt_remove_flag_file_operate_none_d             0x0
   #define kt_remove_flag_file_operate_child_d            0x1
   #define kt_remove_flag_file_operate_directory_d        0x2
-  #define kt_remove_flag_file_operate_directory_parent_d 0x22
+  #define kt_remove_flag_file_operate_directory_parent_d 0x42
   #define kt_remove_flag_file_operate_empty_d            0x4
   #define kt_remove_flag_file_operate_follow_d           0x8
   #define kt_remove_flag_file_operate_link_d             0x10
-  #define kt_remove_flag_file_operate_parent_d           0x20
-  #define kt_remove_flag_file_operate_processed_d        0x40
-  #define kt_remove_flag_file_operate_recurse_d          0x80
-  #define kt_remove_flag_file_operate_remove_d           0x100
-  #define kt_remove_flag_file_operate_remove_fail_d      0x200
-  #define kt_remove_flag_file_operate_remove_not_d       0x400
-  #define kt_remove_flag_file_operate_remove_not_fail_d  0x800
+  #define kt_remove_flag_file_operate_missing_d          0x20
+  #define kt_remove_flag_file_operate_parent_d           0x40
+  #define kt_remove_flag_file_operate_processed_d        0x80
+  #define kt_remove_flag_file_operate_recurse_d          0x100
+  #define kt_remove_flag_file_operate_remove_d           0x200
+  #define kt_remove_flag_file_operate_remove_fail_d      0x400
+  #define kt_remove_flag_file_operate_remove_not_d       0x800
+  #define kt_remove_flag_file_operate_remove_not_fail_d  0x1000
 #endif // _di_kt_remove_flag_file_operate_d_
 
 /**
index 6d7d715d4a6909e46b7eb4c21a7ac26621d87da4..25876b451b93b52a82c63b8c21230e3a6f9d0c56 100644 (file)
@@ -9,6 +9,7 @@ extern "C" {
     "f_console_parameter_prioritize_right",
     "f_console_parameter_process",
     "f_directory_remove",
+    "f_file_exists",
     "f_file_mode_from_string",
     "f_file_mode_to_mode",
     "f_file_poll",
index c72df87dd474722af68456ecfc4b1ff5cf8122f0..0ac29ea1f710f508bbdb5ebda33a3c7c6d56a8aa 100644 (file)
@@ -42,6 +42,7 @@ extern "C" {
     kt_remove_f_f_console_parameter_prioritize_right_e,
     kt_remove_f_f_console_parameter_process_e,
     kt_remove_f_f_directory_remove_e,
+    kt_remove_f_f_file_exists_e,
     kt_remove_f_f_file_mode_from_string_e,
     kt_remove_f_f_file_mode_to_mode_e,
     kt_remove_f_f_file_poll_e,
index 9c38df5d3ce515aef3348afcfc348cb43faa0152..ffb261f771624dc837b8ae4b407c37701ec90d6e 100644 (file)
@@ -174,18 +174,20 @@ extern "C" {
  *
  * print_help:                    Print help.
  * process_normal:                Process normally (data from parameters and files).
+ * process_operate_directory:     Process an individual directory, returning F_done to designate handled, and F_okay for letting parent continue handling.
  * process_operate_file:          Process an individual file, returning F_done to designate handled, and F_okay for letting parent continue handling.
  * process_operate_file_simulate: Simulate process of an individual file, returning F_done to designate handled, and F_okay for letting parent continue handling.
  */
 #ifndef _di_kt_remove_callback_t_
   typedef f_status_t (*print_help_call_t)(fl_print_t * const print, const f_color_context_t context);
   typedef void (*process_normal_call_t)(kt_remove_main_t * const main);
-  typedef void (*process_operate_file_call_t)(kt_remove_main_t * const main, const f_string_static_t path, const struct stat statistics, uint16_t * const flag);
-  typedef void (*process_operate_file_simulate_call_t)(kt_remove_main_t * const main, const f_string_static_t path, const struct stat statistics, const uint32_t flag_operate, uint32_t * const flag);
+  typedef f_status_t (*process_operate_file_call_t)(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
+  typedef void (*process_operate_file_simulate_call_t)(kt_remove_main_t * const main, const f_string_static_t path, const struct stat statistics, const uint32_t flag_operate, uint32_t * const flag_out);
 
   typedef struct {
     print_help_call_t print_help;
     process_normal_call_t process_normal;
+    process_operate_file_call_t process_operate_directory;
     process_operate_file_call_t process_operate_file;
     process_operate_file_simulate_call_t process_operate_file_simulate;
   } kt_remove_callback_t;
@@ -196,6 +198,7 @@ extern "C" {
       0, \
       0, \
       0, \
+      0, \
     }
 #endif // _di_kt_remove_callback_t_
 
index c5d677e98bc4853bc3835b80a377ba1ae1005f47..f5cb17dfae882e4e7772d9985a7deb1d8d7e3bee 100644 (file)
@@ -20,13 +20,35 @@ extern "C" {
     const uint32_t flag_operate = kt_remove_preprocess_file(main, path, 0);
     f_status_t status = F_no;
 
-    if (F_status_is_error_not(main->setting.state.status) && !(main->setting.flag & kt_remove_main_flag_simulate_d) && !(flag_operate & kt_remove_flag_file_operate_processed_d)) {
-      kt_remove_operate_file_prompt(main, path, flag_operate);
+    if (F_status_is_error_not(main->setting.state.status)) {
+      if (flag_operate & kt_remove_flag_file_operate_missing_d) {
+        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);
+      }
+      else if (!(main->setting.flag & kt_remove_main_flag_simulate_d) && !(flag_operate & kt_remove_flag_file_operate_processed_d)) {
+        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 (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);
+            }
+          }
+
+          if (status == F_done) {
+            main->setting.state.status = F_okay;
 
-      if (F_status_is_error_not(main->setting.state.status) && main->setting.state.status != F_skip) {
-        status = main->setting.state.status = flag_operate & kt_remove_flag_file_operate_directory_d
-          ? kt_remove_operate_file_directory(main, path, flag_operate)
-          : kt_remove_operate_file_remove(main, path, flag_operate);
+            return;
+          }
+        }
       }
     }
 
@@ -87,15 +109,27 @@ extern "C" {
         : f_string_null_s
       : recurse->path;
 
-    recurse->state.status = kt_remove_operate_file_remove(
-      (kt_remove_main_t *) recurse->state.custom,
-      path,
-      flag & f_directory_recurse_do_flag_top_after_e
-        ? recurse->state.code
-        : flag & f_directory_recurse_do_flag_directory_e
-          ? (recurse->state.code | kt_remove_flag_file_operate_child_d | kt_remove_flag_file_operate_directory_d) & ~kt_remove_flag_file_operate_parent_d
-          : (recurse->state.code | kt_remove_flag_file_operate_child_d) & ~kt_remove_flag_file_operate_directory_parent_d
-    );
+    kt_remove_main_t * const main = (kt_remove_main_t *) recurse->state.custom;
+
+    if (main->call.process_operate_file) {
+      recurse->state.status = F_okay;
+
+      recurse->state.status = main->call.process_operate_file(
+        main,
+        path,
+        flag & f_directory_recurse_do_flag_top_after_e
+          ? recurse->state.code
+          : flag & f_directory_recurse_do_flag_directory_e
+            ? (recurse->state.code | kt_remove_flag_file_operate_child_d | kt_remove_flag_file_operate_directory_d) & ~kt_remove_flag_file_operate_parent_d
+            : (recurse->state.code | kt_remove_flag_file_operate_child_d) & ~kt_remove_flag_file_operate_directory_parent_d
+      );
+
+      if (recurse->state.status == F_done) {
+        recurse->state.status = F_okay;
+
+        return;
+      }
+    }
   }
 #endif // _di_kt_remove_operate_file_directory_action_
 
@@ -117,7 +151,18 @@ extern "C" {
     if (!kt_remove_operate_shall_remove(flag_operate) || (main->setting.flag & kt_remove_main_flag_simulate_d)) return;
 
     if (F_status_is_error_not(main->setting.state.status) && !(flag_operate & kt_remove_flag_file_operate_processed_d)) {
-      main->setting.state.status = kt_remove_operate_file_remove(main, path, flag_operate);
+      if (main->call.process_operate_file) {
+        main->setting.state.status = F_okay;
+
+        main->setting.state.status = main->call.process_operate_file(main, path, flag_operate);
+        if (F_status_is_error(main->setting.state.status)) return;
+
+        if (main->setting.state.status == F_done) {
+          main->setting.state.status = F_okay;
+
+          return;
+        }
+      }
     }
 
     if (F_status_is_error_not(main->setting.state.status)) {
index 3b071eeaf87e74016c7e8c2b82018dd87576a428..25402077670a07160df1301b0419fe7bfb6f68f5 100644 (file)
@@ -44,16 +44,11 @@ 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_force_d) {
-        kt_remove_print_simulate_operate_boolean(&main->program.output, kt_remove_force_s, F_true);
-      }
-      else {
-        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_simulate_d)) {
+        remove_print_warning_file_reason(&main->program.warning, path, kt_remove_print_reason_not_found_s);
       }
 
-      return 0;
+      return kt_remove_flag_file_operate_missing_d;
     }
 
     if (F_status_is_error(main->setting.state.status)) {
index 308bca7f9bf189d9008a0dc9f3fb57c9c7992de2..b8a2ddbd9954ea3a0f9ad7ecfb9696a8588c012d 100644 (file)
@@ -35,15 +35,6 @@ extern "C" {
  *   F_output_not on success, but no printing is performed.
  *
  *   F_output_not (with error bit) if setting is NULL.
- *
- * @see f_file_stream_flush()
- * @see f_file_stream_lock()
- * @see f_file_stream_unlock()
- * @see f_print_dynamic_raw()
- * @see fl_print_format()
- * @see fll_program_print_help_header()
- * @see fll_program_print_help_option()
- * @see fll_program_print_help_option_long()
  */
 #ifndef _di_kt_remove_print_message_help_
   extern f_status_t kt_remove_print_message_help(fl_print_t * const print, const f_color_context_t context);
index 7c635ec8acffa96eede164ac6b7a594f61bff44c..f6b094042108602289275119fb7cdb683e1c31c2 100644 (file)
@@ -32,6 +32,8 @@ int
 
   data.call.print_help = &kt_remove_print_message_help;
   data.call.process_normal = &kt_remove_process_normal_operate;
+  data.call.process_operate_directory = &kt_remove_operate_file_directory;
+  data.call.process_operate_file = &kt_remove_operate_file_remove;
 
   #ifdef _en_kt_default_to_utc_
     data.setting.flag |= kt_remove_flag_utc_d;
diff --git a/sources/c/program/kevux/tools/remove/unlink/config.c b/sources/c/program/kevux/tools/remove/unlink/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/unlink/config.h b/sources/c/program/kevux/tools/remove/unlink/config.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sources/c/program/kevux/tools/remove/unlink/enumeration.c b/sources/c/program/kevux/tools/remove/unlink/enumeration.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sources/c/program/kevux/tools/remove/unlink/enumeration.h b/sources/c/program/kevux/tools/remove/unlink/enumeration.h
new file mode 100644 (file)
index 0000000..f9c7e84
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * Kevux Tools - Unlink
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * 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_unlink_enumeration_h
+#define _kt_remove_unlink_enumeration_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The unlink program parameters.
+ */
+#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_version_alt_e,
+  }; // enum
+
+  #define kt_remove_unlink_console_parameter_t_initialize \
+    { \
+      macro_fll_program_console_parameter_standard_initialize, \
+      \
+      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_5(                            f_console_standard_long_version_s, 0, f_console_flag_normal_e), \
+    }
+
+  #define kt_remove_unlink_total_parameters_d (f_console_parameter_state_type_total_d + 1)
+#endif // _di_kt_remove_unlink_parameter_e_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_unlink_enumeration_h
diff --git a/sources/c/program/kevux/tools/remove/unlink/main.c b/sources/c/program/kevux/tools/remove/unlink/main.c
new file mode 100644 (file)
index 0000000..9464481
--- /dev/null
@@ -0,0 +1,93 @@
+#include "unlink.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_unlink_print_message_help;
+  data.call.process_normal = &kt_remove_process_normal_operate;
+  data.call.process_operate_directory = &kt_remove_unlink_operate_file_remove;
+  data.call.process_operate_file = &kt_remove_unlink_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_unlink_console_parameter_t_initialize;
+
+  data.program.parameters.array = parameters;
+  data.program.parameters.used = kt_remove_unlink_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_unlink_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_unlink_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/unlink/main.h b/sources/c/program/kevux/tools/remove/unlink/main.h
new file mode 100644 (file)
index 0000000..64831bf
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Kevux Tools - Unlink
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * 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 "unlink" program functionality in some manner.
+ */
+#ifndef _kt_remove_unlink_main_h
+#define _kt_remove_unlink_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_unlink_main_h
diff --git a/sources/c/program/kevux/tools/remove/unlink/print.c b/sources/c/program/kevux/tools/remove/unlink/print.c
new file mode 100644 (file)
index 0000000..852c5dc
--- /dev/null
@@ -0,0 +1,69 @@
+#include "unlink.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_remove_unlink_print_error_link_not_
+  f_status_t kt_remove_unlink_print_error_link_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 unlink '%]", 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 link.%]%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_unlink_print_error_link_not_
+
+#ifndef _di_kt_remove_unlink_print_message_help_
+  f_status_t kt_remove_unlink_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_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 unlinking.");
+
+    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_unlink_print_message_help_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/unlink/print.h b/sources/c/program/kevux/tools/remove/unlink/print.h
new file mode 100644 (file)
index 0000000..2c0a2b0
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * Kevux Tools - Unlink
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * 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_unlink_print_h
+#define _kt_remove_unlink_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print error message about not being able to delete a file because that file is not a link.
+ *
+ * @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_unlink_print_error_link_not_
+  extern f_status_t kt_remove_unlink_print_error_link_not(fl_print_t * const print, const f_string_static_t path);
+#endif // _di_kt_remove_unlink_print_error_link_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_unlink_print_message_help_
+  extern f_status_t kt_remove_unlink_print_message_help(fl_print_t * const print, const f_color_context_t context);
+#endif // _di_kt_remove_unlink_print_message_help_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_unlink_print_h
diff --git a/sources/c/program/kevux/tools/remove/unlink/string.c b/sources/c/program/kevux/tools/remove/unlink/string.c
new file mode 100644 (file)
index 0000000..b7833ce
--- /dev/null
@@ -0,0 +1,14 @@
+#include "unlink.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_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/unlink/string.h b/sources/c/program/kevux/tools/remove/unlink/string.h
new file mode 100644 (file)
index 0000000..ae358a2
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * Kevux Tools - Unlink
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * 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_unlink_string_h
+#define _kt_remove_unlink_string_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The program name.
+ */
+#ifndef _di_kt_remove_program_name_s_
+  #define KT_REMOVE_program_name_s      "unlink"
+  #define KT_REMOVE_program_name_long_s "Unlink"
+
+  #define KT_REMOVE_program_name_s_length      6
+  #define KT_REMOVE_program_name_long_s_length 6
+#endif // _di_kt_remove_program_name_s_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_unlink_string_h
diff --git a/sources/c/program/kevux/tools/remove/unlink/unlink.c b/sources/c/program/kevux/tools/remove/unlink/unlink.c
new file mode 100644 (file)
index 0000000..0bc8e13
--- /dev/null
@@ -0,0 +1,140 @@
+#include "unlink.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_kt_remove_unlink_operate_file_remove_
+  f_status_t kt_remove_unlink_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_link_d) {
+      return kt_remove_operate_file_remove(main, path, flag_operate);
+    }
+
+    kt_remove_unlink_print_error_link_not(&main->program.error, path);
+
+    return F_status_set_error(F_no);
+  }
+#endif // _di_kt_remove_unlink_operate_file_remove_
+
+#ifndef _di_kt_remove_unlink_setting_load_
+  void kt_remove_unlink_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_unlink_parameter_no_color_e, kt_remove_unlink_parameter_light_e, kt_remove_unlink_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.
+      {
+        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 };
+        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_unlink_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)) {
+      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) {
+      main->setting.flag |= kt_remove_main_flag_copyright_d;
+    }
+
+    if (main->program.parameters.array[kt_remove_unlink_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 links are deleted.
+    main->setting.flag |= kt_remove_main_flag_link_d | kt_remove_main_flag_option_used_d;
+  }
+#endif // _di_kt_remove_unlink_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/sources/c/program/kevux/tools/remove/unlink/unlink.h b/sources/c/program/kevux/tools/remove/unlink/unlink.h
new file mode 100644 (file)
index 0000000..dbd6f18
--- /dev/null
@@ -0,0 +1,99 @@
+/**
+ * Kevux Tools - Unlink
+ *
+ * Project: Kevux Tools
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * This program provides the base include for the unlink program.
+ */
+#ifndef _kt_remove_unlink_unlink_h
+#define _kt_remove_unlink_unlink_h
+
+// Unlink includes.
+#include <program/kevux/tools/remove/main/remove.h>
+#include <program/kevux/tools/remove/unlink/enumeration.h>
+#include <program/kevux/tools/remove/unlink/print.h>
+#include <program/kevux/tools/remove/unlink/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform unlink 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_unlink_operate_file_remove_
+  extern f_status_t kt_remove_unlink_operate_file_remove(kt_remove_main_t * const main, const f_string_static_t path, const uint32_t flag_operate);
+#endif // _di_kt_remove_unlink_operate_file_remove_
+
+/**
+ * Perform the unlink 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_unlink_setting_load_
+  extern void kt_remove_unlink_setting_load(const f_console_arguments_t arguments, kt_remove_main_t * const main);
+#endif // _di_kt_remove_unlink_setting_load_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _kt_remove_unlink_unlink_h