Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
45442498
Commit
45442498
authored
Apr 07, 2017
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make string parse exceptions recoverable under -fno-exceptions.
parent
f93ea92c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
37 deletions
+39
-37
json-test.c++
c++/src/capnp/compat/json-test.c++
+7
-6
string-test.c++
c++/src/kj/string-test.c++
+20
-20
string.c++
c++/src/kj/string.c++
+12
-11
No files found.
c++/src/capnp/compat/json-test.c++
View file @
45442498
...
@@ -222,8 +222,8 @@ KJ_TEST("decode all types") {
...
@@ -222,8 +222,8 @@ KJ_TEST("decode all types") {
CASE
(
R"({"int64Field":9007199254740991})"
,
root
.
getInt64Field
()
==
9007199254740991LL
);
CASE
(
R"({"int64Field":9007199254740991})"
,
root
.
getInt64Field
()
==
9007199254740991LL
);
CASE
(
R"({"int64Field":"-9223372036854775808"})"
,
root
.
getInt64Field
()
==
-
9223372036854775808ULL
);
CASE
(
R"({"int64Field":"-9223372036854775808"})"
,
root
.
getInt64Field
()
==
-
9223372036854775808ULL
);
CASE
(
R"({"int64Field":"9223372036854775807"})"
,
root
.
getInt64Field
()
==
9223372036854775807LL
);
CASE
(
R"({"int64Field":"9223372036854775807"})"
,
root
.
getInt64Field
()
==
9223372036854775807LL
);
CASE_THROW
(
R"({"int64Field":"-9223372036854775809"})"
,
"Value out-of-range"
);
CASE_THROW
_RECOVERABLE
(
R"({"int64Field":"-9223372036854775809"})"
,
"Value out-of-range"
);
CASE_THROW
(
R"({"int64Field":"9223372036854775808"})"
,
"Value out-of-range"
);
CASE_THROW
_RECOVERABLE
(
R"({"int64Field":"9223372036854775808"})"
,
"Value out-of-range"
);
CASE
(
R"({"uInt8Field":255})"
,
root
.
getUInt8Field
()
==
255
);
CASE
(
R"({"uInt8Field":255})"
,
root
.
getUInt8Field
()
==
255
);
CASE
(
R"({"uInt8Field":"0"})"
,
root
.
getUInt8Field
()
==
0
);
CASE
(
R"({"uInt8Field":"0"})"
,
root
.
getUInt8Field
()
==
0
);
CASE_THROW_RECOVERABLE
(
R"({"uInt8Field":"256"})"
,
"Value out-of-range"
);
CASE_THROW_RECOVERABLE
(
R"({"uInt8Field":"256"})"
,
"Value out-of-range"
);
...
@@ -239,7 +239,7 @@ KJ_TEST("decode all types") {
...
@@ -239,7 +239,7 @@ KJ_TEST("decode all types") {
CASE
(
R"({"uInt64Field":9007199254740991})"
,
root
.
getUInt64Field
()
==
9007199254740991ULL
);
CASE
(
R"({"uInt64Field":9007199254740991})"
,
root
.
getUInt64Field
()
==
9007199254740991ULL
);
CASE
(
R"({"uInt64Field":"18446744073709551615"})"
,
root
.
getUInt64Field
()
==
18446744073709551615ULL
);
CASE
(
R"({"uInt64Field":"18446744073709551615"})"
,
root
.
getUInt64Field
()
==
18446744073709551615ULL
);
CASE
(
R"({"uInt64Field":"0"})"
,
root
.
getUInt64Field
()
==
0
);
CASE
(
R"({"uInt64Field":"0"})"
,
root
.
getUInt64Field
()
==
0
);
CASE_THROW
(
R"({"uInt64Field":"18446744073709551616"})"
,
"Value out-of-range"
);
CASE_THROW
_RECOVERABLE
(
R"({"uInt64Field":"18446744073709551616"})"
,
"Value out-of-range"
);
CASE
(
R"({"float32Field":0})"
,
root
.
getFloat32Field
()
==
0
);
CASE
(
R"({"float32Field":0})"
,
root
.
getFloat32Field
()
==
0
);
CASE
(
R"({"float32Field":4.5})"
,
root
.
getFloat32Field
()
==
4.5
);
CASE
(
R"({"float32Field":4.5})"
,
root
.
getFloat32Field
()
==
4.5
);
CASE
(
R"({"float32Field":null})"
,
kj
::
isNaN
(
root
.
getFloat32Field
()));
CASE
(
R"({"float32Field":null})"
,
kj
::
isNaN
(
root
.
getFloat32Field
()));
...
@@ -264,9 +264,9 @@ KJ_TEST("decode all types") {
...
@@ -264,9 +264,9 @@ KJ_TEST("decode all types") {
CASE
(
R"({"structField":{"boolField":true}})"
,
root
.
getStructField
().
getBoolField
()
==
true
);
CASE
(
R"({"structField":{"boolField":true}})"
,
root
.
getStructField
().
getBoolField
()
==
true
);
CASE
(
R"({"enumField":"bar"})"
,
root
.
getEnumField
()
==
TestEnum
::
BAR
);
CASE
(
R"({"enumField":"bar"})"
,
root
.
getEnumField
()
==
TestEnum
::
BAR
);
CASE_THROW
(
R"({"int64Field":"177a"})"
,
"String does not contain valid"
);
CASE_THROW
_RECOVERABLE
(
R"({"int64Field":"177a"})"
,
"String does not contain valid"
);
CASE_THROW
(
R"({"uInt64Field":"177a"})"
,
"String does not contain valid"
);
CASE_THROW
_RECOVERABLE
(
R"({"uInt64Field":"177a"})"
,
"String does not contain valid"
);
CASE_THROW
(
R"({"float64Field":"177a"})"
,
"String does not contain valid"
);
CASE_THROW
_RECOVERABLE
(
R"({"float64Field":"177a"})"
,
"String does not contain valid"
);
CASE
(
R"({})"
,
root
.
hasBoolList
()
==
false
);
CASE
(
R"({})"
,
root
.
hasBoolList
()
==
false
);
CASE
(
R"({"boolList":null})"
,
root
.
hasBoolList
()
==
false
);
CASE
(
R"({"boolList":null})"
,
root
.
hasBoolList
()
==
false
);
...
@@ -315,6 +315,7 @@ KJ_TEST("decode all types") {
...
@@ -315,6 +315,7 @@ KJ_TEST("decode all types") {
CASE
(
R"({"enumList":["bar"]})"
,
root
.
getEnumList
()[
0
]
==
TestEnum
::
BAR
);
CASE
(
R"({"enumList":["bar"]})"
,
root
.
getEnumList
()[
0
]
==
TestEnum
::
BAR
);
#undef CASE
#undef CASE
#undef CASE_THROW
#undef CASE_THROW
#undef CASE_THROW_RECOVERABLE
}
}
KJ_TEST
(
"decode test message"
)
{
KJ_TEST
(
"decode test message"
)
{
...
...
c++/src/kj/string-test.c++
View file @
45442498
...
@@ -86,22 +86,22 @@ TEST(String, parseAs) {
...
@@ -86,22 +86,22 @@ TEST(String, parseAs) {
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"nan"
).
parseAs
<
double
>
()));
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"nan"
).
parseAs
<
double
>
()));
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"NAN"
).
parseAs
<
double
>
()));
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"NAN"
).
parseAs
<
double
>
()));
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"NaN"
).
parseAs
<
double
>
()));
EXPECT_TRUE
(
isNaN
(
StringPtr
(
"NaN"
).
parseAs
<
double
>
()));
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
double
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
double
>
());
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
float
>
(),
1.0
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
float
>
(),
1.0
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int64_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int64_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"9223372036854775807"
).
parseAs
<
int64_t
>
(),
9223372036854775807LL
);
EXPECT_EQ
(
StringPtr
(
"9223372036854775807"
).
parseAs
<
int64_t
>
(),
9223372036854775807LL
);
EXPECT_EQ
(
StringPtr
(
"-9223372036854775808"
).
parseAs
<
int64_t
>
(),
-
9223372036854775808ULL
);
EXPECT_EQ
(
StringPtr
(
"-9223372036854775808"
).
parseAs
<
int64_t
>
(),
-
9223372036854775808ULL
);
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"9223372036854775808"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"9223372036854775808"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"-9223372036854775809"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"-9223372036854775809"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
int64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
int64_t
>
());
EXPECT_EQ
(
StringPtr
(
"010"
).
parseAs
<
int64_t
>
(),
10
);
EXPECT_EQ
(
StringPtr
(
"010"
).
parseAs
<
int64_t
>
(),
10
);
EXPECT_EQ
(
StringPtr
(
"0010"
).
parseAs
<
int64_t
>
(),
10
);
EXPECT_EQ
(
StringPtr
(
"0010"
).
parseAs
<
int64_t
>
(),
10
);
EXPECT_EQ
(
StringPtr
(
"0x10"
).
parseAs
<
int64_t
>
(),
16
);
EXPECT_EQ
(
StringPtr
(
"0x10"
).
parseAs
<
int64_t
>
(),
16
);
...
@@ -113,24 +113,24 @@ TEST(String, parseAs) {
...
@@ -113,24 +113,24 @@ TEST(String, parseAs) {
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint64_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint64_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"0"
).
parseAs
<
uint64_t
>
(),
0
);
EXPECT_EQ
(
StringPtr
(
"0"
).
parseAs
<
uint64_t
>
(),
0
);
EXPECT_EQ
(
StringPtr
(
"18446744073709551615"
).
parseAs
<
uint64_t
>
(),
18446744073709551615ULL
);
EXPECT_EQ
(
StringPtr
(
"18446744073709551615"
).
parseAs
<
uint64_t
>
(),
18446744073709551615ULL
);
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"-1"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"-1"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"18446744073709551616"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"18446744073709551616"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
""
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"a"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"1a"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
uint64_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"not contain valid"
,
StringPtr
(
"+-1"
).
parseAs
<
uint64_t
>
());
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int32_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int32_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"2147483647"
).
parseAs
<
int32_t
>
(),
2147483647
);
EXPECT_EQ
(
StringPtr
(
"2147483647"
).
parseAs
<
int32_t
>
(),
2147483647
);
EXPECT_EQ
(
StringPtr
(
"-2147483648"
).
parseAs
<
int32_t
>
(),
-
2147483648
);
EXPECT_EQ
(
StringPtr
(
"-2147483648"
).
parseAs
<
int32_t
>
(),
-
2147483648
);
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"2147483648"
).
parseAs
<
int32_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"2147483648"
).
parseAs
<
int32_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"-2147483649"
).
parseAs
<
int32_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"-2147483649"
).
parseAs
<
int32_t
>
());
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint32_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint32_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"0"
).
parseAs
<
uint32_t
>
(),
0U
);
EXPECT_EQ
(
StringPtr
(
"0"
).
parseAs
<
uint32_t
>
(),
0U
);
EXPECT_EQ
(
StringPtr
(
"4294967295"
).
parseAs
<
uint32_t
>
(),
4294967295U
);
EXPECT_EQ
(
StringPtr
(
"4294967295"
).
parseAs
<
uint32_t
>
(),
4294967295U
);
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"-1"
).
parseAs
<
uint32_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"-1"
).
parseAs
<
uint32_t
>
());
KJ_EXPECT_THROW_MESSAGE
(
"out-of-range"
,
StringPtr
(
"4294967296"
).
parseAs
<
uint32_t
>
());
KJ_EXPECT_THROW_
RECOVERABLE_
MESSAGE
(
"out-of-range"
,
StringPtr
(
"4294967296"
).
parseAs
<
uint32_t
>
());
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int16_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
int16_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint16_t
>
(),
1
);
EXPECT_EQ
(
StringPtr
(
"1"
).
parseAs
<
uint16_t
>
(),
1
);
...
...
c++/src/kj/string.c++
View file @
45442498
...
@@ -40,25 +40,26 @@ bool isHex(const char *s) {
...
@@ -40,25 +40,26 @@ bool isHex(const char *s) {
}
}
long
long
parseSigned
(
const
StringPtr
&
s
,
long
long
min
,
long
long
max
)
{
long
long
parseSigned
(
const
StringPtr
&
s
,
long
long
min
,
long
long
max
)
{
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
;
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
{
return
0
;
}
char
*
endPtr
;
char
*
endPtr
;
errno
=
0
;
errno
=
0
;
auto
value
=
strtoll
(
s
.
begin
(),
&
endPtr
,
isHex
(
s
.
cStr
())
?
16
:
10
);
auto
value
=
strtoll
(
s
.
begin
(),
&
endPtr
,
isHex
(
s
.
cStr
())
?
16
:
10
);
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid number"
,
s
)
;
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid number"
,
s
)
{
return
0
;
}
KJ_REQUIRE
(
errno
!=
ERANGE
,
"Value out-of-range"
,
s
)
;
KJ_REQUIRE
(
errno
!=
ERANGE
,
"Value out-of-range"
,
s
)
{
return
0
;
}
KJ_REQUIRE
(
value
>=
min
&&
value
<=
max
,
"Value out-of-range"
,
value
,
min
,
max
)
;
KJ_REQUIRE
(
value
>=
min
&&
value
<=
max
,
"Value out-of-range"
,
value
,
min
,
max
)
{
return
0
;
}
return
value
;
return
value
;
}
}
unsigned
long
long
parseUnsigned
(
const
StringPtr
&
s
,
unsigned
long
long
max
)
{
unsigned
long
long
parseUnsigned
(
const
StringPtr
&
s
,
unsigned
long
long
max
)
{
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
;
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
{
return
0
;
}
char
*
endPtr
;
char
*
endPtr
;
errno
=
0
;
errno
=
0
;
auto
value
=
strtoull
(
s
.
begin
(),
&
endPtr
,
isHex
(
s
.
cStr
())
?
16
:
10
);
auto
value
=
strtoull
(
s
.
begin
(),
&
endPtr
,
isHex
(
s
.
cStr
())
?
16
:
10
);
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid number"
,
s
);
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid number"
,
s
)
{
return
0
;
}
KJ_REQUIRE
(
errno
!=
ERANGE
,
"Value out-of-range"
,
s
);
KJ_REQUIRE
(
errno
!=
ERANGE
,
"Value out-of-range"
,
s
)
{
return
0
;
}
KJ_REQUIRE
(
value
<=
max
,
"Value out-of-range"
,
value
,
max
);
KJ_REQUIRE
(
value
<=
max
,
"Value out-of-range"
,
value
,
max
)
{
return
0
;
}
KJ_REQUIRE
(
s
[
0
]
!=
'-'
,
"Value out-of-range"
,
s
);
//strtoull("-1") does not fail with ERANGE
//strtoull("-1") does not fail with ERANGE
KJ_REQUIRE
(
s
[
0
]
!=
'-'
,
"Value out-of-range"
,
s
)
{
return
0
;
}
return
value
;
return
value
;
}
}
...
@@ -75,11 +76,11 @@ T parseInteger(const StringPtr& s) {
...
@@ -75,11 +76,11 @@ T parseInteger(const StringPtr& s) {
}
}
double
parseDouble
(
const
StringPtr
&
s
)
{
double
parseDouble
(
const
StringPtr
&
s
)
{
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
;
KJ_REQUIRE
(
s
!=
nullptr
,
"String does not contain valid number"
,
s
)
{
return
0
;
}
char
*
endPtr
;
char
*
endPtr
;
errno
=
0
;
errno
=
0
;
auto
value
=
strtod
(
s
.
begin
(),
&
endPtr
);
auto
value
=
strtod
(
s
.
begin
(),
&
endPtr
);
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid floating number"
,
s
)
;
KJ_REQUIRE
(
endPtr
==
s
.
end
(),
"String does not contain valid floating number"
,
s
)
{
return
0
;
}
return
value
;
return
value
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment