Skip to content

Commit

Permalink
Merge pull request #5 from jonasschnelli/2015/09/custom_num_parse
Browse files Browse the repository at this point in the history
remove optional compiling/linking of number parse functions
  • Loading branch information
Jeff Garzik committed Sep 7, 2015
2 parents 1211c40 + c00cda3 commit a243b3d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 85 deletions.
8 changes: 0 additions & 8 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ AC_PATH_TOOL(RANLIB, ranlib)
AC_PATH_TOOL(STRIP, strip)
PKG_PROG_PKG_CONFIG

# Enable numfunc
AC_ARG_WITH([numfunc],
[AS_HELP_STRING([--with-numfunc],
[enable compiling of number parsing functions (default is yes)])],
[use_numfunc=$withval],
[use_numfunc=yes])
AM_CONDITIONAL([USE_NUMFUNC], [test x$use_numfunc = xyes])

AC_LANG_PUSH([C++])

AC_CONFIG_FILES([lib/Makefile test/Makefile Makefile])
Expand Down
7 changes: 0 additions & 7 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ libunivalue_a_SOURCES = \
univalue_read.cpp \
univalue_write.cpp

# ----------------------------------
# optional add numberparse functions
# ----------------------------------
if USE_NUMFUNC
libunivalue_a_SOURCES += numberparse.cpp
endif

noinst_PROGRAMS = gen

gen_SOURCES = gen.cpp
Expand Down
67 changes: 0 additions & 67 deletions lib/numberparse.cpp

This file was deleted.

65 changes: 62 additions & 3 deletions lib/univalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,74 @@

#include <stdint.h>
#include <ctype.h>
#include <errno.h>
#include <iomanip>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <stdlib.h>
#include <string.h>

#include "univalue.h"

extern bool ParseInt32(const std::string& str, int32_t *out);
extern bool ParseInt64(const std::string& str, int64_t *out);
extern bool ParseDouble(const std::string& str, double *out);
namespace
{
static bool ParsePrechecks(const std::string& str)
{
if (str.empty()) // No empty string allowed
return false;
if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
return false;
if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
return false;
return true;
}

bool ParseInt32(const std::string& str, int32_t *out)
{
if (!ParsePrechecks(str))
return false;
char *endp = NULL;
errno = 0; // strtol will not set errno if valid
long int n = strtol(str.c_str(), &endp, 10);
if(out) *out = (int32_t)n;
// Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
// platforms the size of these types may be different.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<int32_t>::min() &&
n <= std::numeric_limits<int32_t>::max();
}

bool ParseInt64(const std::string& str, int64_t *out)
{
if (!ParsePrechecks(str))
return false;
char *endp = NULL;
errno = 0; // strtoll will not set errno if valid
long long int n = strtoll(str.c_str(), &endp, 10);
if(out) *out = (int64_t)n;
// Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
// we still have to check that the returned value is within the range of an *int64_t*.
return endp && *endp == 0 && !errno &&
n >= std::numeric_limits<int64_t>::min() &&
n <= std::numeric_limits<int64_t>::max();
}

bool ParseDouble(const std::string& str, double *out)
{
if (!ParsePrechecks(str))
return false;
if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
return false;
std::istringstream text(str);
text.imbue(std::locale::classic());
double result;
text >> result;
if(out) *out = result;
return text.eof() && !text.fail();
}
}

using namespace std;

Expand Down

0 comments on commit a243b3d

Please sign in to comment.