summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2024-05-31 11:48:58 -0300
committerEuAndreh <eu@euandre.org>2024-05-31 11:48:58 -0300
commitfa2862fa648cca9a181184a849444409d07e9fb2 (patch)
tree3f3e79879df960b493f9c5f903464b03dc321855
parentsrc/util.h: Add EXIT_USAGE (diff)
downloadpindaiba-fa2862fa648cca9a181184a849444409d07e9fb2.tar.gz
pindaiba-fa2862fa648cca9a181184a849444409d07e9fb2.tar.xz
src/math.h: Add "add_size()"
-rw-r--r--src/math.c18
-rw-r--r--src/math.h3
-rw-r--r--tests/math.c66
3 files changed, 85 insertions, 2 deletions
diff --git a/src/math.c b/src/math.c
index 366bd5e..4e9fee0 100644
--- a/src/math.c
+++ b/src/math.c
@@ -1,6 +1,7 @@
#include "config.h"
#include <assert.h>
+#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -9,8 +10,23 @@
int
+add_size(const size_t x, const size_t y, size_t *const out) {
+ int rc = EOVERFLOW;
+
+ const bool overflows = (SIZE_MAX - x) < y;
+ if (overflows) {
+ goto out;
+ }
+
+ *out = x + y;
+ rc = 0;
+out:
+ return rc;
+}
+
+int
mul_size(const size_t x, const size_t y, size_t *const out) {
- int rc = -1;
+ int rc = EOVERFLOW;
assert(x != 0U);
assert(y != 0U);
diff --git a/src/math.h b/src/math.h
index 13f1795..4dab4a7 100644
--- a/src/math.h
+++ b/src/math.h
@@ -1,2 +1,5 @@
int
+add_size(const size_t x, const size_t y, size_t *const out);
+
+int
mul_size(const size_t x, const size_t y, size_t *const out);
diff --git a/tests/math.c b/tests/math.c
index 34f54ce..d2b64c6 100644
--- a/tests/math.c
+++ b/tests/math.c
@@ -1,9 +1,72 @@
#include "../src/math.c"
+#include <stdlib.h>
+
#include "../src/testing.h"
static void
+test_add_size(void) {
+ test_start("add_size()");
+
+ size_t val;
+ {
+ testing("zero values");
+
+ assert(add_size(0U, 0U, &val) == 0);
+ assert(val == 0U);
+
+ assert(add_size(1U, 0U, &val) == 0);
+ assert(val == 1U);
+
+ assert(add_size(0U, 1U, &val) == 0);
+ assert(val == 1U);
+
+ assert(add_size(0U, 3U, &val) == 0);
+ assert(val == 3U);
+
+ assert(add_size(30U, 0U, &val) == 0);
+ assert(val == 30U);
+
+ test_ok();
+ }
+ {
+ testing("small values");
+
+ assert(add_size(1U, 2U, &val) == 0);
+ assert(val == 3U);
+
+ assert(add_size(34U, 56U, &val) == 0);
+ assert(val == 90U);
+
+ assert(add_size(121U, 122U, &val) == 0);
+ assert(val == 243U);
+
+ test_ok();
+ }
+ {
+ testing("big values");
+
+ assert(add_size(SIZE_MAX, 0U, &val) == 0);
+ assert(val == SIZE_MAX);
+
+ assert(add_size(SIZE_MAX - 10U, 3U, &val) == 0);
+ assert(val == (SIZE_MAX - 7U));
+
+ test_ok();
+ }
+ {
+ testing("overflowing values");
+
+ val = 0U;
+ assert(add_size(SIZE_MAX, 1U, &val) != 0);
+ assert(val == 0U);
+
+ test_ok();
+ }
+}
+
+static void
test_mul_size(void) {
test_start("mul_size()");
@@ -62,6 +125,7 @@ test_mul_size(void) {
int
main(void) {
+ test_add_size();
test_mul_size();
- return 0;
+ return EXIT_SUCCESS;
}