summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-06-22 05:09:36 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2000-06-22 05:09:36 +0000
commited7cd88b0d7e89ea34aff78903fa83c4c5d6bb32 (patch)
treeb078ed0863bdf7fb5f2ee490440f0a1f34d99b86
parenta719a5044de1e6c68df533367714fd396dbf6c74 (diff)
2000-06-22
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_4@773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--bignum.c88
-rw-r--r--configure4
2 files changed, 70 insertions, 22 deletions
diff --git a/bignum.c b/bignum.c
index 17fab7bf85..12af58e9b8 100644
--- a/bignum.c
+++ b/bignum.c
@@ -13,12 +13,17 @@
#include <ctype.h>
VALUE rb_cBignum;
+
+#if defined __MINGW32__
+#define USHORT _USHORT
+#endif
+
typedef unsigned short USHORT;
-#define BDIGITS(x) RBIGNUM(x)->digits
-#define BITSPERDIG (sizeof(USHORT)*CHAR_BIT)
+#define BDIGITS(x) ((USHORT*)RBIGNUM(x)->digits)
+#define BITSPERDIG (sizeof(short)*CHAR_BIT)
#define BIGRAD (1L << BITSPERDIG)
-#define DIGSPERLONG ((unsigned int)(sizeof(long)/sizeof(USHORT)))
+#define DIGSPERLONG ((unsigned int)(sizeof(long)/sizeof(short)))
#define BIGUP(x) ((unsigned long)(x) << BITSPERDIG)
#define BIGDN(x) RSHIFT(x,BITSPERDIG)
#define BIGLO(x) ((USHORT)((x) & (BIGRAD-1)))
@@ -168,6 +173,9 @@ rb_str2inum(str, base)
const char *str;
int base;
{
+ const char *s = str;
+ char *end;
+ int badcheck = (base==0)?1:0;
char sign = 1, c;
unsigned long num;
long len, blen = 1;
@@ -175,7 +183,7 @@ rb_str2inum(str, base)
VALUE z;
USHORT *zds;
- while (ISSPACE(*str)) str++;
+ while (*str && ISSPACE(*str)) str++;
if (*str == '+') {
str++;
@@ -197,11 +205,12 @@ rb_str2inum(str, base)
}
else {
base = 8;
+ if (!*str) return INT2FIX(0);
}
- if (*str == '\0') return INT2FIX(0);
}
else {
base = 10;
+ if (!*str) return INT2FIX(0);
}
}
if (base == 8) {
@@ -215,12 +224,23 @@ rb_str2inum(str, base)
if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
str += 2;
}
- while (str[0] == '0') str++;
+ while (*str && *str == '0') str++;
+ if (!*str) str--;
len = 4*strlen(str)*sizeof(char);
}
if (len <= (sizeof(VALUE)*CHAR_BIT)) {
- unsigned long val = strtoul((char*)str, 0, base);
+ unsigned long val = strtoul((char*)str, &end, base);
+
+ if (badcheck) {
+ if (end == str || *end)
+ goto bad;
+ while (*end && ISSPACE(*end)) end++;
+ if (*end) {
+ bad:
+ rb_raise(rb_eArgError, "invalid literal for Integer: %s", s);
+ }
+ }
if (POSFIXABLE(val)) {
if (sign) return INT2FIX(val);
@@ -256,6 +276,15 @@ rb_str2inum(str, base)
break;
default:
c = base;
+ if (badcheck) {
+ if (ISSPACE(c)) {
+ while (*str && ISSPACE(*str)) str++;
+ if (*str) {
+ break;
+ }
+ }
+ rb_raise(rb_eArgError, "invalid literal for Integer: %s", s);
+ }
break;
}
if (c >= base) break;
@@ -274,6 +303,7 @@ rb_str2inum(str, base)
break;
}
}
+
return bignorm(z);
}
@@ -354,16 +384,17 @@ rb_big_to_s(x)
return rb_big2str(x, 10);
}
-unsigned long
-rb_big2ulong(x)
+static unsigned long
+big2ulong(x, type)
VALUE x;
+ char *type;
{
unsigned long num;
long len = RBIGNUM(x)->len;
USHORT *ds;
if (len > sizeof(long)/sizeof(USHORT))
- rb_raise(rb_eArgError, "bignum too big to convert into `uint'");
+ rb_raise(rb_eArgError, "bignum too big to convert into `%s'", type);
ds = BDIGITS(x);
num = 0;
while (len--) {
@@ -373,11 +404,21 @@ rb_big2ulong(x)
return num;
}
+unsigned long
+rb_big2ulong(x)
+ VALUE x;
+{
+ unsigned long num = big2ulong(x, "unsigned long");
+
+ if (!RBIGNUM(x)->sign) return -num;
+ return num;
+}
+
long
rb_big2long(x)
VALUE x;
{
- unsigned long num = rb_big2ulong(x);
+ unsigned long num = big2ulong(x, "int");
if ((long)num < 0) {
rb_raise(rb_eArgError, "bignum too big to convert into `int'");
@@ -393,8 +434,8 @@ rb_big_to_i(x)
return bignorm(x);
}
-VALUE
-rb_dbl2big(d)
+static VALUE
+dbl2big(d)
double d;
{
unsigned long i = 0;
@@ -423,7 +464,14 @@ rb_dbl2big(d)
digits[i] = (USHORT)c;
}
- return bignorm(z);
+ return z;
+}
+
+VALUE
+rb_dbl2big(d)
+ double d;
+{
+ return bignorm(dbl2big(d));
}
double
@@ -460,7 +508,7 @@ rb_big_cmp(x, y)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
case T_BIGNUM:
@@ -495,7 +543,7 @@ rb_big_eq(x, y)
case T_BIGNUM:
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
default:
return Qfalse;
@@ -836,7 +884,7 @@ bigdivmod(x, y, div, mod, modulo)
if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) {
long len = ny;
zds = BDIGITS(*mod);
- while (len-- && !zds[len]);
+ while (len && !zds[len]) len--;
if (len > 0) {
*mod = bigadd(*mod, y, 1);
return;
@@ -888,7 +936,7 @@ rb_big_modulo(x, y, modulo)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
default:
@@ -925,7 +973,7 @@ rb_big_divmod(x, y)
break;
case T_FLOAT:
- y = rb_dbl2big(RFLOAT(y)->value);
+ y = dbl2big(RFLOAT(y)->value);
break;
case T_BIGNUM:
@@ -936,7 +984,7 @@ rb_big_divmod(x, y)
}
bigdivmod(x, y, &div, &mod, 1);
- return rb_assoc_new(div, mod);;
+ return rb_assoc_new(div, mod);
}
VALUE
diff --git a/configure b/configure
index fe9be2281a..726207a187 100644
--- a/configure
+++ b/configure
@@ -2579,7 +2579,7 @@ else
#include "confdefs.h"
#include <alloca.h>
int main() {
-char *p = alloca(2 * sizeof(int));
+void *p = alloca(2 * sizeof(int));
; return 0; }
EOF
if { (eval echo configure:2586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
@@ -3682,7 +3682,7 @@ else
int main() {
/* Ultrix mips cc rejects this. */
-typedef int charset[2]; const charset x;
+typedef int charset[2]; const charset x = {0,0};
/* SunOS 4.1.1 cc rejects this. */
char const *const *ccp;
char **p;