Skip to content

Instantly share code, notes, and snippets.

@matthewd
Created March 14, 2010 06:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewd/331803 to your computer and use it in GitHub Desktop.
Save matthewd/331803 to your computer and use it in GitHub Desktop.
From e31a244f78dfcdeef1381a24a657a6779792767c Mon Sep 17 00:00:00 2001
From: Matthew Draper <matthew@trebex.net>
Date: Sat, 13 Mar 2010 19:26:58 +1030
Subject: [PATCH 1/3] Correctly handle large numeric Config values.
Previously, values > Fixnum::MAX would behave incorrectly.
In passing, also fix handling of negative values: don't strip their
sign(!), but still treat them as numeric.
---
vm/builtin/system.cpp | 2 +-
vm/config_parser.cpp | 8 +++++---
vm/test/test_config.hpp | 12 ++++++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/vm/builtin/system.cpp b/vm/builtin/system.cpp
index a2db04d..5083b94 100644
--- a/vm/builtin/system.cpp
+++ b/vm/builtin/system.cpp
@@ -273,7 +273,7 @@ namespace rubinius {
if(!ent) return Qnil;
if(ent->is_number()) {
- return Fixnum::from(atoi(ent->value.c_str()));
+ return Bignum::from_string(state, ent->value.c_str(), 10);
} else if(ent->is_true()) {
return Qtrue;
}
diff --git a/vm/config_parser.cpp b/vm/config_parser.cpp
index 86a6a39..3c33d72 100644
--- a/vm/config_parser.cpp
+++ b/vm/config_parser.cpp
@@ -7,8 +7,10 @@
#include "configuration.hpp"
namespace rubinius {
- /* utility: checks whether string contains only digits */
+ /* utility: checks whether string contains only digits, with optional
+ * leading '-' */
static bool is_number(const char *str) {
+ if(*str == '-') str++;
while(*str) {
if(!isdigit(*str)) return false;
str++;
@@ -21,9 +23,9 @@ namespace rubinius {
/* utility: strips trailing non-alnum chars from string */
static char *trim_str(char *str) {
int i;
- while(*str && !isalnum(*str) && *str != '/') str++;
+ while(*str && !isalnum(*str) && *str != '/' && *str != '-') str++;
- for(i = strlen(str); i-- && !isalnum(str[i]) && str[i] != '/';) {
+ for(i = strlen(str); i-- && !isalnum(str[i]) && str[i] != '/' && str[i] != '-';) {
str[i] = 0;
}
diff --git a/vm/test/test_config.hpp b/vm/test/test_config.hpp
index 4547e23..5c7aa6b 100644
--- a/vm/test/test_config.hpp
+++ b/vm/test/test_config.hpp
@@ -27,6 +27,14 @@ class TestConfig : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(std::string("8"), e->value);
}
+ void test_parse_line_with_negative() {
+ ConfigParser cfg;
+
+ ConfigParser::Entry* e = cfg.parse_line("rbx.blah = -3");
+ TS_ASSERT_EQUALS(std::string("rbx.blah"), e->variable);
+ TS_ASSERT_EQUALS(std::string("-3"), e->value);
+ }
+
void test_parse_stream() {
std::istringstream stream;
@@ -56,6 +64,10 @@ class TestConfig : public CxxTest::TestSuite {
ent->value = std::string("8");
TS_ASSERT(ent->is_number());
+
+ ent->value = std::string("-3");
+
+ TS_ASSERT(ent->is_number());
}
void test_get_section() {
--
1.7.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment