[前][次][番号順一覧][スレッド一覧]

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

[前][次][番号順一覧][スレッド一覧]