Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions include/zephyr/sys/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@
* @retval -1 if x is negative
* @retval 0 if x is zero
*/
#define SIGN(x) (((x) > 0) - ((x) < 0))
#define SYS_SIGN(x) (((x) > 0) - ((x) < 0))

/**
* @brief Compute the Greatest Common Divisor (GCD) of two integers
Expand All @@ -1048,9 +1048,12 @@
* @return The greatest common divisor of a and b, always returns an unsigned value.
* If one of the parameters is 0, returns the absolute value of the other parameter.
*/
#define gcd(a, b) ((((__typeof__(a))-1) < 0) ? gcd_s(a, b) : gcd_u(a, b))
#define sys_gcd(a, b) ((((__typeof__(a))-1) < 0) ? sys_gcd_s(a, b) : sys_gcd_u(a, b))

static ALWAYS_INLINE uint32_t gcd_u(uint32_t a, uint32_t b)
/**
* @cond INTERNAL_HIDDEN
*/
static ALWAYS_INLINE uint32_t sys_gcd_u(uint32_t a, uint32_t b)
{
uint32_t c;

Expand All @@ -1072,10 +1075,13 @@
return b;
}

static ALWAYS_INLINE uint32_t gcd_s(int32_t a, int32_t b)
static ALWAYS_INLINE uint32_t sys_gcd_s(int32_t a, int32_t b)
{
return gcd_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b);
return sys_gcd_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b);

Check warning on line 1080 in include/zephyr/sys/util.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unary minus operator or change the expression's underlying type.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZsCmkhYLh3lS8elvrV6&open=AZsCmkhYLh3lS8elvrV6&pullRequest=100725

Check warning on line 1080 in include/zephyr/sys/util.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unary minus operator or change the expression's underlying type.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZsCmkhYLh3lS8elvrV5&open=AZsCmkhYLh3lS8elvrV5&pullRequest=100725
}
/**
* @endcond
*/

/**
* @brief Compute the Least Common Multiple (LCM) of two integers.
Expand All @@ -1086,21 +1092,27 @@
* @retval The least common multiple of a and b.
* @retval 0 if either input is 0.
*/
#define lcm(a, b) ((((__typeof__(a))-1) < 0) ? lcm_s(a, b) : lcm_u(a, b))
#define sys_lcm(a, b) ((((__typeof__(a))-1) < 0) ? sys_lcm_s(a, b) : sys_lcm_u(a, b))

static ALWAYS_INLINE uint64_t lcm_u(uint32_t a, uint32_t b)
/**
* @cond INTERNAL_HIDDEN
*/
static ALWAYS_INLINE uint64_t sys_lcm_u(uint32_t a, uint32_t b)
{
if (a == 0 || b == 0) {
return 0;
}

return (uint64_t)(a / gcd_u(a, b)) * (uint64_t)b;
return (uint64_t)(a / sys_gcd_u(a, b)) * (uint64_t)b;
}

static ALWAYS_INLINE uint64_t lcm_s(int32_t a, int32_t b)
static ALWAYS_INLINE uint64_t sys_lcm_s(int32_t a, int32_t b)
{
return lcm_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b);
return sys_lcm_u(a < 0 ? -(uint32_t)a : (uint32_t)a, b < 0 ? -(uint32_t)b : (uint32_t)b);

Check warning on line 1111 in include/zephyr/sys/util.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unary minus operator or change the expression's underlying type.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZsCmkhYLh3lS8elvrV8&open=AZsCmkhYLh3lS8elvrV8&pullRequest=100725

Check warning on line 1111 in include/zephyr/sys/util.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unary minus operator or change the expression's underlying type.

See more on https://sonarcloud.io/project/issues?id=zephyrproject-rtos_zephyr&issues=AZsCmkhYLh3lS8elvrV7&open=AZsCmkhYLh3lS8elvrV7&pullRequest=100725
}
/**
* @endcond
*/

#ifdef __cplusplus
}
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/getopt/getopt_long.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: getopt_long.c,v 1.22 2006/10/04 21:29:04 jmc Exp $ */

Check warning on line 1 in lib/utils/getopt/getopt_long.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License may not be allowed

lib/utils/getopt/getopt_long.c:1 License file for 'BSD-3-Clause' not found in /LICENSES. Please check https://docs.zephyrproject.org/latest/contribute/guidelines.html#components-using-other-licenses.

Check warning on line 1 in lib/utils/getopt/getopt_long.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License may not be allowed

lib/utils/getopt/getopt_long.c:1 License file for 'BSD-3-Clause' not found in /LICENSES. Please check https://docs.zephyrproject.org/latest/contribute/guidelines.html#components-using-other-licenses.

Check warning on line 1 in lib/utils/getopt/getopt_long.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License may not be allowed

lib/utils/getopt/getopt_long.c:1 License file for 'BSD-3-Clause' not found in /LICENSES. Please check https://docs.zephyrproject.org/latest/contribute/guidelines.html#components-using-other-licenses.
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/* SPDX-License-Identifier: BSD-3-Clause */

Expand Down Expand Up @@ -52,6 +52,7 @@

#include <string.h>
#include <zephyr/sys/sys_getopt.h>
#include <zephyr/sys/util.h>
#include "getopt_common.h"

#include <zephyr/logging/log.h>
Expand Down Expand Up @@ -120,7 +121,7 @@
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
ncycle = sys_gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;

