Skip to content

Commit

Permalink
Merge pull request RIOT-OS#20902 from maribu/work-around-newlib-nano-…
Browse files Browse the repository at this point in the history
…stdio-missing-64-bit-support

tree-wide: fix compilation with newlib and GCC 13.2.1
  • Loading branch information
benpicco authored Oct 10, 2024
2 parents 68789a9 + 8c9105c commit 3abfc81
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
From 81fe23c11da5f7e528846e8b3d5aaa9ae0f7aadd Mon Sep 17 00:00:00 2001
From: Marian Buschsieweke <[email protected]>
Date: Wed, 9 Oct 2024 22:17:05 +0200
Subject: [PATCH] fix(pretty): fix compilation with newlib and GCC 13.2.1

newlib (nano) is missing 64 bit support in stdio and inttypes.h. This
works around the issue.
---
src/cborpretty.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/cborpretty.c b/src/cborpretty.c
index 49d3cae..4397f39 100644
--- a/src/cborpretty.c
+++ b/src/cborpretty.c
@@ -374,12 +374,26 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
cbor_value_get_raw_integer(it, &val); /* can't fail */

if (cbor_value_is_unsigned_integer(it)) {
+#ifdef PRIu64
err = stream(out, "%" PRIu64, val);
+#else
+ err = stream(out, "%" PRIu32, (uint32_t)val);
+ if (!err && ((uint32_t)val != val)) {
+ err = stream(out, "!trunc!");
+ }
+#endif
} else {
/* CBOR stores the negative number X as -1 - X
* (that is, -1 is stored as 0, -2 as 1 and so forth) */
if (++val) { /* unsigned overflow may happen */
+#ifdef PRIu64
err = stream(out, "-%" PRIu64, val);
+#else
+ err = stream(out, "-%" PRIu32, (uint32_t)val);
+ if (!err && ((uint32_t)val != val)) {
+ err = stream(out, "!trunc!");
+ }
+#endif
} else {
/* overflown
* 0xffff`ffff`ffff`ffff + 1 =
@@ -450,7 +464,13 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
case CborTagType: {
CborTag tag;
cbor_value_get_tag(it, &tag); /* can't fail */
+#ifdef PRIu64
err = stream(out, "%" PRIu64 "%s(", tag, get_indicator(it, flags));
+#else
+ err = stream(out, "%" PRIu32 "%s%s(", (uint32_t)tag,
+ ((uint32_t)tag != tag) ? "!trunc!" : "",
+ get_indicator(it, flags));
+#endif
if (!err)
err = cbor_value_advance_fixed(it);
if (!err && recursionsLeft)
@@ -490,7 +510,6 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
const char *suffix;
double val;
int r;
- uint64_t ival;

if (false) {
float f;
@@ -521,14 +540,19 @@ static CborError value_to_pretty(CborStreamFunction stream, void *out, CborValue
suffix = "";
}

+#ifdef PRIu64
+ uint64_t ival;
if (convertToUint64(val, &ival)) {
/* this double value fits in a 64-bit integer, so show it as such
* (followed by a floating point suffix, to disambiguate) */
err = stream(out, "%s%" PRIu64 ".%s", val < 0 ? "-" : "", ival, suffix);
} else {
+#endif
/* this number is definitely not a 64-bit integer */
err = stream(out, "%." DBL_DECIMAL_DIG_STR "g%s", val, suffix);
+#ifdef PRIu64
}
+#endif
break;
}
#else
--
2.43.0

7 changes: 7 additions & 0 deletions sys/matstat/matstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ uint64_t matstat_variance(const matstat_state_t *state)
return 0;
}
uint64_t variance = state->sum_sq / (state->count - 1);
#ifdef PRIu64
DEBUG("Var: (%" PRIu64 " / (%" PRId32 " - 1)) = %" PRIu64 "\n",
state->sum_sq, state->count, variance);
#else
DEBUG("Var: (%" PRIu32 "%s / (%" PRId32 " - 1)) = %" PRIu32 "%s\n",
(uint32_t)state->sum_sq, (state->sum_sq > UINT32_MAX) ? "!trunc " : "",
state->count,
(uint32_t)variance, (variance > UINT32_MAX) ? "!trunc " : "");
#endif
return variance;
}

