···11+// Copyright 2023, Collabora, Ltd.
22+// SPDX-License-Identifier: BSL-1.0
33+/*!
44+ * @file
55+ * @brief Truncating versions of string printing functions.
66+ * @author Jakob Bornecrantz <jakob@collabora.com>
77+ * @ingroup aux_util
88+ */
99+1010+#pragma once
1111+1212+#include "xrt/xrt_compiler.h"
1313+1414+#include <stdio.h>
1515+#include <stdarg.h>
1616+#include <limits.h>
1717+1818+1919+#ifdef __cplusplus
2020+extern "C" {
2121+#endif
2222+2323+2424+/*!
2525+ * We want to truncate the value, not get the possible written.
2626+ *
2727+ * There are no version of the *many* Windows versions of this functions that
2828+ * truncates and returns the number of bytes written (not including null). Also
2929+ * need to have the same behaviour on Linux.
3030+ *
3131+ * @ingroup @aux_util
3232+ */
3333+static inline int
3434+u_truncate_vsnprintf(char *chars, size_t char_count, const char *fmt, va_list args)
3535+{
3636+ /*
3737+ * We always want to be able to write null terminator, and
3838+ * something propbly went wrong if char_count larger then INT_MAX.
3939+ */
4040+ if (char_count == 0 || char_count > INT_MAX) {
4141+ return -1;
4242+ }
4343+4444+ // Will always be able to write null terminator.
4545+ int ret = vsnprintf(chars, char_count, fmt, args);
4646+ if (ret < 0) {
4747+ return ret;
4848+ }
4949+5050+ // Safe, ret is checked for negative above.
5151+ if ((size_t)ret > char_count - 1) {
5252+ return (int)char_count - 1;
5353+ }
5454+5555+ return ret;
5656+}
5757+5858+/*!
5959+ * We want to truncate the value, not get the possible written, and error when
6060+ * we can not write out anything.
6161+ *
6262+ * See @ref u_truncate_vsnprintf for more info.
6363+ *
6464+ * @ingroup @aux_util
6565+ */
6666+static inline int
6767+u_truncate_snprintf(char *chars, size_t char_count, const char *fmt, ...)
6868+{
6969+ /*
7070+ * We always want to be able to write null terminator, and
7171+ * something propbly went wrong if char_count larger then INT_MAX.
7272+ */
7373+ if (char_count == 0 || char_count > INT_MAX) {
7474+ return -1;
7575+ }
7676+7777+ va_list args;
7878+ va_start(args, fmt);
7979+ int ret = u_truncate_vsnprintf(chars, char_count, fmt, args);
8080+ va_end(args);
8181+8282+ return ret;
8383+}
8484+8585+8686+#ifdef __cplusplus
8787+}
8888+#endif