Diff
Not logged in

Differences From Artifact [daaa3f769c]:

To Artifact [a537977100]:


10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







 *	'double' and 'mp_int' types.
 *
 * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclStrToD.c,v 1.26 2006/11/15 20:08:45 dgp Exp $
 * RCS: @(#) $Id: tclStrToD.c,v 1.27 2007/02/20 23:24:03 nijtmans Exp $
 *
 *----------------------------------------------------------------------
 */

#include <tclInt.h>
#include <stdio.h>
#include <stdlib.h>
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110







-
+







static double tiny;		/* The smallest representable double */
static int maxDigits;		/* The maximum number of digits to the left of
				 * the decimal point of a double. */
static int minDigits;		/* The maximum number of digits to the right
				 * of the decimal point in a double. */
static int mantDIGIT;		/* Number of mp_digit's needed to hold the
				 * significand of a double. */
static CONST double pow_10_2_n[] = {	/* Inexact higher powers of ten. */
static const double pow_10_2_n[] = {	/* Inexact higher powers of ten. */
    1.0,
    100.0,
    10000.0,
    1.0e+8,
    1.0e+16,
    1.0e+32,
    1.0e+64,
240
241
242
243
244
245
246
247

248
249
250

251
252

253
254
255
256
257
258
259
240
241
242
243
244
245
246

247
248
249

250
251

252
253
254
255
256
257
258
259







-
+


-
+

-
+







 *----------------------------------------------------------------------
 */

int
TclParseNumber(
    Tcl_Interp *interp,		/* Used for error reporting. May be NULL */
    Tcl_Obj *objPtr,		/* Object to receive the internal rep */
    CONST char *expected,	/* Description of the type of number the caller
    const char *expected,	/* Description of the type of number the caller
				 * expects to be able to parse ("integer", 
				 * "boolean value", etc.). */
    CONST char *bytes,		/* Pointer to the start of the string to scan */
    const char *bytes,		/* Pointer to the start of the string to scan */
    int numBytes,		/* Maximum number of bytes to scan, see above */
    CONST char **endPtrPtr,	/* Place to store pointer to the character
    const char **endPtrPtr,	/* Place to store pointer to the character
				 * that terminated the scan */
    int flags)			/* Flags governing the parse */
{
    enum State {
	INITIAL, SIGNUM, ZERO, ZERO_X, 
	ZERO_O, ZERO_B, BINARY,
	HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL, 
287
288
289
290
291
292
293
294

295
296

297
298
299
300
301
302
303
287
288
289
290
291
292
293

294
295

296
297
298
299
300
301
302
303







-
+

-
+







    int numTrailZeros = 0;	/* Number of trailing zeroes at the current
				 * point in the parse. */
    int numDigitsAfterDp = 0;	/* Number of digits scanned after the decimal
				 * point */
    int exponentSignum = 0;	/* Signum of the exponent of a floating point
				 * number */
    long exponent = 0;		/* Exponent of a floating point number */
    CONST char *p;		/* Pointer to next character to scan */
    const char *p;		/* Pointer to next character to scan */
    size_t len;			/* Number of characters remaining after p */
    CONST char *acceptPoint;	/* Pointer to position after last character in
    const char *acceptPoint;	/* Pointer to position after last character in
				 * an acceptable number */
    size_t acceptLen;		/* Number of characters following that
				 * point. */
    int status = TCL_OK;	/* Status to return to caller */
    char d = 0;			/* Last hexadecimal digit scanned; initialized
				 * to avoid a compiler warning. */
    int shift = 0;		/* Amount to shift when accumulating binary */
2260
2261
2262
2263
2264
2265
2266
2267

2268
2269
2270
2271
2272
2273
2274
2260
2261
2262
2263
2264
2265
2266

2267
2268
2269
2270
2271
2272
2273
2274







-
+








    /*
     * Infinite values can't convert to bignum.
     */

    if (TclIsInfinite(d)) {
	if (interp != NULL) {
	    char *s = "integer value too large to represent";
	    const char *s = "integer value too large to represent";
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
	}
	return TCL_ERROR;
    }

    fract = frexp(d,&expt);