summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-01-11 15:34:15 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-01-17 14:20:55 +0900
commit4550b4cf832b256d6bca49a5e536c2327bbd5e8c (patch)
treefc8a78df24a6b3e108bd80609e13836c9fd106e1 /src
parent4f5e64fdea88ba7362d77a6d42ea22cf13d3323f (diff)
eina: Introduce Eina_Slstr for short-lived strings
Built on top of the new 'postponed' free queue, the short-lived strings API allows users to return new strings without caring about freeing them. EFL main loop will do this automatically for them you at a later point in time (at the end of an iteration). The APIs provided will either duplicate (copy) or more generally steal an existing string (char *, stringshare, tmpstr, strbuf), taking ownership of it and controling its lifetime. Those strings can then be safely returned by an API. From a user point of view, those strings must be considered like simple const char *, ie. no need to free() them and their validity is limited to the local scope. There is no function to remove such a string from the freeq. The short lived strings API is not thread-safe: do not send a short-lived object from one thread to another. @feature
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Eina.am9
-rw-r--r--src/lib/ecore/ecore_main.c7
-rw-r--r--src/lib/eina/Eina.h1
-rw-r--r--src/lib/eina/eina_freeq.h3
-rw-r--r--src/lib/eina/eina_main.c3
-rw-r--r--src/lib/eina/eina_slstr.c215
-rw-r--r--src/lib/eina/eina_slstr.h179
-rw-r--r--src/tests/eina/eina_suite.c1
-rw-r--r--src/tests/eina/eina_suite.h1
-rw-r--r--src/tests/eina/eina_test_slstr.c208
10 files changed, 623 insertions, 4 deletions
diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am
index 56b195910f..ae3d94ba2f 100644
--- a/src/Makefile_Eina.am
+++ b/src/Makefile_Eina.am
@@ -103,7 +103,8 @@ lib/eina/eina_inline_safepointer.x \
103lib/eina/eina_slice.h \ 103lib/eina/eina_slice.h \
104lib/eina/eina_inline_slice.x \ 104lib/eina/eina_inline_slice.x \
105lib/eina/eina_inline_modinfo.x \ 105lib/eina/eina_inline_modinfo.x \
106lib/eina/eina_freeq.h 106lib/eina/eina_freeq.h \
107lib/eina/eina_slstr.h
107 108
108 109
109lib_eina_libeina_la_SOURCES = \ 110lib_eina_libeina_la_SOURCES = \
@@ -177,7 +178,8 @@ lib/eina/eina_strbuf_common.h \
177lib/eina/eina_quaternion.c \ 178lib/eina/eina_quaternion.c \
178lib/eina/eina_bezier.c \ 179lib/eina/eina_bezier.c \
179lib/eina/eina_safepointer.c \ 180lib/eina/eina_safepointer.c \
180lib/eina/eina_freeq.c 181lib/eina/eina_freeq.c \
182lib/eina/eina_slstr.c
181 183
182 184
183if HAVE_WIN32 185if HAVE_WIN32
@@ -348,7 +350,8 @@ tests/eina/eina_test_vector.c \
348tests/eina/eina_test_bezier.c \ 350tests/eina/eina_test_bezier.c \
349tests/eina/eina_test_safepointer.c \ 351tests/eina/eina_test_safepointer.c \
350tests/eina/eina_test_slice.c \ 352tests/eina/eina_test_slice.c \
351tests/eina/eina_test_freeq.c 353tests/eina/eina_test_freeq.c \
354tests/eina/eina_test_slstr.c
352 355
353tests_eina_eina_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 356tests_eina_eina_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
354-DTESTS_WD=\"`pwd`\" \ 357-DTESTS_WD=\"`pwd`\" \
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 6bff19156f..ebd272d669 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -2,6 +2,8 @@
2# include <config.h> 2# include <config.h>
3#endif 3#endif
4 4
5#define EINA_SLSTR_INTERNAL
6
5#ifdef _WIN32 7#ifdef _WIN32
6# define WIN32_LEAN_AND_MEAN 8# define WIN32_LEAN_AND_MEAN
7# include <winsock2.h> 9# include <winsock2.h>
@@ -2388,6 +2390,11 @@ process_all: /*-*********************************************************/
2388done: /*-*****************************************************************/ 2390done: /*-*****************************************************************/
2389 /* Agressively flush animator */ 2391 /* Agressively flush animator */
2390 _ecore_animator_flush(); 2392 _ecore_animator_flush();
2393 if (!once_only)
2394 {
2395 /* Free all short lived strings */
2396 eina_slstr_local_clear();
2397 }
2391 in_main_loop--; 2398 in_main_loop--;
2392} 2399}
2393 2400
diff --git a/src/lib/eina/Eina.h b/src/lib/eina/Eina.h
index 374e4ecfc2..6a99b4fe68 100644
--- a/src/lib/eina/Eina.h
+++ b/src/lib/eina/Eina.h
@@ -271,6 +271,7 @@ extern "C" {
271#include <eina_safepointer.h> 271#include <eina_safepointer.h>
272#include <eina_slice.h> 272#include <eina_slice.h>
273#include <eina_freeq.h> 273#include <eina_freeq.h>
274#include <eina_slstr.h>
274 275
275#undef EAPI 276#undef EAPI
276#define EAPI 277#define EAPI
diff --git a/src/lib/eina/eina_freeq.h b/src/lib/eina/eina_freeq.h
index 643aa1e5ce..7b34669452 100644
--- a/src/lib/eina/eina_freeq.h
+++ b/src/lib/eina/eina_freeq.h
@@ -89,7 +89,8 @@ typedef enum _Eina_FreeQ_Type
89 * immediately. Use this kind of freeq for debugging and additional memory 89 * immediately. Use this kind of freeq for debugging and additional memory
90 * safety purposes only. 90 * safety purposes only.
91 * 91 *
92 * This type of free queue is thread-safe. 92 * As this type of free queue is thread-safe, the free functions used must
93 * also be thread-safe (eg. libc free()).
93 * 94 *
94 * @since 1.19 95 * @since 1.19
95 */ 96 */
diff --git a/src/lib/eina/eina_main.c b/src/lib/eina/eina_main.c
index ab0aec90b1..c0e2825151 100644
--- a/src/lib/eina/eina_main.c
+++ b/src/lib/eina/eina_main.c
@@ -69,6 +69,7 @@
69#include "eina_value.h" 69#include "eina_value.h"
70#include "eina_evlog.h" 70#include "eina_evlog.h"
71#include "eina_freeq.h" 71#include "eina_freeq.h"
72#include "eina_slstr.h"
72 73
73/*============================================================================* 74/*============================================================================*
74* Local * 75* Local *
@@ -153,6 +154,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
153 S(rbtree); 154 S(rbtree);
154 S(file); 155 S(file);
155 S(safepointer); 156 S(safepointer);
157 S(slstr);
156#undef S 158#undef S
157 159
158struct eina_desc_setup 160struct eina_desc_setup
@@ -198,6 +200,7 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
198 S(rbtree), 200 S(rbtree),
199 S(file), 201 S(file),
200 S(safepointer), 202 S(safepointer),
203 S(slstr),
201#undef S 204#undef S
202}; 205};
203static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / 206static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
diff --git a/src/lib/eina/eina_slstr.c b/src/lib/eina/eina_slstr.c
new file mode 100644
index 0000000000..5367db010f
--- /dev/null
+++ b/src/lib/eina/eina_slstr.c
@@ -0,0 +1,215 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#define EINA_SLSTR_INTERNAL
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include "Eina.h"
12#include "eina_private.h"
13
14// ========================================================================= //
15
16static int _slstr_init = 0;
17static Eina_FreeQ *_slstr_main_fq = NULL;
18static Eina_TLS _slstr_tls = 0;
19
20// ========================================================================= //
21
22#if 0
23// 2 extension ideas here: slices for short-lived raw data buffers
24EAPI Eina_Rw_Slice eina_slslice_new(size_t length); // alloc
25EAPI Eina_Rw_Slice eina_slslice_copy(Eina_Slice slice); // copies
26EAPI Eina_Rw_Slice eina_slslice_free(Eina_Rw_Slice slice); // steals
27#endif
28
29static void
30_slstr_tls_free_cb(void *ptr)
31{
32 Eina_FreeQ *fq = ptr;
33
34 eina_freeq_free(fq);
35}
36
37Eina_Bool
38eina_slstr_init(void)
39{
40 if (_slstr_init++) return EINA_TRUE;
41
42 _slstr_main_fq = eina_freeq_new(EINA_FREEQ_POSTPONED);
43 if (!_slstr_main_fq) goto fail;
44 if (!eina_tls_cb_new(&_slstr_tls, _slstr_tls_free_cb)) goto fail_tls;
45
46 return EINA_TRUE;
47
48fail_tls:
49 eina_tls_free(_slstr_tls);
50 _slstr_tls = 0;
51fail:
52 eina_freeq_free(_slstr_main_fq);
53 _slstr_main_fq = NULL;
54 return EINA_FALSE;
55}
56
57Eina_Bool
58eina_slstr_shutdown(void)
59{
60 if (_slstr_init == 0) return EINA_FALSE;
61 if (--_slstr_init) return EINA_TRUE;
62
63 eina_freeq_free(_slstr_main_fq);
64 eina_tls_free(_slstr_tls);
65 _slstr_main_fq = NULL;
66 _slstr_tls = 0;
67
68 return EINA_TRUE;
69}
70
71static inline Eina_FreeQ *
72_slstr_freeq_get(Eina_Bool nocreate)
73{
74 if (eina_main_loop_is())
75 return _slstr_main_fq;
76 else
77 {
78 Eina_FreeQ *fq;
79
80 fq = eina_tls_get(_slstr_tls);
81 if (!nocreate && EINA_UNLIKELY(!fq))
82 {
83 fq = eina_freeq_new(EINA_FREEQ_POSTPONED);
84 eina_tls_set(_slstr_tls, fq);
85 }
86 return fq;
87 }
88}
89
90EAPI Eina_Slstr *
91eina_slstr_copy_new(const char *string)
92{
93 Eina_FreeQ *fq;
94 char *copy;
95 size_t len = 0;
96
97 if (!string) return NULL;
98
99 fq = _slstr_freeq_get(EINA_FALSE);
100 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
101
102 copy = eina_strdup(string);
103 if (!copy) return NULL;
104#ifdef DEBUG
105 len = strlen(string) + 1;
106#endif
107 eina_freeq_ptr_add(fq, copy, free, len);
108 return copy;
109}
110
111EAPI Eina_Slstr *
112eina_slstr_steal_new(char *string)
113{
114 Eina_FreeQ *fq;
115 size_t len = 0;
116
117 if (!string) return NULL;
118
119 fq = _slstr_freeq_get(EINA_FALSE);
120 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
121
122#ifdef DEBUG
123 len = strlen(string) + 1;
124#endif
125 eina_freeq_ptr_add(fq, string, free, len);
126 return string;
127}
128
129EAPI Eina_Slstr *
130eina_slstr_stringshare_new(Eina_Stringshare *string)
131{
132 Eina_FreeQ *fq;
133 size_t len = 0;
134
135 if (!string) return NULL;
136
137 fq = _slstr_freeq_get(EINA_FALSE);
138 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
139
140#ifdef DEBUG
141 len = eina_stringshare_strlen(string) + 1;
142#endif
143 eina_freeq_ptr_add(fq, (void *) string, EINA_FREE_CB(eina_stringshare_del), len);
144 return string;
145}
146
147EAPI Eina_Slstr *
148eina_slstr_tmpstr_new(Eina_Tmpstr *string)
149{
150 Eina_FreeQ *fq;
151 size_t len = 0;
152
153 if (!string) return NULL;
154
155 fq = _slstr_freeq_get(EINA_FALSE);
156 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
157
158#ifdef DEBUG
159 len = eina_tmpstr_strlen(string) + 1;
160#endif
161 eina_freeq_ptr_add(fq, (void *) string, EINA_FREE_CB(eina_tmpstr_del), len);
162 return string;
163}
164
165EAPI Eina_Slstr *
166eina_slstr_strbuf_new(Eina_Strbuf *string)
167{
168 Eina_FreeQ *fq;
169 size_t len = 0;
170 char *str;
171
172 if (!string) return NULL;
173
174 fq = _slstr_freeq_get(EINA_FALSE);
175 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
176
177 str = eina_strbuf_release(string);
178#ifdef DEBUG
179 len = eina_strbuf_length_get(string) + 1;
180#endif
181 eina_freeq_ptr_add(fq, str, free, len);
182 return str;
183}
184
185EAPI Eina_Slstr *
186eina_slstr_vasprintf_new(const char *fmt, va_list args)
187{
188 Eina_FreeQ *fq;
189 size_t len = 0;
190 char *str;
191 int r;
192
193 fq = _slstr_freeq_get(EINA_FALSE);
194 EINA_SAFETY_ON_NULL_RETURN_VAL(fq, NULL);
195
196 r = vasprintf(&str, fmt, args);
197 if (r == -1) return NULL;
198
199#ifdef DEBUG
200 len = r + 1;
201#endif
202 eina_freeq_ptr_add(fq, str, free, len);
203 return str;
204}
205
206EAPI void
207eina_slstr_local_clear(void)
208{
209 Eina_FreeQ *fq;
210
211 fq = _slstr_freeq_get(EINA_TRUE);
212 if (!fq) return;
213
214 eina_freeq_clear(fq);
215}
diff --git a/src/lib/eina/eina_slstr.h b/src/lib/eina/eina_slstr.h
new file mode 100644
index 0000000000..0e5d66e310
--- /dev/null
+++ b/src/lib/eina/eina_slstr.h
@@ -0,0 +1,179 @@
1#ifndef EINA_SLSTR_H_
2#define EINA_SLSTR_H_
3
4#include <stdlib.h>
5
6#include "eina_config.h"
7
8#include "eina_types.h"
9#include "eina_tmpstr.h"
10#include "eina_strbuf.h"
11#include "eina_stringshare.h"
12#include "eina_slice.h"
13
14/**
15 * @addtogroup Eina_Slstr Short lived strings
16 * @ingroup Eina
17 *
18 * @brief API for short lived strings (thread- and scope-local)
19 *
20 * This set of APIs provide a convenience feature to create and return strings
21 * that are meant to be consumed in the local scope of the calling code block.
22 * The lifecycle of those strings is bound to the loop of the current thread
23 * or until the clear function is called explicitely.
24 *
25 * These strings will be automatically deleted.
26 *
27 * These functions shall return NULL only if out of memory.
28 *
29 * Do not call free or any similar function on a string created with this API!
30 *
31 * @since 1.19
32 */
33
34typedef const char Eina_Slstr;
35
36/**
37 * @brief Create a new short lived string by duplicating another string.
38 *
39 * @param string An existing string, it will be copied.
40 * @return A new Eina_Slstr or NULL if out of memory.
41 *
42 * Usage example:
43 * @code
44 * char local[200];
45 * sprintf(local, "Hello %d", value);
46 * return eina_slstr_copy_new(local);
47 * @endcode
48 *
49 * @since 1.19
50 */
51EAPI Eina_Slstr *
52eina_slstr_copy_new(const char *string);
53
54/**
55 * @brief Create a new short lived string by taking ownership of a string.
56 *
57 * @param string An existing string. It will not be duplicated.
58 * @return A new Eina_Slstr or NULL if out of memory.
59 *
60 * Usage example:
61 * @code
62 * char *local = strdup("Hello");
63 * return eina_slstr_steal_new(local);
64 * @endcode
65 *
66 * @since 1.19
67 */
68EAPI Eina_Slstr *
69eina_slstr_steal_new(char *string);
70
71/**
72 * @brief Create a new short lived string by taking ownership of a stringshare.
73 *
74 * @param string An existing stringshare, one reference belongs to this slstr.
75 * @return A new Eina_Slstr or NULL if out of memory.
76 *
77 * Usage example:
78 * @code
79 * Eina_Stringshare *local = eina_stringshare_add("Hello");
80 * return eina_slstr_stringshare_new(local);
81 * @endcode
82 *
83 * @since 1.19
84 */
85EAPI Eina_Slstr *
86eina_slstr_stringshare_new(Eina_Stringshare *string);
87
88/**
89 * @brief Create a new short lived string by taking ownership of a tmpstr.
90 *
91 * @param string An existing tmpstr, it will be freed later.
92 * @return A new Eina_Slstr or NULL if out of memory.
93 *
94 * Usage example:
95 * @code
96 * Eina_Tmpstr *local = eina_tmpstr_add("Hello");
97 * return eina_slstr_tmpstr_new(local);
98 * @endcode
99 *
100 * @since 1.19
101 */
102EAPI Eina_Slstr *
103eina_slstr_tmpstr_new(Eina_Tmpstr *string);
104
105/**
106 * @brief Create a new short lived string by taking ownership of a strbuf.
107 *
108 * @param string An existing strbuf, that will be released (ie. steal + free).
109 * @return A new Eina_Slstr or NULL if out of memory.
110 *
111 * Usage example:
112 * @code
113 * Eina_Strbuf *local = eina_strbuf_new();
114 * eina_strbuf_append(local, "Hello");
115 * eina_strbuf_append(local, " world");
116 * return eina_slstr_strbuf_new(local);
117 * @endcode
118 *
119 * @note Use eina_slstr_steal_new() if the strbuf will be used after this call.
120 *
121 * @since 1.19
122 */
123EAPI Eina_Slstr *
124eina_slstr_strbuf_new(Eina_Strbuf *string);
125
126/**
127 * @brief Create a new short lived string using sprintf.
128 *
129 * @param fmt Format string for printf
130 * @param args List of format parameters for printf
131 * @return A new Eina_Slstr or NULL if out of memory.
132 *
133 * @since 1.19
134 */
135EAPI Eina_Slstr *
136eina_slstr_vasprintf_new(const char *fmt, va_list args);
137
138/**
139 * @brief Create a new short lived string using sprintf.
140 *
141 * @param fmt Format string for printf
142 * @param args List of format parameters for printf
143 * @return A new Eina_Slstr or NULL if out of memory.
144 *
145 * Usage example:
146 * @code
147 * return eina_slstr_printf("Hello world %d!", 42);
148 * @endcode
149 *
150 * @since 1.19
151 */
152static inline Eina_Slstr *
153eina_slstr_printf(const char *fmt, ...)
154{
155 Eina_Slstr *str;
156 va_list args;
157
158 va_start(args, fmt);
159 str = eina_slstr_vasprintf_new(fmt, args);
160 va_end(args);
161
162 return str;
163}
164
165#ifdef EINA_SLSTR_INTERNAL
166/**
167 * @brief Internal function to clear the strings.
168 *
169 * This internal function will be called by the local thread's loop to free
170 * all the strings. Do not call this function unless you are absolutely certain
171 * that no string in the queue will be used after this point.
172 *
173 * @since 1.19
174 */
175EAPI void
176eina_slstr_local_clear(void);
177#endif
178
179#endif
diff --git a/src/tests/eina/eina_suite.c b/src/tests/eina/eina_suite.c
index 5cb67f909e..e7e1b623d9 100644
--- a/src/tests/eina/eina_suite.c
+++ b/src/tests/eina/eina_suite.c
@@ -86,6 +86,7 @@ static const Efl_Test_Case etc[] = {
86 { "Slice", eina_test_slice }, 86 { "Slice", eina_test_slice },
87 { "Free Queue", eina_test_freeq }, 87 { "Free Queue", eina_test_freeq },
88 { "Util", eina_test_util }, 88 { "Util", eina_test_util },
89 { "Short Lived Strings", eina_test_slstr },
89 { NULL, NULL } 90 { NULL, NULL }
90}; 91};
91 92
diff --git a/src/tests/eina/eina_suite.h b/src/tests/eina/eina_suite.h
index 6f46580aa5..7bf643e478 100644
--- a/src/tests/eina/eina_suite.h
+++ b/src/tests/eina/eina_suite.h
@@ -73,5 +73,6 @@ void eina_test_bezier(TCase *tc);
73void eina_test_safepointer(TCase *tc); 73void eina_test_safepointer(TCase *tc);
74void eina_test_slice(TCase *tc); 74void eina_test_slice(TCase *tc);
75void eina_test_freeq(TCase *tc); 75void eina_test_freeq(TCase *tc);
76void eina_test_slstr(TCase *tc);
76 77
77#endif /* EINA_SUITE_H_ */ 78#endif /* EINA_SUITE_H_ */
diff --git a/src/tests/eina/eina_test_slstr.c b/src/tests/eina/eina_test_slstr.c
new file mode 100644
index 0000000000..d7778a23bc
--- /dev/null
+++ b/src/tests/eina/eina_test_slstr.c
@@ -0,0 +1,208 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#define EINA_SLSTR_INTERNAL
6#include <Eina.h>
7
8#include "eina_suite.h"
9
10static Eina_Slstr *
11_slstr_copy(void)
12{
13 const char local[] = "Hello world 1";
14
15 return eina_slstr_copy_new(local);
16}
17
18START_TEST(slstr_copy)
19{
20 Eina_Slstr *str;
21
22 eina_init();
23
24 str = _slstr_copy();
25 ck_assert_str_eq(str, "Hello world 1");
26
27 eina_shutdown();
28}
29END_TEST
30
31static Eina_Slstr *
32_slstr_steal(void)
33{
34 char *local = strdup("Hello world 2");
35
36 return eina_slstr_copy_new(local);
37}
38
39START_TEST(slstr_steal)
40{
41 Eina_Slstr *str;
42
43 eina_init();
44
45 str = _slstr_steal();
46 ck_assert_str_eq(str, "Hello world 2");
47
48 eina_shutdown();
49}
50END_TEST
51
52static Eina_Slstr *
53_slstr_stringshare(void)
54{
55 Eina_Stringshare *str = eina_stringshare_add("Hello world 3");
56
57 return eina_slstr_stringshare_new(str);
58}
59
60START_TEST(slstr_stringshare)
61{
62 Eina_Stringshare *ss;
63 Eina_Slstr *str;
64
65 eina_init();
66
67 str = _slstr_stringshare();
68 ss = eina_stringshare_add("Hello world 3");
69 fail_if(ss != str);
70
71 eina_shutdown();
72}
73END_TEST
74
75static Eina_Slstr *
76_slstr_tmpstr(void)
77{
78 Eina_Tmpstr *str = eina_tmpstr_add("Hello world 4");
79
80 return eina_slstr_tmpstr_new(str);
81}
82
83START_TEST(slstr_tmpstr)
84{
85 Eina_Slstr *str;
86
87 eina_init();
88
89 str = _slstr_tmpstr();
90 ck_assert_str_eq(str, "Hello world 4");
91
92 eina_shutdown();
93}
94END_TEST
95
96static Eina_Slstr *
97_slstr_strbuf(void)
98{
99 Eina_Strbuf *str = eina_strbuf_new();
100
101 eina_strbuf_append(str, "Hello ");
102 eina_strbuf_append(str, "world ");
103 eina_strbuf_append_printf(str, "%d", 5);
104
105 return eina_slstr_strbuf_new(str);
106}
107
108START_TEST(slstr_strbuf)
109{
110 Eina_Slstr *str;
111
112 eina_init();
113
114 str = _slstr_strbuf();
115 ck_assert_str_eq(str, "Hello world 5");
116
117 eina_shutdown();
118}
119END_TEST
120
121static Eina_Slstr *
122_slstr_printf(int val)
123{
124 return eina_slstr_printf("Hello %s %d", "world", val);
125}
126
127START_TEST(slstr_slstr_printf)
128{
129 Eina_Slstr *str;
130
131 eina_init();
132
133 str = _slstr_printf(6);
134 ck_assert_str_eq(str, "Hello world 6");
135
136 eina_shutdown();
137}
138END_TEST
139
140static void
141_many_do(void)
142{
143 const int many = 2048;
144 Eina_Slstr *str;
145 int k;
146
147 for (k = 0; k < many; k++)
148 {
149 char local[64];
150
151 str = _slstr_printf(k);
152 sprintf(local, "Hello world %d", k);
153 ck_assert_str_eq(str, local);
154 }
155}
156
157START_TEST(slstr_many)
158{
159 eina_init();
160
161 _many_do();
162
163 eina_slstr_local_clear();
164
165 eina_shutdown();
166}
167END_TEST
168
169static void *
170_thread_cb(void *data EINA_UNUSED, Eina_Thread th EINA_UNUSED)
171{
172 _many_do();
173
174 return NULL;
175}
176
177START_TEST(slstr_thread)
178{
179 const int threads = 8;
180 Eina_Thread th[threads];
181 int k;
182
183 eina_init();
184
185 for (k = 0; k < threads; k++)
186 fail_if(!eina_thread_create(&th[k], EINA_THREAD_NORMAL, -1, _thread_cb, NULL));
187
188 for (k = 0; k < threads; k++)
189 eina_thread_join(th[k]);
190
191 eina_slstr_local_clear();
192
193 eina_shutdown();
194}
195END_TEST
196
197void
198eina_test_slstr(TCase *tc)
199{
200 tcase_add_test(tc, slstr_copy);
201 tcase_add_test(tc, slstr_steal);
202 tcase_add_test(tc, slstr_stringshare);
203 tcase_add_test(tc, slstr_tmpstr);
204 tcase_add_test(tc, slstr_strbuf);
205 tcase_add_test(tc, slstr_slstr_printf);
206 tcase_add_test(tc, slstr_many);
207 tcase_add_test(tc, slstr_thread);
208}