ruby-changes:3357
From: ko1@a...
Date: 2 Jan 2008 15:24:44 +0900
Subject: [ruby-changes:3357] akr - Ruby:r14850 (trunk): * util.c (ruby_strtoul): locale independent strtoul is implemented to
akr 2008-01-02 15:24:27 +0900 (Wed, 02 Jan 2008) New Revision: 14850 Removed files: trunk/missing/strtoul.c Modified files: trunk/ChangeLog trunk/LEGAL trunk/bignum.c trunk/common.mk trunk/configure.in trunk/ext/socket/socket.c trunk/include/ruby/missing.h trunk/include/ruby/ruby.h trunk/pack.c trunk/util.c Log: * 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. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/ruby.h?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/missing/strtoul.c http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/missing.h?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bignum.c?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ext/socket/socket.c?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/util.c?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/configure.in?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/LEGAL?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/pack.c?r1=14850&r2=14849&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/common.mk?r1=14850&r2=14849&diff_format=u Index: include/ruby/missing.h =================================================================== --- include/ruby/missing.h (revision 14849) +++ include/ruby/missing.h (revision 14850) @@ -133,10 +133,6 @@ #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 *, ...); Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 14849) +++ include/ruby/ruby.h (revision 14850) @@ -986,4 +986,7 @@ #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 */ Index: LEGAL =================================================================== --- LEGAL (revision 14849) +++ LEGAL (revision 14850) @@ -157,22 +157,6 @@ 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: Index: configure.in =================================================================== --- configure.in (revision 14849) +++ configure.in (revision 14850) @@ -633,7 +633,7 @@ 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\ Index: ChangeLog =================================================================== --- ChangeLog (revision 14849) +++ ChangeLog (revision 14850) @@ -1,3 +1,24 @@ +Wed Jan 2 15:23:15 2008 Tanaka Akira <akr@f...> + + * 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@f...> * common.mk (strcasecmp.o): removed. Index: pack.c =================================================================== --- pack.c (revision 14849) +++ pack.c (revision 14850) @@ -492,7 +492,7 @@ p++; } else if (ISDIGIT(*p)) { - len = strtoul(p, (char**)&p, 10); + len = STRTOUL(p, (char**)&p, 10); } else { len = 1; @@ -1351,7 +1351,7 @@ p++; } else if (ISDIGIT(*p)) { - len = strtoul(p, (char**)&p, 10); + len = STRTOUL(p, (char**)&p, 10); } else { len = (type != '@'); Index: common.mk =================================================================== --- common.mk (revision 14849) +++ common.mk (revision 14850) @@ -394,7 +394,6 @@ 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 Index: util.c =================================================================== --- util.c (revision 14849) +++ util.c (revision 14850) @@ -63,6 +63,117 @@ 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 Index: ext/socket/socket.c =================================================================== --- ext/socket/socket.c (revision 14849) +++ ext/socket/socket.c (revision 14850) @@ -817,7 +817,7 @@ 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 @@ 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)); } Index: bignum.c =================================================================== --- bignum.c (revision 14849) +++ bignum.c (revision 14850) @@ -11,6 +11,7 @@ **********************************************************************/ #include "ruby/ruby.h" +#include "ruby/util.h" #include <math.h> #include <float.h> @@ -483,7 +484,7 @@ 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) { Index: missing/strtoul.c =================================================================== --- missing/strtoul.c (revision 14849) +++ missing/strtoul.c (revision 14850) @@ -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; -} -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml