diff options
author | Alejandro Colomar <alx@kernel.org> | 2024-01-12 17:28:44 +0100 |
---|---|---|
committer | Alejandro Colomar <alx@kernel.org> | 2024-01-13 19:42:36 +0100 |
commit | f055932d64fa3bfa97a9fa5e53d2eafe906ced4e (patch) | |
tree | 1b0dceb3b8306aa04f4175a70c969dda151fce4c | |
parent | ee23a0d38b650977b72095502ea8d1346841f30b (diff) | |
download | liba2i-f055932d64fa3bfa97a9fa5e53d2eafe906ced4e.tar.gz |
share/tests/: Add tests
Signed-off-by: Alejandro Colomar <alx@kernel.org>
84 files changed, 11094 insertions, 0 deletions
diff --git a/share/tests/a2i.h/a2i/a2i.c b/share/tests/a2i.h/a2i/a2i.c new file mode 100644 index 0000000..c65c081 --- /dev/null +++ b/share/tests/a2i.h/a2i/a2i.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned int n; + + assert(a2i(unsigned int, &n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(unsigned int, &n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i(unsigned int, &n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2i(unsigned int, &n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2i(unsigned int, &n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2i(unsigned int, &n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2i(unsigned int, &n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2i(unsigned int, &n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2i(unsigned int, &n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2i(unsigned int, &n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + long n; + + assert(a2i(long, &n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2i(long, &n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2i(long, &n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2i(long, &n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2i(long, &n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2i(long, &n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2i(long, &n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i(long, &n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2i(long, &n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(long, &n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned long long n; + + assert(a2i(unsigned long long, &n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2i(unsigned long long, &n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2i(unsigned long long, &n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2i(unsigned long long, &n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2i(unsigned long long, &n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(unsigned long long, &n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(unsigned long long, &n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + signed char n; + + assert(a2i(signed char, &n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i(signed char, &n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i(signed char, &n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2i(signed char, &n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2i(signed char, &n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2i(signed char, &n, "-1", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "0x7F", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == 0x7F); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i(signed char, &n, "-0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned short n; + + assert(a2i(unsigned short, &n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2i(unsigned short, &n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2i(unsigned short, &n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2i/a2i.sh b/share/tests/a2i.h/a2i/a2i.sh new file mode 100755 index 0000000..5d15c49 --- /dev/null +++ b/share/tests/a2i.h/a2i/a2i.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2i.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2i/a2i_nobuild.sh b/share/tests/a2i.h/a2i/a2i_nobuild.sh new file mode 100755 index 0000000..a91c0fa --- /dev/null +++ b/share/tests/a2i.h/a2i/a2i_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected error: [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned char n; + + a2i(signed char, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected error: [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2i(unsigned int, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'error: ._Generic. selector' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected error: '_Generic' selector"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + float n; + + a2i(float, &n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2s/a2s.c b/share/tests/a2i.h/a2s/a2s.c new file mode 100644 index 0000000..c07b01e --- /dev/null +++ b/share/tests/a2i.h/a2s/a2s.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + int n; + + assert(a2s(int, &n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(int, &n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2s(int, &n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2s(int, &n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2s(int, &n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2s(int, &n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2s(int, &n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2s(int, &n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2s(int, &n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2s(int, &n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + long n; + + assert(a2s(long, &n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2s(long, &n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2s(long, &n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2s(long, &n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2s(long, &n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2s(long, &n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2s(long, &n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2s(long, &n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2s(long, &n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long, &n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + long long n; + + assert(a2s(long long, &n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2s(long long, &n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2s(long long, &n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2s(long long, &n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2s(long long, &n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long long, &n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(long long, &n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + signed char n; + + assert(a2s(signed char, &n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2s(signed char, &n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2s(signed char, &n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2s(signed char, &n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2s(signed char, &n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2s(signed char, &n, "-1", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "0x7F", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == 0x7F); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2s(signed char, &n, "-0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + short n; + + assert(a2s(short, &n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2s(short, &n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2s(short, &n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2s/a2s.sh b/share/tests/a2i.h/a2s/a2s.sh new file mode 100755 index 0000000..33a5e2b --- /dev/null +++ b/share/tests/a2i.h/a2s/a2s.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2s.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2s/a2s_nobuild.sh b/share/tests/a2i.h/a2s/a2s_nobuild.sh new file mode 100755 index 0000000..addcf7f --- /dev/null +++ b/share/tests/a2i.h/a2s/a2s_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned char n; + + a2s(signed char, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2s(int, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'static assertion failed' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected static assertion failed"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2s(unsigned long, &n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2sh/a2sh.c b/share/tests/a2i.h/a2sh/a2sh.c new file mode 100644 index 0000000..d12fab5 --- /dev/null +++ b/share/tests/a2i.h/a2sh/a2sh.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + short n; + + assert(a2sh(&n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2sh(&n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2sh(&n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2sh(&n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2sh(&n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2sh(&n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2sh(&n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2sh(&n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2sh(&n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + short n; + + assert(a2sh(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2sh(&n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2sh(&n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2sh(&n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2sh(&n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2sh(&n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sh(&n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sh(&n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sh(&n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sh(&n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sh(&n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + short n; + + assert(a2sh(&n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2sh(&n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2sh(&n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2sh(&n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + short n; + + assert(a2sh(&n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sh(&n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sh(&n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2sh(&n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2sh(&n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sh(&n, "-1", &e, 0, SHRT_MIN, SHRT_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0xFFF", &e, 0, SHRT_MIN, SHRT_MAX) == 0); + assert(n == 0xFFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "0xFFFF", &e, 0, SHRT_MIN, SHRT_MAX) == -1); + assert(n == SHRT_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sh(&n, "-0xFFFF", &e, 0, SHRT_MIN, SHRT_MAX) == -1); + assert(n == SHRT_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + short n; + + assert(a2sh(&n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2sh(&n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2sh(&n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2sh/a2sh.sh b/share/tests/a2i.h/a2sh/a2sh.sh new file mode 100755 index 0000000..b49a23d --- /dev/null +++ b/share/tests/a2i.h/a2sh/a2sh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2sh.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2sh/a2sh_nobuild.sh b/share/tests/a2i.h/a2sh/a2sh_nobuild.sh new file mode 100755 index 0000000..09a7b1c --- /dev/null +++ b/share/tests/a2i.h/a2sh/a2sh_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned short n; + + a2sh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2sh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2shh/a2shh.c b/share/tests/a2i.h/a2shh/a2shh.c new file mode 100644 index 0000000..3f4b9b7 --- /dev/null +++ b/share/tests/a2i.h/a2shh/a2shh.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + signed char n; + + assert(a2shh(&n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2shh(&n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2shh(&n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2shh(&n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2shh(&n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2shh(&n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2shh(&n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2shh(&n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2shh(&n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + signed char n; + + assert(a2shh(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2shh(&n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2shh(&n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2shh(&n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2shh(&n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2shh(&n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2shh(&n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2shh(&n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2shh(&n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2shh(&n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2shh(&n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + signed char n; + + assert(a2shh(&n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2shh(&n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2shh(&n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2shh(&n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + signed char n; + + assert(a2shh(&n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2shh(&n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2shh(&n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2shh(&n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2shh(&n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2shh(&n, "-1", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0x7F", &e, 0, SCHAR_MIN, SCHAR_MAX) == 0); + assert(n == 0x7F); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2shh(&n, "-0xFF", &e, 0, SCHAR_MIN, SCHAR_MAX) == -1); + assert(n == SCHAR_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + signed char n; + + assert(a2shh(&n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2shh(&n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2shh(&n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2shh/a2shh.sh b/share/tests/a2i.h/a2shh/a2shh.sh new file mode 100755 index 0000000..0b0a9d5 --- /dev/null +++ b/share/tests/a2i.h/a2shh/a2shh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2shh.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2shh/a2shh_nobuild.sh b/share/tests/a2i.h/a2shh/a2shh_nobuild.sh new file mode 100755 index 0000000..e01d682 --- /dev/null +++ b/share/tests/a2i.h/a2shh/a2shh_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned char n; + + a2shh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + char n; + + a2shh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2shh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2si/a2si.c b/share/tests/a2i.h/a2si/a2si.c new file mode 100644 index 0000000..3ee3295 --- /dev/null +++ b/share/tests/a2i.h/a2si/a2si.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + int n; + + assert(a2si(&n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2si(&n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2si(&n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2si(&n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2si(&n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2si(&n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2si(&n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2si(&n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2si(&n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + int n; + + assert(a2si(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2si(&n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2si(&n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2si(&n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2si(&n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2si(&n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2si(&n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2si(&n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2si(&n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2si(&n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2si(&n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2si(&n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2si(&n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2si(&n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2si(&n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2si(&n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2si(&n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2si(&n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + int n; + + assert(a2si(&n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2si(&n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2si(&n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2si(&n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + int n; + + assert(a2si(&n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2si(&n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2si(&n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2si(&n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2si(&n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2si(&n, "-1", &e, 0, INT_MIN, INT_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0xFFF", &e, 0, INT_MIN, INT_MAX) == 0); + assert(n == 0xFFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "0xFFFFffffFFFFffff", &e, 0, INT_MIN, INT_MAX) == -1); + assert(n == INT_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2si(&n, "-0xFFFFffffFFFFffff", &e, 0, INT_MIN, INT_MAX) == -1); + assert(n == INT_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + int n; + + assert(a2si(&n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2si(&n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2si(&n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2si/a2si.sh b/share/tests/a2i.h/a2si/a2si.sh new file mode 100755 index 0000000..109338c --- /dev/null +++ b/share/tests/a2i.h/a2si/a2si.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2si.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2si/a2si_nobuild.sh b/share/tests/a2i.h/a2si/a2si_nobuild.sh new file mode 100755 index 0000000..ecb2db6 --- /dev/null +++ b/share/tests/a2i.h/a2si/a2si_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned int n; + + a2si(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2si(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2sl/a2sl.c b/share/tests/a2i.h/a2sl/a2sl.c new file mode 100644 index 0000000..a91fb37 --- /dev/null +++ b/share/tests/a2i.h/a2sl/a2sl.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + long n; + + assert(a2sl(&n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2sl(&n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2sl(&n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2sl(&n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2sl(&n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2sl(&n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2sl(&n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2sl(&n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2sl(&n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + long n; + + assert(a2sl(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2sl(&n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2sl(&n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2sl(&n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2sl(&n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2sl(&n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sl(&n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sl(&n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sl(&n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sl(&n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sl(&n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + long n; + + assert(a2sl(&n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2sl(&n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2sl(&n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2sl(&n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + long n; + + assert(a2sl(&n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sl(&n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sl(&n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2sl(&n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2sl(&n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sl(&n, "-1", &e, 0, LONG_MIN, LONG_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0xFFFffff", &e, 0, LONG_MIN, LONG_MAX) == 0); + assert(n == 0xFFFffff); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "0xFFFFffffFFFFffff", &e, 0, LONG_MIN, LONG_MAX) == -1); + assert(n == LONG_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sl(&n, "-0xFFFFffffFFFFffff", &e, 0, LONG_MIN, LONG_MAX) == -1); + assert(n == LONG_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + long n; + + assert(a2sl(&n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2sl(&n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2sl(&n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2sl/a2sl.sh b/share/tests/a2i.h/a2sl/a2sl.sh new file mode 100755 index 0000000..edec276 --- /dev/null +++ b/share/tests/a2i.h/a2sl/a2sl.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2sl.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2sl/a2sl_nobuild.sh b/share/tests/a2i.h/a2sl/a2sl_nobuild.sh new file mode 100755 index 0000000..fd2b483 --- /dev/null +++ b/share/tests/a2i.h/a2sl/a2sl_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2sl(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + int n; + + a2sl(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2sll/a2sll.c b/share/tests/a2i.h/a2sll/a2sll.c new file mode 100644 index 0000000..ffce91f --- /dev/null +++ b/share/tests/a2i.h/a2sll/a2sll.c @@ -0,0 +1,457 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + long long n; + + assert(a2sll(&n, "x99z", NULL, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "x99z", &e, 1, -7, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2sll(&n, "x99z", NULL, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2sll(&n, "x99z", &e, 0, -7, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2sll(&n, "99z", NULL, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2sll(&n, "99z", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2sll(&n, "9z", NULL, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2sll(&n, "9z", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2sll(&n, "9", NULL, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2sll(&n, "9", &e, 0, -7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + long long n; + + assert(a2sll(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, -1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, -2, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, 37, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, 38, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2sll(&n, "", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "43", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, 1, -42, -7) == -1); + assert(n == -7); + assert(errno == EINVAL); + assert(a2sll(&n, "1", &e, 1, 42, -42) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2sll(&n, "4foo", &e, 1, -42, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2sll(&n, "1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "1", &e, 2, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "1", &e, 3, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "1", &e, 35, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "1", &e, 36, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2sll(&n, "0b11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "0B11", &e, 0, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "-0b11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "-0B11", &e, 0, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sll(&n, "011", &e, 0, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-011", &e, 0, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "11", &e, 0, -42, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-11", &e, 0, -42, 42) == 0); + assert(n == -11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0x11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0X11", &e, 0, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-0x11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-0X11", &e, 0, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sll(&n, "011", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "11", &e, 2, -42, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "0b11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "0B11", NULL, 2, -42, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-011", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-11", &e, 2, -42, 42) == 0); + assert(n == -3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "-0b11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2sll(&n, "-0B11", NULL, 2, -42, 42) == 0); + //assertn == -3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2sll(&n, "011", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0x11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0X11", &e, 16, -42, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-011", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-0x11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-0X11", &e, 16, -42, 42) == 0); + assert(n == -17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sll(&n, "011", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "11", &e, 7, -42, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-011", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-11", &e, 7, -42, 42) == 0); + assert(n == -8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "011", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "11", &e, 8, -42, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-011", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-11", &e, 8, -42, 42) == 0); + assert(n == -9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "Z", &e, 36, -42, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-Z", &e, 36, -42, 42) == 0); + assert(n == -35); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + long long n; + + assert(a2sll(&n, "", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "foo", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2sll(&n, "foo 7", &e, 0, -42, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2sll(&n, "", &e, 0, 42, -42) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2sll(&n, " 1", &e, 0, -42, 42) == 0); + assert(n == 1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, " \t\na", &e, 16, -42, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, " \t\n-a", &e, 16, -42, 42) == 0); + assert(n == -10); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + long long n; + + assert(a2sll(&n, "-9", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-8", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "43", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "44", &e, 0, -7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sll(&n, "7", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "42", &e, 0, 7, -42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2sll(&n, "-9z", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2sll(&n, "-9 ", &e, 0, -7, 42) == -1); + assert(n == -7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + + assert(a2sll(&n, "-7", &e, 0, -7, 42) == 0); + assert(n == -7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-6", &e, 0, -7, 42) == 0); + assert(n == -6); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "41", &e, 0, -7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "42", &e, 0, -7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2sll(&n, "-1", &e, 0, LLONG_MIN, LLONG_MAX) == 0); + assert(n == -1); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0xFFFffffFFFFffff", &e, 0, LLONG_MIN, LLONG_MAX) == 0); + assert(n == 0xFFFffffFFFFffff); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "0xFFFFffffFFFFffff", &e, 0, LLONG_MIN, LLONG_MAX) == -1); + assert(n == LLONG_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2sll(&n, "-0xFFFFffffFFFFffff", &e, 0, LLONG_MIN, LLONG_MAX) == -1); + assert(n == LLONG_MIN); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + long long n; + + assert(a2sll(&n, "\n9 fff 7", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2sll(&n, "\n9\t", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2sll(&n, "9 ", &e, 0, -7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2sll/a2sll.sh b/share/tests/a2i.h/a2sll/a2sll.sh new file mode 100755 index 0000000..ed2aaaf --- /dev/null +++ b/share/tests/a2i.h/a2sll/a2sll.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2sll.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2sll/a2sll_nobuild.sh b/share/tests/a2i.h/a2sll/a2sll_nobuild.sh new file mode 100755 index 0000000..863714a --- /dev/null +++ b/share/tests/a2i.h/a2sll/a2sll_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long long n; + + a2sll(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2sll(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2u/a2u.c b/share/tests/a2i.h/a2u/a2u.c new file mode 100644 index 0000000..28d1701 --- /dev/null +++ b/share/tests/a2i.h/a2u/a2u.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned int n; + + assert(a2u(unsigned int, &n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned int, &n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2u(unsigned int, &n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2u(unsigned int, &n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2u(unsigned int, &n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2u(unsigned int, &n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2u(unsigned int, &n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2u(unsigned int, &n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2u(unsigned int, &n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2u(unsigned int, &n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned long n; + + assert(a2u(unsigned long, &n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2u(unsigned long, &n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2u(unsigned long, &n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2u(unsigned long, &n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2u(unsigned long, &n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned long, &n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned long, &n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2u(unsigned long, &n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2u(unsigned long, &n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned long, &n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2u(unsigned long, &n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned long, &n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned long, &n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long, &n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned long long n; + + assert(a2u(unsigned long long, &n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long long, &n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2u(unsigned long long, &n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2u(unsigned long long, &n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2u(unsigned long long, &n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long long, &n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned long long, &n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned char n; + + assert(a2u(unsigned char, &n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2u(unsigned char, &n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2u(unsigned char, &n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2u(unsigned char, &n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2u(unsigned char, &n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2u(unsigned char, &n, "-1", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2u(unsigned char, &n, "0xFF", &e, 0, 0, UCHAR_MAX) == 0); + assert(n == 0xFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "-0xFF", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "0xFF9", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == UCHAR_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2u(unsigned char, &n, "-0xFF9", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned short n; + + assert(a2u(unsigned short, &n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2u(unsigned short, &n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2u(unsigned short, &n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2u/a2u.sh b/share/tests/a2i.h/a2u/a2u.sh new file mode 100755 index 0000000..c873f1d --- /dev/null +++ b/share/tests/a2i.h/a2u/a2u.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2u.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2u/a2u_nobuild.sh b/share/tests/a2i.h/a2u/a2u_nobuild.sh new file mode 100755 index 0000000..15b83c9 --- /dev/null +++ b/share/tests/a2i.h/a2u/a2u_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + signed char n; + + a2u(unsigned char, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2u(unsigned int, &n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'static assertion failed' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected static assertion failed"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2u(long, &n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2uh/a2uh.c b/share/tests/a2i.h/a2uh/a2uh.c new file mode 100644 index 0000000..a5c88bf --- /dev/null +++ b/share/tests/a2i.h/a2uh/a2uh.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned short n; + + assert(a2uh(&n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2uh(&n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2uh(&n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2uh(&n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2uh(&n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2uh(&n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2uh(&n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2uh(&n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2uh(&n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned short n; + + assert(a2uh(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2uh(&n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2uh(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2uh(&n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2uh(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2uh(&n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2uh(&n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2uh(&n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2uh(&n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2uh(&n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned short n; + + assert(a2uh(&n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2uh(&n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2uh(&n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2uh(&n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned short n; + + assert(a2uh(&n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2uh(&n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2uh(&n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2uh(&n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2uh(&n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2uh(&n, "-1", &e, 0, 0, USHRT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uh(&n, "0xFFFF", &e, 0, 0, USHRT_MAX) == 0); + assert(n == 0xFFFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0xFFFF", &e, 0, 0, USHRT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "0xFFFF9", &e, 0, 0, USHRT_MAX) == -1); + assert(n == USHRT_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uh(&n, "-0xFFFF9", &e, 0, 0, USHRT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned short n; + + assert(a2uh(&n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2uh(&n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2uh(&n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2uh/a2uh.sh b/share/tests/a2i.h/a2uh/a2uh.sh new file mode 100755 index 0000000..77586a2 --- /dev/null +++ b/share/tests/a2i.h/a2uh/a2uh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2uh.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2uh/a2uh_nobuild.sh b/share/tests/a2i.h/a2uh/a2uh_nobuild.sh new file mode 100755 index 0000000..923da5a --- /dev/null +++ b/share/tests/a2i.h/a2uh/a2uh_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + short n; + + a2uh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2uh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2uhh/a2uhh.c b/share/tests/a2i.h/a2uhh/a2uhh.c new file mode 100644 index 0000000..ef0f2a8 --- /dev/null +++ b/share/tests/a2i.h/a2uhh/a2uhh.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned char n; + + assert(a2uhh(&n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2uhh(&n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2uhh(&n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2uhh(&n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2uhh(&n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2uhh(&n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2uhh(&n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2uhh(&n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2uhh(&n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned char n; + + assert(a2uhh(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2uhh(&n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2uhh(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2uhh(&n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2uhh(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2uhh(&n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2uhh(&n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2uhh(&n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2uhh(&n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned char n; + + assert(a2uhh(&n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2uhh(&n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2uhh(&n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2uhh(&n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned char n; + + assert(a2uhh(&n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2uhh(&n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2uhh(&n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2uhh(&n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2uhh(&n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2uhh(&n, "-1", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2uhh(&n, "0xFF", &e, 0, 0, UCHAR_MAX) == 0); + assert(n == 0xFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0xFF", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "0xFF9", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == UCHAR_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2uhh(&n, "-0xFF9", &e, 0, 0, UCHAR_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned char n; + + assert(a2uhh(&n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2uhh(&n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2uhh(&n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2uhh/a2uhh.sh b/share/tests/a2i.h/a2uhh/a2uhh.sh new file mode 100755 index 0000000..3576757 --- /dev/null +++ b/share/tests/a2i.h/a2uhh/a2uhh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2uhh.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2uhh/a2uhh_nobuild.sh b/share/tests/a2i.h/a2uhh/a2uhh_nobuild.sh new file mode 100755 index 0000000..7a85a33 --- /dev/null +++ b/share/tests/a2i.h/a2uhh/a2uhh_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + signed char n; + + a2uhh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + char n; + + a2uhh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2uhh(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2ui/a2ui.c b/share/tests/a2i.h/a2ui/a2ui.c new file mode 100644 index 0000000..d94afbb --- /dev/null +++ b/share/tests/a2i.h/a2ui/a2ui.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned int n; + + assert(a2ui(&n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2ui(&n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2ui(&n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2ui(&n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2ui(&n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2ui(&n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2ui(&n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2ui(&n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2ui(&n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned int n; + + assert(a2ui(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2ui(&n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ui(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ui(&n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2ui(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2ui(&n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ui(&n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ui(&n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2ui(&n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ui(&n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned int n; + + assert(a2ui(&n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2ui(&n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2ui(&n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2ui(&n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned int n; + + assert(a2ui(&n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ui(&n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ui(&n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2ui(&n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2ui(&n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2ui(&n, "-1", &e, 0, 0, UINT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ui(&n, "0xFFFF", &e, 0, 0, UINT_MAX) == 0); + assert(n == 0xFFFF); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0xFFFFffffFFFFffff", &e, 0, 0, UINT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "0xFFFFffffFFFFffff9", &e, 0, 0, UINT_MAX) == -1); + assert(n == UINT_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ui(&n, "-0xFFFFffffFFFFffff9", &e, 0, 0, UINT_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned int n; + + assert(a2ui(&n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2ui(&n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2ui(&n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2ui/a2ui.sh b/share/tests/a2i.h/a2ui/a2ui.sh new file mode 100755 index 0000000..d58eba8 --- /dev/null +++ b/share/tests/a2i.h/a2ui/a2ui.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2ui.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2ui/a2ui_nobuild.sh b/share/tests/a2i.h/a2ui/a2ui_nobuild.sh new file mode 100755 index 0000000..dfe578c --- /dev/null +++ b/share/tests/a2i.h/a2ui/a2ui_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + int n; + + a2ui(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2ui(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2ul/a2ul.c b/share/tests/a2i.h/a2ul/a2ul.c new file mode 100644 index 0000000..fce7089 --- /dev/null +++ b/share/tests/a2i.h/a2ul/a2ul.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned long n; + + assert(a2ul(&n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2ul(&n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2ul(&n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2ul(&n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2ul(&n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2ul(&n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2ul(&n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2ul(&n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2ul(&n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned long n; + + assert(a2ul(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2ul(&n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ul(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ul(&n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2ul(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2ul(&n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ul(&n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ul(&n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2ul(&n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ul(&n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned long n; + + assert(a2ul(&n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2ul(&n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2ul(&n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2ul(&n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned long n; + + assert(a2ul(&n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ul(&n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ul(&n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2ul(&n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2ul(&n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2ul(&n, "-1", &e, 0, 0, ULONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ul(&n, "0xFFFFffff", &e, 0, 0, ULONG_MAX) == 0); + assert(n == 0xFFFFffff); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0xFFFFffffFFFFffff", &e, 0, 0, ULONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "0xFFFFffffFFFFffff9", &e, 0, 0, ULONG_MAX) == -1); + assert(n == ULONG_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ul(&n, "-0xFFFFffffFFFFffff9", &e, 0, 0, ULONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned long n; + + assert(a2ul(&n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2ul(&n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2ul(&n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2ul/a2ul.sh b/share/tests/a2i.h/a2ul/a2ul.sh new file mode 100755 index 0000000..d0806e3 --- /dev/null +++ b/share/tests/a2i.h/a2ul/a2ul.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2ul.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2ul/a2ul_nobuild.sh b/share/tests/a2i.h/a2ul/a2ul_nobuild.sh new file mode 100755 index 0000000..3b544dd --- /dev/null +++ b/share/tests/a2i.h/a2ul/a2ul_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long n; + + a2ul(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned int n; + + a2ul(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/a2i.h/a2ull/a2ull.c b/share/tests/a2i.h/a2ull/a2ull.c new file mode 100644 index 0000000..9c9b8b7 --- /dev/null +++ b/share/tests/a2i.h/a2ull/a2ull.c @@ -0,0 +1,468 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/a2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + char *e = "unmodified"; + unsigned long long n; + + assert(a2ull(&n, "x99z", NULL, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "x99z", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2ull(&n, "x99z", NULL, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(a2ull(&n, "x99z", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2ull(&n, "99z", NULL, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(a2ull(&n, "99z", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2ull(&n, "9z", NULL, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(a2ull(&n, "9z", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "z") == 0); + + errno = 0; + + assert(a2ull(&n, "9", NULL, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(a2ull(&n, "9", &e, 0, 7, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); +} + + +static void +test_base(void) +{ + char *e = "unmodified"; + unsigned long long n; + + assert(a2ull(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, -1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, -2, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, 37, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, 38, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(a2ull(&n, "", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "43", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ull(&n, "9", &e, 1, 42, 0) == -1); + assert(n == 42); + assert(errno == EINVAL); + assert(a2ull(&n, "9foo", &e, 1, 0, 42) == -1); + assert(n == 0); + assert(errno == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + errno = 0; + + assert(a2ull(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 3, 2, 42) == 0); + assert(n == 4); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 35, 2, 42) == 0); + assert(n == 36); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 36, 2, 42) == 0); + assert(n == 37); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2ull(&n, "0b11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "0B11", &e, 0, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "-0b11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "-0B11", &e, 0, 2, 42) == 0); + //assertn == 2); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ull(&n, "011", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-011", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "11", &e, 0, 2, 42) == 0); + assert(n == 11); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "0x11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "0X11", &e, 0, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0x11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0X11", &e, 0, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ull(&n, "011", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 2, 2, 42) == 0); + assert(n == 3); + assert(errno == 0); + assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "0b11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "0B11", NULL, 2, 2, 42) == 0); + //assertn == 3); + //assert(errno == 0); + //assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-011", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-11", &e, 2, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "-0b11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2ull(&n, "-0B11", NULL, 2, 2, 42) == -1); + //assertn == 2); + //assert(errno == ERANGE); + //assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "011", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "0x11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "0X11", &e, 16, 2, 42) == 0); + assert(n == 17); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-011", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0x11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0X11", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + errno = 0; + assert(a2ull(&n, "011", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 7, 2, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-011", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-11", &e, 7, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "011", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "11", &e, 8, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-011", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-11", &e, 8, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "Z", &e, 36, 2, 42) == 0); + assert(n == 35); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-Z", &e, 36, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_leading_text(void) +{ + char *e; + unsigned long long n; + + assert(a2ull(&n, "", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "foo", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2ull(&n, "foo 7", &e, 0, 0, 42) == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2ull(&n, "", &e, 0, 42, 0) == -1); + assert(n == 42); + assert(errno == ECANCELED); + assert(strcmp(e, "") == 0); + + errno = 0; + + assert(a2ull(&n, " 9", &e, 0, 2, 42) == 0); + assert(n == 9); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, " \t\na", &e, 16, 2, 42) == 0); + assert(n == 10); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, " \t\n-a", &e, 16, 2, 42) == -1); + assert(n == 2); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_range(void) +{ + char *e; + unsigned long long n; + + assert(a2ull(&n, "5", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "6", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "43", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "44", &e, 0, 7, 42) == -1); + assert(n == 42); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ull(&n, "7", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "42", &e, 0, 7, 4) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2ull(&n, "6z", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2ull(&n, "6 ", &e, 0, 7, 42) == -1); + assert(n == 7); + assert(errno == ERANGE); + assert(strcmp(e, " ") == 0); + + errno = 0; + assert(a2ull(&n, "7", &e, 0, 7, 42) == 0); + assert(n == 7); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "8", &e, 0, 7, 42) == 0); + assert(n == 8); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "41", &e, 0, 7, 42) == 0); + assert(n == 41); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "42", &e, 0, 7, 42) == 0); + assert(n == 42); + assert(errno == 0); + assert(strcmp(e, "") == 0); + + assert(a2ull(&n, "-1", &e, 0, 0, ULLONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + errno = 0; + assert(a2ull(&n, "0xFFFFffffFFFFffff", &e, 0, 0, ULLONG_MAX) == 0); + assert(n == ULLONG_MAX); + assert(errno == 0); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0xFFFFffffFFFFffff", &e, 0, 0, ULLONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "0xFFFFffffFFFFffff9", &e, 0, 0, ULLONG_MAX) == -1); + assert(n == ULLONG_MAX); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2ull(&n, "-0xFFFFffffFFFFffff9", &e, 0, 0, ULLONG_MAX) == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(strcmp(e, "") == 0); +} + + +static void +test_trailing_text(void) +{ + char *e; + unsigned long long n; + + assert(a2ull(&n, "\n9 fff 7", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2ull(&n, "\n9\t", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2ull(&n, "9 ", &e, 0, 7, 42) == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(strcmp(e, " ") == 0); +} diff --git a/share/tests/a2i.h/a2ull/a2ull.sh b/share/tests/a2i.h/a2ull/a2ull.sh new file mode 100755 index 0000000..70c92db --- /dev/null +++ b/share/tests/a2i.h/a2ull/a2ull.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/a2ull.c $LIBS; +"$out"; diff --git a/share/tests/a2i.h/a2ull/a2ull_nobuild.sh b/share/tests/a2i.h/a2ull/a2ull_nobuild.sh new file mode 100755 index 0000000..5f1c6a8 --- /dev/null +++ b/share/tests/a2i.h/a2ull/a2ull_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + long long n; + + a2ull(&n, "0", NULL, 0, 0, 0); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/a2i.h> + + int + main(void) + { + unsigned long n; + + a2ull(&n, "0", NULL, 0, 0, 0); + } +__EOF__ diff --git a/share/tests/str2i.h/str2i/str2i.c b/share/tests/str2i.h/str2i/str2i.c new file mode 100644 index 0000000..db2d70a --- /dev/null +++ b/share/tests/str2i.h/str2i/str2i.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned int n; + + errno = 0; + + assert(str2i(unsigned int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2i(unsigned int, &n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2i(unsigned int, &n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2i(unsigned int, &n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2i(unsigned int, &n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2i(unsigned int, &n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2i(unsigned int, &n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2i(unsigned int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2i(unsigned int, &n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2i(unsigned int, &n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2i(unsigned int, &n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2i(unsigned int, &n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2i(unsigned int, &n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + long long n; + + assert(str2i(long long, &n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2i(long long, &n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2i(long long, &n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2i(long long, &n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2i(long long, &n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2i(long long, &n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + unsigned char n; + + assert(str2i(unsigned char, &n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2i(unsigned char, &n, "0xFF") == 0); + assert(n == 0xFF); + assert(errno == 0); + assert(str2i(unsigned char, &n, "-0xFF") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2i(unsigned char, &n, "0xFF9") == -1); + assert(n == UCHAR_MAX); + assert(errno == ERANGE); + assert(str2i(unsigned char, &n, "-0xFF9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + short n; + + assert(str2i(short, &n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2i(short, &n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2i(short, &n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2i/str2i.sh b/share/tests/str2i.h/str2i/str2i.sh new file mode 100755 index 0000000..e22ff0c --- /dev/null +++ b/share/tests/str2i.h/str2i/str2i.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2i.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2i/str2i_nobuild.sh b/share/tests/str2i.h/str2i/str2i_nobuild.sh new file mode 100755 index 0000000..3645b84 --- /dev/null +++ b/share/tests/str2i.h/str2i/str2i_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected error: [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned char n; + + str2i(signed char, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2s(unsigned int, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'error: ._Generic. selector' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected error: '_Generic' selector"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + float n; + + str2i(float, &n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2s/str2s.c b/share/tests/str2i.h/str2s/str2s.c new file mode 100644 index 0000000..9c302f2 --- /dev/null +++ b/share/tests/str2i.h/str2s/str2s.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + int n; + + errno = 0; + + assert(str2s(int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2s(int, &n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2s(int, &n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2s(int, &n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2s(int, &n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2s(int, &n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2s(int, &n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2s(int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2s(int, &n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2s(int, &n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2s(int, &n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2s(int, &n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2s(int, &n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + long long n; + + assert(str2s(long long, &n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2s(long long, &n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2s(long long, &n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2s(long long, &n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2s(long long, &n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2s(long long, &n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + signed char n; + + assert(str2s(signed char, &n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2s(signed char, &n, "0x7F") == 0); + assert(n == 0x7F); + assert(errno == 0); + assert(str2s(signed char, &n, "0xFF") == -1); + assert(n == SCHAR_MAX); + assert(errno == ERANGE); + assert(str2s(signed char, &n, "-0xFF") == -1); + assert(n == SCHAR_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + short n; + + assert(str2s(short, &n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2s(short, &n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2s(short, &n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2s/str2s.sh b/share/tests/str2i.h/str2s/str2s.sh new file mode 100755 index 0000000..0849100 --- /dev/null +++ b/share/tests/str2i.h/str2s/str2s.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2s.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2s/str2s_nobuild.sh b/share/tests/str2i.h/str2s/str2s_nobuild.sh new file mode 100755 index 0000000..c026b34 --- /dev/null +++ b/share/tests/str2i.h/str2s/str2s_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned char n; + + str2s(signed char, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2s(int, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'static assertion failed' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected static assertion failed"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2s(unsigned long, &n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2sh/str2sh.c b/share/tests/str2i.h/str2sh/str2sh.c new file mode 100644 index 0000000..84b0b88 --- /dev/null +++ b/share/tests/str2i.h/str2sh/str2sh.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + short n; + + errno = 0; + + assert(str2sh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2sh(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sh(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sh(&n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2sh(&n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2sh(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2sh(&n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2sh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2sh(&n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2sh(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sh(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sh(&n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2sh(&n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + short n; + + assert(str2sh(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sh(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sh(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2sh(&n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2sh(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2sh(&n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + short n; + + assert(str2sh(&n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2sh(&n, "0xFFF") == 0); + assert(n == 0xFFF); + assert(errno == 0); + assert(str2sh(&n, "0xFFFF") == -1); + assert(n == SHRT_MAX); + assert(errno == ERANGE); + assert(str2sh(&n, "-0xFFFF") == -1); + assert(n == SHRT_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + short n; + + assert(str2sh(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sh(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sh(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2sh/str2sh.sh b/share/tests/str2i.h/str2sh/str2sh.sh new file mode 100755 index 0000000..57da282 --- /dev/null +++ b/share/tests/str2i.h/str2sh/str2sh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2sh.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2sh/str2sh_nobuild.sh b/share/tests/str2i.h/str2sh/str2sh_nobuild.sh new file mode 100755 index 0000000..5577bb7 --- /dev/null +++ b/share/tests/str2i.h/str2sh/str2sh_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned short n; + + str2sh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2sh(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2shh/str2shh.c b/share/tests/str2i.h/str2shh/str2shh.c new file mode 100644 index 0000000..95b0540 --- /dev/null +++ b/share/tests/str2i.h/str2shh/str2shh.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + signed char n; + + errno = 0; + + assert(str2shh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2shh(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2shh(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2shh(&n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2shh(&n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2shh(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2shh(&n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2shh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2shh(&n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2shh(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2shh(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2shh(&n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2shh(&n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + signed char n; + + assert(str2shh(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2shh(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2shh(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2shh(&n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2shh(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2shh(&n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + signed char n; + + assert(str2shh(&n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2shh(&n, "0x7F") == 0); + assert(n == 0x7F); + assert(errno == 0); + assert(str2shh(&n, "0xFF") == -1); + assert(n == SCHAR_MAX); + assert(errno == ERANGE); + assert(str2shh(&n, "-0xFF") == -1); + assert(n == SCHAR_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + signed char n; + + assert(str2shh(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2shh(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2shh(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2shh/str2shh.sh b/share/tests/str2i.h/str2shh/str2shh.sh new file mode 100755 index 0000000..4fc8719 --- /dev/null +++ b/share/tests/str2i.h/str2shh/str2shh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2shh.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2shh/str2shh_nobuild.sh b/share/tests/str2i.h/str2shh/str2shh_nobuild.sh new file mode 100755 index 0000000..ea29e27 --- /dev/null +++ b/share/tests/str2i.h/str2shh/str2shh_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned char n; + + str2shh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + char n; + + str2shh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2shh(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2si/str2si.c b/share/tests/str2i.h/str2si/str2si.c new file mode 100644 index 0000000..279bd84 --- /dev/null +++ b/share/tests/str2i.h/str2si/str2si.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + int n; + + errno = 0; + + assert(str2si(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2si(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2si(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2si(&n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2si(&n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2si(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2si(&n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2si(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2si(&n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2si(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2si(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2si(&n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2si(&n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + int n; + + assert(str2si(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2si(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2si(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2si(&n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2si(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2si(&n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + int n; + + assert(str2si(&n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2si(&n, "0xFFF") == 0); + assert(n == 0xFFF); + assert(errno == 0); + assert(str2si(&n, "0xFFFFffffFFFFffff") == -1); + assert(n == INT_MAX); + assert(errno == ERANGE); + assert(str2si(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == INT_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + int n; + + assert(str2si(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2si(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2si(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2si/str2si.sh b/share/tests/str2i.h/str2si/str2si.sh new file mode 100755 index 0000000..582379f --- /dev/null +++ b/share/tests/str2i.h/str2si/str2si.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2si.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2si/str2si_nobuild.sh b/share/tests/str2i.h/str2si/str2si_nobuild.sh new file mode 100755 index 0000000..e25cb44 --- /dev/null +++ b/share/tests/str2i.h/str2si/str2si_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned int n; + + str2si(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2si(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2sl/str2sl.c b/share/tests/str2i.h/str2sl/str2sl.c new file mode 100644 index 0000000..62f7697 --- /dev/null +++ b/share/tests/str2i.h/str2sl/str2sl.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + long n; + + errno = 0; + + assert(str2sl(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2sl(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sl(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sl(&n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2sl(&n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2sl(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2sl(&n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2sl(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2sl(&n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2sl(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sl(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sl(&n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2sl(&n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + long n; + + assert(str2sl(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sl(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sl(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2sl(&n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2sl(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2sl(&n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + long n; + + assert(str2sl(&n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2sl(&n, "0xFFFffff") == 0); + assert(n == 0xFFFffff); + assert(errno == 0); + assert(str2sl(&n, "0xFFFFffffFFFFffff") == -1); + assert(n == LONG_MAX); + assert(errno == ERANGE); + assert(str2sl(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == LONG_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + long n; + + assert(str2sl(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sl(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sl(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2sl/str2sl.sh b/share/tests/str2i.h/str2sl/str2sl.sh new file mode 100755 index 0000000..a1d12b5 --- /dev/null +++ b/share/tests/str2i.h/str2sl/str2sl.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2sl.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2sl/str2sl_nobuild.sh b/share/tests/str2i.h/str2sl/str2sl_nobuild.sh new file mode 100755 index 0000000..8bda94e --- /dev/null +++ b/share/tests/str2i.h/str2sl/str2sl_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2sl(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + int n; + + str2sl(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2sll/str2sll.c b/share/tests/str2i.h/str2sll/str2sll.c new file mode 100644 index 0000000..3cb1d04 --- /dev/null +++ b/share/tests/str2i.h/str2sll/str2sll.c @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + long long n; + + errno = 0; + + assert(str2sll(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2sll(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sll(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2sll(&n, "-0b11") == 0); + //assertn == -3); + //assert(errno == 0); + //assert(str2sll(&n, "-0B11") == 0); + //assertn == -3); + //assert(errno == 0); + assert(str2sll(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2sll(&n, "-011") == 0); + assert(n == -9); + assert(errno == 0); + assert(str2sll(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2sll(&n, "-11") == 0); + assert(n == -11); + assert(errno == 0); + assert(str2sll(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sll(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2sll(&n, "-0x11") == 0); + assert(n == -17); + assert(errno == 0); + assert(str2sll(&n, "-0X11") == 0); + assert(n == -17); + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + long long n; + + assert(str2sll(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sll(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2sll(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2sll(&n, " 1") == 0); + assert(n == 1); + assert(errno == 0); + assert(str2sll(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2sll(&n, " \t\n-0xa") == 0); + assert(n == -10); + assert(errno == 0); +} + + +static void +test_range(void) +{ + long long n; + + assert(str2sll(&n, "-1") == 0); + assert(n == -1); + assert(errno == 0); + assert(str2sll(&n, "0xFFFffffFFFFffff") == 0); + assert(n == 0xFFFffffFFFFffff); + assert(errno == 0); + assert(str2sll(&n, "0xFFFFffffFFFFffff") == -1); + assert(n == LLONG_MAX); + assert(errno == ERANGE); + assert(str2sll(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == LLONG_MIN); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + long long n; + + assert(str2sll(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sll(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2sll(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2sll/str2sll.sh b/share/tests/str2i.h/str2sll/str2sll.sh new file mode 100755 index 0000000..13b6fc5 --- /dev/null +++ b/share/tests/str2i.h/str2sll/str2sll.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2sll.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2sll/str2sll_nobuild.sh b/share/tests/str2i.h/str2sll/str2sll_nobuild.sh new file mode 100755 index 0000000..a354c2d --- /dev/null +++ b/share/tests/str2i.h/str2sll/str2sll_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long long n; + + str2sll(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2sll(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2u/str2u.c b/share/tests/str2i.h/str2u/str2u.c new file mode 100644 index 0000000..9a227fe --- /dev/null +++ b/share/tests/str2i.h/str2u/str2u.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned int n; + + errno = 0; + + assert(str2u(unsigned int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2u(unsigned int, &n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2u(unsigned int, &n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2u(unsigned int, &n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2u(unsigned int, &n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2u(unsigned int, &n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2u(unsigned int, &n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2u(unsigned int, &n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2u(unsigned int, &n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2u(unsigned int, &n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2u(unsigned int, &n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2u(unsigned int, &n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2u(unsigned int, &n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned long long n; + + assert(str2u(unsigned long long, &n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2u(unsigned long long, &n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2u(unsigned long long, &n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2u(unsigned long long, &n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2u(unsigned long long, &n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2u(unsigned long long, &n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned char n; + + assert(str2u(unsigned char, &n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2u(unsigned char, &n, "0xFF") == 0); + assert(n == 0xFF); + assert(errno == 0); + assert(str2u(unsigned char, &n, "-0xFF") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2u(unsigned char, &n, "0xFF9") == -1); + assert(n == UCHAR_MAX); + assert(errno == ERANGE); + assert(str2u(unsigned char, &n, "-0xFF9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned short n; + + assert(str2u(unsigned short, &n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2u(unsigned short, &n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2u(unsigned short, &n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2u/str2u.sh b/share/tests/str2i.h/str2u/str2u.sh new file mode 100755 index 0000000..8c60d8e --- /dev/null +++ b/share/tests/str2i.h/str2u/str2u.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2u.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2u/str2u_nobuild.sh b/share/tests/str2i.h/str2u/str2u_nobuild.sh new file mode 100755 index 0000000..0e7a15a --- /dev/null +++ b/share/tests/str2i.h/str2u/str2u_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + signed char n; + + str2u(unsigned char, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2u(unsigned int, &n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- 'static assertion failed' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected static assertion failed"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2u(long, &n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2uh/str2uh.c b/share/tests/str2i.h/str2uh/str2uh.c new file mode 100644 index 0000000..998a88f --- /dev/null +++ b/share/tests/str2i.h/str2uh/str2uh.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned short n; + + errno = 0; + + assert(str2uh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2uh(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2uh(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2uh(&n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2uh(&n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2uh(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2uh(&n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2uh(&n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uh(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2uh(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2uh(&n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2uh(&n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned short n; + + assert(str2uh(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2uh(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2uh(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2uh(&n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2uh(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2uh(&n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned short n; + + assert(str2uh(&n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uh(&n, "0xFFFF") == 0); + assert(n == 0xFFFF); + assert(errno == 0); + assert(str2uh(&n, "-0xFFFF") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2uh(&n, "0xFFFF9") == -1); + assert(n == USHRT_MAX); + assert(errno == ERANGE); + assert(str2uh(&n, "-0xFFFF9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned short n; + + assert(str2uh(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2uh(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2uh(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2uh/str2uh.sh b/share/tests/str2i.h/str2uh/str2uh.sh new file mode 100755 index 0000000..66bb5ad --- /dev/null +++ b/share/tests/str2i.h/str2uh/str2uh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2uh.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2uh/str2uh_nobuild.sh b/share/tests/str2i.h/str2uh/str2uh_nobuild.sh new file mode 100755 index 0000000..60ca5a2 --- /dev/null +++ b/share/tests/str2i.h/str2uh/str2uh_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + short n; + + str2uh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2uh(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2uhh/str2uhh.c b/share/tests/str2i.h/str2uhh/str2uhh.c new file mode 100644 index 0000000..f25f99e --- /dev/null +++ b/share/tests/str2i.h/str2uhh/str2uhh.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned char n; + + errno = 0; + + assert(str2uhh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2uhh(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2uhh(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2uhh(&n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2uhh(&n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2uhh(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2uhh(&n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uhh(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2uhh(&n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uhh(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2uhh(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2uhh(&n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2uhh(&n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned char n; + + assert(str2uhh(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2uhh(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2uhh(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2uhh(&n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2uhh(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2uhh(&n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned char n; + + assert(str2uhh(&n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2uhh(&n, "0xFF") == 0); + assert(n == 0xFF); + assert(errno == 0); + assert(str2uhh(&n, "-0xFF") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2uhh(&n, "0xFF9") == -1); + assert(n == UCHAR_MAX); + assert(errno == ERANGE); + assert(str2uhh(&n, "-0xFF9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned char n; + + assert(str2uhh(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2uhh(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2uhh(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2uhh/str2uhh.sh b/share/tests/str2i.h/str2uhh/str2uhh.sh new file mode 100755 index 0000000..7454d65 --- /dev/null +++ b/share/tests/str2i.h/str2uhh/str2uhh.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2uhh.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2uhh/str2uhh_nobuild.sh b/share/tests/str2i.h/str2uhh/str2uhh_nobuild.sh new file mode 100755 index 0000000..d4fd98d --- /dev/null +++ b/share/tests/str2i.h/str2uhh/str2uhh_nobuild.sh @@ -0,0 +1,72 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + signed char n; + + str2uhh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + char n; + + str2uhh(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2uhh(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2ui/str2ui.c b/share/tests/str2i.h/str2ui/str2ui.c new file mode 100644 index 0000000..ca2c740 --- /dev/null +++ b/share/tests/str2i.h/str2ui/str2ui.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned int n; + + errno = 0; + + assert(str2ui(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2ui(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ui(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ui(&n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2ui(&n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2ui(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ui(&n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ui(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2ui(&n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ui(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ui(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ui(&n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ui(&n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned int n; + + assert(str2ui(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ui(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ui(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2ui(&n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ui(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2ui(&n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned int n; + + assert(str2ui(&n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ui(&n, "0xFFFF") == 0); + assert(n == 0xFFFF); + assert(errno == 0); + assert(str2ui(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ui(&n, "0xFFFFffffFFFFffff9") == -1); + assert(n == UINT_MAX); + assert(errno == ERANGE); + assert(str2ui(&n, "-0xFFFFffffFFFFffff9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned int n; + + assert(str2ui(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ui(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ui(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2ui/str2ui.sh b/share/tests/str2i.h/str2ui/str2ui.sh new file mode 100755 index 0000000..3bc1669 --- /dev/null +++ b/share/tests/str2i.h/str2ui/str2ui.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2ui.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2ui/str2ui_nobuild.sh b/share/tests/str2i.h/str2ui/str2ui_nobuild.sh new file mode 100755 index 0000000..60add18 --- /dev/null +++ b/share/tests/str2i.h/str2ui/str2ui_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + int n; + + str2ui(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2ui(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2ul/str2ul.c b/share/tests/str2i.h/str2ul/str2ul.c new file mode 100644 index 0000000..5b8f1c3 --- /dev/null +++ b/share/tests/str2i.h/str2ul/str2ul.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned long n; + + errno = 0; + + assert(str2ul(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2ul(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ul(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ul(&n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2ul(&n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2ul(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ul(&n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ul(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2ul(&n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ul(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ul(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ul(&n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ul(&n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned long n; + + assert(str2ul(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ul(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ul(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2ul(&n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ul(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2ul(&n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned long n; + + assert(str2ul(&n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ul(&n, "0xFFFFffff") == 0); + assert(n == 0xFFFFffff); + assert(errno == 0); + assert(str2ul(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ul(&n, "0xFFFFffffFFFFffff9") == -1); + assert(n == ULONG_MAX); + assert(errno == ERANGE); + assert(str2ul(&n, "-0xFFFFffffFFFFffff9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned long n; + + assert(str2ul(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ul(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ul(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2ul/str2ul.sh b/share/tests/str2i.h/str2ul/str2ul.sh new file mode 100755 index 0000000..8ca5b06 --- /dev/null +++ b/share/tests/str2i.h/str2ul/str2ul.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2ul.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2ul/str2ul_nobuild.sh b/share/tests/str2i.h/str2ul/str2ul_nobuild.sh new file mode 100755 index 0000000..ce29ec0 --- /dev/null +++ b/share/tests/str2i.h/str2ul/str2ul_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long n; + + str2ul(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned int n; + + str2ul(&n, "0"); + } +__EOF__ diff --git a/share/tests/str2i.h/str2ull/str2ull.c b/share/tests/str2i.h/str2ull/str2ull.c new file mode 100644 index 0000000..9c6d7cf --- /dev/null +++ b/share/tests/str2i.h/str2ull/str2ull.c @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/str2i.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_base(void) +{ + unsigned long long n; + + errno = 0; + + assert(str2ull(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + + // Binary with "0b" depends on libc support. + //assert(str2ull(&n, "0b11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ull(&n, "0B11") == 0); + //assertn == 3); + //assert(errno == 0); + //assert(str2ull(&n, "-0b11") == 0); + //assertn == 2); + //assert(errno == 0); + //assert(str2ull(&n, "-0B11") == 0); + //assertn == 2); + //assert(errno == 0); + assert(str2ull(&n, "011") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ull(&n, "-011") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ull(&n, "11") == 0); + assert(n == 11); + assert(errno == 0); + assert(str2ull(&n, "-11") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ull(&n, "0x11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ull(&n, "0X11") == 0); + assert(n == 17); + assert(errno == 0); + assert(str2ull(&n, "-0x11") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ull(&n, "-0X11") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_leading_text(void) +{ + unsigned long long n; + + assert(str2ull(&n, "") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ull(&n, "foo") == -1); + assert(n == 0); + assert(errno == ECANCELED); + assert(str2ull(&n, "foo 7") == -1); + assert(n == 0); + assert(errno == ECANCELED); + + errno = 0; + + assert(str2ull(&n, " 9") == 0); + assert(n == 9); + assert(errno == 0); + assert(str2ull(&n, " \t\n0xa") == 0); + assert(n == 10); + assert(errno == 0); + assert(str2ull(&n, " \t\n-0xa") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_range(void) +{ + unsigned long long n; + + assert(str2ull(&n, "-1") == -1); + assert(n == 0); + assert(errno == ERANGE); + errno = 0; + assert(str2ull(&n, "0xFFFFffffFFFFffff") == 0); + assert(n == ULLONG_MAX); + assert(errno == 0); + assert(str2ull(&n, "-0xFFFFffffFFFFffff") == -1); + assert(n == 0); + assert(errno == ERANGE); + assert(str2ull(&n, "0xFFFFffffFFFFffff9") == -1); + assert(n == ULLONG_MAX); + assert(errno == ERANGE); + assert(str2ull(&n, "-0xFFFFffffFFFFffff9") == -1); + assert(n == 0); + assert(errno == ERANGE); +} + + +static void +test_trailing_text(void) +{ + unsigned long long n; + + assert(str2ull(&n, "\n9 fff 7") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ull(&n, "\n9\t") == -1); + assert(n == 9); + assert(errno == ENOTSUP); + assert(str2ull(&n, "9 ") == -1); + assert(n == 9); + assert(errno == ENOTSUP); +} diff --git a/share/tests/str2i.h/str2ull/str2ull.sh b/share/tests/str2i.h/str2ull/str2ull.sh new file mode 100755 index 0000000..bcc4a98 --- /dev/null +++ b/share/tests/str2i.h/str2ull/str2ull.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/str2ull.c $LIBS; +"$out"; diff --git a/share/tests/str2i.h/str2ull/str2ull_nobuild.sh b/share/tests/str2i.h/str2ull/str2ull_nobuild.sh new file mode 100755 index 0000000..9bb0eb2 --- /dev/null +++ b/share/tests/str2i.h/str2ull/str2ull_nobuild.sh @@ -0,0 +1,53 @@ +#!/usr/bin/bash +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + + +set -Eeuf; + + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=pointer-sign' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=pointer-sign]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + long long n; + + str2ull(&n, "0"); + } +__EOF__ + + +cc $CFLAGS -o "$out" -x c - $LIBS 2>&1 <<__EOF__ \ +| if ! grep -- '-Werror=incompatible-pointer-types' >/dev/null; then \ + >&2 printf '%s\n' "$0:$LINENO: Expected [-Werror=incompatible-pointer-types]"; \ + exit 1; \ +else \ + true; \ +fi; + #include <a2i/str2i.h> + + int + main(void) + { + unsigned long n; + + str2ull(&n, "0"); + } +__EOF__ diff --git a/share/tests/strtoi.h/strtoi/strtoi.c b/share/tests/strtoi.h/strtoi/strtoi.c new file mode 100644 index 0000000..fd40689 --- /dev/null +++ b/share/tests/strtoi.h/strtoi/strtoi.c @@ -0,0 +1,387 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/strtoi.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtoi("x99z", NULL, 1, -7, 42, NULL) == 0); + assert(a2i_strtoi("x99z", &e, 1, -7, 42, NULL) == 0); + assert(a2i_strtoi("x99z", NULL, 1, -7, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("x99z", &e, 1, -7, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtoi("x99z", NULL, 0, -7, 42, NULL) == 0); + assert(a2i_strtoi("x99z", &e, 0, -7, 42, NULL) == 0); + assert(strcmp(e, "x99z") == 0); + assert(a2i_strtoi("x99z", NULL, 0, -7, 42, &s) == 0); + assert(s == ECANCELED); + assert(a2i_strtoi("x99z", &e, 0, -7, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2i_strtoi("99z", NULL, 0, -7, 42, NULL) == 42); + assert(a2i_strtoi("99z", &e, 0, -7, 42, NULL) == 42); + assert(strcmp(e, "z") == 0); + assert(a2i_strtoi("99z", NULL, 0, -7, 42, &s) == 42); + assert(s == ERANGE); + assert(a2i_strtoi("99z", &e, 0, -7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtoi("9z", NULL, 0, -7, 42, NULL) == 9); + assert(a2i_strtoi("9z", &e, 0, -7, 42, NULL) == 9); + assert(strcmp(e, "z") == 0); + assert(a2i_strtoi("9z", NULL, 0, -7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(a2i_strtoi("9z", &e, 0, -7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtoi("9", NULL, 0, -7, 42, NULL) == 9); + assert(a2i_strtoi("9", &e, 0, -7, 42, NULL) == 9); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("9", NULL, 0, -7, 42, &s) == 9); + assert(s == 0); + assert(a2i_strtoi("9", &e, 0, -7, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_base(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtoi("1", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, -1, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, -2, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, 37, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, 38, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + + assert(a2i_strtoi("", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("foo", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("43", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, 1, -42, -7, &s) == -7); + assert(s == EINVAL); + assert(a2i_strtoi("1", &e, 1, 42, -42, &s) == 42); + assert(s == EINVAL); + assert(a2i_strtoi("4foo", &e, 1, -42, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtoi("1", &e, 0, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("1", &e, 2, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("1", &e, 3, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("1", &e, 35, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("1", &e, 36, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2i_strtoi("0b11", &e, 0, -42, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("0B11", &e, 0, -42, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("-0b11", &e, 0, -42, 42, &s) == -3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("-0B11", &e, 0, -42, 42, &s) == -3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtoi("011", &e, 0, -42, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-011", &e, 0, -42, 42, &s) == -9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("11", &e, 0, -42, 42, &s) == 11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-11", &e, 0, -42, 42, &s) == -11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("0x11", &e, 0, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("0X11", &e, 0, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-0x11", &e, 0, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-0X11", &e, 0, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi("011", &e, 2, -42, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("11", &e, 2, -42, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("0b11", NULL, 2, -42, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("0B11", NULL, 2, -42, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-011", &e, 2, -42, 42, &s) == -3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-11", &e, 2, -42, 42, &s) == -3); + assert(s == 0); + assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("-0b11", NULL, 2, -42, 42, &s) == -3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtoi("-0B11", NULL, 2, -42, 42, &s) == -3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtoi("011", &e, 16, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("11", &e, 16, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("0x11", &e, 16, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("0X11", &e, 16, -42, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-011", &e, 16, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-11", &e, 16, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-0x11", &e, 16, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-0X11", &e, 16, -42, 42, &s) == -17); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi("011", &e, 7, -42, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("11", &e, 7, -42, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-011", &e, 7, -42, 42, &s) == -8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-11", &e, 7, -42, 42, &s) == -8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("011", &e, 8, -42, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("11", &e, 8, -42, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-011", &e, 8, -42, 42, &s) == -9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-11", &e, 8, -42, 42, &s) == -9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("z", &e, 36, -42, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("Z", &e, 36, -42, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-z", &e, 36, -42, 42, &s) == -35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-Z", &e, 36, -42, 42, &s) == -35); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtoi("", &e, 0, -42, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("foo", &e, 0, -42, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2i_strtoi("foo 7", &e, 0, -42, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2i_strtoi("", &e, 0, 42, -42, &s) == 42); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi(" 1", &e, 0, -42, 42, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi(" \t\na", &e, 16, -42, 42, &s) == 10); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi(" \t\n-a", &e, 16, -42, 42, &s) == -10); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_range(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtoi("-9", &e, 0, -7, 42, &s) == -7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-8", &e, 0, -7, 42, &s) == -7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("43", &e, 0, -7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("44", &e, 0, -7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi("7", &e, 0, 7, -42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("42", &e, 0, 7, -42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi("-9z", &e, 0, -7, 42, &s) == -7); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2i_strtoi("-9 ", &e, 0, -7, 42, &s) == -7); + assert(s == ERANGE); + assert(strcmp(e, " ") == 0); + + assert(a2i_strtoi("-7", &e, 0, -7, 42, &s) == -7); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-6", &e, 0, -7, 42, &s) == -6); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("41", &e, 0, -7, 42, &s) == 41); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("42", &e, 0, -7, 42, &s) == 42); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(a2i_strtoi("-1", &e, 0, INTMAX_MIN, INTMAX_MAX, &s) == -1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("0xFFFFffffFFFFffff", &e, 0, INTMAX_MIN, INTMAX_MAX, &s) == INTMAX_MAX); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtoi("-0xFFFFffffFFFFffff", &e, 0, INTMAX_MIN, INTMAX_MAX, &s) == INTMAX_MIN); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_trailing_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtoi("\n9 fff 7", &e, 0, -7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2i_strtoi("\n9\t", &e, 0, -7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2i_strtoi("9 ", &e, 0, -7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " ") == 0); + + assert(errno == 0); +} diff --git a/share/tests/strtoi.h/strtoi/strtoi.sh b/share/tests/strtoi.h/strtoi/strtoi.sh new file mode 100755 index 0000000..b2199bd --- /dev/null +++ b/share/tests/strtoi.h/strtoi/strtoi.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/strtoi.c $LIBS; +"$out"; diff --git a/share/tests/strtoi.h/strtou/strtou.c b/share/tests/strtoi.h/strtou/strtou.c new file mode 100644 index 0000000..7d5cd51 --- /dev/null +++ b/share/tests/strtoi.h/strtou/strtou.c @@ -0,0 +1,393 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/strtoi.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtou("x99z", NULL, 1, 0, 42, NULL) == 0); + assert(a2i_strtou("x99z", &e, 1, 0, 42, NULL) == 0); + assert(a2i_strtou("x99z", NULL, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("x99z", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtou("x99z", NULL, 0, 0, 42, NULL) == 0); + assert(a2i_strtou("x99z", &e, 0, 0, 42, NULL) == 0); + assert(strcmp(e, "x99z") == 0); + assert(a2i_strtou("x99z", NULL, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(a2i_strtou("x99z", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2i_strtou("99z", NULL, 0, 7, 42, NULL) == 42); + assert(a2i_strtou("99z", &e, 0, 7, 42, NULL) == 42); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou("99z", NULL, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(a2i_strtou("99z", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtou("9z", NULL, 0, 7, 42, NULL) == 9); + assert(a2i_strtou("9z", &e, 0, 7, 42, NULL) == 9); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou("9z", NULL, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(a2i_strtou("9z", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtou("9", NULL, 0, 7, 42, NULL) == 9); + assert(a2i_strtou("9", &e, 0, 7, 42, NULL) == 9); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("9", NULL, 0, 7, 42, &s) == 9); + assert(s == 0); + assert(a2i_strtou("9", &e, 0, 7, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_base(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtou("9", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, -1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, -2, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, 37, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, 38, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(a2i_strtou("", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("foo", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("43", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, 1, 42, 0, &s) == 42); + assert(s == EINVAL); + assert(a2i_strtou("9", &e, 1, 42, 0, &s) == 42); + assert(s == EINVAL); + assert(a2i_strtou("9foo", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtou("11", &e, 0, 2, 42, &s) == 11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 3, 2, 42, &s) == 4); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 35, 2, 42, &s) == 36); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 36, 2, 42, &s) == 37); + assert(s == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2i_strtou("0b11", &e, 0, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou("0B11", &e, 0, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou("-0b11", &e, 0, 2, 42, &s) == 42); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou("-0B11", &e, 0, 2, 42, &s) == 42); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou("011", &e, 0, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-011", &e, 0, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 0, 2, 42, &s) == 11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-11", &e, 0, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0x11", &e, 0, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0X11", &e, 0, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0x11", &e, 0, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0X11", &e, 0, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou("011", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + //assert(a2i_strtou("0b11", NULL, 2, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou("0B11", NULL, 2, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou("-011", &e, 2, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-11", &e, 2, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2i_strtou("-0b11", NULL, 2, 2, 42, &s) == 42); + //assert(s == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou("-0B11", NULL, 2, 2, 42, &s) == 42); + //assert(s == ERANGE); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou("011", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0x11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0X11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-011", &e, 16, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-11", &e, 16, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0x11", &e, 16, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0X11", &e, 16, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou("011", &e, 7, 2, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 7, 2, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-011", &e, 7, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-11", &e, 7, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("011", &e, 8, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("11", &e, 8, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-011", &e, 8, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-11", &e, 8, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("z", &e, 36, 2, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("Z", &e, 36, 2, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-z", &e, 36, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-Z", &e, 36, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou("", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("foo", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2i_strtou("foo 7", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2i_strtou("", &e, 0, 42, 0, &s) == 42); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou(" 9", &e, 0, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou(" \t\na", &e, 16, 2, 42, &s) == 10); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou(" \t\n-a", &e, 16, 2, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_range(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou("5", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("6", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("43", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("44", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou("7", &e, 0, 7, 4, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("42", &e, 0, 7, 4, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou("6z", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou("6 ", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, " ") == 0); + + assert(a2i_strtou("7", &e, 0, 7, 42, &s) == 7); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("8", &e, 0, 7, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("41", &e, 0, 7, 42, &s) == 41); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("42", &e, 0, 7, 42, &s) == 42); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou("-1", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0xFFFFffffFFFFffff", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0xFFFFffffFFFFffff", &e, 0, 0, UINTMAX_MAX, &s) == 1); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("0xFFFFffffFFFFffff9", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou("-0xFFFFffffFFFFffff9", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_trailing_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou("\n9 fff 7", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2i_strtou("\n9\t", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2i_strtou("9 ", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " ") == 0); + + assert(errno == 0); +} diff --git a/share/tests/strtoi.h/strtou/strtou.sh b/share/tests/strtoi.h/strtou/strtou.sh new file mode 100755 index 0000000..7ddab58 --- /dev/null +++ b/share/tests/strtoi.h/strtou/strtou.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/strtou.c $LIBS; +"$out"; diff --git a/share/tests/strtoi.h/strtou_noneg/strtou_noneg.c b/share/tests/strtoi.h/strtou_noneg/strtou_noneg.c new file mode 100644 index 0000000..17cbfea --- /dev/null +++ b/share/tests/strtoi.h/strtou_noneg/strtou_noneg.c @@ -0,0 +1,393 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception + + +#include <a2i/strtoi.h> + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#undef NDEBUG +#include <assert.h> + + +static void test_null(void); +static void test_base(void); +static void test_leading_text(void); +static void test_range(void); +static void test_trailing_text(void); + + +int +main(void) +{ + test_null(); + test_base(); + test_leading_text(); + test_range(); + test_trailing_text(); +} + + +static void +test_null(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtou_noneg("x99z", NULL, 1, 0, 42, NULL) == 0); + assert(a2i_strtou_noneg("x99z", &e, 1, 0, 42, NULL) == 0); + assert(a2i_strtou_noneg("x99z", NULL, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("x99z", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtou_noneg("x99z", NULL, 0, 0, 42, NULL) == 0); + assert(a2i_strtou_noneg("x99z", &e, 0, 0, 42, NULL) == 0); + assert(strcmp(e, "x99z") == 0); + assert(a2i_strtou_noneg("x99z", NULL, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(a2i_strtou_noneg("x99z", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "x99z") == 0); + + assert(a2i_strtou_noneg("99z", NULL, 0, 7, 42, NULL) == 42); + assert(a2i_strtou_noneg("99z", &e, 0, 7, 42, NULL) == 42); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou_noneg("99z", NULL, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(a2i_strtou_noneg("99z", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtou_noneg("9z", NULL, 0, 7, 42, NULL) == 9); + assert(a2i_strtou_noneg("9z", &e, 0, 7, 42, NULL) == 9); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou_noneg("9z", NULL, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(a2i_strtou_noneg("9z", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "z") == 0); + + assert(a2i_strtou_noneg("9", NULL, 0, 7, 42, NULL) == 9); + assert(a2i_strtou_noneg("9", &e, 0, 7, 42, NULL) == 9); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("9", NULL, 0, 7, 42, &s) == 9); + assert(s == 0); + assert(a2i_strtou_noneg("9", &e, 0, 7, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_base(void) +{ + int s; + char *e = "unmodified"; + + errno = 0; + + assert(a2i_strtou_noneg("9", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, -1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, -2, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, 37, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, 38, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(a2i_strtou_noneg("", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("foo", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("43", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, 1, 42, 0, &s) == 42); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9", &e, 1, 42, 0, &s) == 42); + assert(s == EINVAL); + assert(a2i_strtou_noneg("9foo", &e, 1, 0, 42, &s) == 0); + assert(s == EINVAL); + + assert(strcmp(e, "unmodified") == 0); + + assert(a2i_strtou_noneg("11", &e, 0, 2, 42, &s) == 11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 3, 2, 42, &s) == 4); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 35, 2, 42, &s) == 36); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 36, 2, 42, &s) == 37); + assert(s == 0); + assert(strcmp(e, "") == 0); + + // Binary with "0b" depends on libc support. + //assert(a2i_strtou_noneg("0b11", &e, 0, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("0B11", &e, 0, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("-0b11", &e, 0, 2, 42, &s) == 2); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("-0B11", &e, 0, 2, 42, &s) == 2); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("011", &e, 0, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-011", &e, 0, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 0, 2, 42, &s) == 11); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-11", &e, 0, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0x11", &e, 0, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0X11", &e, 0, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0x11", &e, 0, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0X11", &e, 0, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg("011", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 2, 2, 42, &s) == 3); + assert(s == 0); + assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("0b11", NULL, 2, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("0B11", NULL, 2, 2, 42, &s) == 3); + //assert(s == 0); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-011", &e, 2, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-11", &e, 2, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("-0b11", NULL, 2, 2, 42, &s) == 2); + //assert(s == ERANGE); + //assert(strcmp(e, "") == 0); + //assert(a2i_strtou_noneg("-0B11", NULL, 2, 2, 42, &s) == 2); + //assert(s == ERANGE); + //assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("011", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0x11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0X11", &e, 16, 2, 42, &s) == 17); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-011", &e, 16, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-11", &e, 16, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0x11", &e, 16, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0X11", &e, 16, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg("011", &e, 7, 2, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 7, 2, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-011", &e, 7, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-11", &e, 7, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("011", &e, 8, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("11", &e, 8, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-011", &e, 8, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-11", &e, 8, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("z", &e, 36, 2, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("Z", &e, 36, 2, 42, &s) == 35); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-z", &e, 36, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-Z", &e, 36, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_leading_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou_noneg("", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("foo", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo") == 0); + assert(a2i_strtou_noneg("foo 7", &e, 0, 0, 42, &s) == 0); + assert(s == ECANCELED); + assert(strcmp(e, "foo 7") == 0); + assert(a2i_strtou_noneg("", &e, 0, 42, 0, &s) == 42); + assert(s == ECANCELED); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg(" 9", &e, 0, 2, 42, &s) == 9); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg(" \t\na", &e, 16, 2, 42, &s) == 10); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg(" \t\n-a", &e, 16, 2, 42, &s) == 2); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_range(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou_noneg("5", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("6", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("43", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("44", &e, 0, 7, 42, &s) == 42); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg("7", &e, 0, 7, 4, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("42", &e, 0, 7, 4, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg("6z", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, "z") == 0); + assert(a2i_strtou_noneg("6 ", &e, 0, 7, 42, &s) == 7); + assert(s == ERANGE); + assert(strcmp(e, " ") == 0); + + assert(a2i_strtou_noneg("7", &e, 0, 7, 42, &s) == 7); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("8", &e, 0, 7, 42, &s) == 8); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("41", &e, 0, 7, 42, &s) == 41); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("42", &e, 0, 7, 42, &s) == 42); + assert(s == 0); + assert(strcmp(e, "") == 0); + + assert(a2i_strtou_noneg("-1", &e, 0, 0, UINTMAX_MAX, &s) == 0); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0xFFFFffffFFFFffff", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == 0); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0xFFFFffffFFFFffff", &e, 0, 0, UINTMAX_MAX, &s) == 0); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("0xFFFFffffFFFFffff9", &e, 0, 0, UINTMAX_MAX, &s) == UINTMAX_MAX); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + assert(a2i_strtou_noneg("-0xFFFFffffFFFFffff9", &e, 0, 0, UINTMAX_MAX, &s) == 0); + assert(s == ERANGE); + assert(strcmp(e, "") == 0); + + assert(errno == 0); +} + + +static void +test_trailing_text(void) +{ + int s; + char *e; + + errno = 0; + + assert(a2i_strtou_noneg("\n9 fff 7", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " fff 7") == 0); + assert(a2i_strtou_noneg("\n9\t", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, "\t") == 0); + assert(a2i_strtou_noneg("9 ", &e, 0, 7, 42, &s) == 9); + assert(s == ENOTSUP); + assert(strcmp(e, " ") == 0); + + assert(errno == 0); +} diff --git a/share/tests/strtoi.h/strtou_noneg/strtou_noneg.sh b/share/tests/strtoi.h/strtou_noneg/strtou_noneg.sh new file mode 100755 index 0000000..989a492 --- /dev/null +++ b/share/tests/strtoi.h/strtou_noneg/strtou_noneg.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright 2024 Alejandro Colomar <alx@kernel.org> +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception + +out="$(mktemp)"; +CFLAGS="-std=gnu2x"; +CFLAGS="$CFLAGS -Wall"; +CFLAGS="$CFLAGS -Wextra"; +CFLAGS="$CFLAGS -Werror"; +CFLAGS="$CFLAGS $(pkgconf --cflags liba2i)"; +LIBS="$(pkgconf --libs liba2i)"; + +cc $CFLAGS -o "$out" "$(dirname "$0")"/strtou_noneg.c $LIBS; +"$out"; |