for (int i = 0; i < ncycle; i++) {
Expand Down
52 changes: 26 additions & 26 deletions tests/unit/util/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1240,67 +1240,67 @@ ZTEST(util, test_bitmask_find_gap)
test_single_bitmask_find_gap(0x0000000F, 2, 6, false, 4, __LINE__);
}

ZTEST(util, test_gcd)
ZTEST(util, test_sys_gcd)
{
/* Zero cases */
zassert_equal(gcd(0, 0), 0, "should be 0");
zassert_equal(gcd(0, INT_MAX), INT_MAX, "should be 0");
zassert_equal(gcd(INT_MAX, 0), INT_MAX, "should be 0");
zassert_equal(sys_gcd(0, 0), 0, "should be 0");
zassert_equal(sys_gcd(0, INT_MAX), INT_MAX, "should be 0");
zassert_equal(sys_gcd(INT_MAX, 0), INT_MAX, "should be 0");

/* Normal cases */
zassert_equal(gcd(12, 8), 4, "should be 4");
zassert_equal(sys_gcd(12, 8), 4, "should be 4");

/* Negative number cases */
zassert_equal(gcd(-12, 8), 4, "should be 4");
zassert_equal(gcd(-12, -8), 4, "should be 4");
zassert_equal(sys_gcd(-12, 8), 4, "should be 4");
zassert_equal(sys_gcd(-12, -8), 4, "should be 4");

/* Prime numbers */
zassert_equal(gcd(17, 13), 1, "should be 1");
zassert_equal(gcd(25, 49), 1, "should be 1");
zassert_equal(sys_gcd(17, 13), 1, "should be 1");
zassert_equal(sys_gcd(25, 49), 1, "should be 1");

/* Boundary values */
zassert_equal(gcd(INT_MAX, INT_MAX), INT_MAX, "should be INT_MAX");
zassert_equal(gcd(INT_MIN, INT_MIN), (uint32_t)(-(int64_t)INT_MIN),
zassert_equal(sys_gcd(INT_MAX, INT_MAX), INT_MAX, "should be INT_MAX");
zassert_equal(sys_gcd(INT_MIN, INT_MIN), (uint32_t)(-(int64_t)INT_MIN),
"should be INT_MAX + 1");
zassert_equal(gcd(INT_MIN, INT_MAX), 1, "should be 1");
zassert_equal(gcd(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX");
zassert_equal(sys_gcd(INT_MIN, INT_MAX), 1, "should be 1");
zassert_equal(sys_gcd(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX");

/* Macro expansion */
int a = 12, b = 8;

zassert_equal(gcd(a++, b++), 4, "should be 4");
zassert_equal(sys_gcd(a++, b++), 4, "should be 4");
zassert_equal(a, 13, "should be 13");
zassert_equal(b, 9, "should be 9");
}

ZTEST(util, test_lcm)
ZTEST(util, test_sys_lcm)
{
/* Zero cases - lcm with 0 should be 0 */
zassert_equal(lcm(0, 0), 0, "should be 0");
zassert_equal(lcm(0, INT_MAX), 0, "should be 0");
zassert_equal(sys_lcm(0, 0), 0, "should be 0");
zassert_equal(sys_lcm(0, INT_MAX), 0, "should be 0");

/* Normal cases */
zassert_equal(lcm(12, 8), 24, "should be 24");
zassert_equal(lcm(8, 12), 24, "should be 24");
zassert_equal(sys_lcm(12, 8), 24, "should be 24");
zassert_equal(sys_lcm(8, 12), 24, "should be 24");

/* Negative number cases - lcm should always be positive */
zassert_equal(lcm(-12, 8), 24, "should be 24");
zassert_equal(sys_lcm(-12, 8), 24, "should be 24");

/* Prime numbers (gcd = 1, so lcm = a * b) */
zassert_equal(lcm(17, 13), 221, "should be 221");
zassert_equal(sys_lcm(17, 13), 221, "should be 221");

/* Boundary values */
zassert_equal(lcm(INT_MAX, INT_MAX - 1), (uint64_t)INT_MAX * (INT_MAX - 1),
zassert_equal(sys_lcm(INT_MAX, INT_MAX - 1), (uint64_t)INT_MAX * (INT_MAX - 1),
"should be INT_MAX * (INT_MAX - 1)");
zassert_equal(lcm(INT_MIN, INT_MIN), (uint64_t)INT_MAX + 1, "should be INT_MAX + 1");
zassert_equal(lcm(INT_MIN, INT_MAX), (uint64_t)INT_MAX * (uint64_t)(-(int64_t)INT_MIN),
zassert_equal(sys_lcm(INT_MIN, INT_MIN), (uint64_t)INT_MAX + 1, "should be INT_MAX + 1");
zassert_equal(sys_lcm(INT_MIN, INT_MAX), (uint64_t)INT_MAX * (uint64_t)(-(int64_t)INT_MIN),
"should be INT_MAX * (INT_MAX + 1)");
zassert_equal(lcm(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX");
zassert_equal(sys_lcm(UINT32_MAX, UINT32_MAX), UINT32_MAX, "should be UINT32_MAX");

/* Macro expansion */
int a = 12, b = 8;

zassert_equal(lcm(a++, b++), 24, "should be 4");
zassert_equal(sys_lcm(a++, b++), 24, "should be 4");
zassert_equal(a, 13, "should be 13");
zassert_equal(b, 9, "should be 9");
}
Expand Down
Loading