Advertisement
Guest User

Untitled

a guest
Jan 14th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.93 KB | None | 0 0
  1. int cstrings_intbase(const char * s)
  2. {
  3.     if (s != NULL && s[0] != 0) {
  4.         int offset = (s[0] == '+' || s[0] == '-' ? 1 : 0);
  5.         if ((s[offset] == '0' && (s[offset + 1] == 'd' || s[offset + 1] == 'D'))
  6.             || (s[offset] >= '0' && s[offset] <= '9' && (s[offset + 1] == 0 || (s[offset + 1] >= '0' && s[offset + 1] <= '9'))))
  7.             return 10;
  8.         else if ((s[offset] == '$' || (s[offset] == '0' && (s[offset + 1] == 'x' || s[offset + 1] == 'X')))
  9.                  && ((s[offset + 2] >= '0' && s[offset + 2] <= '9') || (s[offset + 2] >= 'a' && s[offset + 2] <= 'f') || (s[offset + 2] >= 'A' && s[offset + 2] <= 'F')))
  10.             return 16;
  11.         else if ((s[offset] == '@' || (s[offset] == '0' && (s[offset + 1] == 'o' || s[offset + 1] == 'O')))
  12.                  && (s[offset + 2] >= '0' && s[offset + 2] <= '7'))
  13.             return 8;
  14.         else if ((s[offset] == '%' || (s[offset] == '0' && (s[offset + 1] == 'b' || s[offset + 1] == 'B')))
  15.                  && (s[offset + 2] >= '0' && s[offset + 2] <= '1'))
  16.             return 2;
  17.     }
  18.     return 0;
  19. }
  20.  
  21. #define CSTRINGS_DEFINE_INT_FUNC(funcsuffix, inttype, intmax, intmin) \
  22.     bool cstrings_is##funcsuffix(const char * s, int base, inttype * ret_value) \
  23.     { \
  24.         if (base <= 0) \
  25.             base = cstrings_intbase(s); \
  26.         if (base == 10 || base == 16 || base == 8 || base == 2) { \
  27.             int start = (s[0] == '+' || s[0] == '-' ? 1 : 0); \
  28.             if (base == 16)  \
  29.                 start += (s[start] == '$' ? 1 : (s[start] == '0' && (s[start + 1] == 'x' || s[start + 1] == 'X')) ? 2 : 0); \
  30.             else if (base == 8)  \
  31.                 start += (s[start] == '@' ? 1 : (s[start] == '0' && (s[start + 1] == 'o' || s[start + 1] == 'O')) ? 2 : 0); \
  32.             else if (base == 2)  \
  33.                 start += (s[start] == '%' ? 1 : (s[start] == '0' && (s[start + 1] == 'b' || s[start + 1] == 'B')) ? 2 : 0); \
  34.             int len = start; \
  35.             while (s[len] != 0) \
  36.                 len++; \
  37.             inttype multiplier = (s[0] == '-' ? -1 : 1); \
  38.             inttype result = 0; \
  39.             int offset = len - 1; \
  40.             while (offset >= start) { \
  41.                 inttype digitvalue = 0; \
  42.                 if (base == 10) { \
  43.                     if (s[offset] >= '0' && s[offset] <= '9') \
  44.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  45.                     else \
  46.                         return false; \
  47.                 } else if (base == 16) { \
  48.                     if (s[offset] >= '0' && s[offset] <= '9') \
  49.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  50.                     else if (s[offset] >= 'a' && s[offset] <= 'f') \
  51.                         digitvalue = ((inttype)s[offset]) - ((inttype)'a') + 10; \
  52.                     else if (s[offset] >= 'A' && s[offset] <= 'F') \
  53.                         digitvalue = ((inttype)s[offset]) - ((inttype)'A') + 10; \
  54.                     else \
  55.                         return false; \
  56.                 } else if (base == 8) { \
  57.                     if (s[offset] >= '0' && s[offset] <= '7') \
  58.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  59.                     else \
  60.                         return false; \
  61.                 } else if (base == 2) { \
  62.                     if (s[offset] >= '0' && s[offset] <= '1') \
  63.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  64.                     else \
  65.                         return false; \
  66.                 } else \
  67.                     return false; \
  68.                 inttype value = digitvalue * multiplier; \
  69.                 if (value / multiplier != digitvalue) \
  70.                     return false; \
  71.                 if (multiplier > 0 && value > intmax - result) \
  72.                     return false; \
  73.                 else if (multiplier < 0 && value < intmin - result) \
  74.                     return false; \
  75.                 result += value; \
  76.                 if (offset >= start) { \
  77.                     inttype premult = multiplier * (inttype)base; \
  78.                     if (premult / (inttype)base != multiplier) { \
  79.                         offset--; \
  80.                         while (offset >= start)  \
  81.                             if (s[offset--] != '0')  \
  82.                                 return false; \
  83.                         break; \
  84.                     } \
  85.                     multiplier = premult; \
  86.                 } \
  87.                 offset--; \
  88.             } \
  89.             if (ret_value != NULL) \
  90.                 *ret_value = result; \
  91.             return true; \
  92.         } \
  93.         return false; \
  94.     } \
  95.     inttype cstrings_to##funcsuffix(const char * s, int base, inttype errvalue) \
  96.     { \
  97.         inttype ret = errvalue; \
  98.         cstrings_is##funcsuffix(s, base, &ret); \
  99.         return ret; \
  100.     }
  101.  
  102. #define CSTRINGS_DEFINE_UINT_FUNC(funcsuffix, inttype, intmax) \
  103.     bool cstrings_is##funcsuffix(const char * s, int base, inttype * ret_value) \
  104.     { \
  105.         if (base <= 0) \
  106.             base = cstrings_intbase(s); \
  107.         if (base == 10 || base == 16 || base == 8 || base == 2) { \
  108.             int start = (s[0] == '+' ? 1 : 0); \
  109.             if (base == 16)  \
  110.                 start += (s[start] == '$' ? 1 : (s[start] == '0' && (s[start + 1] == 'x' || s[start + 1] == 'X')) ? 2 : 0); \
  111.             else if (base == 8)  \
  112.                 start += (s[start] == '@' ? 1 : (s[start] == '0' && (s[start + 1] == 'o' || s[start + 1] == 'O')) ? 2 : 0); \
  113.             else if (base == 2)  \
  114.                 start += (s[start] == '%' ? 1 : (s[start] == '0' && (s[start + 1] == 'b' || s[start + 1] == 'B')) ? 2 : 0); \
  115.             int len = start; \
  116.             while (s[len] != 0) \
  117.                 len++; \
  118.             inttype multiplier = 1; \
  119.             inttype result = 0; \
  120.             int offset = len - 1; \
  121.             while (offset >= start) { \
  122.                 inttype digitvalue = 0; \
  123.                 if (base == 10) { \
  124.                     if (s[offset] >= '0' && s[offset] <= '9') \
  125.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  126.                     else \
  127.                         return false; \
  128.                 } else if (base == 16) { \
  129.                     if (s[offset] >= '0' && s[offset] <= '9') \
  130.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  131.                     else if (s[offset] >= 'a' && s[offset] <= 'f') \
  132.                         digitvalue = ((inttype)s[offset]) - ((inttype)'a') + 10; \
  133.                     else if (s[offset] >= 'A' && s[offset] <= 'F') \
  134.                         digitvalue = ((inttype)s[offset]) - ((inttype)'A') + 10; \
  135.                     else \
  136.                         return false; \
  137.                 } else if (base == 8) { \
  138.                     if (s[offset] >= '0' && s[offset] <= '7') \
  139.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  140.                     else \
  141.                         return false; \
  142.                 } else if (base == 2) { \
  143.                     if (s[offset] >= '0' && s[offset] <= '1') \
  144.                         digitvalue = ((inttype)s[offset]) - ((inttype)'0'); \
  145.                     else \
  146.                         return false; \
  147.                 } else \
  148.                     return false; \
  149.                 inttype value = digitvalue * multiplier; \
  150.                 if (value / multiplier != digitvalue) \
  151.                     return false; \
  152.                 if (value > intmax - result) \
  153.                     return false; \
  154.                 result += value; \
  155.                 if (offset >= start) { \
  156.                     inttype premult = multiplier * (inttype)base; \
  157.                     if (premult / (inttype)base != multiplier) { \
  158.                         offset--; \
  159.                         while (offset >= start)  \
  160.                             if (s[offset--] != '0')  \
  161.                                 return false; \
  162.                         break; \
  163.                     } \
  164.                     multiplier = premult; \
  165.                 } \
  166.                 offset--; \
  167.             } \
  168.             if (ret_value != NULL) \
  169.                 *ret_value = result; \
  170.             return true; \
  171.         } \
  172.         return false; \
  173.     } \
  174.     inttype cstrings_to##funcsuffix(const char * s, int base, inttype errvalue) \
  175.     { \
  176.         inttype ret = errvalue; \
  177.         cstrings_is##funcsuffix(s, base, &ret); \
  178.         return ret; \
  179.     }
  180.  
  181. CSTRINGS_DEFINE_INT_FUNC(short, short, SHRT_MAX, SHRT_MIN)
  182. CSTRINGS_DEFINE_UINT_FUNC(ushort, unsigned short, USHRT_MAX)
  183. CSTRINGS_DEFINE_INT_FUNC(int, int, INT_MAX, INT_MIN)
  184. CSTRINGS_DEFINE_UINT_FUNC(uint, unsigned int, UINT_MAX)
  185. CSTRINGS_DEFINE_INT_FUNC(long, long, LONG_MAX, LONG_MIN)
  186. CSTRINGS_DEFINE_UINT_FUNC(ulong, unsigned long, ULONG_MAX)
  187. CSTRINGS_DEFINE_INT_FUNC(longlong, long long, LLONG_MAX, LLONG_MIN)
  188. CSTRINGS_DEFINE_UINT_FUNC(ulonglong, unsigned long long, ULLONG_MAX)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement