From 526b92a6294bc3453fb3998bb45285b4a7e9f357 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 19 Sep 2020 11:58:04 -0500 Subject: [PATCH] Update: cleanup f_print and add f_print_to* functions. Move shared/duplicated code into a private function. Add the f_print_to* functions to allow for printing to a file descriptor, similar to dprintf(). --- build/level_0/settings | 2 +- build/monolithic/settings | 2 +- level_0/f_print/c/print.c | 76 +++++++++++----------- level_0/f_print/c/print.h | 122 +++++++++++++++++++++++++++++++++--- level_0/f_print/c/private-print.c | 52 +++++++++++++++ level_0/f_print/c/private-print.h | 80 +++++++++++++++++++++++ level_0/f_print/data/build/settings | 2 +- 7 files changed, 289 insertions(+), 47 deletions(-) create mode 100644 level_0/f_print/c/private-print.c create mode 100644 level_0/f_print/c/private-print.h diff --git a/build/level_0/settings b/build/level_0/settings index c299ec0..a99981a 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -20,7 +20,7 @@ build_indexer ar build_language c build_libraries -lc build_libraries-level -build_sources_library account.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c +build_sources_library account.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c build_sources_program build_sources_headers account.h color.h console.h conversion.h directory.h directory_type.h environment.h file.h fss.h fss-common.h fss-named.h fss-nest.h fss-quoted.h fss-set.h iki.h iki-common.h memory.h memory-structure.h path.h pipe.h print.h serialize.h signal.h socket.h status.h status_array.h string.h string_common.h string_dynamic.h string_map.h string_quantity.h string_range.h type.h type_array.h utf.h utf-common.h build_sources_script diff --git a/build/monolithic/settings b/build/monolithic/settings index e4997af..43f03d5 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -20,7 +20,7 @@ build_indexer ar build_language c build_libraries -lc build_libraries-monolithic -build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c +build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c build_sources_program build_sources_headers level_0/account.h level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.h level_0/fss-set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory-structure.h level_0/path.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/signal.h level_0/socket.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string_common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h build_sources_script diff --git a/level_0/f_print/c/print.c b/level_0/f_print/c/print.c index 64eed4e..2ff8259 100644 --- a/level_0/f_print/c/print.c +++ b/level_0/f_print/c/print.c @@ -1,4 +1,5 @@ #include "print.h" +#include "private-print.h" #ifdef __cplusplus extern "C" { @@ -7,67 +8,70 @@ extern "C" { #ifndef _di_f_print_string_ f_return_status f_print_string(FILE *output, const f_string_t string, const f_string_length_t length) { #ifndef _di_level_0_parameter_checking_ + if (output == 0) return F_status_set_error(F_parameter); if (string == 0) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (length == 0) return F_data_not; - - register f_string_length_t i = 0; - - for (; i < length; i++) { - if (string[i] != 0) { - if (fputc(string[i], output) == 0) { - return F_status_set_error(F_output); - } - } - } // for - - return F_none; + return private_f_print_string(output, string, length); } #endif // _di_f_print_string_ #ifndef _di_f_print_string_dynamic_ f_return_status f_print_string_dynamic(FILE *output, const f_string_static_t buffer) { - if (buffer.used == 0) return F_data_not; - - register f_string_length_t i = 0; - - for (; i < buffer.used; i++) { - if (buffer.string[i] != 0) { - if (fputc(buffer.string[i], output) == 0) { - return F_status_set_error(F_output); - } - } - } // for + #ifndef _di_level_0_parameter_checking_ + if (output == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ - return F_none; + return private_f_print_string(output, buffer.string, buffer.used); } #endif // _di_f_print_string_dynamic_ #ifndef _di_f_print_string_dynamic_partial_ f_return_status f_print_string_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range) { #ifndef _di_level_0_parameter_checking_ + if (output == 0) return F_status_set_error(F_parameter); if (range.start < 0) return F_status_set_error(F_parameter); if (range.start > range.stop) return F_status_set_error(F_parameter); if (range.start >= buffer.used) return F_status_set_error(F_parameter); if (range.stop >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (buffer.used == 0) return F_data_not; + const f_string_length_t length = (range.stop - range.start) + 1; - register f_string_length_t i = range.start; + return private_f_print_string(output, buffer.string + range.start, length); + } +#endif // _di_f_print_string_dynamic_partial_ - for (; i <= range.stop; i++) { - if (buffer.string[i] != 0) { - if (fputc(buffer.string[i], output) == 0) { - return F_status_set_error(F_output); - } - } - } // for +#ifndef _di_f_print_to_ + f_return_status f_print_to(const int id, const f_string_t string, const f_string_length_t length) { + #ifndef _di_level_0_parameter_checking_ + if (string == 0) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ - return F_none; + return private_f_print_to(id, string, length); } -#endif // _di_f_print_string_dynamic_partial_ +#endif // _di_f_print_to_ + +#ifndef _di_f_print_to_dynamic_ + f_return_status f_print_to_dynamic(const int id, const f_string_static_t buffer) { + return private_f_print_to(id, buffer.string, buffer.used); + } +#endif // _di_f_print_to_dynamic_ + +#ifndef _di_f_print_to_dynamic_partial_ + f_return_status f_print_to_dynamic_partial(const int id, const f_string_static_t buffer, const f_string_range_t range) { + #ifndef _di_level_0_parameter_checking_ + if (range.start < 0) return F_status_set_error(F_parameter); + if (range.start > range.stop) return F_status_set_error(F_parameter); + if (range.start >= buffer.used) return F_status_set_error(F_parameter); + if (range.stop >= buffer.used) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const f_string_length_t length = (range.stop - range.start) + 1; + + return private_f_print_to(id, buffer.string + range.start, length); + } +#endif // _di_f_print_to_dynamic_partial_ #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_print/c/print.h b/level_0/f_print/c/print.h index 213daf0..40e8485 100644 --- a/level_0/f_print/c/print.h +++ b/level_0/f_print/c/print.h @@ -17,6 +17,7 @@ #include #include #include +#include // fll-0 includes #include @@ -33,8 +34,8 @@ extern "C" { * * The string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -48,18 +49,20 @@ extern "C" { * F_data_not if length is 0. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() */ #ifndef _di_f_print_string_ extern f_return_status f_print_string(FILE *output, const f_string_t string, const f_string_length_t length); #endif // _di_f_print_string_ /** - * Similar to a c-library printf, except that this will only print a specific range. + * Similar to a c-library printf, except that this prints a given dynamic string. * * The string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will print the entire dynamic string. * * @param output @@ -72,18 +75,20 @@ extern "C" { * F_data_not if buffer.used is 0. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() */ #ifndef _di_f_print_string_dynamic_ extern f_return_status f_print_string_dynamic(FILE *output, const f_string_static_t buffer); #endif // _di_f_print_string_dynamic_ /** - * Similar to a c-library printf, except that this will only print a specific range. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * The string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will print the only the buffer range specified by range. * * @param output @@ -98,11 +103,112 @@ extern "C" { * F_data_not if buffer.used is 0. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() */ #ifndef _di_f_print_string_dynamic_partial_ extern f_return_status f_print_string_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range); #endif // _di_f_print_string_dynamic_partial_ +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * The string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will not print NULL. + * + * @param id + * The file descriptor to output to. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * + * @return + * F_none on success. + * F_data_not if length is 0. + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_input_output (with error bit) on I/O error. + * F_interrupted (with error bit) if interrupt was received. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + */ +#ifndef _di_f_print_to_ + extern f_return_status f_print_to(const int id, const f_string_t string, const f_string_length_t length); +#endif // _di_f_print_to_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * The string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will not print NULL. + * + * @param id + * The file descriptor to output to. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * + * @return + * F_none on success. + * F_data_not if buffer.used is 0. + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_input_output (with error bit) on I/O error. + * F_interrupted (with error bit) if interrupt was received. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + */ +#ifndef _di_f_print_dynamic_to_ + extern f_return_status f_print_dynamic_to(const int id, const f_string_t string, const f_string_length_t length); +#endif // _di_f_print_dynamic_to_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * The string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will not print NULL. + * + * @param id + * The file descriptor to output to. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * + * @return + * F_none on success. + * F_data_not if buffer.used is 0. + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_input_output (with error bit) on I/O error. + * F_interrupted (with error bit) if interrupt was received. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + */ +#ifndef _di_f_print_dynamic_partial_to_ + extern f_return_status f_print_dynamic_partial_to(const int id, const f_string_t string, const f_string_length_t length); +#endif // _di_f_print_dynamic_partial_to_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_print/c/private-print.c b/level_0/f_print/c/private-print.c new file mode 100644 index 0000000..21314fb --- /dev/null +++ b/level_0/f_print/c/private-print.c @@ -0,0 +1,52 @@ +#include "print.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_print_string_) || !defined(_di_f_print_string_dynamic_) || !defined(_di_f_print_string_dynamic_partial_) + f_return_status private_f_print_string(FILE *output, const f_string_t string, const f_string_length_t length) { + + if (length == 0) return F_data_not; + + for (register f_string_length_t i = 0; i < length; ++i) { + if (!string[i]) continue; + + if (!fputc(string[i], output)) { + return F_status_set_error(F_output); + } + } // for + + return F_none; + } +#endif // !defined(_di_f_print_string_) || !defined(_di_f_print_string_dynamic_) || !defined(_di_f_print_string_dynamic_partial_) + +#if !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + f_return_status private_f_print_to(const int id, const f_string_t string, const f_string_length_t length) { + + if (length == 0) return F_data_not; + + for (register f_string_length_t i = 0; i < length; ++i) { + if (!string[i]) continue; + + if (write(id, string + i, 1) == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); + if (errno == EBADF) return F_status_set_error(F_file_descriptor); + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINTR) return F_status_set_error(F_interrupted); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + + return F_status_set_error(F_output); + } + } // for + + return F_none; + } +#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_print/c/private-print.h b/level_0/f_print/c/private-print.h new file mode 100644 index 0000000..07e6863 --- /dev/null +++ b/level_0/f_print/c/private-print.h @@ -0,0 +1,80 @@ +/** + * FLL - Level 0 + * + * Project: Print + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_print_h +#define _PRIVATE_F_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation of f_print_string(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * + * @return + * F_none on success. + * F_data_not if length is 0. + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see f_print_string() + * @see f_print_string_dynamic() + * @see f_print_string_dynamic_partial() + */ +#if !defined(_di_f_print_string_) || !defined(_di_f_print_string_dynamic_) || !defined(_di_f_print_string_dynamic_partial_) + extern f_return_status private_f_print_string(FILE *output, const f_string_t string, const f_string_length_t length) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_print_string_) || !defined(_di_f_print_string_dynamic_) || !defined(_di_f_print_string_dynamic_partial_) + +/** + * Private implementation of f_print_to(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * + * @return + * F_none on success. + * F_data_not if length is 0. + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_input_output (with error bit) on I/O error. + * F_interrupted (with error bit) if interrupt was received. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see f_print_to() + * @see f_print_to_dynamic() + * @see f_print_to_dynamic_partial() + */ +#if !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + extern f_return_status private_f_print_to(const int id, const f_string_t string, const f_string_length_t length) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_print_h diff --git a/level_0/f_print/data/build/settings b/level_0/f_print/data/build/settings index de690a5..fa40717 100644 --- a/level_0/f_print/data/build/settings +++ b/level_0/f_print/data/build/settings @@ -20,7 +20,7 @@ build_indexer ar build_language c build_libraries -lc build_libraries-individual -lf_memory -build_sources_library print.c +build_sources_library print.c private-print.c build_sources_program build_sources_headers print.h build_sources_script -- 1.8.3.1