/** * 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 . */ #ifndef _SLIBC_PRINT_H #define _SLIBC_PRINT_H #include #include #ifndef __PORTABLE /** * `NULL`'s canonical header is */ #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 /** * 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