diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/eina/src/lib/eina_convert.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/eina/src/lib/eina_convert.c')
-rw-r--r-- | libraries/eina/src/lib/eina_convert.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_convert.c b/libraries/eina/src/lib/eina_convert.c new file mode 100644 index 0000000..63b6654 --- /dev/null +++ b/libraries/eina/src/lib/eina_convert.c | |||
@@ -0,0 +1,483 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric BAIL, Vincent Torri | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <math.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <stdio.h> | ||
27 | |||
28 | #ifdef HAVE_EVIL | ||
29 | # include <Evil.h> | ||
30 | #endif | ||
31 | |||
32 | #include "eina_config.h" | ||
33 | #include "eina_private.h" | ||
34 | #include "eina_log.h" | ||
35 | |||
36 | /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ | ||
37 | #include "eina_safety_checks.h" | ||
38 | #include "eina_convert.h" | ||
39 | #include "eina_fp.h" | ||
40 | |||
41 | /*============================================================================* | ||
42 | * Local * | ||
43 | *============================================================================*/ | ||
44 | |||
45 | /** | ||
46 | * @cond LOCAL | ||
47 | */ | ||
48 | |||
49 | static const char look_up_table[] = {'0', '1', '2', '3', '4', | ||
50 | '5', '6', '7', '8', '9', | ||
51 | 'a', 'b', 'c', 'd', 'e', 'f'}; | ||
52 | static int _eina_convert_log_dom = -1; | ||
53 | |||
54 | #ifdef ERR | ||
55 | #undef ERR | ||
56 | #endif | ||
57 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_convert_log_dom, __VA_ARGS__) | ||
58 | |||
59 | #ifdef DBG | ||
60 | #undef DBG | ||
61 | #endif | ||
62 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_convert_log_dom, __VA_ARGS__) | ||
63 | |||
64 | #define HEXA_TO_INT(Hexa) (Hexa >= 'a') ? Hexa - 'a' + 10 : Hexa - '0' | ||
65 | |||
66 | static inline void reverse(char s[], int length) | ||
67 | { | ||
68 | int i, j; | ||
69 | char c; | ||
70 | |||
71 | for (i = 0, j = length - 1; i < j; i++, j--) | ||
72 | { | ||
73 | c = s[i]; | ||
74 | s[i] = s[j]; | ||
75 | s[j] = c; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * @endcond | ||
81 | */ | ||
82 | |||
83 | /*============================================================================* | ||
84 | * Global * | ||
85 | *============================================================================*/ | ||
86 | |||
87 | /** | ||
88 | * @cond LOCAL | ||
89 | */ | ||
90 | |||
91 | EAPI Eina_Error EINA_ERROR_CONVERT_P_NOT_FOUND = 0; | ||
92 | EAPI Eina_Error EINA_ERROR_CONVERT_0X_NOT_FOUND = 0; | ||
93 | EAPI Eina_Error EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = 0; | ||
94 | |||
95 | static const char EINA_ERROR_CONVERT_0X_NOT_FOUND_STR[] = | ||
96 | "Error during string conversion to float, First '0x' was not found."; | ||
97 | static const char EINA_ERROR_CONVERT_P_NOT_FOUND_STR[] = | ||
98 | "Error during string conversion to float, First 'p' was not found."; | ||
99 | static const char EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH_STR[] = | ||
100 | "Error outrun string limit during conversion string conversion to float."; | ||
101 | |||
102 | /** | ||
103 | * @endcond | ||
104 | */ | ||
105 | |||
106 | /** | ||
107 | * @internal | ||
108 | * @brief Initialize the convert module. | ||
109 | * | ||
110 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
111 | * | ||
112 | * This function sets up the convert module of Eina. It is called by | ||
113 | * eina_init(). | ||
114 | * | ||
115 | * This function sets up the error module of Eina and registers the | ||
116 | * errors #EINA_ERROR_CONVERT_0X_NOT_FOUND, | ||
117 | * #EINA_ERROR_CONVERT_P_NOT_FOUND and | ||
118 | * #EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH. | ||
119 | * | ||
120 | * @see eina_init() | ||
121 | */ | ||
122 | Eina_Bool | ||
123 | eina_convert_init(void) | ||
124 | { | ||
125 | _eina_convert_log_dom = eina_log_domain_register("eina_convert", | ||
126 | EINA_LOG_COLOR_DEFAULT); | ||
127 | if (_eina_convert_log_dom < 0) | ||
128 | { | ||
129 | EINA_LOG_ERR("Could not register log domain: eina_convert"); | ||
130 | return EINA_FALSE; | ||
131 | } | ||
132 | |||
133 | #define EEMR(n) n = eina_error_msg_static_register(n ## _STR) | ||
134 | EEMR(EINA_ERROR_CONVERT_0X_NOT_FOUND); | ||
135 | EEMR(EINA_ERROR_CONVERT_P_NOT_FOUND); | ||
136 | EEMR(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); | ||
137 | #undef EEMR | ||
138 | |||
139 | return EINA_TRUE; | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * @internal | ||
144 | * @brief Shut down the convert module. | ||
145 | * | ||
146 | * @return #EINA_TRUE on success, #EINA_FALSE on failure. | ||
147 | * | ||
148 | * This function shuts down the convert module set up by | ||
149 | * eina_convert_init(). It is called by eina_shutdown(). | ||
150 | * | ||
151 | * @see eina_shutdown() | ||
152 | */ | ||
153 | Eina_Bool | ||
154 | eina_convert_shutdown(void) | ||
155 | { | ||
156 | eina_log_domain_unregister(_eina_convert_log_dom); | ||
157 | _eina_convert_log_dom = -1; | ||
158 | return EINA_TRUE; | ||
159 | } | ||
160 | |||
161 | /*============================================================================* | ||
162 | * API * | ||
163 | *============================================================================*/ | ||
164 | |||
165 | /* | ||
166 | * Come from the second edition of The C Programming Language ("K&R2") on page 64 | ||
167 | */ | ||
168 | |||
169 | EAPI int | ||
170 | eina_convert_itoa(int n, char *s) | ||
171 | { | ||
172 | int i = 0; | ||
173 | int r = 0; | ||
174 | |||
175 | EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); | ||
176 | |||
177 | if (n < 0) | ||
178 | { | ||
179 | n = -n; | ||
180 | *s++ = '-'; | ||
181 | r = 1; | ||
182 | } | ||
183 | |||
184 | do { | ||
185 | s[i++] = n % 10 + '0'; | ||
186 | } while ((n /= 10) > 0); | ||
187 | |||
188 | s[i] = '\0'; | ||
189 | |||
190 | reverse(s, i); | ||
191 | |||
192 | return i + r; | ||
193 | } | ||
194 | |||
195 | EAPI int | ||
196 | eina_convert_xtoa(unsigned int n, char *s) | ||
197 | { | ||
198 | int i; | ||
199 | |||
200 | EINA_SAFETY_ON_NULL_RETURN_VAL(s, 0); | ||
201 | |||
202 | i = 0; | ||
203 | do { | ||
204 | s[i++] = look_up_table[n & 0xF]; | ||
205 | } while ((n >>= 4) > 0); | ||
206 | |||
207 | s[i] = '\0'; | ||
208 | |||
209 | reverse(s, i); | ||
210 | |||
211 | return i; | ||
212 | } | ||
213 | |||
214 | EAPI Eina_Bool | ||
215 | eina_convert_atod(const char *src, int length, long long *m, long *e) | ||
216 | { | ||
217 | const char *str = src; | ||
218 | long long mantisse; | ||
219 | long exponent; | ||
220 | int nbr_decimals = 0; | ||
221 | int sign = 1; | ||
222 | |||
223 | EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); | ||
224 | EINA_SAFETY_ON_NULL_RETURN_VAL(m, EINA_FALSE); | ||
225 | EINA_SAFETY_ON_NULL_RETURN_VAL(e, EINA_FALSE); | ||
226 | |||
227 | if (length <= 0) | ||
228 | goto on_length_error; | ||
229 | |||
230 | /* Compute the mantisse. */ | ||
231 | if (*str == '-') | ||
232 | { | ||
233 | sign = -1; | ||
234 | str++; | ||
235 | length--; | ||
236 | } | ||
237 | |||
238 | if (length <= 2) | ||
239 | goto on_length_error; | ||
240 | |||
241 | if (strncmp(str, "0x", 2)) | ||
242 | { | ||
243 | eina_error_set(EINA_ERROR_CONVERT_0X_NOT_FOUND); | ||
244 | DBG("'0x' not found in '%s'", src); | ||
245 | return EINA_FALSE; | ||
246 | } | ||
247 | |||
248 | str += 2; | ||
249 | length -= 2; | ||
250 | |||
251 | mantisse = HEXA_TO_INT(*str); | ||
252 | |||
253 | str++; | ||
254 | length--; if (length <= 0) | ||
255 | goto on_length_error; | ||
256 | |||
257 | if (*str == '.') | ||
258 | for (str++, length--; | ||
259 | length > 0 && *str != 'p'; | ||
260 | ++str, --length, ++nbr_decimals) | ||
261 | { | ||
262 | mantisse <<= 4; | ||
263 | mantisse += HEXA_TO_INT(*str); | ||
264 | } | ||
265 | |||
266 | if (sign < 0) | ||
267 | mantisse = -mantisse; | ||
268 | |||
269 | /* Compute the exponent. */ | ||
270 | if (*str != 'p') | ||
271 | { | ||
272 | eina_error_set(EINA_ERROR_CONVERT_P_NOT_FOUND); | ||
273 | DBG("'p' not found in '%s'", src); | ||
274 | return EINA_FALSE; | ||
275 | } | ||
276 | |||
277 | sign = +1; | ||
278 | |||
279 | str++; | ||
280 | length--; if (length <= 0) | ||
281 | goto on_length_error; | ||
282 | |||
283 | if (strchr("-+", *str)) | ||
284 | { | ||
285 | sign = (*str == '-') ? -1 : +1; | ||
286 | |||
287 | str++; length--; | ||
288 | } | ||
289 | |||
290 | for (exponent = 0; length > 0 && *str != '\0'; ++str, --length) | ||
291 | { | ||
292 | exponent *= 10; | ||
293 | exponent += *str - '0'; | ||
294 | } | ||
295 | |||
296 | if (length < 0) | ||
297 | goto on_length_error; | ||
298 | |||
299 | if (sign < 0) | ||
300 | exponent = -exponent; | ||
301 | |||
302 | *m = mantisse; | ||
303 | *e = exponent - (nbr_decimals << 2); | ||
304 | |||
305 | return EINA_TRUE; | ||
306 | |||
307 | on_length_error: | ||
308 | eina_error_set(EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH); | ||
309 | return EINA_FALSE; | ||
310 | } | ||
311 | |||
312 | EAPI int | ||
313 | eina_convert_dtoa(double d, char *des) | ||
314 | { | ||
315 | int length = 0; | ||
316 | int p; | ||
317 | int i; | ||
318 | |||
319 | EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); | ||
320 | |||
321 | if (d < 0.0) | ||
322 | { | ||
323 | *(des++) = '-'; | ||
324 | d = -d; | ||
325 | length++; | ||
326 | } | ||
327 | |||
328 | d = frexp(d, &p); | ||
329 | |||
330 | if (p) | ||
331 | { | ||
332 | d *= 2; | ||
333 | p -= 1; | ||
334 | } | ||
335 | |||
336 | *(des++) = '0'; | ||
337 | *(des++) = 'x'; | ||
338 | *(des++) = look_up_table[(size_t)d]; | ||
339 | *(des++) = '.'; | ||
340 | length += 4; | ||
341 | |||
342 | for (i = 0; i < 16; i++, length++) | ||
343 | { | ||
344 | d -= floor(d); | ||
345 | d *= 16; | ||
346 | *(des++) = look_up_table[(size_t)d]; | ||
347 | } | ||
348 | |||
349 | while (*(des - 1) == '0') | ||
350 | { | ||
351 | des--; | ||
352 | length--; | ||
353 | } | ||
354 | |||
355 | if (*(des - 1) == '.') | ||
356 | { | ||
357 | des--; | ||
358 | length--; | ||
359 | } | ||
360 | |||
361 | *(des++) = 'p'; | ||
362 | if (p < 0) | ||
363 | { | ||
364 | *(des++) = '-'; | ||
365 | p = -p; | ||
366 | } | ||
367 | else | ||
368 | *(des++) = '+'; | ||
369 | |||
370 | length += 2; | ||
371 | |||
372 | return length + eina_convert_itoa(p, des); | ||
373 | } | ||
374 | |||
375 | EAPI int | ||
376 | eina_convert_fptoa(Eina_F32p32 fp, char *des) | ||
377 | { | ||
378 | int length = 0; | ||
379 | int p = 0; | ||
380 | int i; | ||
381 | |||
382 | EINA_SAFETY_ON_NULL_RETURN_VAL(des, EINA_FALSE); | ||
383 | |||
384 | if (fp == 0) | ||
385 | { | ||
386 | memcpy(des, "0x0p+0", 7); | ||
387 | return 7; | ||
388 | } | ||
389 | |||
390 | if (fp < 0) | ||
391 | { | ||
392 | *(des++) = '-'; | ||
393 | fp = -fp; | ||
394 | length++; | ||
395 | } | ||
396 | |||
397 | /* fp >= 1 */ | ||
398 | if (fp >= 0x0000000100000000LL) | ||
399 | while (fp >= 0x0000000100000000LL) | ||
400 | { | ||
401 | p++; | ||
402 | /* fp /= 2 */ | ||
403 | fp >>= 1; | ||
404 | } /* fp < 0.5 */ | ||
405 | else if (fp < 0x80000000) | ||
406 | while (fp < 0x80000000) | ||
407 | { | ||
408 | p--; | ||
409 | /* fp *= 2 */ | ||
410 | fp <<= 1; | ||
411 | } | ||
412 | |||
413 | if (p) | ||
414 | { | ||
415 | p--; | ||
416 | /* fp *= 2 */ | ||
417 | fp <<= 1; | ||
418 | } | ||
419 | |||
420 | *(des++) = '0'; | ||
421 | *(des++) = 'x'; | ||
422 | *(des++) = look_up_table[fp >> 32]; | ||
423 | *(des++) = '.'; | ||
424 | length += 4; | ||
425 | |||
426 | for (i = 0; i < 16; i++, length++) | ||
427 | { | ||
428 | fp &= 0x00000000ffffffffLL; | ||
429 | fp <<= 4; /* fp *= 16 */ | ||
430 | *(des++) = look_up_table[fp >> 32]; | ||
431 | } | ||
432 | |||
433 | while (*(des - 1) == '0') | ||
434 | { | ||
435 | des--; | ||
436 | length--; | ||
437 | } | ||
438 | |||
439 | if (*(des - 1) == '.') | ||
440 | { | ||
441 | des--; | ||
442 | length--; | ||
443 | } | ||
444 | |||
445 | *(des++) = 'p'; | ||
446 | if (p < 0) | ||
447 | { | ||
448 | *(des++) = '-'; | ||
449 | p = -p; | ||
450 | } | ||
451 | else | ||
452 | *(des++) = '+'; | ||
453 | |||
454 | length += 2; | ||
455 | |||
456 | return length + eina_convert_itoa(p, des); | ||
457 | } | ||
458 | |||
459 | EAPI Eina_Bool | ||
460 | eina_convert_atofp(const char *src, int length, Eina_F32p32 *fp) | ||
461 | { | ||
462 | long long m; | ||
463 | long e; | ||
464 | |||
465 | if (!eina_convert_atod(src, length, &m, &e)) | ||
466 | return EINA_FALSE; | ||
467 | |||
468 | if (!fp) | ||
469 | return EINA_TRUE; | ||
470 | |||
471 | e += 32; | ||
472 | |||
473 | if (e > 0) | ||
474 | *fp = m << e; | ||
475 | else | ||
476 | *fp = m >> -e; | ||
477 | |||
478 | return EINA_TRUE; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * @} | ||
483 | */ | ||