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
|
/*
* 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.4 2002/02/22 09:04:48 dkf Exp $
*/
#include "tcl.h"
#include "tclPort.h"
#include <ctype.h>
#define TCL_WIDEINT_MAX (((Tcl_WideUInt)Tcl_LongAsWide(-1))>>1)
/*
*----------------------------------------------------------------------
*
* strtol --
*
* 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.
*
*----------------------------------------------------------------------
*/
Tcl_WideInt
strtoll(string, endPtr, base)
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.
*/
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;
}
|