/**
* 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
#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.
*
* @etymology (`generic_printf`)-subsystem: (ext)ension (queue).
*
* @since Always.
*/
struct generic_printf_ext_queue
{
/**
* Sizes, in bytes, of the missing arguments.
* Only 1, 2, 4 and 8 are allowed.
*
* @since Always.
*/
char sizes[4];
/**
* The indices of the missing arguments.
*
* @since Always.
*/
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.
*
* @since Always.
*/
size_t count;
};
/**
* Function-type used by `generic_printf` and `vgeneric_wprintf`
* to write a string.
*
* @etymology (`generic_printf`)-subsystem: (write-func)tion, `(t)ypedef`.
*
* @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.
*
* @since Always.
*/
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`.
*
* @etymology (`generic_wprintf`)-subsystem: (write-func)tion, `(t)ypedef`.
*
* @since Always.
*/
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.
*
* @etymology (`generic_printf`)-subsystem: (ext)ension(-func)tion, `(t)ypedef`.
*
* @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.
*
* @since Always.
*/
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`.
*
* @etymology (`generic_wprintf`)-subsystem: (ext)ension(-func)tion, `(t)ypedef`.
*
* @since Always.
*/
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.
*
* @etymology (Generic) (`wprintf`)-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.
*
* @since Always.
*/
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.
*
* @etymology (V)ariadic version of (`generic_printf`).
*
* @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.
*
* @since Always.
*/
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`;
*
* @etymology (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 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.
*
* @since Always.
*/
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.
*
* @etymology (V)ariadic version of (`generic_wprintf`).
*
* @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.
*
* @since Always.
*/
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