* 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:
akr 2008-01-02 06:24:27 +00:00
Родитель aac5220c66
Коммит 0352d32f05
11 изменённых файлов: 142 добавлений и 211 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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:

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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