1
0
Fork 0
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:
akr 2008-01-02 06:24:27 +00:00
parent aac5220c66
commit 0352d32f05
11 changed files with 142 additions and 211 deletions

View file

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

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

View file

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

View file

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

View file

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

View file

@ -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));
}

View file

@ -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 *, ...);

View file

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

View file

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

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

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