From 6aacfdf27f82a17e046e73a95ce2f8f398766d8a Mon Sep 17 00:00:00 2001
From: Sergei Trofimovich <slyfox@inbox.ru>
Date: Tue, 3 Feb 2009 22:40:31 +0200
Subject: [PATCH] cleanup: mhl_str_concat(): reduced stack usage, removed argument limit
Signed-off-by: Sergei Trofimovich <slyfox@inbox.ru>
---
mhl/string.h | 62 +++++++++++++++++++++++++++------------------------------
1 files changed, 29 insertions(+), 33 deletions(-)
diff --git a/mhl/string.h b/mhl/string.h
index fcbbd86..47f097f 100644
a
|
b
|
static inline void mhl_str_toupper(char* str) |
51 | 51 | *str = toupper(*str); |
52 | 52 | } |
53 | 53 | |
54 | | #define __STR_CONCAT_MAX 32 |
| 54 | /* note: we use ((char*)(1)) as terminator - NULL is a valid argument ! */ |
| 55 | static const char * mhl_s_c_sep__ = (const char *)1; |
55 | 56 | /* _NEVER_ call this function directly ! */ |
56 | | static inline char* __mhl_str_concat_hlp(const char* base, ...) |
| 57 | static inline char* mhl_str_concat_hlp__(const char* va_start_dummy, ...) |
57 | 58 | { |
58 | | static const char* arg_ptr[__STR_CONCAT_MAX]; |
59 | | static size_t arg_sz[__STR_CONCAT_MAX]; |
60 | | int count = 0; |
61 | | size_t totalsize = 0; |
62 | | |
63 | | if (base) |
64 | | { |
65 | | arg_ptr[0] = base; |
66 | | arg_sz[0] = totalsize = strlen(base); |
67 | | count = 1; |
68 | | } |
| 59 | char * result; |
| 60 | size_t result_len = 0; |
| 61 | char * p; |
| 62 | const char * chunk; |
69 | 63 | |
70 | 64 | va_list args; |
71 | | va_start(args,base); |
72 | | char* a; |
73 | | /* note: we use ((char*)(1)) as terminator - NULL is a valid argument ! */ |
74 | | while ((a = va_arg(args, char*))!=(char*)1 && count < __STR_CONCAT_MAX ) |
| 65 | va_start(args,va_start_dummy); |
| 66 | while ((chunk = va_arg(args, const char*)) != mhl_s_c_sep__) |
75 | 67 | { |
76 | | if (a) |
| 68 | if (chunk) |
77 | 69 | { |
78 | | arg_ptr[count] = a; |
79 | | arg_sz[count] = strlen(a); |
80 | | totalsize += arg_sz[count]; |
81 | | count++; |
| 70 | result_len += strlen (chunk); |
82 | 71 | } |
83 | 72 | } |
84 | 73 | va_end(args); |
85 | 74 | |
86 | | if (!count) |
| 75 | if (result_len == 0) |
87 | 76 | return mhl_str_dup(""); |
88 | 77 | |
89 | | /* now as we know how much to copy, allocate the buffer */ |
90 | | char* buffer = (char*)mhl_mem_alloc_u(totalsize+2); |
91 | | char* current = buffer; |
92 | | int x=0; |
93 | | for (x=0; x<count; x++) |
| 78 | /* now as we know how much to copy, allocate the buffer + '\0'*/ |
| 79 | result = (char*)mhl_mem_alloc_u (result_len + 1); |
| 80 | |
| 81 | p = result; |
| 82 | |
| 83 | va_start(args,va_start_dummy); |
| 84 | while ((chunk = va_arg(args, const char*)) != mhl_s_c_sep__) |
94 | 85 | { |
95 | | memcpy(current, arg_ptr[x], arg_sz[x]); |
96 | | current += arg_sz[x]; |
| 86 | if (chunk) |
| 87 | { |
| 88 | size_t chunk_len = strlen (chunk); |
| 89 | memcpy (p, chunk, chunk_len); |
| 90 | p += chunk_len; |
| 91 | } |
97 | 92 | } |
| 93 | va_end(args); |
98 | 94 | |
99 | | *current = 0; |
100 | | return buffer; |
| 95 | *p = '\0'; |
| 96 | return result; |
101 | 97 | } |
102 | 98 | |
103 | | #define mhl_str_concat(...) (__mhl_str_concat_hlp(__VA_ARGS__, (char*)(1))) |
| 99 | #define mhl_str_concat(...) (mhl_str_concat_hlp__(mhl_s_c_sep__, __VA_ARGS__, mhl_s_c_sep__)) |
104 | 100 | |
105 | 101 | static inline char* mhl_str_reverse(char* ptr) |
106 | 102 | { |