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_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
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
#include "print.h"
+#include "private-print.h"
#ifdef __cplusplus
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"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
+#include <unistd.h>
// fll-0 includes
#include <level_0/type.h>
*
* 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.
* 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
* 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
* 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
--- /dev/null
+#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
--- /dev/null
+/**
+ * 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
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