utils.c

Include dependency graph for utils.c:

digraph { graph [bgcolor="#00000000"] node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2] edge [color="#1414CE"] "1" [label="/__w/AtomVM/AtomVM/src/libAtomVM/utils.c" tooltip="/__w/AtomVM/AtomVM/src/libAtomVM/utils.c" fillcolor="#BFBFBF"] "2" [label="utils.h" tooltip="utils.h"] "8" [label="assert.h" tooltip="assert.h"] "3" [label="inttypes.h" tooltip="inttypes.h"] "9" [label="limits.h" tooltip="limits.h"] "4" [label="stdbool.h" tooltip="stdbool.h"] "5" [label="stddef.h" tooltip="stddef.h"] "10" [label="stdint.h" tooltip="stdint.h"] "6" [label="stdio.h" tooltip="stdio.h"] "7" [label="stdlib.h" tooltip="stdlib.h"] "11" [label="string.h" tooltip="string.h"] "1" -> "2" [dir=forward tooltip="include"] "1" -> "8" [dir=forward tooltip="include"] "1" -> "3" [dir=forward tooltip="include"] "1" -> "9" [dir=forward tooltip="include"] "1" -> "4" [dir=forward tooltip="include"] "1" -> "10" [dir=forward tooltip="include"] "1" -> "11" [dir=forward tooltip="include"] "2" -> "3" [dir=forward tooltip="include"] "2" -> "4" [dir=forward tooltip="include"] "2" -> "5" [dir=forward tooltip="include"] "2" -> "6" [dir=forward tooltip="include"] "2" -> "7" [dir=forward tooltip="include"] }

Defines

MIN(a, b) (((a) < (b)) ? (a) : (b))
INT64_MAX_BASE_10_DIGITS 19
INT64_MAX_BASE_16_DIGITS 16

Functions

static char *uintptr_to_a_n(uintptr_t n, unsigned int base, char *out_end)
static char *uintptr_to_a_10(uintptr_t n, char *out_end)
static char *uintptr_to_a_16(uintptr_t n, char *out_end)
size_t intptr_write_to_ascii_buf(intptr_t n, unsigned int base, char *out_end)

Convert intptr_t to ASCII representation in specified base.

Writes the ASCII representation of a signed integer to a buffer, starting from the end and working backwards. The function returns the number of characters written. This design allows efficient conversion without requiring string reversal.

char buffer[INTPTR_WRITE_TO_ASCII_BUF_LEN];
size_t len = intptr_write_to_ascii_buf(-42, 10, buffer + INTPTR_WRITE_TO_ASCII_BUF_LEN);
// Characters written at: buffer + INTPTR_WRITE_TO_ASCII_BUF_LEN - len
// Result: "-42" (3 characters)

Note

Optimized implementations for base 10 and base 16

Note

Negative numbers include leading ‘-’ character

Note

Digits > 9 represented as uppercase letters (A-Z)

Warning

Buffer must be at least INTPTR_WRITE_TO_ASCII_BUF_LEN bytes

Warning

Insufficient buffer size causes undefined behavior (buffer overflow)

Warning

Caller must add null terminator if using result as C string

Parameters:
  • n – Integer value (intptr_t) to convert

  • base – Number base for conversion (2-36)

  • out_end – Pointer to one-past-last position of output buffer

Returns:

Number of characters written to buffer

Pre:

base >= 2 && base <= 36

Pre:

out_end points to valid buffer with at least INTPTR_WRITE_TO_ASCII_BUF_LEN bytes before it

Post:

Characters written to [(out_end - return_value), out_end)

Post:

No null terminator is added

static inline bool is_base_10_digit(char c)
static int buf10_to_smallu64(const char buf[], size_t buf_len, size_t first_digit_index, uint64_t *out)
static int buf10_to_int64(const char buf[], size_t buf_len, size_t first_digit_index, bool is_negative, int64_t *out)
static inline intptr_t char_to_base_n_digit(char c)
static int buf16_to_uintptr(const char buf[], size_t buf_len, size_t pos, uintptr_t *out)
static int buf16_to_int64(const char buf[], size_t buf_len, size_t first_digit_index, bool is_negative, int64_t *out)
static int bufn_to_int64(const char buf[], size_t buf_len, size_t first_digit_index, bool negative, unsigned int base, int64_t *out)
int int64_parse_ascii_buf(const char buf[], size_t buf_len, unsigned int base, buf_to_int64_options_t options, int64_t *out)

Parse ASCII buffer to int64_t in specified base.

Parses an ASCII representation of an integer from a buffer (not necessarily null-terminated) into a 64-bit signed integer. Supports bases 2-36 with optimized paths for base 10 and 16. The function is designed to support parsing arbitrarily large integers by processing them in chunks - it returns the position where parsing stopped, allowing callers to continue parsing from that point.

// Simple parsing
int64_t value;
const char *number = "12345";
int pos = int64_parse_ascii_buf(number, strlen(number), 10, BufToInt64NoOptions, &value);
if (pos == strlen(number)) {
    // Successfully parsed entire buffer: value = 12345
}

// Parsing with overflow detection
const char *big_num = "99999999999999999999999";
int pos = int64_parse_ascii_buf(big_num, strlen(big_num), 10, BufToInt64NoOptions, &value);
if (pos < strlen(big_num)) {
    // Overflow occurred at position pos
    // value contains the maximum representable value before overflow
}

// Chunk parsing for arbitrarily large integers
const char *chunks[] = {"12345", "67890", "12345"};
int64_t accumulated = 0;
for (int i = 0; i < 3; i++) {
    int64_t chunk;
    int pos = int64_parse_ascii_buf(chunks[i], 5, 10, BufToInt64RejectSign, &chunk);
    // Process chunk value...
}

See also

int64_write_to_ascii_buf() for the inverse operation

Note

Leading zeros are skipped automatically

Note

Signs (+/-) accepted unless BufToInt64RejectSign is set

Note

Case-insensitive for letter digits (a-z, A-Z)

Note

Optimized implementations for base 10 and base 16

Note

Stops parsing at first invalid character or overflow

Warning

Return value -1 indicates format error (invalid digit for base)

Warning

Return value < buf_len may indicate overflow or invalid character

Parameters:
  • buf – Buffer containing ASCII digits to parse

  • buf_len – Length of buffer in bytes

  • base – Number base for parsing (2-36)

  • options – Parsing options (e.g., reject sign characters)

  • out[out] Parsed integer value (valid even on overflow)

Returns:

Position after last successfully parsed character, or -1 on format error

Pre:

base >= 2 && base <= 36

Pre:

buf != NULL when buf_len > 0 (NULL allowed only for zero-length buffer)

Pre:

out != NULL

Post:

On success: *out contains parsed value up to position returned

Post:

On overflow: *out contains value parsed before overflow, returns position where overflow occurred

Post:

On format error: returns -1, *out is undefined