Skip to content

StrFromU64

Description

Convert an unsigned 64-bit integer to string

Parameters

Name Direction Description
str out String to store the result in
value in Value to convert
config in Formatting configuration. May be NULL (uses the default: base 10, no prefix).

Success

Returns str

Failure

Returns NULL on allocator OOM while appending to str, or when a non-NULL config has an invalid base. The destination string is untouched.

Usage example (Cross-references)

Usage examples (Cross-references)
                        // (u8) so a high byte (>= 0x80) renders as its two-digit
                        // value, not a sign-extended 16-digit u64 (cf. site below).
                        if (!StrFromU64(&hex, (u8)c, &config)) {
                            return false;
                        }
                    // an 8-byte stack scratch suffices; no allocator needed.
                    StrInitStack(hex, 8) {
                        if (!StrFromU64(&hex, (u8)xs[i], &config)) {
                            return false;
                        }
        // LOG_SYS_* errno scratch), which has no allocator to inherit.
        StrInitStack(temp, 80) {
            if (!StrFromU64(&temp, *v, &config)) {
                return false;
            }
                u64          value  = BitVecToInteger(bv);
                StrIntFormat config = {.base = 16, .uppercase = (fmt_info->flags & FMT_FLAG_CAPS) != 0, .use_prefix = true};
                if (!StrFromU64(o, value, &config)) {
                    return false;
                }
                u64          value  = BitVecToInteger(bv);
                StrIntFormat config = {.base = 8, .uppercase = false, .use_prefix = true};
                if (!StrFromU64(o, value, &config)) {
                    return false;
                }
    }
    
    Str *StrFromU64(Str *str, u64 value, const StrIntFormat *config) {
        ValidateStr(str);
        }
    
        if (!StrFromU64(str, abs_value, config)) {
            return NULL;
        }
    // Test StrFromU64 function
    bool test_str_from_u64(void) {
        WriteFmt("Testing StrFromU64\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
        // Test decimal conversion
        StrIntFormat config = {.base = 10, .uppercase = false};
        StrFromU64(&s, 12345, &config);
        bool result = (ZstrCompare(StrBegin(&s), "12345") == 0);
        if (!result) {
        StrClear(&s);
        config = (StrIntFormat) {.base = 16, .uppercase = false, .use_prefix = true};
        StrFromU64(&s, 0xABCD, &config);
        result = result && (ZstrCompare(StrBegin(&s), "0xabcd") == 0);
        if (!result) {
        StrClear(&s);
        config = (StrIntFormat) {.base = 16, .uppercase = true, .use_prefix = true};
        StrFromU64(&s, 0xABCD, &config);
        result = result && (ZstrCompare(StrBegin(&s), "0xABCD") == 0);
        if (!result) {
        StrClear(&s);
        config = (StrIntFormat) {.base = 2, .uppercase = false, .use_prefix = true};
        StrFromU64(&s, 42, &config);
        result = result && (ZstrCompare(StrBegin(&s), "0b101010") == 0);
        if (!result) {
        StrClear(&s);
        config = (StrIntFormat) {.base = 8, .uppercase = false, .use_prefix = true};
        StrFromU64(&s, 42, &config);
        result = result && (ZstrCompare(StrBegin(&s), "0o52") == 0);
        if (!result) {
        StrClear(&s);
        config = (StrIntFormat) {.base = 10, .uppercase = false};
        StrFromU64(&s, 0, &config);
        result = result && (ZstrCompare(StrBegin(&s), "0") == 0);
        if (!result) {
            // Test decimal round-trip
            StrIntFormat config = {.base = 10, .uppercase = false};
            StrFromU64(&s, u64_values[i], &config);
            u64  recovered_u64 = 0;
            bool success       = StrToU64(&s, &recovered_u64, NULL);
            StrClear(&s);
            config = (StrIntFormat) {.base = 16, .uppercase = false, .use_prefix = true};
            StrFromU64(&s, u64_values[i], &config);
            recovered_u64 = 0;
            success       = StrToU64(&s, &recovered_u64, NULL); // Can now use explicit base 16 with 0x prefix
            // Test with base value itself
            StrIntFormat config = {.base = base, .uppercase = false, .use_prefix = (base == 2 || base == 8 || base == 16)};
            StrFromU64(&s, base, &config);
            u64 recovered = 0;
        // Test maximum u64
        StrIntFormat config = {.base = 10, .uppercase = false};
        StrFromU64(&s, UINT64_MAX, &config);
        u64  recovered_max = 0;
        bool success       = StrToU64(&s, &recovered_max, NULL);
    
            StrIntFormat config = {.base = base, .uppercase = false};
            StrFromU64(&s, large_value, &config);
            u64            recovered = 0;
            StrParseConfig pconfig   = {.base = base};
            // Test StrFromU64
            StrIntFormat config = {.base = base, .uppercase = false, .use_prefix = false};
            StrFromU64(&s, test_value, &config);
    
            // Test StrToU64 round-trip
    
            StrIntFormat config = {.base = base, .uppercase = true, .use_prefix = false};
            StrFromU64(&s, test_value, &config);
    
            u64            recovered    = 0;
    
                StrIntFormat config = {.base = base, .uppercase = false, .use_prefix = false};
                StrFromU64(&s, test_values[i], &config);
    
                u64            recovered    = 0;
            Str          s      = StrInit(&alloc);
            StrIntFormat config = {.base = 10, .uppercase = false};
            StrFromU64(&s, test_value, &config);
    
            u64  recovered = 0;
        // Test NULL string pointer - should abort
        StrIntFormat config = {.base = 10, .uppercase = false};
        StrFromU64(NULL, 42, &config);
    
        return false;
    //   mutant : runs the digit loop (value % 37) and returns &s (non-NULL).
    static bool test_from_u64_rejects_invalid_base(void) {
        WriteFmt("Testing StrFromU64 rejects an invalid base with NULL (564:10)\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str          s      = StrInit(&alloc);
        StrIntFormat config = {.base = 37, .uppercase = false};
        Str         *ret    = StrFromU64(&s, 5, &config);
    
        bool result = (ret == NULL);
    // is what kills the mutant.
    static bool test_from_u64_success_returns_str(void) {
        WriteFmt("Testing StrFromU64 returns the Str pointer on success (595:14)\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str          s      = StrInit(&alloc);
        StrIntFormat config = {.base = 10, .uppercase = false};
        Str         *ret    = StrFromU64(&s, 12345, &config);
    
        bool result = (ret == &s) && (ZstrCompare(StrBegin(&s), "12345") == 0);
    //   mutant : `ok` becomes true -> returns &s (non-NULL).
    static bool test_from_u64_oom_returns_null(void) {
        WriteFmt("Testing StrFromU64 returns NULL when a digit push fails (609:24)\n");
    
        // Buffer large enough for the bitmap word + one 8-byte slot, but the slot
        StrIntFormat config = {.base = 10, .uppercase = false};
        // 10-digit value: any growth request exceeds the 8-byte slot.
        Str *ret = StrFromU64(&s, 9999999999ULL, &config);
    
        bool result = (ret == NULL);
Last updated on