1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
/*
* strtoll.c --
*
* Source code for the "strtoll" library procedure.
*
* Copyright (c) 1988 The Regents of the University of California.
* Copyright (c) 1994 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: strtoll.c,v 1.9 2007/04/16 13:36:34 dkf Exp $
*/
#include "tclInt.h"
#include <ctype.h>
#define TCL_WIDEINT_MAX (((Tcl_WideUInt)Tcl_LongAsWide(-1))>>1)
/*
*----------------------------------------------------------------------
*
* strtoll --
*
* 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.
*
*----------------------------------------------------------------------
*/
#if TCL_WIDE_INT_IS_LONG
long long
#else
Tcl_WideInt
#endif
strtoll(
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;
Tcl_WideInt result = Tcl_LongAsWide(0);
Tcl_WideUInt uwResult;
/*
* Skip any leading blanks.
*/
p = string;
while (isspace(UCHAR(*p))) {
p += 1;
}
/*
* Check for a sign.
*/
errno = 0;
if (*p == '-') {
p += 1;
uwResult = strtoull(p, endPtr, base);
if (errno != ERANGE) {
if (uwResult > TCL_WIDEINT_MAX+1) {
errno = ERANGE;
return Tcl_LongAsWide(-1);
} else if (uwResult > TCL_WIDEINT_MAX) {
return ~((Tcl_WideInt)TCL_WIDEINT_MAX);
} else {
result = -((Tcl_WideInt) uwResult);
}
}
} else {
if (*p == '+') {
p += 1;
}
uwResult = strtoull(p, endPtr, base);
if (errno != ERANGE) {
if (uwResult > TCL_WIDEINT_MAX) {
errno = ERANGE;
return Tcl_LongAsWide(-1);
} else {
result = uwResult;
}
}
}
if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
*endPtr = (char *) string;
}
return result;
}
|