From 35f1df914c8be9e9667a818a9040bc2dd9034ed3 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Thu, 22 Oct 2020 22:05:17 -0500 Subject: [PATCH] Update: level_0 print functions. Relax the parameter checks and have them return F_data_not when length is 0 or string is unavailable. - Based on existing documentation, it seems this behavior was intended at some point anyway. - The range is capped to buffer.used now. The f_print_to* functions are rewritten to print as much of the string in as few calls to write() as possible. - It is likely possible to utilize more complicated logic to further reduce the calls to write() but this is good enough for now. - Reducing the calls to write(), in theory, should improve performance. Add checks to f_print_to* functions to do nothing if the id is -1 (aka: an invalid/closed file descriptor). Add *_except* print functions to print all characters except those specified in the "except" variable as well as not printing NULLs. --- level_0/f_print/c/print.c | 124 ++++++++++++++++++-- level_0/f_print/c/print.h | 235 ++++++++++++++++++++++++++++++++++---- level_0/f_print/c/private-print.c | 119 ++++++++++++++++++- level_0/f_print/c/private-print.h | 68 ++++++++++- 4 files changed, 506 insertions(+), 40 deletions(-) diff --git a/level_0/f_print/c/print.c b/level_0/f_print/c/print.c index 8488538..dd4e348 100644 --- a/level_0/f_print/c/print.c +++ b/level_0/f_print/c/print.c @@ -9,9 +9,10 @@ extern "C" { f_return_status f_print(FILE *output, const f_string_t string, const f_string_length_t length) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); - if (!string) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (!string || length == 0) return F_data_not; + return private_f_print(output, string, length); } #endif // _di_f_print_ @@ -22,6 +23,8 @@ extern "C" { if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (!buffer.used) return F_data_not; + return private_f_print(output, buffer.string, buffer.used); } #endif // _di_f_print_dynamic_ @@ -30,30 +33,82 @@ extern "C" { f_return_status f_print_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range) { #ifndef _di_level_0_parameter_checking_ if (!output) 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_ - const f_string_length_t length = (range.stop - range.start) + 1; + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not; + + f_string_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } return private_f_print(output, buffer.string + range.start, length); } #endif // _di_f_print_dynamic_partial_ +#ifndef _di_f_print_except_ + f_return_status f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || length == 0) return F_data_not; + + return private_f_print_except(output, string, length, except); + } +#endif // _di_f_print_except_ + +#ifndef _di_f_print_except_dynamic_ + f_return_status f_print_except_dynamic(FILE *output, const f_string_static_t buffer, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used) return F_data_not; + + return private_f_print_except(output, buffer.string, buffer.used, except); + } +#endif // _di_f_print_except_dynamic_ + +#ifndef _di_f_print_except_dynamic_partial_ + f_return_status f_print_except_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not; + + f_string_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_f_print_except(output, buffer.string + range.start, length, except); + } +#endif // _di_f_print_except_dynamic_partial_ + #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) return F_status_set_error(F_parameter); + if (id != -1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (!string || length == 0) return F_data_not; + return private_f_print_to(id, string, length); } #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) { + #ifndef _di_level_0_parameter_checking_ + if (id != -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used) return F_data_not; + return private_f_print_to(id, buffer.string, buffer.used); } #endif // _di_f_print_to_dynamic_ @@ -61,18 +116,63 @@ extern "C" { #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); + if (id != -1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const f_string_length_t length = (range.stop - range.start) + 1; + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not; + + f_string_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } return private_f_print_to(id, buffer.string + range.start, length); } #endif // _di_f_print_to_dynamic_partial_ +#ifndef _di_f_print_to_except_ + f_return_status f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (id != -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || length == 0) return F_data_not; + + return private_f_print_to_except(id, string, length, except); + } +#endif // _di_f_print_to_except_ + +#ifndef _di_f_print_to_except_dynamic_ + f_return_status f_print_to_except_dynamic(const int id, const f_string_static_t buffer, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (id != -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used) return F_data_not; + + return private_f_print_to_except(id, buffer.string, buffer.used, except); + } +#endif // _di_f_print_to_except_dynamic_ + +#ifndef _di_f_print_to_except_dynamic_partial_ + f_return_status f_print_to_except_dynamic_partial(const int id, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except) { + #ifndef _di_level_0_parameter_checking_ + if (id != -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not; + + f_string_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_f_print_to_except(id, buffer.string + range.start, length, except); + } +#endif // _di_f_print_to_except_dynamic_partial_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_print/c/print.h b/level_0/f_print/c/print.h index 4d1284c..0c11f4e 100644 --- a/level_0/f_print/c/print.h +++ b/level_0/f_print/c/print.h @@ -32,10 +32,9 @@ extern "C" { /** * Similar to a c-library printf, 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. + * Will print up to length 1-byte characters. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -46,7 +45,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. + * F_data_not if there is nothing to print. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * @@ -59,11 +58,9 @@ extern "C" { /** * 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 NULL. * Will not print NULL. - * Will print the entire dynamic string. + * Will print up to the length of the buffer. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -72,7 +69,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if buffer.used is 0. + * F_data_not if there is nothing to print. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * @@ -85,11 +82,9 @@ extern "C" { /** * 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 NULL. * Will not print NULL. - * Will print the only the buffer range specified by range. + * Will print up to the specified range within the buffer. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -100,7 +95,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if buffer.used is 0. + * F_data_not if there is nothing to print. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * @@ -111,12 +106,100 @@ extern "C" { #endif // _di_f_print_dynamic_partial_ /** - * Similar to a c-library dprintf, except that this will only print a specific range. + * Similar to a c-library printf, 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. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to length 1-byte characters. + * + * @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. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() + */ +#ifndef _di_f_print_except_ + extern f_return_status f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except); +#endif // _di_f_print_except_ + +/** + * Similar to a c-library printf, except that this prints a given dynamic string. + * + * Will not stop at NULL. + * Will not print NULL. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to the length of the buffer. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() + */ +#ifndef _di_f_print_except_dynamic_ + extern f_return_status f_print_except_dynamic(FILE *output, const f_string_static_t buffer, const f_string_lengths_t except); +#endif // _di_f_print_except_dynamic_ + +/** + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * + * Will not stop at NULL. + * Will not print NULL. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to the specified range within the buffer. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fputc() + */ +#ifndef _di_f_print_dynamic_except_partial_ + extern f_return_status f_print_except_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except); +#endif // _di_f_print_except_dynamic_partial_ + + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. * * Will not stop at NULL. * Will not print NULL. + * Will print up to length 1-byte characters. * * @param id * The file descriptor to output to. @@ -127,7 +210,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. + * F_data_not if there is nothing to print. * 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. @@ -146,11 +229,9 @@ extern "C" { /** * 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. - * Will print the entire dynamic string. + * Will print up to the length of the buffer. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -159,7 +240,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if buffer.used is 0. + * F_data_not if there is nothing to print. * 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. @@ -178,11 +259,9 @@ extern "C" { /** * 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. - * Will print the only the buffer range specified by range. + * Will print up to the specified range within the buffer. * * @param output * The file to output to, including standard streams such as stdout and stderr. @@ -193,7 +272,7 @@ extern "C" { * * @return * F_none on success. - * F_data_not if buffer.used is 0. + * F_data_not if there is nothing to print. * 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. @@ -209,6 +288,118 @@ extern "C" { extern f_return_status f_print_to_dynamic_partial(const int id, const f_string_static_t buffer, const f_string_range_t range); #endif // _di_f_print_to_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. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to length 1-byte characters. + * + * @param id + * The file descriptor to output to. + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * 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_except_ + extern f_return_status f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except); +#endif // _di_f_print_to_except_ + +/** + * 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. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to the length of the buffer. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * 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_except_dynamic_ + extern f_return_status f_print_to_except_dynamic(const int id, const f_string_static_t buffer, const f_string_lengths_t except); +#endif // _di_f_print_to_except_dynamic_ + +/** + * 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. + * Will not print any 1-byte character at a location specified in except array. + * Will print up to the specified range within the buffer. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * 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_except_dynamic_partial_ + extern f_return_status f_print_to_except_dynamic_partial(const int id, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except); +#endif // _di_f_print_to_except_dynamic_partial_ + #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 index 670fd37..2b5319e 100644 --- a/level_0/f_print/c/private-print.c +++ b/level_0/f_print/c/private-print.c @@ -22,15 +22,67 @@ extern "C" { } #endif // !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_) +#if !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) + f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) { + + if (!length) return F_data_not; + + f_string_length_t j = 0; + + for (register f_string_length_t i = 0; i < length; ++i) { + for (; j < except.used; j++) { + if (except.array[j] >= i) break; + } // for + + if (j < except.used && except.array[j] == i) continue; + + if (string[i]) { + if (!fputc(string[i], output)) { + return F_status_set_error(F_output); + } + } + } // for + + return F_none; + } +#endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_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) return F_data_not; - for (register f_string_length_t i = 0; i < length; ++i) { - if (!string[i]) continue; + register f_string_length_t i = 0; + f_string_length_t start = 0; + f_string_length_t total = 0; + + for (; i < length; ++i) { + + if (string[i]) { + total++; + continue; + } + + if (total) { + if (write(id, string + start, total) == -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); - if (write(id, string + i, 1) == -1) { + return F_status_set_error(F_output); + } + } + + start = i + 1; + total = 0; + } // for + + if (total) { + if (write(id, string + start, total) == -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); @@ -41,12 +93,71 @@ extern "C" { 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_) +#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) { + + if (!length) return F_data_not; + + register f_string_length_t i = 0; + f_string_length_t j = 0; + f_string_length_t start = 0; + f_string_length_t total = 0; + + for (; i < length; ++i) { + + for (; j < except.used; j++) { + if (except.array[j] >= i) break; + } // for + + if (j >= except.used || except.array[j] != i) { + if (string[i]) { + total++; + continue; + } + } + + if (total) { + if (write(id, string + start, total) == -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); + } + } + + start = i + 1; + total = 0; + } // for + + if (total) { + if (write(id, string + start, total) == -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); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + #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 index 56e40c7..0dbc316 100644 --- a/level_0/f_print/c/private-print.h +++ b/level_0/f_print/c/private-print.h @@ -42,6 +42,35 @@ extern "C" { #endif // !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_) /** + * Private implementation of f_print_except(). + * + * 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. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @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_except() + * @see f_print_except_dynamic() + * @see f_print_except_dynamic_partial() + */ +#if !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) + extern f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) + +/** * Private implementation of f_print_to(). * * Intended to be shared to each of the different implementation variations. @@ -69,9 +98,44 @@ extern "C" { * @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_) +#if !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_dynamic_partial_) 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_) +#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_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. + * @param except + * An array of locations within the given string to not print. + * The array of locations is assumed to be in linear order. + * + * @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_except() + * @see f_print_to_except_dynamic() + * @see f_print_to_except_dynamic_partial() + */ +#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + extern f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) #ifdef __cplusplus } // extern "C" -- 1.8.3.1