zsets.c (1038B)
1 /* See LICENSE file for copyright and license details. */ 2 #include "internals.h" 3 4 #include <ctype.h> 5 6 #ifdef __GNUC__ 7 # pragma GCC diagnostic ignored "-Wswitch-default" 8 #endif 9 10 11 int 12 zsets(z_t a, const char *str) 13 { 14 unsigned long long int temp = 0; 15 int neg = (*str == '-'); 16 const char *str_end; 17 18 str += neg || (*str == '+'); 19 20 if (check(!*str)) { 21 errno = EINVAL; 22 return -1; 23 } 24 for (str_end = str; *str_end; str_end++) { 25 if (check(!isdigit(*str_end))) { 26 errno = EINVAL; 27 return -1; 28 } 29 } 30 31 SET_SIGNUM(a, 0); 32 33 zset(libzahl_tmp_str_num, libzahl_const_1e19); 34 switch ((str_end - str) % 19) { 35 while (*str) { 36 zmul(a, a, libzahl_const_1e19); 37 temp = 0; 38 #define X(n)\ 39 case n:\ 40 temp *= 10, temp += *str++ & 15; 41 X(0) X(18) X(17) X(16) X(15) X(14) X(13) X(12) X(11) 42 X(10) X(9) X(8) X(7) X(6) X(5) X(4) X(3) X(2) X(1) 43 #undef X 44 if (!temp) 45 continue; 46 libzahl_tmp_str_num->chars[0] = (zahl_char_t)temp; 47 zadd(a, a, libzahl_tmp_str_num); 48 } 49 } 50 51 if (unlikely(neg)) 52 SET_SIGNUM(a, -zsignum(a)); 53 return 0; 54 }