mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
pstrtod
This commit is contained in:
parent
ae3d2aceb4
commit
8f96a87460
@ -122,7 +122,7 @@
|
|||||||
|
|
||||||
// And $[frameworks] is the set of OSX-style frameworks we will link with.
|
// And $[frameworks] is the set of OSX-style frameworks we will link with.
|
||||||
#defer frameworks $[unique $[get_frameworks]]
|
#defer frameworks $[unique $[get_frameworks]]
|
||||||
#defer bin_frameworks $[unique $[all_libs $[get_frameworks],$[complete_local_libs]]]
|
#defer bin_frameworks $[unique $[get_frameworks] $[all_libs $[get_frameworks],$[complete_local_libs]]]
|
||||||
//#defer bin_frameworks $[unique $[get_frameworks]]
|
//#defer bin_frameworks $[unique $[get_frameworks]]
|
||||||
|
|
||||||
// This is the set of files we might copy into *.prebuilt, if we have
|
// This is the set of files we might copy into *.prebuilt, if we have
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "cppCommentBlock.h"
|
#include "cppCommentBlock.h"
|
||||||
#include "cppBison.h"
|
#include "cppBison.h"
|
||||||
#include "indent.h"
|
#include "indent.h"
|
||||||
|
#include "pstrtod.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1915,7 +1916,7 @@ get_number(int c, int c2) {
|
|||||||
|
|
||||||
_last_c = c;
|
_last_c = c;
|
||||||
YYSTYPE result;
|
YYSTYPE result;
|
||||||
result.u.real = strtod(num.c_str(), (char **)NULL);
|
result.u.real = pstrtod(num.c_str(), (char **)NULL);
|
||||||
return CPPToken(REAL, first_line, first_col, first_file, num, result);
|
return CPPToken(REAL, first_line, first_col, first_file, num, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
nearly_zero.h \
|
nearly_zero.h \
|
||||||
neverFreeMemory.h neverFreeMemory.I \
|
neverFreeMemory.h neverFreeMemory.I \
|
||||||
numeric_types.h \
|
numeric_types.h \
|
||||||
|
pstrtod.h \
|
||||||
register_type.I register_type.h \
|
register_type.I register_type.h \
|
||||||
selectThreadImpl.h \
|
selectThreadImpl.h \
|
||||||
stl_compares.I stl_compares.h \
|
stl_compares.I stl_compares.h \
|
||||||
@ -56,6 +57,7 @@
|
|||||||
mutexWin32Impl.cxx \
|
mutexWin32Impl.cxx \
|
||||||
mutexSpinlockImpl.cxx \
|
mutexSpinlockImpl.cxx \
|
||||||
neverFreeMemory.cxx \
|
neverFreeMemory.cxx \
|
||||||
|
pstrtod.cxx \
|
||||||
register_type.cxx \
|
register_type.cxx \
|
||||||
typeHandle.cxx \
|
typeHandle.cxx \
|
||||||
typeRegistry.cxx typeRegistryNode.cxx \
|
typeRegistry.cxx typeRegistryNode.cxx \
|
||||||
@ -83,6 +85,7 @@
|
|||||||
nearly_zero.h \
|
nearly_zero.h \
|
||||||
neverFreeMemory.h neverFreeMemory.I \
|
neverFreeMemory.h neverFreeMemory.I \
|
||||||
numeric_types.h \
|
numeric_types.h \
|
||||||
|
pstrtod.h \
|
||||||
register_type.I register_type.h \
|
register_type.I register_type.h \
|
||||||
selectThreadImpl.h \
|
selectThreadImpl.h \
|
||||||
stl_compares.I stl_compares.h \
|
stl_compares.I stl_compares.h \
|
||||||
@ -95,3 +98,9 @@
|
|||||||
lookup3.h
|
lookup3.h
|
||||||
|
|
||||||
#end lib_target
|
#end lib_target
|
||||||
|
|
||||||
|
#begin test_bin_target
|
||||||
|
#define TARGET test_strtod
|
||||||
|
#define SOURCES test_strtod.cxx pstrtod.cxx pstrtod.h
|
||||||
|
|
||||||
|
#end test_bin_target
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "mutexWin32Impl.cxx"
|
#include "mutexWin32Impl.cxx"
|
||||||
#include "mutexSpinlockImpl.cxx"
|
#include "mutexSpinlockImpl.cxx"
|
||||||
#include "neverFreeMemory.cxx"
|
#include "neverFreeMemory.cxx"
|
||||||
|
#include "pstrtod.cxx"
|
||||||
#include "register_type.cxx"
|
#include "register_type.cxx"
|
||||||
#include "typeHandle.cxx"
|
#include "typeHandle.cxx"
|
||||||
#include "typeRegistry.cxx"
|
#include "typeRegistry.cxx"
|
||||||
|
179
dtool/src/dtoolbase/pstrtod.cxx
Normal file
179
dtool/src/dtoolbase/pstrtod.cxx
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
// Filename: pstrtod.cxx
|
||||||
|
// Created by: drose (13Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "pstrtod.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: pstrnicmp
|
||||||
|
// Description: This case-insenstive string compare function is used
|
||||||
|
// by pstrtod, below.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
static int
|
||||||
|
pstrnicmp(const char *s1, const char *s2, size_t n) {
|
||||||
|
if (n == 0) {
|
||||||
|
// Trivial equivalence.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (tolower(*s1) == tolower(*s2)) {
|
||||||
|
--n;
|
||||||
|
if ((*s1) == '\0' || n == 0) {
|
||||||
|
// They reached the end of the string together.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++s1;
|
||||||
|
++s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's a difference somewhere.
|
||||||
|
return (int)(unsigned char)(*s1) - (int)(unsigned char)(*s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: pstrtod
|
||||||
|
// Description: This function re-implements strtod, to avoid the
|
||||||
|
// problems that occur when the LC_NUMERIC locale gets
|
||||||
|
// set to anything other than "C". Regardless of the
|
||||||
|
// user's locale, we need to be able to parse
|
||||||
|
// floating-point numbers internally understanding a "."
|
||||||
|
// as the decimal point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
double
|
||||||
|
pstrtod(const char *nptr, char **endptr) {
|
||||||
|
// First, skip whitespace.
|
||||||
|
const char *p = nptr;
|
||||||
|
while (isspace(*p)) {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip an optional leading sign.
|
||||||
|
char sign = '+';
|
||||||
|
if (*p == '+' || *p == '-') {
|
||||||
|
sign = *p;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
if (pstrnicmp(p, "infinity", 8) == 0) {
|
||||||
|
value = INFINITY;
|
||||||
|
p += 8;
|
||||||
|
} else if (pstrnicmp(p, "inf", 3) == 0) {
|
||||||
|
value = INFINITY;
|
||||||
|
p += 3;
|
||||||
|
} else if (pstrnicmp(p, "nan", 3) == 0) {
|
||||||
|
value = NAN;
|
||||||
|
p += 3;
|
||||||
|
if (pstrnicmp(p, "0x", 2) == 0) {
|
||||||
|
// The NaN code also appears in the string. Use it.
|
||||||
|
static const size_t nan_code_size = 32;
|
||||||
|
char nan_code[nan_code_size + 1];
|
||||||
|
nan_code[0] = '0';
|
||||||
|
nan_code[1] = 'x';
|
||||||
|
const char *q = p + 2;
|
||||||
|
int ni = 2;
|
||||||
|
while (isdigit(*q) || (tolower(*q) >= 'a' && tolower(*q) <= 'f')) {
|
||||||
|
if (ni < nan_code_size) {
|
||||||
|
nan_code[ni] = *q;
|
||||||
|
++ni;
|
||||||
|
}
|
||||||
|
++q;
|
||||||
|
}
|
||||||
|
nan_code[ni] = '\0';
|
||||||
|
value = nan(nan_code);
|
||||||
|
p = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Start reading decimal digits to the left of the decimal point.
|
||||||
|
bool found_digits = false;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
value = (value * 10.0) + (*p - '0');
|
||||||
|
found_digits = true;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '.') {
|
||||||
|
++p;
|
||||||
|
// Read decimal digits to the right of the decimal point.
|
||||||
|
double multiplicand = 0.1;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
value += (*p - '0') * multiplicand;
|
||||||
|
++p;
|
||||||
|
found_digits = true;
|
||||||
|
multiplicand *= 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_digits) {
|
||||||
|
// Not a valid float.
|
||||||
|
if (endptr != NULL) {
|
||||||
|
*endptr = (char *)nptr;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tolower(*p) == 'e') {
|
||||||
|
// There's an exponent.
|
||||||
|
++p;
|
||||||
|
|
||||||
|
char esign = '+';
|
||||||
|
if (*p == '+' || *p == '-') {
|
||||||
|
esign = *p;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start reading decimal digits to the left of the decimal point.
|
||||||
|
double evalue = 0.0;
|
||||||
|
while (isdigit(*p)) {
|
||||||
|
evalue = (evalue * 10.0) + (*p - '0');
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esign == '-') {
|
||||||
|
value /= pow(evalue, 10.0);
|
||||||
|
} else {
|
||||||
|
value *= pow(evalue, 10.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sign == '-') {
|
||||||
|
value = -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endptr != NULL) {
|
||||||
|
*endptr = (char *)p;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: patof
|
||||||
|
// Description: This function re-implements atof, to avoid the
|
||||||
|
// problems that occur when the LC_NUMERIC locale gets
|
||||||
|
// set to anything other than "C". Regardless of the
|
||||||
|
// user's locale, we need to be able to parse
|
||||||
|
// floating-point numbers internally understanding a "."
|
||||||
|
// as the decimal point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
double
|
||||||
|
patof(const char *str) {
|
||||||
|
return pstrtod(str, (char **)NULL);
|
||||||
|
}
|
34
dtool/src/dtoolbase/pstrtod.h
Normal file
34
dtool/src/dtoolbase/pstrtod.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Filename: pstrtod.h
|
||||||
|
// Created by: drose (13Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef PSTRTOD_H
|
||||||
|
#define PSTRTOD_H
|
||||||
|
|
||||||
|
#include "dtoolbase.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXPCL_DTOOL double
|
||||||
|
pstrtod(const char *nptr, char **endptr);
|
||||||
|
|
||||||
|
EXPCL_DTOOL double
|
||||||
|
patof(const char *str);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* end of extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
36
dtool/src/dtoolbase/test_strtod.cxx
Normal file
36
dtool/src/dtoolbase/test_strtod.cxx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Filename: test_strtod.cxx
|
||||||
|
// Created by: drose (14Jun09)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "pstrtod.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[]) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
char *endptr = NULL;
|
||||||
|
double result = pstrtod(argv[i], &endptr);
|
||||||
|
cerr << "pstrtod - " << argv[i] << " : " << result << " : " << endptr << "\n";
|
||||||
|
result = strtod(argv[i], &endptr);
|
||||||
|
cerr << "strtod - " << argv[i] << " : " << result << " : " << endptr << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user