diff options
Diffstat (limited to 'builtin/stdlib.c')
-rw-r--r-- | builtin/stdlib.c | 68 |
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. |