os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strtoll.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* 
     2  * strtoll.c --
     3  *
     4  *	Source code for the "strtoll" library procedure.
     5  *
     6  * Copyright (c) 1988 The Regents of the University of California.
     7  * Copyright (c) 1994 Sun Microsystems, Inc.
     8  *
     9  * See the file "license.terms" for information on usage and redistribution
    10  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    11  *
    12  * RCS: @(#) $Id: strtoll.c,v 1.5 2002/02/24 02:53:25 dgp Exp $
    13  */
    14 
    15 #include "tcl.h"
    16 #include "tclPort.h"
    17 #include <ctype.h>
    18 
    19 #define TCL_WIDEINT_MAX	(((Tcl_WideUInt)Tcl_LongAsWide(-1))>>1)
    20 
    21 
    22 /*
    23  *----------------------------------------------------------------------
    24  *
    25  * strtoll --
    26  *
    27  *	Convert an ASCII string into an integer.
    28  *
    29  * Results:
    30  *	The return value is the integer equivalent of string.  If endPtr
    31  *	is non-NULL, then *endPtr is filled in with the character
    32  *	after the last one that was part of the integer.  If string
    33  *	doesn't contain a valid integer value, then zero is returned
    34  *	and *endPtr is set to string.
    35  *
    36  * Side effects:
    37  *	None.
    38  *
    39  *----------------------------------------------------------------------
    40  */
    41 
    42 #if TCL_WIDE_INT_IS_LONG
    43 long long
    44 #else
    45 Tcl_WideInt
    46 #endif
    47 strtoll(string, endPtr, base)
    48     CONST char *string;		/* String of ASCII digits, possibly
    49 				 * preceded by white space.  For bases
    50 				 * greater than 10, either lower- or
    51 				 * upper-case digits may be used.
    52 				 */
    53     char **endPtr;		/* Where to store address of terminating
    54 				 * character, or NULL. */
    55     int base;			/* Base for conversion.  Must be less
    56 				 * than 37.  If 0, then the base is chosen
    57 				 * from the leading characters of string:
    58 				 * "0x" means hex, "0" means octal, anything
    59 				 * else means decimal.
    60 				 */
    61 {
    62     register CONST char *p;
    63     Tcl_WideInt result = Tcl_LongAsWide(0);
    64     Tcl_WideUInt uwResult;
    65 
    66     /*
    67      * Skip any leading blanks.
    68      */
    69 
    70     p = string;
    71     while (isspace(UCHAR(*p))) {
    72 	p += 1;
    73     }
    74 
    75     /*
    76      * Check for a sign.
    77      */
    78 
    79     errno = 0;
    80     if (*p == '-') {
    81 	p += 1;
    82 	uwResult = strtoull(p, endPtr, base);
    83 	if (errno != ERANGE) {
    84 	    if (uwResult > TCL_WIDEINT_MAX+1) {
    85 		errno = ERANGE;
    86 		return Tcl_LongAsWide(-1);
    87 	    } else if (uwResult > TCL_WIDEINT_MAX) {
    88 		return ~((Tcl_WideInt)TCL_WIDEINT_MAX);
    89 	    } else {
    90 		result = -((Tcl_WideInt) uwResult);
    91 	    }
    92 	}
    93     } else {
    94 	if (*p == '+') {
    95 	    p += 1;
    96 	}
    97 	uwResult = strtoull(p, endPtr, base);
    98 	if (errno != ERANGE) {
    99 	    if (uwResult > TCL_WIDEINT_MAX) {
   100 		errno = ERANGE;
   101 		return Tcl_LongAsWide(-1);
   102 	    } else {
   103 		result = uwResult;
   104 	    }
   105 	}
   106     }
   107     if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
   108 	*endPtr = (char *) string;
   109     }
   110     return result;
   111 }