GBAlatro
A Demake of Balatro for the GBA
Loading...
Searching...
No Matches
util.h File Reference

Utilities relating around number string representation and protected arithmatic helper functions. More...

#include <stdint.h>

Go to the source code of this file.

Macros

#define GBAL_ATTRIBUTE(attr)   __attribute__((attr))
 A friendly wrapper around the not so friendly looking attribute syntax.
 
#define GBAL_UNUSED   GBAL_ATTRIBUTE(unused)
 Wrapper around the "unused" attribute.
 
#define GBAL_FALLTHROUGH   GBAL_ATTRIBUTE(fallthrough)
 Wrapper around for the "fallthrough" attribute.
 
#define UNDEFINED   -1
 
#define MAX_BASE36   0x81BF0FFF
 Hex value of "ZZZZZZ" in base 36.
 
#define SIGN(x)   ((x > 0) - (x < 0))
 Get the sign (signum) of an integer.
 
#define NUM_ELEM_IN_ARR(arr)   (sizeof(arr) / sizeof((arr)[0]))
 Get the number of elements in an array.
 
#define INT_MAX_DIGITS   11
 
#define UINT_MAX_DIGITS   10
 
#define UINT8_MAX_DIGITS   3
 
#define BASE36_MAX_DIGITS   6
 
#define ONE_K   1000
 
#define ONE_M   1000000
 
#define ONE_B   1000000000
 
#define ONE_K_ZEROS   3
 
#define ONE_M_ZEROS   6
 
#define ONE_B_ZEROS   9
 
#define SUFFIXED_NUM_MIN_REQ_CHARS   4
 
#define LOG_ERROR(...)   ((void)(0))
 
#define GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS(expression, ret_val, message, ...)
 Returns ret_val and logs error message if expression is false.
 
#define GBAL_RETURN_IF_ASSERT_FAILS(expression, ret_val)    GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS(expression, ret_val, "Assert failed: %s", #expression)
 Returns ret_val and logs a default error message if expression is false.
 
#define GBAL_CUST_MSG_RETURN_IF_NULL(param, ret_val, message, ...)
 Returns ret_val and prints error message if param is equal to NULL. Useful for checking arguments or function return values during control flow.
 
#define GBAL_RETURN_IF_NULL(param, ret_val)    GBAL_CUST_MSG_RETURN_IF_NULL(param, ret_val, "Unexpected %s == NULL", #param)
 Returns ret_val and prints a default error message if param is equal to NULL. Useful for checking arguments or function return values during control flow.
 
#define RET_NONE
 An empty return value for RETURN_IF macros when used in void functions Expands to nothing because macros expand normally with blank arguments so it's more to explicitly convey that the empty value is intended.
 

Functions

uint32_t u32_protected_add (uint32_t a, uint32_t b)
 Avoid overflow when adding two u32 integers.
 
uint16_t u16_protected_add (uint16_t a, uint16_t b)
 Avoid overflow when adding two u16 integers.
 
uint32_t u32_protected_mult (uint32_t a, uint32_t b)
 Avoid overflow when multiplying two u32 integers.
 
uint16_t u16_protected_mult (uint16_t a, uint16_t b)
 Avoid overflow when multiplying two u16 integers.
 
void truncate_uint_to_suffixed_str (uint32_t num, int num_req_chars, char out_str_buff[UINT_MAX_DIGITS+1])
 Truncate an unsigned number into a suffixed string representation e.g. 12000 -> "12K" The least significant digits are rounded down e.g. 12345 -> "12K", 12987 -> "12K".
 
static int u32_get_digits (uint32_t n)
 Get the number of digits in a 32-bit unsigned number https://stackoverflow.com/questions/1068849/how-do-i-determine-the-number-of-digits-of-an-integer-in-c.
 
uint32_t base36_to_u32 (const char b36_str[])
 Convert a base-36 string representation to a 32-bit unsigned integer. Since we are dealing with base-36 instead of decimal, the 32-bit decimal value of a base-36 string representation b36 is equal to:
 
void u32_to_base36 (uint32_t n, char b36_str[])
 Convert a 32-bit unsigned integer to its base-36 string representation. This will perform 6 divisions, so it will be significantly more expensive than its base36_to_u32 counterpart.
 

Detailed Description

Utilities relating around number string representation and protected arithmatic helper functions.

Definition in file util.h.

Macro Definition Documentation

◆ BASE36_MAX_DIGITS

#define BASE36_MAX_DIGITS   6

Definition at line 60 of file util.h.

◆ GBAL_ATTRIBUTE

#define GBAL_ATTRIBUTE (   attr)    __attribute__((attr))

A friendly wrapper around the not so friendly looking attribute syntax.

Definition at line 19 of file util.h.

◆ GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS

