zsets.c - libzahl - big integer library
 (HTM) git clone git://git.suckless.org/libzahl
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       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 }