From 17a007bc60c69d6ea471a96a465e04ba4ac2d00f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Tue, 26 Aug 2014 23:11:34 -0400 Subject: [PATCH] Add normal alloca() definition and implement a strdupa and friends Change-Id: I21c9c21fd664fb11bc8496ace4a389f535a030d6 --- firmware/include/string-extra.h | 34 ++++++++++++++++++++++++++ firmware/libc/include/stdlib.h | 5 ++++ firmware/target/hosted/system-hosted.h | 12 ++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/firmware/include/string-extra.h b/firmware/include/string-extra.h index 6a9e0c77be..9ab53d8154 100644 --- a/firmware/include/string-extra.h +++ b/firmware/include/string-extra.h @@ -34,4 +34,38 @@ #endif #endif +/* copies a buffer of len bytes and null terminates it */ +static inline char * strmemcpy(char *dst, const char *src, size_t len) +{ + /* NOTE: for now, assumes valid parameters! */ + *(char *)mempcpy(dst, src, len) = '\0'; + return dst; +} + +/* duplicate and null-terminate a memory block on the stack with alloca() */ +#define strmemdupa(s, l) \ + ({ const char *___s = (s); \ + size_t ___l = (l); \ + char *___buf = alloca(___l + 1); \ + strmemcpy(___buf, ___s, ___l); }) + +/* strdupa and strndupa may already be provided by a system's string.h */ + +#ifndef strdupa +/* duplicate an entire string on the stack with alloca() */ +#define strdupa(s) \ + ({ const char *__s = (s); \ + strmemdupa((__s), strlen(__s)); }) +#endif /* strdupa */ + +#ifndef strndupa +/* duplicate a string on the stack with alloca(), truncating it if it is too + long */ +#define strndupa(s, n) \ + ({ const char *__s = (s); \ + size_t __n = (n); \ + size_t __len = strlen(_s); \ + strmemdupa(__s, MIN(__n, __len)); }) +#endif /* strndupa */ + #endif /* STRING_EXTRA_H */ diff --git a/firmware/libc/include/stdlib.h b/firmware/libc/include/stdlib.h index 57553367c4..e24d6a579f 100644 --- a/firmware/libc/include/stdlib.h +++ b/firmware/libc/include/stdlib.h @@ -31,6 +31,11 @@ void free(void *); void *realloc(void *, size_t); int atexit(void (*)(void)); +#ifdef __GNUC__ +# undef alloca +# define alloca(size) __builtin_alloca (size) +#endif /* GCC. */ + #define RAND_MAX INT_MAX void srand(unsigned int seed); diff --git a/firmware/target/hosted/system-hosted.h b/firmware/target/hosted/system-hosted.h index e60803fde0..5e7a7d7d99 100644 --- a/firmware/target/hosted/system-hosted.h +++ b/firmware/target/hosted/system-hosted.h @@ -22,7 +22,7 @@ #ifndef __SYSTEM_HOSTED_H__ #define __SYSTEM_HOSTED_H__ -#include "system.h" +#ifndef __PCTOOL__ static inline void commit_dcache(void) {} static inline void commit_discard_dcache(void) {} @@ -34,4 +34,14 @@ static inline void core_sleep(void) wait_for_interrupt(); } +#endif /* __PCTOOL__ */ + +#if defined(WIN32) || defined(__PCTOOL__) + +#ifndef alloca +#define alloca __builtin_alloca +#endif + +#endif /* WIN32 || __PCTOOL__ */ + #endif