summaryrefslogtreecommitdiff
path: root/builtin/stdlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/stdlib.c')
-rw-r--r--builtin/stdlib.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/builtin/stdlib.c b/builtin/stdlib.c
index 1d07b64869..b3229f4f63 100644
--- a/builtin/stdlib.c
+++ b/builtin/stdlib.c
@@ -7,7 +7,11 @@
#include "common.h"
#include "console.h"
+#include "printf.h"
#include "util.h"
+
+#include <stdio.h>
+
/*
* The following macros are defined in stdlib.h in the C standard library, which
* conflict with the definitions in this file.
@@ -19,6 +23,70 @@
#undef isprint
#undef tolower
+/* Context for snprintf() */
+struct snprintf_context {
+ char *str;
+ int size;
+};
+
+/**
+ * Add a character to the string context.
+ *
+ * @param context Context receiving character
+ * @param c Character to add
+ * @return 0 if character added, 1 if character dropped because no space.
+ */
+static int snprintf_addchar(void *context, int c)
+{
+ struct snprintf_context *ctx = (struct snprintf_context *)context;
+
+ if (!ctx->size)
+ return 1;
+
+ *(ctx->str++) = c;
+ ctx->size--;
+ return 0;
+}
+
+int crec_vsnprintf(char *str, size_t size, const char *format, va_list args)
+{
+ struct snprintf_context ctx;
+ int rv;
+
+ if (!str || !format || size <= 0)
+ return -EC_ERROR_INVAL;
+
+ ctx.str = str;
+ ctx.size = size - 1; /* Reserve space for terminating '\0' */
+
+ rv = vfnprintf(snprintf_addchar, &ctx, format, args);
+
+ /* Terminate string */
+ *ctx.str = '\0';
+
+ return (rv == EC_SUCCESS) ? (ctx.str - str) : -rv;
+}
+#ifndef CONFIG_ZEPHYR
+int vsnprintf(char *str, size_t size, const char *format, va_list args)
+ __attribute__((weak, alias("crec_vsnprintf")));
+#endif /* CONFIG_ZEPHYR */
+
+int crec_snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list args;
+ int rv;
+
+ va_start(args, format);
+ rv = crec_vsnprintf(str, size, format, args);
+ va_end(args);
+
+ return rv;
+}
+#ifndef CONFIG_ZEPHYR
+int snprintf(char *str, size_t size, const char *format, ...)
+ __attribute__((weak, alias("crec_snprintf")));
+#endif /* CONFIG_ZEPHYR */
+
/*
* TODO(b/237712836): Zephyr's libc should provide strcasecmp. For now we'll
* use the EC implementation.