56 #define ST(s) { (char*)s, sizeof(s)-1 } |
56 #define ST(s) { (char*)s, sizeof(s)-1 } |
57 |
57 |
58 /** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */ |
58 /** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */ |
59 #define S(s) sstrn((char*)s, sizeof(s)-1) |
59 #define S(s) sstrn((char*)s, sizeof(s)-1) |
60 |
60 |
61 /** Expands a sstr_t to printf arguments. */ |
61 /** Expands a sstr_t or scstr_t to printf arguments. */ |
62 #define SFMT(s) (int) (s).length, (s).ptr |
62 #define SFMT(s) (int) (s).length, (s).ptr |
63 |
63 |
64 /** Format specifier for a sstr_t. */ |
64 /** Format specifier for a sstr_t or scstr_t. */ |
65 #define PRIsstr ".*s" |
65 #define PRIsstr ".*s" |
66 |
66 |
67 #ifdef __cplusplus |
67 #ifdef __cplusplus |
68 extern "C" { |
68 extern "C" { |
69 #endif |
69 #endif |
70 /** |
70 /** |
71 * The UCX string structure. |
71 * The UCX string structure. |
72 */ |
72 */ |
73 typedef struct { |
73 typedef struct { |
74 /** A reference to the string (<b>not necessarily <code>NULL</code> |
74 /** A pointer to the string |
75 * -terminated</b>) */ |
75 * (<b>not necessarily <code>NULL</code>-terminated</b>) */ |
76 char *ptr; |
76 char *ptr; |
77 /** The length of the string */ |
77 /** The length of the string */ |
78 size_t length; |
78 size_t length; |
79 } sstr_t; |
79 } sstr_t; |
80 |
80 |
|
81 /** |
|
82 * The UCX string structure for immutable (constant) strings. |
|
83 */ |
81 typedef struct { |
84 typedef struct { |
|
85 /** A constant pointer to the immutable string |
|
86 * (<b>not necessarily <code>NULL</code>-terminated</b>) */ |
82 const char *ptr; |
87 const char *ptr; |
83 size_t length; |
88 /** The length of the string */ |
|
89 size_t length; |
84 } scstr_t; |
90 } scstr_t; |
85 |
91 |
86 #ifdef __cplusplus |
92 #ifdef __cplusplus |
87 } |
93 } |
88 #endif |
94 #endif |
99 return c; |
105 return c; |
100 } |
106 } |
101 #define SCSTR s2scstr |
107 #define SCSTR s2scstr |
102 #else |
108 #else |
103 |
109 |
104 scstr_t ucx_sc2sc(scstr_t c); |
110 /** |
|
111 * One of two type adjustment functions that return a scstr_t. |
|
112 * |
|
113 * Used internally to cast a UCX string to an immutable UCX string. |
|
114 * This variant is used, when the string is already immutable and no operation |
|
115 * needs to be performed. |
|
116 * |
|
117 * @param str some scstr_t |
|
118 * @return the argument itself |
|
119 */ |
|
120 scstr_t ucx_sc2sc(scstr_t str); |
|
121 |
|
122 /** |
|
123 * One of two type adjustment functions that return a scstr_t. |
|
124 * |
|
125 * Used internally to cast a UCX string to an immutable UCX string. |
|
126 * |
|
127 * @param str some sstr_t |
|
128 * @return an immutable (scstr_t) version of the provided string. |
|
129 */ |
105 scstr_t ucx_ss2sc(sstr_t str); |
130 scstr_t ucx_ss2sc(sstr_t str); |
|
131 |
106 #if __STDC_VERSION__ >= 201112L |
132 #if __STDC_VERSION__ >= 201112L |
|
133 /** |
|
134 * Casts a UCX string to an immutable UCX string (scstr_t). |
|
135 * @param str some UCX string |
|
136 * @return the an immutable version of the provided string |
|
137 */ |
107 #define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str) |
138 #define SCSTR(str) _Generic(str, sstr_t: ucx_ss2sc, scstr_t: ucx_sc2sc)(str) |
|
139 |
108 #elif defined(__GNUC__) || defined(__clang__) |
140 #elif defined(__GNUC__) || defined(__clang__) |
|
141 |
|
142 /** |
|
143 * Casts a UCX string to an immutable UCX string (scstr_t). |
|
144 * @param str some UCX string |
|
145 * @return the an immutable version of the provided string |
|
146 */ |
109 #define SCSTR(str) __builtin_choose_expr( \ |
147 #define SCSTR(str) __builtin_choose_expr( \ |
110 __builtin_types_compatible_p(typeof(str), sstr_t), \ |
148 __builtin_types_compatible_p(typeof(str), sstr_t), \ |
111 ucx_ss2sc, \ |
149 ucx_ss2sc, \ |
112 ucx_sc2sc)(str) |
150 ucx_sc2sc)(str) |
|
151 |
113 #elif defined(__sun) |
152 #elif defined(__sun) |
|
153 |
|
154 /** |
|
155 * Casts a UCX string to an immutable UCX string (scstr_t). |
|
156 * @param str some UCX string |
|
157 * @return the an immutable version of the provided string |
|
158 */ |
114 #define SCSTR(str) ({typeof(str) ucx_tmp_var_str = str; \ |
159 #define SCSTR(str) ({typeof(str) ucx_tmp_var_str = str; \ |
115 scstr_t ucx_tmp_var_c; \ |
160 scstr_t ucx_tmp_var_c; \ |
116 ucx_tmp_var_c.ptr = ucx_tmp_var_str.ptr;\ |
161 ucx_tmp_var_c.ptr = ucx_tmp_var_str.ptr;\ |
117 ucx_tmp_var_c.length = ucx_tmp_var_str.length;\ |
162 ucx_tmp_var_c.length = ucx_tmp_var_str.length;\ |
118 ucx_tmp_var_c; }) |
163 ucx_tmp_var_c; }) |
119 #else |
164 #else /* no generics and no builtins */ |
|
165 |
|
166 /** |
|
167 * Casts a UCX string to an immutable UCX string (scstr_t). |
|
168 * |
|
169 * This internal function (ab)uses the C standard an expects one single |
|
170 * argument which is then implicitly casted to scstr_t without a warning. |
|
171 * |
|
172 * @return the an immutable version of the provided string |
|
173 */ |
120 scstr_t ucx_ss2c_s(); |
174 scstr_t ucx_ss2c_s(); |
121 #define SCSTR ucx_ss2c_s |
175 |
|
176 /** |
|
177 * Casts a UCX string to an immutable UCX string (scstr_t). |
|
178 * @param str some UCX string |
|
179 * @return the an immutable version of the provided string |
|
180 */ |
|
181 #define SCSTR(str) ucx_ss2c_s(str) |
122 #endif /* C11 feature test */ |
182 #endif /* C11 feature test */ |
123 |
183 |
124 #endif /* C++ */ |
184 #endif /* C++ */ |
125 |
185 |
126 #ifdef __cplusplus |
186 #ifdef __cplusplus |
134 * The length is implicitly inferred by using a call to <code>strlen()</code>. |
194 * The length is implicitly inferred by using a call to <code>strlen()</code>. |
135 * |
195 * |
136 * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you |
196 * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you |
137 * do want a copy, use sstrdup() on the return value of this function. |
197 * do want a copy, use sstrdup() on the return value of this function. |
138 * |
198 * |
|
199 * If you need to wrap a constant string, use scstr(). |
|
200 * |
139 * @param cstring the C string to wrap |
201 * @param cstring the C string to wrap |
140 * @return a new sstr_t containing the C string |
202 * @return a new sstr_t containing the C string |
141 * |
203 * |
142 * @see sstrn() |
204 * @see sstrn() |
143 */ |
205 */ |
146 /** |
208 /** |
147 * Creates a new sstr_t of the specified length based on a C string. |
209 * Creates a new sstr_t of the specified length based on a C string. |
148 * |
210 * |
149 * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you |
211 * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you |
150 * do want a copy, use sstrdup() on the return value of this function. |
212 * do want a copy, use sstrdup() on the return value of this function. |
|
213 * |
|
214 * If you need to wrap a constant string, use scstrn(). |
151 * |
215 * |
152 * @param cstring the C string to wrap |
216 * @param cstring the C string to wrap |
153 * @param length the length of the string |
217 * @param length the length of the string |
154 * @return a new sstr_t containing the C string |
218 * @return a new sstr_t containing the C string |
155 * |
219 * |
156 * @see sstr() |
220 * @see sstr() |
157 * @see S() |
221 * @see S() |
158 */ |
222 */ |
159 sstr_t sstrn(char *cstring, size_t length); |
223 sstr_t sstrn(char *cstring, size_t length); |
160 |
224 |
161 |
225 /** |
|
226 * Creates a new scstr_t based on a constant C string. |
|
227 * |
|
228 * The length is implicitly inferred by using a call to <code>strlen()</code>. |
|
229 * |
|
230 * <b>Note:</b> the scstr_t will hold a <i>reference</i> to the C string. If you |
|
231 * do want a copy, use scstrdup() on the return value of this function. |
|
232 * |
|
233 * @param cstring the C string to wrap |
|
234 * @return a new scstr_t containing the C string |
|
235 * |
|
236 * @see scstrn() |
|
237 */ |
162 scstr_t scstr(const char *cstring); |
238 scstr_t scstr(const char *cstring); |
|
239 |
|
240 |
|
241 /** |
|
242 * Creates a new scstr_t of the specified length based on a constant C string. |
|
243 * |
|
244 * <b>Note:</b> the scstr_t will hold a <i>reference</i> to the C string. If you |
|
245 * do want a copy, use scstrdup() on the return value of this function. |
|
246 * |
|
247 * |
|
248 * @param cstring the C string to wrap |
|
249 * @param length the length of the string |
|
250 * @return a new scstr_t containing the C string |
|
251 * |
|
252 * @see scstr() |
|
253 */ |
163 scstr_t scstrn(const char *cstring, size_t length); |
254 scstr_t scstrn(const char *cstring, size_t length); |
164 |
255 |
165 /** |
256 /** |
166 * Returns the cumulated length of all specified strings. |
257 * Returns the cumulated length of all specified strings. |
167 * |
258 * |
431 * The new sstr_t will contain a copy allocated by standard |
522 * The new sstr_t will contain a copy allocated by standard |
432 * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to |
523 * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to |
433 * <code>free()</code>. |
524 * <code>free()</code>. |
434 * |
525 * |
435 * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- |
526 * The sstr_t.ptr of the return value will <i>always</i> be <code>NULL</code>- |
436 * terminated. |
527 * terminated and mutable. |
437 * |
528 * |
438 * @param string the string to duplicate |
529 * @param string the string to duplicate |
439 * @return a duplicate of the string |
530 * @return a duplicate of the string |
440 * @see sstrdup_a() |
531 * @see sstrdup_a() |
441 */ |
532 */ |