Expand Down
17 changes: 17 additions & 0 deletions tests/unittests/tests-div/tests-div.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include <string.h>
#include <inttypes.h>
#include "embUnit.h"
#include "tests-div.h"

Expand Down Expand Up @@ -78,7 +79,13 @@ static void test_div_u64_by_15625(void)
}

for (unsigned i = 0; i < N_U64_VALS; i++) {
#ifdef PRIu64
DEBUG("Dividing %12"PRIu64" by 15625...\n", u64_test_values[i]);
#else
DEBUG("Dividing %12"PRIu32"%s by 15625...\n", (uint32_t)u64_test_values[i],
((uint32_t)u64_test_values[i] != u64_test_values[i]) ? "!trunc" : "");
#endif

TEST_ASSERT_EQUAL_INT(
(uint64_t)u64_test_values[i] / 15625,
div_u64_by_15625(u64_test_values[i]));
Expand All @@ -105,7 +112,12 @@ static void test_div_u64_by_1000000(void)
}

for (unsigned i = 0; i < N_U64_VALS; i++) {
#ifdef PRIu64
DEBUG("Dividing %"PRIu64" by 1000000...\n", u64_test_values[i]);
#else
DEBUG("Dividing %"PRIu32"%s by 1000000...\n", (uint32_t)u64_test_values[i],
((uint32_t)u64_test_values[i] != u64_test_values[i]) ? "!trunc" : "");
#endif
TEST_ASSERT_EQUAL_INT(
u64_test_values[i] / 1000000lu,
div_u64_by_1000000(u64_test_values[i]));
Expand All @@ -122,7 +134,12 @@ static void test_div_u64_by_15625div512(void)
}

for (unsigned i = 0; i < N_U64_VALS; i++) {
#ifdef PRIu64
DEBUG("Dividing %"PRIu64" by (15625/512)...\n", u64_test_values[i]);
#else
DEBUG("Dividing %"PRIu32"%s by (15625/512)...\n", (uint32_t)u64_test_values[i],
((uint32_t)u64_test_values[i] != u64_test_values[i]) ? "!trunc" : "");
#endif
TEST_ASSERT_EQUAL_INT(
u64_15625_512_expected_values[i],
div_u64_by_15625div512(u64_test_values[i]));
Expand Down
13 changes: 11 additions & 2 deletions tests/unittests/tests-frac/tests-frac.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
* directory for more details.
*/

#include <inttypes.h>
#include <string.h>
#include "embUnit.h"
#include "tests-frac.h"

#include "kernel_defines.h"
#include "frac.h"
#include "div.h"

#define ENABLE_DEBUG 0
#include "debug.h"
Expand Down Expand Up @@ -120,11 +119,21 @@ static void test_frac_scale32(void)
uint32_t actual = frac_scale(&frac, u32_test_values[i]);
if ((uint32_t)expected != actual) {
int32_t diff = actual - expected;
#ifdef PRIu64
DEBUG("%" PRIu32 " * (%" PRIu32 " / %" PRIu32 ")"
" tmp %" PRIu64 " expect %" PRIu32 ", actual %" PRIu32
", diff = %" PRId32 " shift=%u\n",
u32_test_values[i], num, den, tmp, (uint32_t)expected,
actual, diff, frac.shift);
#else
DEBUG("%" PRIu32 " * (%" PRIu32 " / %" PRIu32 ")"
" tmp %" PRIu32"%s expect %" PRIu32 ", actual %" PRIu32
", diff = %" PRId32 " shift=%u\n",
u32_test_values[i], num, den,
(uint32_t)tmp, ((uint32_t)tmp != tmp) ? "!trunc" : "",
(uint32_t)expected,
actual, diff, frac.shift);
#endif

/* The frac algorithm sacrifices accuracy for speed,
* some large numbers will be incorrectly rounded,
Expand Down

0 comments on commit 3abfc81

Please sign in to comment.