mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* util.c (ruby_strtoul): locale independent strtoul is implemented to
avoid "i".to_i(36) cause 0 under tr_TR locale. This is newly implemented, not a copy of missing/strtoul.c. * include/ruby/ruby.h (ruby_strtoul): declared. (STRTOUL): defined to use ruby_strtoul. * bignum.c, pack.c, ext/socket/socket.c: use STRTOUL. * configure.in (strtoul): don't check. * missing/strtoul.c: removed. * include/ruby/missing.h (strtoul): removed. * common.mk (strtoul.o): removed. * LEGAL (missing/strtoul.c): removed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14850 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
aac5220c66
commit
0352d32f05
11 changed files with 142 additions and 211 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
Wed Jan 2 15:23:15 2008 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* util.c (ruby_strtoul): locale independent strtoul is implemented to
|
||||
avoid "i".to_i(36) cause 0 under tr_TR locale.
|
||||
This is newly implemented, not a copy of missing/strtoul.c.
|
||||
|
||||
* include/ruby/ruby.h (ruby_strtoul): declared.
|
||||
(STRTOUL): defined to use ruby_strtoul.
|
||||
|
||||
* bignum.c, pack.c, ext/socket/socket.c: use STRTOUL.
|
||||
|
||||
* configure.in (strtoul): don't check.
|
||||
|
||||
* missing/strtoul.c: removed.
|
||||
|
||||
* include/ruby/missing.h (strtoul): removed.
|
||||
|
||||
* common.mk (strtoul.o): removed.
|
||||
|
||||
* LEGAL (missing/strtoul.c): removed.
|
||||
|
||||
Wed Jan 2 14:41:08 2008 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* common.mk (strcasecmp.o): removed.
|
||||
|
|
16
LEGAL
16
LEGAL
|
@ -157,22 +157,6 @@ ext/digest/sha1/sha1.[ch]:
|
|||
|
||||
These files are all under public domain.
|
||||
|
||||
missing/strtoul.c:
|
||||
|
||||
This file will not be used on most platforms depending on how the
|
||||
configure script results. In any case you must not receive any fee
|
||||
with the file itself.
|
||||
|
||||
Copyright 1988 Regents of the University of California
|
||||
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software and its documentation for any purpose and without
|
||||
fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies. The University of California
|
||||
makes no representations about the suitability of this
|
||||
software for any purpose. It is provided "as is" without
|
||||
express or implied warranty.
|
||||
|
||||
missing/erf.c:
|
||||
missing/crypt.c:
|
||||
missing/vsnprintf.c:
|
||||
|
|
3
bignum.c
3
bignum.c
|
@ -11,6 +11,7 @@
|
|||
**********************************************************************/
|
||||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/util.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
@ -483,7 +484,7 @@ rb_cstr_to_inum(const char *str, int base, int badcheck)
|
|||
len *= strlen(str)*sizeof(char);
|
||||
|
||||
if (len <= (sizeof(long)*CHAR_BIT)) {
|
||||
unsigned long val = strtoul(str, &end, base);
|
||||
unsigned long val = STRTOUL(str, &end, base);
|
||||
|
||||
if (str < end && *end == '_') goto bigparse;
|
||||
if (badcheck) {
|
||||
|
|
|
@ -394,7 +394,6 @@ strftime.$(OBJEXT): {$(VPATH)}strftime.c
|
|||
strstr.$(OBJEXT): {$(VPATH)}strstr.c
|
||||
strtod.$(OBJEXT): {$(VPATH)}strtod.c
|
||||
strtol.$(OBJEXT): {$(VPATH)}strtol.c
|
||||
strtoul.$(OBJEXT): {$(VPATH)}strtoul.c
|
||||
nt.$(OBJEXT): {$(VPATH)}nt.c
|
||||
x68.$(OBJEXT): {$(VPATH)}x68.c
|
||||
os2.$(OBJEXT): {$(VPATH)}os2.c
|
||||
|
|
|
@ -633,7 +633,7 @@ powerpc-darwin*)
|
|||
esac
|
||||
AC_FUNC_MEMCMP
|
||||
AC_REPLACE_FUNCS(dup2 memmove strerror strftime\
|
||||
strchr strstr strtoul crypt flock vsnprintf\
|
||||
strchr strstr crypt flock vsnprintf\
|
||||
isnan finite isinf hypot acosh erf strlcpy strlcat)
|
||||
AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd eaccess\
|
||||
truncate chsize times utimes utimensat fcntl lockf lstat\
|
||||
|
|
|
@ -817,7 +817,7 @@ str_isnumber(const char *p)
|
|||
if (!p || *p == '\0')
|
||||
return 0;
|
||||
ep = NULL;
|
||||
(void)strtoul(p, &ep, 10);
|
||||
(void)STRTOUL(p, &ep, 10);
|
||||
if (ep && *ep == '\0')
|
||||
return 1;
|
||||
else
|
||||
|
@ -3165,7 +3165,7 @@ sock_s_getservbyname(int argc, VALUE *argv)
|
|||
char *s = RSTRING_PTR(service);
|
||||
char *end;
|
||||
|
||||
port = strtoul(s, &end, 0);
|
||||
port = STRTOUL(s, &end, 0);
|
||||
if (*end != '\0') {
|
||||
rb_raise(rb_eSocket, "no such service %s/%s", s, RSTRING_PTR(proto));
|
||||
}
|
||||
|
|
|
@ -133,10 +133,6 @@ extern long strtol(const char *, char **, int);
|
|||
#endif
|
||||
*/
|
||||
|
||||
#ifndef HAVE_STRTOUL
|
||||
extern unsigned long strtoul(const char *, char **, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
# include <stdarg.h>
|
||||
extern int snprintf(char *, size_t n, char const *, ...);
|
||||
|
|
|
@ -986,4 +986,7 @@ int rb_remove_event_hook(rb_event_hook_func_t func);
|
|||
#define STRCASECMP(s1, s2) (st_strcasecmp(s1, s2))
|
||||
#define STRNCASECMP(s1, s2, n) (st_strncasecmp(s1, s2, n))
|
||||
|
||||
unsigned long ruby_strtoul(const char *str, char **endptr, int base);
|
||||
#define STRTOUL(str, endptr, base) (ruby_strtoul(str, endptr, base))
|
||||
|
||||
#endif /* RUBY_H */
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* strtoul.c --
|
||||
*
|
||||
* Source code for the "strtoul" library procedure.
|
||||
*
|
||||
* Copyright 1988 Regents of the University of California
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. The University of California
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* The table below is used to convert from ASCII digits to a
|
||||
* numerical equivalent. It maps from '0' through 'z' to integers
|
||||
* (100 for non-digit characters).
|
||||
*/
|
||||
|
||||
static const char cvtIn[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
|
||||
100, 100, 100, 100, 100, 100, 100, /* punctuation */
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35,
|
||||
100, 100, 100, 100, 100, 100, /* punctuation */
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* strtoul --
|
||||
*
|
||||
* Convert an ASCII string into an integer.
|
||||
*
|
||||
* Results:
|
||||
* The return value is the integer equivalent of string. If endPtr
|
||||
* is non-NULL, then *endPtr is filled in with the character
|
||||
* after the last one that was part of the integer. If string
|
||||
* doesn't contain a valid integer value, then zero is returned
|
||||
* and *endPtr is set to string.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long int
|
||||
strtoul(
|
||||
const char *string, /* String of ASCII digits, possibly
|
||||
* preceded by white space. For bases
|
||||
* greater than 10, either lower- or
|
||||
* upper-case digits may be used.
|
||||
*/
|
||||
char **endPtr, /* Where to store address of terminating
|
||||
* character, or NULL. */
|
||||
int base) /* Base for conversion. Must be less
|
||||
* than 37. If 0, then the base is chosen
|
||||
* from the leading characters of string:
|
||||
* "0x" means hex, "0" means octal, anything
|
||||
* else means decimal.
|
||||
*/
|
||||
{
|
||||
register const char *p;
|
||||
register unsigned long int result = 0;
|
||||
register unsigned digit;
|
||||
int anyDigits = 0;
|
||||
|
||||
/*
|
||||
* Skip any leading blanks.
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no base was provided, pick one from the leading characters
|
||||
* of the string.
|
||||
*/
|
||||
|
||||
if (base == 0)
|
||||
{
|
||||
if (*p == '0') {
|
||||
p += 1;
|
||||
if (*p == 'x') {
|
||||
p += 1;
|
||||
base = 16;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Must set anyDigits here, otherwise "0" produces a
|
||||
* "no digits" error.
|
||||
*/
|
||||
|
||||
anyDigits = 1;
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
else base = 10;
|
||||
} else if (base == 16) {
|
||||
|
||||
/*
|
||||
* Skip a leading "0x" from hex numbers.
|
||||
*/
|
||||
|
||||
if ((p[0] == '0') && (p[1] == 'x')) {
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sorry this code is so messy, but speed seems important. Do
|
||||
* different things for base 8, 10, 16, and other.
|
||||
*/
|
||||
|
||||
if (base == 8) {
|
||||
for ( ; ; p += 1) {
|
||||
digit = *p - '0';
|
||||
if (digit > 7) {
|
||||
break;
|
||||
}
|
||||
result = (result << 3) + digit;
|
||||
anyDigits = 1;
|
||||
}
|
||||
} else if (base == 10) {
|
||||
for ( ; ; p += 1) {
|
||||
digit = *p - '0';
|
||||
if (digit > 9) {
|
||||
break;
|
||||
}
|
||||
result = (10*result) + digit;
|
||||
anyDigits = 1;
|
||||
}
|
||||
} else if (base == 16) {
|
||||
for ( ; ; p += 1) {
|
||||
digit = *p - '0';
|
||||
if (digit > ('z' - '0')) {
|
||||
break;
|
||||
}
|
||||
digit = cvtIn[digit];
|
||||
if (digit > 15) {
|
||||
break;
|
||||
}
|
||||
result = (result << 4) + digit;
|
||||
anyDigits = 1;
|
||||
}
|
||||
} else {
|
||||
for ( ; ; p += 1) {
|
||||
digit = *p - '0';
|
||||
if (digit > ('z' - '0')) {
|
||||
break;
|
||||
}
|
||||
digit = cvtIn[digit];
|
||||
if (digit >= base) {
|
||||
break;
|
||||
}
|
||||
result = result*base + digit;
|
||||
anyDigits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there were any digits at all.
|
||||
*/
|
||||
|
||||
if (!anyDigits) {
|
||||
p = string;
|
||||
}
|
||||
|
||||
if (endPtr != 0) {
|
||||
*endPtr = (char *)p;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
4
pack.c
4
pack.c
|
@ -492,7 +492,7 @@ pack_pack(VALUE ary, VALUE fmt)
|
|||
p++;
|
||||
}
|
||||
else if (ISDIGIT(*p)) {
|
||||
len = strtoul(p, (char**)&p, 10);
|
||||
len = STRTOUL(p, (char**)&p, 10);
|
||||
}
|
||||
else {
|
||||
len = 1;
|
||||
|
@ -1351,7 +1351,7 @@ pack_unpack(VALUE str, VALUE fmt)
|
|||
p++;
|
||||
}
|
||||
else if (ISDIGIT(*p)) {
|
||||
len = strtoul(p, (char**)&p, 10);
|
||||
len = STRTOUL(p, (char**)&p, 10);
|
||||
}
|
||||
else {
|
||||
len = (type != '@');
|
||||
|
|
111
util.c
111
util.c
|
@ -63,6 +63,117 @@ ruby_scan_hex(const char *start, int len, int *retlen)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
scan_digits(const char *str, int base, size_t *retlen, int *overflow)
|
||||
{
|
||||
static char table[] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||
/*0*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*1*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*2*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*3*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
/*4*/ -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
|
||||
/*5*/ 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
|
||||
/*6*/ -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
|
||||
/*7*/ 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
|
||||
/*8*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*9*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*a*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*b*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*c*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*d*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*e*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
/*f*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
};
|
||||
|
||||
const char *start = str;
|
||||
unsigned long ret = 0, x;
|
||||
unsigned long MUL_OVERFLOW = (~(unsigned long)0) / base;
|
||||
int c;
|
||||
*overflow = 0;
|
||||
|
||||
while ((c = (unsigned char)*str++) != '\0') {
|
||||
int d = table[c];
|
||||
if (d == -1 || base <= d) {
|
||||
*retlen = (str-1) - start;
|
||||
return ret;
|
||||
}
|
||||
if (MUL_OVERFLOW < ret)
|
||||
*overflow = 1;
|
||||
ret *= base;
|
||||
x = ret;
|
||||
ret += d;
|
||||
if (ret < x)
|
||||
*overflow = 1;
|
||||
}
|
||||
*retlen = (str-1) - start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
ruby_strtoul(const char *str, char **endptr, int base)
|
||||
{
|
||||
int c, b, overflow;
|
||||
int sign = 0;
|
||||
size_t len;
|
||||
unsigned long ret;
|
||||
|
||||
if (base == 1 || 36 < base) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((c = *str) && ISSPACE(c))
|
||||
str++;
|
||||
|
||||
if (c == '+') {
|
||||
sign = 1;
|
||||
str++;
|
||||
}
|
||||
else if (c == '-') {
|
||||
sign = -1;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (str[0] == '0') {
|
||||
if (base == 0 || base == 16) {
|
||||
if (str[1] == 'x' || str[1] == 'X') {
|
||||
b = 16;
|
||||
str += 2;
|
||||
}
|
||||
else {
|
||||
b = base == 0 ? 8 : 16;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
b = base;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
b = base == 0 ? 10 : base;
|
||||
}
|
||||
|
||||
ret = scan_digits(str, b, &len, &overflow);
|
||||
|
||||
if (endptr)
|
||||
*endptr = (char*)(str+len);
|
||||
|
||||
if (overflow) {
|
||||
errno = ERANGE;
|
||||
return ULONG_MAX;
|
||||
}
|
||||
|
||||
if (sign < 0) {
|
||||
ret = -(long)ret;
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
|
Loading…
Reference in a new issue