#define GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS (   expression,
  ret_val,
  message,
  ... 
)
Value:
do \
{ \
if (!(expression)) \
{ \
LOG_ERROR(message __VA_OPT__(, ) __VA_ARGS__); \
return ret_val; \
} \
} while (0)

Returns ret_val and logs error message if expression is false.

Parameters
ret_valThe value to return in case expression is false. Pass RET_NONE in a void function
messageThe message to log if expression is false. See GBAL_RETURN_IF_ASSERT_FAILS for a version with a default message

Definition at line 90 of file util.h.

◆ GBAL_CUST_MSG_RETURN_IF_NULL

#define GBAL_CUST_MSG_RETURN_IF_NULL (   param,
  ret_val,
  message,
  ... 
)
Value:
(param) != NULL, \
ret_val, \
message __VA_OPT__(, ) __VA_ARGS__ \
)
#define GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS(expression, ret_val, message,...)
Returns ret_val and logs error message if expression is false.
Definition util.h:90

Returns ret_val and prints error message if param is equal to NULL. Useful for checking arguments or function return values during control flow.

Parameters
ret_valThe value to return in case param is equal to NULL. Pass RET_NONE in a void function

See GBAL_RETURN_IF_NULL for a version that logs a default error message.

Definition at line 121 of file util.h.

◆ GBAL_FALLTHROUGH

#define GBAL_FALLTHROUGH   GBAL_ATTRIBUTE(fallthrough)

Wrapper around for the "fallthrough" attribute.

Definition at line 31 of file util.h.

◆ GBAL_RETURN_IF_ASSERT_FAILS

