aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-07-07 23:50:39 -0400
committerDavid Robillard <d@drobilla.net>2019-04-13 19:15:32 +0200
commit07c3c06f59348c5558c909b2aa10734bf95e62e7 (patch)
tree052785f9621b3b7aac8620660faf8ec0a3cd6038
parent8f88d086f0d94c1d6e8afbcd16c10b392cbb207c (diff)
downloadserd-07c3c06f59348c5558c909b2aa10734bf95e62e7.tar.gz
serd-07c3c06f59348c5558c909b2aa10734bf95e62e7.tar.bz2
serd-07c3c06f59348c5558c909b2aa10734bf95e62e7.zip
Make serd_strtod API const-correct
This is an API breakage, but a minor one (particularly since NULL is allowed) that avoids the flaw in the C API.
-rw-r--r--NEWS1
-rw-r--r--serd/serd.h8
-rw-r--r--src/reader.c2
-rw-r--r--src/reader.h2
-rw-r--r--src/serd_internal.h2
-rw-r--r--src/string.c6
-rw-r--r--tests/serd_test.c6
7 files changed, 16 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index a503eaee..72deca90 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ serd (1.0.0) unstable;
* Remove useless character counting from API
* Use char* for strings in public API
* Rename SerdChunk to SerdStringView
+ * Make serd_strtod API const-correct
-- David Robillard <d@drobilla.net> Sat, 19 Jan 2019 13:31:12 +0100
diff --git a/serd/serd.h b/serd/serd.h
index e8aff1e8..ba285255 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -316,13 +316,15 @@ serd_strlen(const char* str, SerdNodeFlags* flags);
/**
Parse a string to a double.
- The API of this function is identical to the standard C strtod function,
+ The API of this function is similar to the standard C strtod function,
except this function is locale-independent and always matches the lexical
- format used in the Turtle grammar (the decimal point is always ".").
+ format used in the Turtle grammar (the decimal point is always "."). The
+ end parameter is an offset from the start of `str` to avoid the
+ const-correctness issues of the strtod API.
*/
SERD_API
double
-serd_strtod(const char* str, char** endptr);
+serd_strtod(const char* str, size_t* end);
/**
Decode a base64 string.
diff --git a/src/reader.c b/src/reader.c
index 0eb06c88..37c4719c 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -79,7 +79,7 @@ Ref
push_node_padded(SerdReader* reader, size_t maxlen,
SerdType type, const char* str, size_t n_bytes)
{
- char* mem = (char*)serd_stack_push_aligned(
+ void* mem = serd_stack_push_aligned(
&reader->stack, sizeof(SerdNode) + maxlen + 1, sizeof(SerdNode));
SerdNode* const node = (SerdNode*)mem;
diff --git a/src/reader.h b/src/reader.h
index 6e1a24d7..f3ddde0a 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -68,7 +68,7 @@ static inline SerdStatus
push_byte(SerdReader* reader, Ref ref, const uint8_t c)
{
SERD_STACK_ASSERT_TOP(reader, ref);
- char* const s = serd_stack_push(&reader->stack, 1);
+ char* const s = (char*)serd_stack_push(&reader->stack, 1);
SerdNode* const node = (SerdNode*)(reader->stack.buf + ref);
++node->n_bytes;
*(s - 1) = c;
diff --git a/src/serd_internal.h b/src/serd_internal.h
index c51b88ed..62c0a72c 100644
--- a/src/serd_internal.h
+++ b/src/serd_internal.h
@@ -195,7 +195,7 @@ serd_stack_free(SerdStack* stack)
stack->size = 0;
}
-static inline char*
+static inline void*
serd_stack_push(SerdStack* stack, size_t n_bytes)
{
const size_t new_size = stack->size + n_bytes;
diff --git a/src/string.c b/src/string.c
index a1d46507..01ed25a0 100644
--- a/src/string.c
+++ b/src/string.c
@@ -100,7 +100,7 @@ read_sign(const char** sptr)
}
double
-serd_strtod(const char* str, char** endptr)
+serd_strtod(const char* str, size_t* end)
{
double result = 0.0;
@@ -136,8 +136,8 @@ serd_strtod(const char* str, char** endptr)
result *= pow(10, expt * expt_sign);
}
- if (endptr) {
- *endptr = (char*)s;
+ if (end) {
+ *end = s - str;
}
return result * sign;
diff --git a/tests/serd_test.c b/tests/serd_test.c
index c2d70136..6f041e2d 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -39,11 +39,13 @@ test_strtod(double dbl, double max_delta)
char buf[1024];
snprintf(buf, sizeof(buf), "%f", dbl);
- char* endptr = NULL;
- const double out = serd_strtod(buf, &endptr);
+ size_t end = 0;
+ const double out = serd_strtod(buf, &end);
const double diff = fabs(out - dbl);
assert(diff <= max_delta);
+ assert(end == strlen(buf));
+
return 0;
}