summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2022-06-17 15:47:18 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-07-19 17:55:21 +0000
commit1bc7945394c90dd2b00d8ea7c9201dc368904718 (patch)
tree77b11ce134657aec9efab0c8d23ab11aa26a7469 /builtin
parent3eb29b6aa5a4e5e8c85046be789c6dd8d38afbaa (diff)
downloadchrome-ec-1bc7945394c90dd2b00d8ea7c9201dc368904718.tar.gz
tree: Move printf declarations to stdio.h
The "builtin" directory is EC's copy of the C standard library headers. Move the declarations for printf functions that are provided by the standard library to the "builtin" directory. This change makes it easier for future changes to optionally build with the C standard library instead of the standalone EC subset. BRANCH=none BUG=b:172020503, b:234181908, b:237823627 TEST=make buildall Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: I4a5b4f8b98b972e86c4cca65d4910b5aa07ec524 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3712034 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/stdio.h61
-rw-r--r--builtin/stdlib.c68
2 files changed, 129 insertions, 0 deletions
diff --git a/builtin/stdio.h b/builtin/stdio.h
new file mode 100644
index 0000000000..b8b6949c45
--- /dev/null
+++ b/builtin/stdio.h
@@ -0,0 +1,61 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_STDIO_H__
+#define __CROS_EC_STDIO_H__
+
+#include <stddef.h>
+#include <stdarg.h>
+
+#include "common.h"
+
+/**
+ * Print formatted outut to a string.
+ *
+ * Guarantees null-termination if size!=0.
+ *
+ * @param str Destination string
+ * @param size Size of destination in bytes
+ * @param format Format string
+ * @return EC_SUCCESS, or EC_ERROR_OVERFLOW if the output was truncated.
+ */
+__attribute__((__format__(__printf__, 3, 4)))
+__warn_unused_result __stdlib_compat int
+crec_snprintf(char *str, size_t size, const char *format, ...);
+
+/**
+ * Print formatted output to a string.
+ *
+ * Guarantees null-termination if size!=0.
+ *
+ * @param str Destination string
+ * @param size Size of destination in bytes
+ * @param format Format string
+ * @param args Parameters
+ * @return The string length written to str, or a negative value on error.
+ * The negative values can be -EC_ERROR_INVAL or -EC_ERROR_OVERFLOW.
+ */
+__warn_unused_result __stdlib_compat int
+crec_vsnprintf(char *str, size_t size, const char *format, va_list args);
+
+/*
+ * Create weak aliases to the crec_* printf functions. This lets us call the
+ * crec_* printf functions in tests that link the C standard library.
+ */
+
+/**
+ * Alias to crec_snprintf.
+ */
+__attribute__((__format__(__printf__, 3, 4)))
+__warn_unused_result __stdlib_compat int
+snprintf(char *str, size_t size, const char *format, ...);
+
+/**
+ * Alias to crec_vsnprintf.
+ */
+__warn_unused_result __stdlib_compat int
+vsnprintf(char *str, size_t size, const char *format, va_list args);
+
+#endif /* __CROS_EC_STDIO_H__ */
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.