commit c8ecc164f1635bf713d6c9d7cd4b1311f42f4bc1
parent c2b0ad0bf55d5fe63c6e56e64cbd252a772dbbc0
Author: sin <sin@2f30.org>
Date: Fri, 13 Mar 2015 17:03:52 +0000
Implement snprintf() and sprintf() using __builtin_va_arg_pack()
Requires at least GCC 4.3.
Diffstat:
1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/include/stdio.h b/include/stdio.h
@@ -84,28 +84,35 @@ int vsprintf(char *s, const char *fmt, __builtin_va_list ap)
return r;
}
-#undef snprintf
-#define snprintf(s, n, fmt, ...) ({ \
- size_t _n = n; \
- size_t bos = __builtin_object_size(s, 0); \
- if (_n > bos) \
- __builtin_trap(); \
- (snprintf)(s, _n, fmt, ## __VA_ARGS__); \
-})
+extern int __snprintf_orig(char *, size_t, const char *, ...)
+ __asm__(__USER_LABEL_PREFIX__ "snprintf");
+extern __inline __attribute__((__always_inline__,__gnu_inline__))
+int snprintf(char *s, size_t n, const char *fmt, ...)
+{
+ size_t bos = __builtin_object_size(s, 0);
-#undef sprintf
-#define sprintf(s, fmt, ...) ({ \
- size_t bos = __builtin_object_size(s, 0); \
- int r; \
- if (bos != (size_t)-1) { \
- r = (snprintf)(s, bos, fmt, ## __VA_ARGS__); \
- if (r != -1 && (size_t)r >= bos) \
- __builtin_trap(); \
- } else { \
- r = (sprintf)(s, fmt, ## __VA_ARGS__); \
- } \
- r; \
-})
+ if (n > bos)
+ __builtin_trap();
+ return __snprintf_orig(s, n, fmt, __builtin_va_arg_pack());
+}
+
+extern int __sprintf_orig(char *, const char *, ...)
+ __asm__(__USER_LABEL_PREFIX__ "sprintf");
+extern __inline __attribute__((__always_inline__,__gnu_inline__))
+int sprintf(char *s, const char *fmt, ...)
+{
+ size_t bos = __builtin_object_size(s, 0);
+ int r;
+
+ if (bos != (size_t)-1) {
+ r = __snprintf_orig(s, bos, fmt, __builtin_va_arg_pack());
+ if (r != -1 && (size_t)r >= bos)
+ __builtin_trap();
+ } else {
+ r = __sprintf_orig(s, fmt, __builtin_va_arg_pack());
+ }
+ return r;
+}
#endif