aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/slibc-print.h252
-rw-r--r--include/slibc/features.h6
-rw-r--r--include/stdio.h845
3 files changed, 1084 insertions, 19 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
+
diff --git a/include/slibc/features.h b/include/slibc/features.h
index 7363215..c5a1e1b 100644
--- a/include/slibc/features.h
+++ b/include/slibc/features.h
@@ -110,6 +110,12 @@
#endif
+/**
+ * Format for the `format` GCC function attribute.
+ */
+#define slibc_printf printf /* TODO write GCC extension */
+
+
#endif
diff --git a/include/stdio.h b/include/stdio.h
index d23339d..598c6ef 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -26,35 +26,842 @@
#define __NEED_off_t
#define __NEED_size_t
#define __NEED_ssize_t
+#define __NEED_wchar_t
#define __NEED_va_list
#if __STDC_VERSION__ >= 201112L
# define __NEED_max_align_t
#endif
+#define FILE void /* TODO temporary */
#include <bits/types.h>
/* TODO implement I/O */
-int fflush(void*);
-#define stdin NULL
-#define stdout NULL
-#define stderr NULL
-int printf(const char*, ...);
-int fprintf(void*, const char*, ...);
-int dprintf(int, const char*, ...);
-int sprintf(char*, const char*, ...);
-int snprintf(char*, size_t, const char*, ...);
-#if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE)
-int asprintf(char**, const char*, ...);
-#endif
-int vprintf(const char*, va_list);
-int vfprintf(void*, const char*, va_list);
-int vdprintf(int, const char*, va_list);
-int vsprintf(char*, const char*, va_list);
-int vsnprintf(char*, size_t, const char*, va_list);
-#if (defined(_GNU_SOURCE) || defined(_SLIBC_SOURCE)) && !defined(__PORTABLE)
-int vasprintf(char**, const char*, va_list);
+int fflush(FILE*);
+#define stdin ((void*)1) /* TODO temporary */
+#define stdout ((void*)2) /* TODO temporary */
+#define stderr ((void*)3) /* TODO temporary */
+
+
+/**
+ * This function is identical to `fprintf` with
+ * `stdout` as the first argument.
+ *
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int printf(const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1), format(slibc_printf, 1, 2))));
+
+/**
+ * Print a formatted string to a stream.
+ *
+ * TODO list format rules for fprintf
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int fprintf(FILE* restrict, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), format(slibc_printf, 2, 3))));
+
+#if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `fprintf`,
+ * except it does not lock the stream.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite_unlocked`.
+ */
+int fprintf_unlocked(FILE* restrict, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), format(slibc_printf, 2, 3))));
+#endif
+
+/**
+ * This function is identical to `fprintf`,
+ * except it is limited to file descriptor-backed
+ * streams, and uses the file descriptor as the
+ * first argument rather than the stream.
+ *
+ * @param fd The file descriptor.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `write`.
+ */
+int dprintf(int, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(2), format(slibc_printf, 2, 3))));
+
+/**
+ * This function is identical to `fprintf`,
+ * except it is limited to buffer-backed
+ * streams, and uses the buffer as the first
+ * argument rather than then the stream.
+ *
+ * This is identical to `sprintf` with
+ * `SIZE_MAX` as the second argument.
+ *
+ * @param buffer The output buffer.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int sprintf(char* restrict, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), format(slibc_printf, 2, 3))));
+
+/**
+ * This function is identical to `sprintf`,
+ * expect it truncates the output.
+ *
+ * @param buffer The output buffer.
+ * @param size The allocation size of `buffer`.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte, that would have been written
+ * if `size` was ignored. On error, a negative
+ * value (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes would have been written; in slibc,
+ * `INT_MAX` is returned if more would have
+ * been written, you can use "%zn" to find the
+ * actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int snprintf(char* restrict, size_t, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(3), format(slibc_printf, 3, 4))));
+
+#if defined(_GNU_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `sprintf`,
+ * except it allocates a sufficiently large
+ * buffer.
+ *
+ * This is a GNU extension.
+ *
+ * @param buffer Output parameter for the output buffer.
+ * On error the content of this pointer is undefined.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int asprintf(char** restrict, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), format(slibc_printf, 2, 3), warn_unused_result)));
+#endif
+
+#if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `asprintf`,
+ * except it can reuse allocated buffers.
+ *
+ * This is a slibc extension.
+ *
+ * @param buffer Reference parameter for the output buffer.
+ * It should point to the buffer than shall
+ * be used, or point to `NULL` if a new buffer
+ * shall be allocated. It will be updated with
+ * a new buffer if it points to `NULL`, or the
+ * new pointer if `buffer` needed to be reallocated.
+ * On error, this pointer will only have been
+ * updated if the buffer was reallocated during
+ * the call; if it pointed to `NULL`, it will
+ * still point to `NULL`.
+ * @param size Reference parameter for the buffer size.
+ * It shall point to a variable whose value is
+ * the allocation size of `*buffer`, or point to
+ * a variable whose value is zero if `*buffer`
+ * is `NULL`
+ * @param offset The offset in the buffer where the function
+ * shall start the printing.
+ * @param secure Non-zero if the function must override the
+ * buffer with zero before freeing it if it
+ * creates a new allocation.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int bprintf(char** restrict, size_t* restrict, size_t, int, const char* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2, 5), format(slibc_printf, 5, 6), warn_unused_result)));
+#endif
+
+
+/**
+ * This function is identical to `printf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int vprintf(const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1))));
+
+/**
+ * This function is identical to `fprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int vfprintf(FILE* restrict, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+#if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `fprintf_unlocked`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite_unlocked`.
+ */
+int vfprintf_unlocked(FILE* restrict, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+#endif
+
+/**
+ * This function is identical to `vdprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param fd The file descriptor.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` bytes are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `write`.
+ */
+int vdprintf(int, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(2))));
+
+/**
+ * This function is identical to `sprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param buffer The output buffer.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int vsprintf(char* restrict, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+/**
+ * This function is identical to `snprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param buffer The output buffer.
+ * @param size The allocation size of `buffer`.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte, that would have been written
+ * if `size` was ignored. On error, a negative
+ * value (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes would have been written; in slibc,
+ * `INT_MAX` is returned if more would have
+ * been written, you can use "%zn" to find the
+ * actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int vsnprintf(char* restrict, size_t, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 3))));
+
+#if defined(_GNU_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `asprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a GNU extension.
+ *
+ * @param buffer Output parameter for the output buffer.
+ * On error the content of this pointer is undefined.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int vasprintf(char** restrict, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), warn_unused_result)));
+#endif
+
+#if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `bprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension.
+ *
+ * @param buffer Reference parameter for the output buffer.
+ * It should point to the buffer than shall
+ * be used, or point to `NULL` if a new buffer
+ * shall be allocated. It will be updated with
+ * a new buffer if it points to `NULL`, or the
+ * new pointer if `buffer` needed to be reallocated.
+ * On error, this pointer will only have been
+ * updated if the buffer was reallocated during
+ * the call; if it pointed to `NULL`, it will
+ * still point to `NULL`.
+ * @param size Reference parameter for the buffer size.
+ * It shall point to a variable whose value is
+ * the allocation size of `*buffer`, or point to
+ * a variable whose value is zero if `*buffer`
+ * is `NULL`
+ * @param offset The offset in the buffer where the function
+ * shall start the printing.
+ * @param secure Non-zero if the function must override the
+ * buffer with zero before freeing it if it
+ * creates a new allocation.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written bytes, excluding
+ * the NUL byte. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * bytes are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int vbprintf(char** restrict, size_t* restrict, size_t, int, const char* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2, 5), warn_unused_result)));
+#endif
+
+
+#if !defined(__PORTABLE) /* wchar_t is not portable. */
+/**
+ * This function is identical to `printf` except
+ * it uses wide characters.
+ *
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int wprintf(const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1))));
+
+/**
+ * This function is identical to `fprintf` except
+ * it uses wide characters.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int fwprintf(FILE* restrict, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+# if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `fprintf_unlocked` except
+ * it uses wide characters.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite_unlocked`.
+ */
+int fwprintf_unlocked(FILE* restrict, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+/**
+ * This function is identical to `dprintf` except
+ * it uses wide characters.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param fd The file descriptor.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `write`.
+ */
+int dwprintf(int, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(2))));
+# endif
+
+/**
+ * This function is identical to `snprintf`
+ * (not `sprintf`) except it uses wide characters.
+ *
+ * @param buffer The output buffer.
+ * @param size The allocation size of `buffer`.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character, that would have been written
+ * if `size` was ignored. On error, a negative
+ * value (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters would have been written; in slibc,
+ * `INT_MAX` is returned if more would have
+ * been written, you can use "%zn" to find the
+ * actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int swprintf(wchar_t* restrict, size_t, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(3))));
+
+# if defined(_GNU_SOURCE) && defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `aswprintf` except
+ * it uses wide characters.
+ *
+ * This is a slibc extension added for completeness.
+ * This is only available if GNU extensions are enabled.
+ *
+ * @param buffer Output parameter for the output buffer.
+ * On error the content of this pointer is undefined.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int aswprintf(wchar_t** restrict, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), warn_unused_result)));
+# endif
+
+# if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `bprintf` except
+ * it uses wide characters.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param buffer Reference parameter for the output buffer.
+ * It should point to the buffer than shall
+ * be used, or point to `NULL` if a new buffer
+ * shall be allocated. It will be updated with
+ * a new buffer if it points to `NULL`, or the
+ * new pointer if `buffer` needed to be reallocated.
+ * On error, this pointer will only have been
+ * updated if the buffer was reallocated during
+ * the call; if it pointed to `NULL`, it will
+ * still point to `NULL`.
+ * @param size Reference parameter for the buffer size,
+ * in `wchar_t`.
+ * It shall point to a variable whose value is
+ * the allocation size of `*buffer`, or point to
+ * a variable whose value is zero if `*buffer`
+ * is `NULL`
+ * @param offset The offset in the buffer where the function
+ * shall start the printing.
+ * @param secure Non-zero if the function must override the
+ * buffer with zero before freeing it if it
+ * creates a new allocation.
+ * @param format The formatting-string.
+ * @param ... The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int bwprintf(wchar_t** restrict, size_t* restrict, size_t, int, const wchar_t* restrict, ...)
+ __GCC_ONLY(__attribute__((nonnull(1, 2, 5), warn_unused_result)));
+# endif
+
+
+/**
+ * This function is identical to `wprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int vwprintf(const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1))));
+
+/**
+ * This function is identical to `fwprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite`.
+ */
+int vfwprintf(FILE* restrict, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+# if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `fwprintf_unlocked`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param stream The output stream.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `fwrite_unlocked`.
+ */
+int vfwprintf_unlocked(FILE* restrict, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2))));
+
+/**
+ * This function is identical to `vdprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param fd The file descriptor.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters.
+ * On error, a negative value (namely -1
+ * in this implementation) is returned.
+ * It is unspecified what shall happen if
+ * more than `INT_MAX` characters are written;
+ * in slibc, `INT_MAX` is returned if more
+ * is written, you can use "%zn" to find
+ * the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws Any error specified for `write`.
+ */
+int vdwprintf(int, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(2))));
+# endif
+
+/**
+ * This function is identical to `swprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * @param buffer The output buffer.
+ * @param size The allocation size of `buffer`.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character, that would have been written
+ * if `size` was ignored. On error, a negative
+ * value (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters would have been written; in slibc,
+ * `INT_MAX` is returned if more would have
+ * been written, you can use "%zn" to find the
+ * actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ */
+int vswprintf(wchar_t* restrict, size_t, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(3))));
+
+# if defined(_GNU_SOURCE) && defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `aswprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension added for completeness.
+ * This is only available if GNU extensions are enabled.
+ *
+ * @param buffer Output parameter for the output buffer.
+ * On error the content of this pointer is undefined.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int vaswprintf(wchar_t** restrict, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2), warn_unused_result)));
+# endif
+
+# if defined(_SLIBC_SOURCE) && !defined(__PORTABLE)
+/**
+ * This function is identical to `bwprintf`,
+ * except it uses `va_list` instead of variadic argument.
+ *
+ * This is a slibc extension added for completeness.
+ *
+ * @param buffer Reference parameter for the output buffer.
+ * It should point to the buffer than shall
+ * be used, or point to `NULL` if a new buffer
+ * shall be allocated. It will be updated with
+ * a new buffer if it points to `NULL`, or the
+ * new pointer if `buffer` needed to be reallocated.
+ * On error, this pointer will only have been
+ * updated if the buffer was reallocated during
+ * the call; if it pointed to `NULL`, it will
+ * still point to `NULL`.
+ * @param size Reference parameter for the buffer size,
+ * in `wchar_t`.
+ * It shall point to a variable whose value is
+ * the allocation size of `*buffer`, or point to
+ * a variable whose value is zero if `*buffer`
+ * is `NULL`
+ * @param offset The offset in the buffer where the function
+ * shall start the printing.
+ * @param secure Non-zero if the function must override the
+ * buffer with zero before freeing it if it
+ * creates a new allocation.
+ * @param format The formatting-string.
+ * @param args The formatting-arguments.
+ * @return The number of written characters, excluding
+ * the NUL character. On error, a negative value
+ * (namely -1 in this implementation) is
+ * returned. It is unspecified what shall
+ * happen if more than `INT_MAX` non-NUL
+ * characters are written; in slibc, `INT_MAX`
+ * is returned if more is written, you can
+ * use "%zn" to find the actual length.
+ *
+ * @throws EINVAL `format` contained unsupported formatting codes.
+ * @throws ENOMEM The process cannot allocation the
+ * sufficient amount of memory.
+ */
+int vbwprintf(wchar_t** restrict, size_t* restrict, size_t, int, const wchar_t* restrict, va_list)
+ __GCC_ONLY(__attribute__((nonnull(1, 2, 5), warn_unused_result)));
+# endif
#endif