diff options
Diffstat (limited to 'include/c/str/cpy/stp/stpe/stpeprintf.h')
-rw-r--r-- | include/c/str/cpy/stp/stpe/stpeprintf.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/include/c/str/cpy/stp/stpe/stpeprintf.h b/include/c/str/cpy/stp/stpe/stpeprintf.h new file mode 100644 index 0000000..1a74dd8 --- /dev/null +++ b/include/c/str/cpy/stp/stpe/stpeprintf.h @@ -0,0 +1,61 @@ +// Copyright 2022 Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +#ifndef INCLUDE_C_STR_CPY_STP_STPE_STPEPRINTF_H_ +#define INCLUDE_C_STR_CPY_STP_STPE_STPEPRINTF_H_ + + +#include <stdarg.h> +#include <stdio.h> + +#include <c/str/cpy/stp/_compiler.h> + + +#pragma clang assume_nonnull begin +inline char *c_nullable c_stpeprintf(char *c_nullable dst, char *end, + const char *restrict fmt, ...); +inline char *c_nullable c_vstpeprintf(char *c_nullable dst, char *end, + const char *restrict fmt, va_list ap); + + +inline char *c_nullable +c_stpeprintf(char *c_nullable dst, char *end, const char *restrict fmt, ...) +{ + char *c_nullable p; + va_list ap; + + va_start(ap, fmt); + p = c_vstpeprintf(dst, end, fmt, ap); + va_end(ap); + + return p; +} + + +inline char *c_nullable +c_vstpeprintf(char *c_nullable dst, char *end, const char *restrict fmt, + va_list ap) +{ + int len; + + if (dst == end) + return end; + if (c_unlikely(dst == NULL)) + return NULL; + c_impossible(dst > end); + + len = vsnprintf(dst, end - dst, fmt, ap); + + c_impossible(len < -1); + if (c_unlikely(len == -1)) + return NULL; + if (len >= end - dst) + return end; + + return dst + len; +} +#pragma clang assume_nonnull end + + +#endif // Header guard |