#define GBAL_RETURN_IF_ASSERT_FAILS (   expression,
  ret_val 
)     GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS(expression, ret_val, "Assert failed: %s", #expression)

Returns ret_val and logs a default error message if expression is false.

Parameters
ret_valThe value to return in case expression is false. Pass RET_NONE in a void function

See GBAL_CUST_MSG_RETURN_IF_ASSERT_FAILS for a version that allows passing any custom error message.

Definition at line 109 of file util.h.

◆ GBAL_RETURN_IF_NULL

#define GBAL_RETURN_IF_NULL (   param,
  ret_val 
)     GBAL_CUST_MSG_RETURN_IF_NULL(param, ret_val, "Unexpected %s == NULL", #param)

Returns ret_val and prints a default error message if param is equal to NULL. Useful for checking arguments or function return values during control flow.

Parameters
ret_valThe value to return in case param is equal to NULL. Pass RET_NONE in a void function

See GBAL_CUST_MSG_RETURN_IF_NULL for a version that allows passing any custom error message.

Definition at line 138 of file util.h.

◆ GBAL_UNUSED

#define GBAL_UNUSED   GBAL_ATTRIBUTE(unused)

Wrapper around the "unused" attribute.

Definition at line 25 of file util.h.

◆ INT_MAX_DIGITS

#define INT_MAX_DIGITS   11

Definition at line 57 of file util.h.

◆ LOG_ERROR

#define LOG_ERROR (   ...)    ((void)(0))

Definition at line 78 of file util.h.

◆ MAX_BASE36

#define MAX_BASE36   0x81BF0FFF

Hex value of "ZZZZZZ" in base 36.

Definition at line 39 of file util.h.

◆ NUM_ELEM_IN_ARR

#define NUM_ELEM_IN_ARR (   arr)    (sizeof(arr) / sizeof((arr)[0]))

Get the number of elements in an array.

Parameters
arrinput array

Definition at line 55 of file util.h.

◆ ONE_B

#define ONE_B   1000000000

Definition at line 64 of file util.h.

◆ ONE_B_ZEROS

#define ONE_B_ZEROS   9

Definition at line 68 of file util.h.

◆ ONE_K

#define ONE_K   1000

Definition at line 62 of file util.h.

◆ ONE_K_ZEROS

#define ONE_K_ZEROS   3

Definition at line 66 of file util.h.

◆ ONE_M

#define ONE_M   1000000

Definition at line 63 of file util.h.

◆ ONE_M_ZEROS

#define ONE_M_ZEROS   6

Definition at line 67 of file util.h.

◆ RET_NONE

#define RET_NONE

An empty return value for RETURN_IF macros when used in void functions Expands to nothing because macros expand normally with blank arguments so it's more to explicitly convey that the empty value is intended.

Definition at line 146 of file util.h.

◆ SIGN

#define SIGN (   x)    ((x > 0) - (x < 0))

Get the sign (signum) of an integer.

Returns
1,-1,0 if the number is positive,negative, or 0, respectively.

Definition at line 47 of file util.h.

◆ SUFFIXED_NUM_MIN_REQ_CHARS

#define SUFFIXED_NUM_MIN_REQ_CHARS   4

Definition at line 72 of file util.h.

◆ UINT8_MAX_DIGITS

#define UINT8_MAX_DIGITS   3

Definition at line 59 of file util.h.

◆ UINT_MAX_DIGITS

#define UINT_MAX_DIGITS   10

Definition at line 58 of file util.h.

◆ UNDEFINED

#define UNDEFINED   -1

Definition at line 33 of file util.h.

Function Documentation

◆ base36_to_u32()

uint32_t base36_to_u32 ( const char  b36_str[])

Convert a base-36 string representation to a 32-bit unsigned integer. Since we are dealing with base-36 instead of decimal, the 32-bit decimal value of a base-36 string representation b36 is equal to:

 b36[0] * 36^0 + b36[1] * 36^1 + b36[2] * 36^2 ...

Parameters
b36_strinput char[] to convert to decimal, must be of size BASE36_MAX_DIGITS+1
Returns
the 32-bit unsigned value of b36_str

Definition at line 260 of file util.c.

◆ truncate_uint_to_suffixed_str()

void truncate_uint_to_suffixed_str ( uint32_t  num,
int  num_req_chars,
char  out_str_buff[UINT_MAX_DIGITS+1] 
)

Truncate an unsigned number into a suffixed string representation e.g. 12000 -> "12K" The least significant digits are rounded down e.g. 12345 -> "12K", 12987 -> "12K".

Parameters
numThe number to truncate, can be anything from 0 to UINT32_MAX.
num_req_charsThe number of characters to constrain the string to. The function will use up as much characters as it can in order to maintain as much accuracy as possible. So numbers are not fully truncated if not necessary, e.g. 123123000 -> "123123K" for example value 7, and if num_req_chars > u32_get_digits(num) the number will not be truncated at all. Passing less than SUFFIXED_NUM_MIN_REQ_CHARS may result in an output string longer than num_req_chars but can be done to truncate 1000s -> "1K", 2000 -> "2K" etc. which wouldn't be otherwise.
out_strAn output buffer to write the resulting string to. Must be of size UINT_MAX_DIGITS + 1. + 1 for null-terminator. At that size the suffix character will always be accounted for since a number with more digits than UINT_MAX_DIGITS will not be handled nor truncated.

Definition at line 116 of file util.c.

◆ u16_protected_add()

uint16_t u16_protected_add ( uint16_t  a,
uint16_t  b 
)

Avoid overflow when adding two u16 integers.

Parameters
aleft operator a + b
bleft operator a + b
Returns
the result of a + b or UINT16_MAX in case of overflow

Definition at line 180 of file util.c.

◆ u16_protected_mult()

uint16_t u16_protected_mult ( uint16_t  a,
uint16_t  b 
)

Avoid overflow when multiplying two u16 integers.

Parameters
aleft operator a * b
bleft operator a * b
Returns
the result of a * b or UINT16_MAX in case of overflow

Definition at line 190 of file util.c.

◆ u32_get_digits()

static int u32_get_digits ( uint32_t  n)
inlinestatic

Get the number of digits in a 32-bit unsigned number https://stackoverflow.com/questions/1068849/how-do-i-determine-the-number-of-digits-of-an-integer-in-c.

Parameters
n32-bit unsigned value to find the number of decimal digits of
Returns
the number of digits in a number

Definition at line 226 of file util.h.

◆ u32_protected_add()

uint32_t u32_protected_add ( uint32_t  a,
uint32_t  b 
)

Avoid overflow when adding two u32 integers.

Parameters
aleft operator a + b
bleft operator a + b
Returns
the result of a + b or UINT32_MAX in case of overflow

Definition at line 175 of file util.c.

◆ u32_protected_mult()

uint32_t u32_protected_mult ( uint32_t  a,
uint32_t  b 
)

Avoid overflow when multiplying two u32 integers.

Parameters
aleft operator a * b
bleft operator a * b
Returns
the result of a * b or UINT32_MAX in case of overflow

Definition at line 185 of file util.c.

◆ u32_to_base36()

void u32_to_base36 ( uint32_t  n,
char  b36_str[] 
)

Convert a 32-bit unsigned integer to its base-36 string representation. This will perform 6 divisions, so it will be significantly more expensive than its base36_to_u32 counterpart.

We will iterate over all digits from BASE36_MAX_DIGITS-1 to 0 and determine their values in base-36, to then construct the string representation b36_str in base-36 or the integer n

Initially set to n, the variable acc will contain any given stage i:

b32[i] * 36^i + b32[i-1] * 36^(i-1) + ... + b32[0]

And we can thus extract the two following values:

b32[i] = acc / 36^i
acc = acc mod 36^i = b32[i-1] * 36^(i-1) + ... + b32[0]

So that acc can now be used for the following step, until i hits 0

Parameters
ninteger value to convert to a base-36 representation
b36_stroutput char[], representation of n in base-36
See also
base36_to_u32

Definition at line 272 of file util.c.