From babe38ad74481c06c324e1d2bd677b5f20d7e4e1 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 26 Mar 2025 22:34:00 -0500 Subject: [PATCH] Progress: Continue working on completing the remove program. 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. --- data/build/fakefile | 1 + data/build/remove/fakefile | 1 + data/build/remove/settings | 9 -- data/build/remove/settings.remove | 9 -- data/build/remove/settings.unlink | 93 ++++++++++++++ data/build/stand_alone/fakefile | 9 ++ data/build/stand_alone/settings/settings.unlink | 129 +++++++++++++++++++ install.sh | 2 +- .../kevux/tools/remove/main/common/define.h | 18 +-- .../program/kevux/tools/remove/main/common/print.c | 1 + .../program/kevux/tools/remove/main/common/print.h | 1 + .../program/kevux/tools/remove/main/common/type.h | 7 +- .../c/program/kevux/tools/remove/main/operate.c | 77 +++++++++--- .../c/program/kevux/tools/remove/main/preprocess.c | 11 +- .../kevux/tools/remove/main/print/message.h | 9 -- sources/c/program/kevux/tools/remove/remove/main.c | 2 + .../c/program/kevux/tools/remove/unlink/config.c | 1 + .../c/program/kevux/tools/remove/unlink/config.h | 0 .../kevux/tools/remove/unlink/enumeration.c | 0 .../kevux/tools/remove/unlink/enumeration.h | 55 ++++++++ sources/c/program/kevux/tools/remove/unlink/main.c | 93 ++++++++++++++ sources/c/program/kevux/tools/remove/unlink/main.h | 38 ++++++ .../c/program/kevux/tools/remove/unlink/print.c | 69 ++++++++++ .../c/program/kevux/tools/remove/unlink/print.h | 71 +++++++++++ .../c/program/kevux/tools/remove/unlink/string.c | 14 +++ .../c/program/kevux/tools/remove/unlink/string.h | 34 +++++ .../c/program/kevux/tools/remove/unlink/unlink.c | 140 +++++++++++++++++++++ .../c/program/kevux/tools/remove/unlink/unlink.h | 99 +++++++++++++++ 28 files changed, 931 insertions(+), 62 deletions(-) create mode 100644 data/build/remove/settings.unlink create mode 100644 data/build/stand_alone/settings/settings.unlink create mode 100644 sources/c/program/kevux/tools/remove/unlink/config.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/config.h create mode 100644 sources/c/program/kevux/tools/remove/unlink/enumeration.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/enumeration.h create mode 100644 sources/c/program/kevux/tools/remove/unlink/main.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/main.h create mode 100644 sources/c/program/kevux/tools/remove/unlink/print.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/print.h create mode 100644 sources/c/program/kevux/tools/remove/unlink/string.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/string.h create mode 100644 sources/c/program/kevux/tools/remove/unlink/unlink.c create mode 100644 sources/c/program/kevux/tools/remove/unlink/unlink.h diff --git a/data/build/fakefile b/data/build/fakefile index 255b8fa..ece49a3 100644 --- a/data/build/fakefile +++ b/data/build/fakefile @@ -14,6 +14,7 @@ main: remove: build remove/settings build remove/settings.remove + build remove/settings.unlink tacocat: build tacocat/settings diff --git a/data/build/remove/fakefile b/data/build/remove/fakefile index 60048da..c732f2d 100644 --- a/data/build/remove/fakefile +++ b/data/build/remove/fakefile @@ -10,6 +10,7 @@ settings: main: build settings build settings.remove + build settings.unlink install: shell ./install.sh parameter:'work' parameter:'verbosity' parameter:'color' diff --git a/data/build/remove/settings b/data/build/remove/settings index 2ab1792..2f82108 100644 --- a/data/build/remove/settings +++ b/data/build/remove/settings @@ -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 diff --git a/data/build/remove/settings.remove b/data/build/remove/settings.remove index 6144799..4d98b1b 100644 --- a/data/build/remove/settings.remove +++ b/data/build/remove/settings.remove @@ -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 index 0000000..65d977c --- /dev/null +++ b/data/build/remove/settings.unlink @@ -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 diff --git a/data/build/stand_alone/fakefile b/data/build/stand_alone/fakefile index 39e5b58..8018226 100644 --- a/data/build/stand_alone/fakefile +++ b/data/build/stand_alone/fakefile @@ -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 index 0000000..e3c5925 --- /dev/null +++ b/data/build/stand_alone/settings/settings.unlink @@ -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 diff --git a/install.sh b/install.sh index c820acf..a47b4f1 100755 --- a/install.sh +++ b/install.sh @@ -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." diff --git a/sources/c/program/kevux/tools/remove/main/common/define.h b/sources/c/program/kevux/tools/remove/main/common/define.h index 6ce4908..3bfe071 100644 --- a/sources/c/program/kevux/tools/remove/main/common/define.h +++ b/sources/c/program/kevux/tools/remove/main/common/define.h @@ -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_ /** diff --git a/sources/c/program/kevux/tools/remove/main/common/print.c b/sources/c/program/kevux/tools/remove/main/common/print.c index 6d7d715..25876b4 100644 --- a/sources/c/program/kevux/tools/remove/main/common/print.c +++ b/sources/c/program/kevux/tools/remove/main/common/print.c @@ -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", diff --git a/sources/c/program/kevux/tools/remove/main/common/print.h b/sources/c/program/kevux/tools/remove/main/common/print.h index c72df87..0ac29ea 100644 --- a/sources/c/program/kevux/tools/remove/main/common/print.h +++ b/sources/c/program/kevux/tools/remove/main/common/print.h @@ -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, diff --git a/sources/c/program/kevux/tools/remove/main/common/type.h b/sources/c/program/kevux/tools/remove/main/common/type.h index 9c38df5..ffb261f 100644 --- a/sources/c/program/kevux/tools/remove/main/common/type.h +++ b/sources/c/program/kevux/tools/remove/main/common/type.h @@ -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_ diff --git a/sources/c/program/kevux/tools/remove/main/operate.c b/sources/c/program/kevux/tools/remove/main/operate.c index c5d677e..f5cb17d 100644 --- a/sources/c/program/kevux/tools/remove/main/operate.c +++ b/sources/c/program/kevux/tools/remove/main/operate.c @@ -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)) { diff --git a/sources/c/program/kevux/tools/remove/main/preprocess.c b/sources/c/program/kevux/tools/remove/main/preprocess.c index 3b071ee..2540207 100644 --- a/sources/c/program/kevux/tools/remove/main/preprocess.c +++ b/sources/c/program/kevux/tools/remove/main/preprocess.c @@ -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)) { diff --git a/sources/c/program/kevux/tools/remove/main/print/message.h b/sources/c/program/kevux/tools/remove/main/print/message.h index 308bca7..b8a2ddb 100644 --- a/sources/c/program/kevux/tools/remove/main/print/message.h +++ b/sources/c/program/kevux/tools/remove/main/print/message.h @@ -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); diff --git a/sources/c/program/kevux/tools/remove/remove/main.c b/sources/c/program/kevux/tools/remove/remove/main.c index 7c635ec..f6b0940 100644 --- a/sources/c/program/kevux/tools/remove/remove/main.c +++ b/sources/c/program/kevux/tools/remove/remove/main.c @@ -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 index 0000000..1ac2545 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/config.c @@ -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 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 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 index 0000000..f9c7e84 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/enumeration.h @@ -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 index 0000000..9464481 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/main.c @@ -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 index 0000000..64831bf --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/main.h @@ -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 index 0000000..852c5dc --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/print.c @@ -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 index 0000000..2c0a2b0 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/print.h @@ -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 index 0000000..b7833ce --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/string.c @@ -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 index 0000000..ae358a2 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/string.h @@ -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 index 0000000..0bc8e13 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/unlink.c @@ -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 index 0000000..dbd6f18 --- /dev/null +++ b/sources/c/program/kevux/tools/remove/unlink/unlink.h @@ -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 +#include +#include +#include + +#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 -- 1.8.3.1