diff options
Diffstat (limited to 'include/slibc-print.h')
-rw-r--r-- | include/slibc-print.h | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/include/slibc-print.h b/include/slibc-print.h new file mode 100644 index 0000000..b992537 --- /dev/null +++ b/include/slibc-print.h @@ -0,0 +1,252 @@ +/** + * slibc — Yet another C library + * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef _SLIBC_PRINT_H +#define _SLIBC_PRINT_H +#include <slibc/version.h> +#include <slibc/features.h> +#ifndef __PORTABLE + + + +/** + * `NULL`'s canonical header is <stddef.h> + */ +#ifndef NULL +# define NULL ((void*)0) +#endif + + +#define __NEED_size_t +#define __NEED_ssize_t +#define __NEED_wchar_t +#define __NEED_intmax_t +#define __NEED_va_list +#include <bits/types.h> + + + +/** + * Structure used by extensions to `generic_printf`-function + * to request that additionally arguments be added before the + * function is called again. + */ +struct generic_printf_ext_queue +{ + /** + * Sizes, in bytes, of the missing arguments. + * Only 1, 2, 4 and 8 are allowed. + */ + char sizes[4]; + + /** + * The indices of the missing arguments. + */ + size_t indices[4]; + + /** + * The amount of missing arguments. + * `sizes` and `indices` can only hold up to + * 4 arguments, the function will be later + * again to retrieve information about the + * omitted arguments. To avoid a deadlock, + * add arguments in the order of their index + * if there are more than 4 missing arguments. + */ + size_t count; +}; + + +/** + * Function-type used by `generic_printf` and `vgeneric_wprintf` + * to write a string. + * + * @param text The text segment to print, it will only contain + * a NUL byte if that NUL byte shall be printed. + * @param length The length of `text`. + * @param data The value passed to `generic_printf` or + * `vgeneric_wprintf` via the parameter `data`. + * @return Zero on success, -1 on error. `errno` shall + * be set on error. + */ +typedef int (* generic_printf_write_func_t)(const char*, size_t, void*); + +/** + * Variant of `generic_printf_write_func_t` used for + * `generic_wprintf` and `vgeneric_wprintf`. + */ +typedef int (* generic_wprintf_write_func_t)(const wchar_t*, size_t, void*); + +/** + * Function-type used by `generic_printf` and `vgeneric_wprintf` + * to write a string if a custom formatting code was encountered. + * + * @param code The %-code, excluding the %. + * @param args Formatting arguments cased to `intmax`. + * @param argn The number of formatting arguments in `args`. + * @param silent Non-zero if the function must not perform a write. + * @param data The value passed to `generic_printf` or + * `vgeneric_wprintf` via the parameter `data`. + * @param queue_data Used to send information to the calling function + * about missing arguments. + * @return The number of written characters, -1 on error. + * `errno` shall be set on error. -2 shall be returned + * if argument index equal to or greater than the + * value of `argn`, if `queue_data` must be set. + * + * @throws EINVAL If `code` could not be recognised. + */ +typedef ssize_t (* generic_printf_ext_func_t)(const char*, intmax_t*, size_t, int, void*, + struct generic_printf_ext_queue*); + +/** + * Variant of `generic_printf_ext_func_t` used for + * `generic_wprintf` and `vgeneric_wprintf`. + */ +typedef ssize_t (* generic_wprintf_ext_func_t)(const wchar_t*, intmax_t*, size_t, int, void*, + struct generic_printf_ext_queue*); + + +/** + * An almost fully generic `printf`-function. + * + * @param write_function Function used to write the string. `NULL` if + * it shall not be printed but only measured. + * @param extension_function Function used to extend the functions formatting codes. + * `NULL` if not extensions are to be used. + * @param maximum_length The maximum amount of bytes to write, including the + * NUL byte, ignored if `limited_length` is zero. + * @param limited_length Whether `maximum_length` shall be used. + * @param actual_length Output parameter for the length of the printed string, + * this includes any text that was truncated but not the + * NUL character. Must not be `NULL`. + * @param terminate Whether a NUL character shall be printed at the end. + * @param data Data to pass to `write_function` and + * `extension_function`, it should contain + * the print-sink, and any state data neccessary + * since the functions may be called multiple times. + * @param format The formatting-string, see `fprintf` for details. + * @param ... The formatting-arguments. + * @return Zero on success, -1 on error. On error, `errno` + * is set to indicate the error. + * + * @throws Any error thrown by `write_function` or `extension_function`. + * @throws EINVAL `format` contained unsupported formatting codes. + */ +int generic_printf(generic_printf_write_func_t, generic_printf_ext_func_t, + size_t, int, size_t* restrict, int, void*, const char*, ...) + __GCC_ONLY(__attribute__((nonnull(5, 8), format(slibc_printf, 8, 9), warn_unused_result))); + +/** + * Variant of `generic_printf` that uses `va_list` + * instead of variadic arguments. + * + * @param write_function Function used to write the string. `NULL` if + * it shall not be printed but only measured. + * @param extension_function Function used to extend the functions formatting codes. + * `NULL` if not extensions are to be used. + * @param maximum_length The maximum amount of bytes to write, including the + * NUL byte, ignored if `limited_length` is zero. + * @param limited_length Whether `maximum_length` shall be used. + * @param actual_length Output parameter for the length of the printed string, + * this includes any text that was truncated but not the + * NUL character. Must not be `NULL`. + * @param terminate Whether a NUL character shall be printed at the end. + * @param data Data to pass to `write_function` and + * `extension_function`, it should contain + * the print-sink, and any state data neccessary + * since the functions may be called multiple times. + * @param format The formatting-string, see `fprintf` for details. + * @param args The formatting-arguments. + * @return Zero on success, -1 on error. On error, `errno` + * is set to indicate the error. + * + * @throws Any error thrown by `write_function` or `extension_function`. + * @throws EINVAL `format` contained unsupported formatting codes. + */ +int vgeneric_printf(generic_printf_write_func_t, generic_printf_ext_func_t, + size_t, int, size_t* restrict, int, void*, const char*, va_list) + __GCC_ONLY(__attribute__((nonnull(5, 8), warn_unused_result))); + +/** + * Variant of `generic_printf` uses `wchar_t` instead of `char`; + * + * @param write_function Function used to write the string. `NULL` if + * it shall not be printed but only measured. + * @param extension_function Function used to extend the functions formatting codes. + * `NULL` if not extensions are to be used. + * @param maximum_length The maximum amount of wide characters to write, + * including the NUL wide character, ignored if + * `limited_length` is zero. + * @param limited_length Whether `maximum_length` shall be used. + * @param actual_length Output parameter for the length of the printed string, + * this includes any text that was truncated but not the + * NUL character. Must not be `NULL`. + * @param terminate Whether a NUL character shall be printed at the end. + * @param data Data to pass to `write_function` and + * `extension_function`, it should contain + * the print-sink, and any state data neccessary + * since the functions may be called multiple times. + * @param format The formatting-string, see `fprintf` for details. + * @param ... The formatting-arguments. + * @return Zero on success, -1 on error. On error, `errno` + * is set to indicate the error. + * + * @throws Any error thrown by `write_function` or `extension_function`. + * @throws EINVAL `format` contained unsupported formatting codes. + */ +int generic_wprintf(generic_wprintf_write_func_t, generic_wprintf_ext_func_t, + size_t, int, size_t* restrict, int, void*, const wchar_t*, ...) + __GCC_ONLY(__attribute__((nonnull(5, 8), warn_unused_result))); + +/** + * Variant of `generic_wprintf` that uses `va_list` + * instead of variadic arguments. + * + * @param write_function Function used to write the string. `NULL` if + * it shall not be printed but only measured. + * @param extension_function Function used to extend the functions formatting codes. + * `NULL` if not extensions are to be used. + * @param maximum_length The maximum amount of wide characters to write, + * including the NUL wide character, ignored if + * `limited_length` is zero. + * @param limited_length Whether `maximum_length` shall be used. + * @param actual_length Output parameter for the length of the printed string, + * this includes any text that was truncated but not the + * NUL character. Must not be `NULL`. + * @param terminate Whether a NUL character shall be printed at the end. + * @param data Data to pass to `write_function` and + * `extension_function`, it should contain + * the print-sink, and any state data neccessary + * since the functions may be called multiple times. + * @param format The formatting-string, see `fprintf` for details. + * @param ... The formatting-arguments. + * @return Zero on success, -1 on error. On error, `errno` + * is set to indicate the error. + * + * @throws Any error thrown by `write_function` or `extension_function`. + * @throws EINVAL `format` contained unsupported formatting codes. + */ +int vgeneric_wprintf(generic_wprintf_write_func_t, generic_wprintf_ext_func_t, + size_t, int, size_t* restrict, int, void*, const wchar_t*, va_list) + __GCC_ONLY(__attribute__((nonnull(5, 8), warn_unused_result))); + + + +#endif +#endif + |