absyntax_utils/absyntax_utils.cc
changeset 589 de4c2a058767
parent 587 1ecf916cc397
child 591 76bad7199896
equal deleted inserted replaced
588:3d72d09bd40f 589:de4c2a058767
    95   /* identifiers do not match! */
    95   /* identifiers do not match! */
    96   return 1;
    96   return 1;
    97 }
    97 }
    98 
    98 
    99 
    99 
       
   100 
       
   101   /* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int,
       
   102    * so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64().
       
   103    *
       
   104    * So, we create our own strtouint64() and strtoint64() functions.
       
   105    * (We actually call them matiec_strtoint64() so they will not clash with any function
       
   106    *  that may be added to the standard library in the future).
       
   107    * We actually create several of each, and let the compiler choose which is the correct one,
       
   108    * by having it resolve the call to the overloaded function. For the C++ compiler to be able
       
   109    * to resolve this ambiguity, we need to add a dummy parameter to each function!
       
   110    *
       
   111    * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
       
   112    */
       
   113 static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
       
   114 static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
       
   115   
       
   116 static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
       
   117 static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
       
   118 
       
   119 
   100 /* extract the value of an integer from an integer_c object !! */
   120 /* extract the value of an integer from an integer_c object !! */
   101 /* NOTE: it must ignore underscores! */
   121 /* NOTE: it must ignore underscores! */
   102 int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
   122 int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
   103   std::string str = "";
   123   std::string str = "";
   104   integer_c *integer;
   124   integer_c *integer;
   112   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   132   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   113 
   133 
   114   for(unsigned int i = 0; i < strlen(integer->value); i++)
   134   for(unsigned int i = 0; i < strlen(integer->value); i++)
   115     if (integer->value[i] != '_')  str += integer->value[i];
   135     if (integer->value[i] != '_')  str += integer->value[i];
   116 
   136 
   117   errno = 0;
   137   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   118   ret = strtoll(str.c_str(), &endptr, 10);
   138   ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, 10);
   119   if (overflow != NULL)
   139   if (overflow != NULL)
   120     *overflow = (errno == ERANGE);
   140     *overflow = (errno == ERANGE);
   121   if ((errno != 0) && (errno != ERANGE))
   141   if ((errno != 0) && (errno != ERANGE))
   122     ERROR;
   142     ERROR;
   123 
   143 
   134   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   154   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   135 
   155 
   136   for(unsigned int i = 0; i < strlen(integer->value); i++)
   156   for(unsigned int i = 0; i < strlen(integer->value); i++)
   137     if (integer->value[i] != '_')  str += integer->value[i];
   157     if (integer->value[i] != '_')  str += integer->value[i];
   138 
   158 
   139   errno = 0;
   159   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   140   ret = strtoull(str.c_str(), &endptr, 10);
   160   ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, 10);
   141   if (overflow != NULL)
   161   if (overflow != NULL)
   142     *overflow = (errno == ERANGE);
   162     *overflow = (errno == ERANGE);
   143   if ((errno != 0) && (errno != ERANGE))
   163   if ((errno != 0) && (errno != ERANGE))
   144     ERROR;
   164     ERROR;
   145 
   165