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.
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_
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_
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_
#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
/**
* 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.
*
* @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.
*
/**
* 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.
*
* @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.
*
/**
* 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.
*
* @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.
*
#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.
*
* @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.
/**
* 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.
*
* @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.
/**
* 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.
*
* @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.
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
}
#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);
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
#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.
* @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"