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…
	
	Add table
		Add a link
		
	
		Reference in a new issue