Skip to content

StrAppendFmt

Description

Append a formatted string to out. Existing contents are preserved; new content lands at the end of the buffer.

Parameters

Name Direction Description
out out Destination Str. Existing bytes are kept.
fmtstr in Format string with {} placeholders.

Success

out extended with the formatted content; returns true.

Failure

Returns false. May log diagnostics; out may be left partially extended on allocation failure mid-write.

Usage example (Cross-references)

Usage examples (Cross-references)
                Str source_key = StrInit(&alloc);
                u64 source_id  = response.data.length > 0 ? VecAt(&response.data, 0).source_function_id : 0;
                StrAppendFmt(&source_key, "{}", source_id);
    
                JW_OBJ_KV(json, source_key.data, {
                        AnnSymbol *s          = &VecAt(&response.data, 0);
                        Str        target_key = StrInit(&alloc);
                        StrAppendFmt(&target_key, "{}", s->target_function_id);
    
                        JW_OBJ_KV(json, target_key.data, {
                VecForeach(&symbols, symbol) {
                    Str source_key = StrInit(&alloc);
                    StrAppendFmt(&source_key, "{}", symbol.source_function_id);
    
                    JW_OBJ_KV(json, source_key.data, {
                    JW_OBJ_KV(json, source_key.data, {
                Str target_key = StrInit(&alloc);
                StrAppendFmt(&target_key, "{}", symbol.target_function_id);
    
                JW_OBJ_KV(json, target_key.data, {
    // Test StrAppendFmt function
    bool test_str_WriteFmt(void) {
        WriteFmt("Testing StrAppendFmt\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        Str s = StrInit(&alloc);
        StrAppendFmt(&s, "Hello, {}!", &"World"[0]);
    
        // Validate the string
        HttpResponse response = HttpResponseInit(alloc_base);
        Str          body     = StrInit(alloc_base);
        StrAppendFmt(&body, "<h1>hi</h1>");
        HttpRespondWithHtml(&response, HTTP_RESPONSE_CODE_OK, &body);
        StrDeinit(&body);
        Str result = StrInit(&alloc);
        StrForeachIdx(&s, chr, idx) {
            StrAppendFmt(&result, "{c}{}", chr, idx);
        }
        StrForeachReverseIdx(&s, chr, idx) {
            // Append the character and its index to the result string
            StrAppendFmt(&result, "{c}{}", chr, idx);
        }
        StrForeachPtrIdx(&s, chrptr, idx) {
            // Append the character (via pointer) and its index to the result string
            StrAppendFmt(&result, "{c}{}", *chrptr, idx);
    
            // Modify the original string by converting to uppercase
        StrForeachReversePtrIdx(&s, chrptr, idx) {
            // Append the character (via pointer) and its index to the result string
            StrAppendFmt(&result, "{c}{}", *chrptr, idx);
    
            // Modify the original string by converting to uppercase
        StrForeachInRangeIdx(&s, chr, idx, 6, 11) {
            // Append the character and its index to the result string
            StrAppendFmt(&result, "{c}{}", chr, idx);
        }
        StrForeachPtrInRangeIdx(&s, chrptr, idx, 6, 11) {
            // Append the character and its index to the result string
            StrAppendFmt(&result, "{c}{}", *chrptr, idx);
    
            // Modify the original string by converting to uppercase
    
        // Test empty format string
        StrAppendFmt(&output, "");
        success = success && (output.length == 0);
        StrClear(&output);
    
        // Test literal text
        StrAppendFmt(&output, "Hello, world!");
        success = success && (ZstrCompare(output.data, "Hello, world!") == 0);
        StrClear(&output);
    
        // Test escaped braces
        StrAppendFmt(&output, "{{Hello}}");
        success = success && (ZstrCompare(output.data, "{Hello}") == 0);
        StrClear(&output);
    
        // Test double escaped braces
        StrAppendFmt(&output, "{{{{");
        success = success && (ZstrCompare(output.data, "{{") == 0);
        // Test basic string
        const char *str = "Hello";
        StrAppendFmt(&output, "{}", str);
        success = success && (ZstrCompare(output.data, "Hello") == 0);
        StrClear(&output);
        // Test empty string
        const char *empty = "";
        StrAppendFmt(&output, "{}", empty);
        success = success && (output.length == 0);
        StrClear(&output);
    
        // Test string with width and alignment
        StrAppendFmt(&output, "{>10}", str);
        success = success && (ZstrCompare(output.data, "     Hello") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{<10}", str);
        success = success && (ZstrCompare(output.data, "Hello     ") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{^10}", str);
        success = success && (ZstrCompare(output.data, "  Hello   ") == 0);
        StrClear(&output);
        // Test Str object
        Str s = StrInitFromZstr("World", &alloc);
        StrAppendFmt(&output, "{}", s);
        success = success && (ZstrCompare(output.data, "World") == 0);
        StrDeinit(&s);
        // Test signed integers
        i8 i8_val = -42;
        StrAppendFmt(&output, "{}", i8_val);
        success = success && (ZstrCompare(output.data, "-42") == 0);
        StrClear(&output);
    
        i16 i16_val = -1234;
        StrAppendFmt(&output, "{}", i16_val);
        success = success && (ZstrCompare(output.data, "-1234") == 0);
        StrClear(&output);
    
        i32 i32_val = -123456;
        StrAppendFmt(&output, "{}", i32_val);
        success = success && (ZstrCompare(output.data, "-123456") == 0);
        StrClear(&output);
    
        i64 i64_val = -1234567890LL;
        StrAppendFmt(&output, "{}", i64_val);
        success = success && (ZstrCompare(output.data, "-1234567890") == 0);
        StrClear(&output);
        // Test unsigned integers
        u8 u8_val = 42;
        StrAppendFmt(&output, "{}", u8_val);
        success = success && (ZstrCompare(output.data, "42") == 0);
        StrClear(&output);
    
        u16 u16_val = 1234;
        StrAppendFmt(&output, "{}", u16_val);
        success = success && (ZstrCompare(output.data, "1234") == 0);
        StrClear(&output);
    
        u32 u32_val = 123456;
        StrAppendFmt(&output, "{}", u32_val);
        success = success && (ZstrCompare(output.data, "123456") == 0);
        StrClear(&output);
    
        u64 u64_val = 1234567890ULL;
        StrAppendFmt(&output, "{}", u64_val);
        success = success && (ZstrCompare(output.data, "1234567890") == 0);
        StrClear(&output);
        // Test edge cases
        i8 i8_max = 127;
        StrAppendFmt(&output, "{}", i8_max);
        success = success && (ZstrCompare(output.data, "127") == 0);
        StrClear(&output);
    
        i8 i8_min = -128;
        StrAppendFmt(&output, "{}", i8_min);
        success = success && (ZstrCompare(output.data, "-128") == 0);
        StrClear(&output);
    
        u8 u8_max = 255;
        StrAppendFmt(&output, "{}", u8_max);
        success = success && (ZstrCompare(output.data, "255") == 0);
        StrClear(&output);
    
        u8 u8_min = 0;
        StrAppendFmt(&output, "{}", u8_min);
        success = success && (ZstrCompare(output.data, "0") == 0);
    
        u32 val = 0xDEADBEEF;
        StrAppendFmt(&output, "{x}", val);
        success = success && (ZstrCompare(output.data, "0xdeadbeef") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{X}", val);
        success = success && (ZstrCompare(output.data, "0xDEADBEEF") == 0);
    
        u8 val = 0xA5; // 10100101 in binary
        StrAppendFmt(&output, "{b}", val);
        success = success && (ZstrCompare(output.data, "0b10100101") == 0);
    
        u16 val = 0777;
        StrAppendFmt(&output, "{o}", val);
        success = success && (ZstrCompare(output.data, "0o777") == 0);
    
        f32 f32_val = 3.14159f;
        StrAppendFmt(&output, "{}", f32_val);
        success = success && (ZstrCompare(output.data, "3.141590") == 0);
        StrClear(&output);
    
        f64 f64_val = 2.71828;
        StrAppendFmt(&output, "{}", f64_val);
        success = success && (ZstrCompare(output.data, "2.718280") == 0);
    
        // Test different precisions
        StrAppendFmt(&output, "{.2}", val);
        success = success && (ZstrCompare(output.data, "3.14") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{.0}", val);
        success = success && (ZstrCompare(output.data, "3") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{.10}", val);
        success = success && (ZstrCompare(output.data, "3.1415926536") == 0);
        // Test infinity
        f64 pos_inf = INFINITY;
        StrAppendFmt(&output, "{}", pos_inf);
        success = success && (ZstrCompare(output.data, "inf") == 0);
        StrClear(&output);
    
        f64 neg_inf = -INFINITY;
        StrAppendFmt(&output, "{}", neg_inf);
        success = success && (ZstrCompare(output.data, "-inf") == 0);
        StrClear(&output);
        // Test NaN
        f64 nan_val = NAN;
        StrAppendFmt(&output, "{}", nan_val);
        success = success && (ZstrCompare(output.data, "nan") == 0);
        // Test with integers
        i32 val = 42;
        StrAppendFmt(&output, "{5}", val);
        success = success && (ZstrCompare(output.data, "   42") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{<5}", val);
        success = success && (ZstrCompare(output.data, "42   ") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{^5}", val);
        success = success && (ZstrCompare(output.data, " 42  ") == 0);
        StrClear(&output);
        // Test with strings
        const char *str = "abc";
        StrAppendFmt(&output, "{5}", str);
        success = success && (ZstrCompare(output.data, "  abc") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{<5}", str);
        success = success && (ZstrCompare(output.data, "abc  ") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{^5}", str);
        success = success && (ZstrCompare(output.data, " abc ") == 0);
        f64         pi    = 3.14;
    
        StrAppendFmt(&output, "{} {} {}", hello, num, pi);
        success = success && (ZstrCompare(output.data, "Hello 42 3.140000") == 0);
        StrClear(&output);
    
        // Instead of using positional arguments, we'll just reorder the arguments themselves
        StrAppendFmt(&output, "{} {} {}", pi, hello, num);
        success = success && (ZstrCompare(output.data, "3.140000 Hello 42") == 0);
        // Test mixed case string with :c (preserve case)
        const char *mixed_case = "MiXeD CaSe";
        StrAppendFmt(&output, "{c}", mixed_case);
        success = success && (ZstrCompare(output.data, "MiXeD CaSe") == 0);
        StrClear(&output);
    
        // Test mixed case string with :a (lowercase)
        StrAppendFmt(&output, "{a}", mixed_case);
        success = success && (ZstrCompare(output.data, "mixed case") == 0);
        StrClear(&output);
    
        // Test mixed case string with :A (uppercase)
        StrAppendFmt(&output, "{A}", mixed_case);
        success = success && (ZstrCompare(output.data, "MIXED CASE") == 0);
        StrClear(&output);
    
        // Test with :c (preserve case)
        StrAppendFmt(&output, "{c}", s);
        success = success && (ZstrCompare(output.data, "MiXeD CaSe") == 0);
        StrClear(&output);
    
        // Test with :a (lowercase)
        StrAppendFmt(&output, "{a}", s);
        success = success && (ZstrCompare(output.data, "mixed case") == 0);
        StrClear(&output);
    
        // Test with :A (uppercase)
        StrAppendFmt(&output, "{A}", s);
        success = success && (ZstrCompare(output.data, "MIXED CASE") == 0);
        StrClear(&output);
    
        // Test uppercase char with :c (preserve case)
        StrAppendFmt(&output, "{c}", upper_char);
        success = success && (ZstrCompare(output.data, "M") == 0);
        StrClear(&output);
    
        // Test uppercase char with :a (lowercase)
        StrAppendFmt(&output, "{a}", upper_char);
        success = success && (ZstrCompare(output.data, "m") == 0);
        StrClear(&output);
    
        // Test lowercase char with :A (uppercase)
        StrAppendFmt(&output, "{A}", lower_char);
        success = success && (ZstrCompare(output.data, "M") == 0);
        StrClear(&output);
    
        // Test u16 with :c (preserve case)
        StrAppendFmt(&output, "{c}", u16_value);
        success = success && (output.length == 2 && output.data[0] == 'A' && output.data[1] == 'B');
        StrClear(&output);
    
        // Test u16 with :a (lowercase)
        StrAppendFmt(&output, "{a}", u16_value);
        success = success && (output.length == 2 && output.data[0] == 'a' && output.data[1] == 'b');
        StrClear(&output);
    
        // Test u16 with :A (uppercase)
        StrAppendFmt(&output, "{A}", u16_value);
        success = success && (output.length == 2 && output.data[0] == 'A' && output.data[1] == 'B');
        StrClear(&output);
    
        // Test i16 with :c (preserve case)
        StrAppendFmt(&output, "{c}", i16_value);
        success = success && (output.length == 2 && output.data[0] == 'C' && output.data[1] == 'd');
        StrClear(&output);
    
        // Test i16 with :a (lowercase)
        StrAppendFmt(&output, "{a}", i16_value);
        success = success && (output.length == 2 && output.data[0] == 'c' && output.data[1] == 'd');
        StrClear(&output);
    
        // Test i16 with :A (uppercase)
        StrAppendFmt(&output, "{A}", i16_value);
        success = success && (output.length == 2 && output.data[0] == 'C' && output.data[1] == 'D');
        StrClear(&output);
    
        // Test u32 with :c (preserve case)
        StrAppendFmt(&output, "{c}", u32_value);
        success = success && (output.length == 4 && output.data[0] == 'E' && output.data[1] == 'f' &&
                              output.data[2] == 'G' && output.data[3] == 'h');
    
        // Test u32 with :a (lowercase)
        StrAppendFmt(&output, "{a}", u32_value);
        success = success && (output.length == 4 && output.data[0] == 'e' && output.data[1] == 'f' &&
                              output.data[2] == 'g' && output.data[3] == 'h');
    
        // Test u32 with :A (uppercase)
        StrAppendFmt(&output, "{A}", u32_value);
        success = success && (output.length == 4 && output.data[0] == 'E' && output.data[1] == 'F' &&
                              output.data[2] == 'G' && output.data[3] == 'H');
    
        // Test i32 with :c (preserve case)
        StrAppendFmt(&output, "{c}", i32_value);
        success = success && (output.length == 4 && output.data[0] == 'I' && output.data[1] == 'j' &&
                              output.data[2] == 'K' && output.data[3] == 'l');
    
        // Test i32 with :a (lowercase)
        StrAppendFmt(&output, "{a}", i32_value);
        success = success && (output.length == 4 && output.data[0] == 'i' && output.data[1] == 'j' &&
                              output.data[2] == 'k' && output.data[3] == 'l');
    
        // Test i32 with :A (uppercase)
        StrAppendFmt(&output, "{A}", i32_value);
        success = success && (output.length == 4 && output.data[0] == 'I' && output.data[1] == 'J' &&
                              output.data[2] == 'K' && output.data[3] == 'L');
    
        // Test u64 with :c (preserve case)
        StrAppendFmt(&output, "{c}", u64_value);
        success = success && (output.length == 8 && output.data[0] == 'M' && output.data[1] == 'n' &&
                              output.data[2] == 'O' && output.data[3] == 'p' && output.data[4] == 'Q' &&
    
        // Test u64 with :a (lowercase)
        StrAppendFmt(&output, "{a}", u64_value);
        success = success && (output.length == 8 && output.data[0] == 'm' && output.data[1] == 'n' &&
                              output.data[2] == 'o' && output.data[3] == 'p' && output.data[4] == 'q' &&
    
        // Test u64 with :A (uppercase)
        StrAppendFmt(&output, "{A}", u64_value);
        success = success && (output.length == 8 && output.data[0] == 'M' && output.data[1] == 'N' &&
                              output.data[2] == 'O' && output.data[3] == 'P' && output.data[4] == 'Q' &&
    
        // Test i64 with :c (preserve case)
        StrAppendFmt(&output, "{c}", i64_value);
        success = success && (output.length == 8 && output.data[0] == 'U' && output.data[1] == 'v' &&
                              output.data[2] == 'W' && output.data[3] == 'x' && output.data[4] == 'Y' &&
    
        // Test i64 with :a (lowercase)
        StrAppendFmt(&output, "{a}", i64_value);
        success = success && (output.length == 8 && output.data[0] == 'u' && output.data[1] == 'v' &&
                              output.data[2] == 'w' && output.data[3] == 'x' && output.data[4] == 'y' &&
    
        // Test i64 with :A (uppercase)
        StrAppendFmt(&output, "{A}", i64_value);
        success = success && (output.length == 8 && output.data[0] == 'U' && output.data[1] == 'V' &&
                              output.data[2] == 'W' && output.data[3] == 'X' && output.data[4] == 'Y' &&
        // Test 1: Basic binary formatting
        BitVec bv1 = BitVecFromStr("10110", alloc_base);
        StrAppendFmt(&output, "{}", bv1);
        success = success && (ZstrCompare(output.data, "10110") == 0);
        StrClear(&output);
        // Test 2: Empty BitVec
        BitVec bv_empty = BitVecInit(alloc_base);
        StrAppendFmt(&output, "{}", bv_empty);
        success = success && (output.length == 0);
        StrClear(&output);
        // Test 3: Hex formatting
        BitVec bv2 = BitVecFromInteger(0xABCD, 16, alloc_base);
        StrAppendFmt(&output, "{x}", bv2);
        success = success && (ZstrCompare(output.data, "0xabcd") == 0);
        StrClear(&output);
    
        // Test 4: Uppercase hex formatting
        StrAppendFmt(&output, "{X}", bv2);
        success = success && (ZstrCompare(output.data, "0xABCD") == 0);
        StrClear(&output);
        // Test 5: Octal formatting
        BitVec bv3 = BitVecFromInteger(0755, 10, alloc_base);
        StrAppendFmt(&output, "{o}", bv3);
        success = success && (ZstrCompare(output.data, "0o755") == 0);
        StrClear(&output);
    
        // Test 6: Width and alignment
        StrAppendFmt(&output, "{>10}", bv1);
        success = success && (ZstrCompare(output.data, "     10110") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{<10}", bv1);
        success = success && (ZstrCompare(output.data, "10110     ") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{^10}", bv1);
        success = success && (ZstrCompare(output.data, "  10110   ") == 0);
        StrClear(&output);
        // Test 7: Zero value
        BitVec bv_zero = BitVecFromInteger(0, 1, alloc_base);
        StrAppendFmt(&output, "{x}", bv_zero);
        success = success && (ZstrCompare(output.data, "0x0") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{o}", bv_zero);
        success = success && (ZstrCompare(output.data, "0o0") == 0);
        StrClear(&output);
        Int oct_val = IntFrom(493, alloc_base);
    
        StrAppendFmt(&output, "{}", big_dec);
        success = success && (ZstrCompare(output.data, "123456789012345678901234567890") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{x}", hex_val);
        success = success && (ZstrCompare(output.data, "deadbeefcafebabe1234") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{X}", hex_val);
        success = success && (ZstrCompare(output.data, "DEADBEEFCAFEBABE1234") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{b}", bin_val);
        success = success && (ZstrCompare(output.data, "10100011") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{o}", oct_val);
        success = success && (ZstrCompare(output.data, "755") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{>34}", big_dec);
        success = success && (ZstrCompare(output.data, "    123456789012345678901234567890") == 0);
        Float short_v = FloatFromStr("1.2", alloc_base);
    
        StrAppendFmt(&output, "{}", exact);
        success = success && (ZstrCompare(output.data, "1234567890.012345") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{e}", sci);
        success = success && (ZstrCompare(output.data, "1.234567e+04") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{E}", sci);
        success = success && (ZstrCompare(output.data, "1.234567E+04") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{.3}", short_v);
        success = success && (ZstrCompare(output.data, "1.200") == 0);
        StrClear(&output);
        StrClear(&output);
    
        StrAppendFmt(&output, "{>18}", sci);
        success = success && (ZstrCompare(output.data, "          12345.67") == 0);
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str              s     = StrInit(&alloc);
        StrAppendFmt(&s, "old prefix ");
        StrWriteFmt(&s, "fresh {}", LVAL(42));
        bool ok = (s.length == 8) && (s.data[0] == 'f') && (s.data[s.length - 1] == '2');
        DefaultAllocator alloc = DefaultAllocatorInit();
        Str              s     = StrInit(&alloc);
        StrAppendFmt(&s, "AAAAAAAA");
        size before_length = s.length;
        bool ok            = StrPatchFmt(&s, 2, "{}", LVAL(1234));
    // StrAppendf printf-style formatter.
    bool test_str_write_fmt_append(void) {
        WriteFmt("Testing StrAppendFmt append\n");
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // Append formatted suffix.
        StrAppendFmt(&s, " {} {}", (const char *)"World", (u32)2023);
    
        // Check that the string was appended correctly
        Allocator *alloc = err_str->allocator;
        Str        out   = StrInit(alloc);
        StrAppendFmt(&out, "{} (errno {})", errno_description(eno), eno);
        StrDeinit(err_str);
        *err_str = out;
    
            if (named) {
                StrAppendFmt(out, "  #{} {}+{x} [{x}]", (u32)i, sym_name, (u64)sym_off, (u64)ip);
            } else {
                StrAppendFmt(out, "  #{} {x}", (u32)i, (u64)ip);
                StrAppendFmt(out, "  #{} {}+{x} [{x}]", (u32)i, sym_name, (u64)sym_off, (u64)ip);
            } else {
                StrAppendFmt(out, "  #{} {x}", (u32)i, (u64)ip);
            }
            if (g_dbghelp_initialized && SymGetLineFromAddr64(proc, ip, &line_disp, &line) && line.FileName) {
                const char *fname = basename_of(line.FileName);
                StrAppendFmt(out, " ({}:{})", fname, (u32)line.LineNumber);
            }
            StrPushBack(out, '\n');
            if (named) {
                const char *mod = basename_of(mod_path);
                StrAppendFmt(out, "  #{} {}!{}+{x} [{x}]\n", (u32)i, mod, sym_name, (u64)sym_off, ip);
            } else if (mod_path) {
                const char *mod = basename_of(mod_path);
            } else if (mod_path) {
                const char *mod = basename_of(mod_path);
                StrAppendFmt(out, "  #{} {}+? [{x}]\n", (u32)i, mod, ip);
            } else {
                StrAppendFmt(out, "  #{} {x}\n", (u32)i, ip);
                StrAppendFmt(out, "  #{} {}+? [{x}]\n", (u32)i, mod, ip);
            } else {
                StrAppendFmt(out, "  #{} {x}\n", (u32)i, ip);
            }
        }
        if (r->symbol_name) {
            const char *mod = basename_of(r->module_path);
            StrAppendFmt(out, "  #{} {}!{}+{x} [{x}]", idx, mod, r->symbol_name, r->offset, (u64)(uintptr_t)ip);
        } else if (r->module_path) {
            const char *mod = basename_of(r->module_path);
        } else if (r->module_path) {
            const char *mod = basename_of(r->module_path);
            StrAppendFmt(out, "  #{} {}+{x} [{x}]", idx, mod, r->offset, (u64)(uintptr_t)ip);
        } else {
            StrAppendFmt(out, "  #{} {x}", idx, (u64)(uintptr_t)ip);
            StrAppendFmt(out, "  #{} {}+{x} [{x}]", idx, mod, r->offset, (u64)(uintptr_t)ip);
        } else {
            StrAppendFmt(out, "  #{} {x}", idx, (u64)(uintptr_t)ip);
        }
        if (r->source_file) {
            const char *file = basename_of(r->source_file);
            if (r->source_line > 0) {
                StrAppendFmt(out, " ({}:{})", file, r->source_line);
            } else {
                StrAppendFmt(out, " ({})", file);
                StrAppendFmt(out, " ({}:{})", file, r->source_line);
            } else {
                StrAppendFmt(out, " ({})", file);
            }
        }
                emit_resolved_line(out, (u32)i, &r, frames[i].ip);
            } else {
                StrAppendFmt(out, "  #{} {x}\n", (u32)i, (u64)(uintptr_t)frames[i].ip);
            }
        }
        if (!SymbolResolverInit(&res, alloc)) {
            for (size i = 0; i < count; ++i) {
                StrAppendFmt(out, "  #{} {x}\n", (u32)i, (u64)(uintptr_t)frames[i].ip);
            }
            return;
            }
            port = FROM_BIG_ENDIAN2(sa->sin_port);
            StrAppendFmt(&out, "{}:{}", host_p, (u32)port);
        } else if (addr->family == SOCKET_FAMILY_INET6) {
            const struct sockaddr_in6 *sa = (const struct sockaddr_in6 *)addr->raw;
            }
            port = FROM_BIG_ENDIAN2(sa->sin6_port);
            StrAppendFmt(&out, "[{}]:{}", host_p, (u32)port);
        } else {
            LOG_ERROR("SocketAddrFormat: unknown family {}", (u32)addr->family);
                Str         entry_path = StrInit(alloc);
                const char *dir_name   = &entry->d_name[0];
                StrAppendFmt(&entry_path, "{}/{}", path, dir_name);
    
                struct stat path_stat;
        }
    
        StrAppendFmt(
            &out,
            "HTTP/1.1 {}\r\n"
    
        VecForeachPtr(&response->headers, header) {
            StrAppendFmt(&out, "{}: {}\r\n", header->key, header->value);
        }
        }
    
        StrAppendFmt(&out, "\r\n");
    
        if (response->body.length) {
        Allocator    *a    = ALLOCATOR_OF(&h);
        Str           full = StrInit(a);
        StrAppendFmt(&full, "[{}] [{}:{}] {}\n", (const char *)NAMES[type], (const char *)tag, line, (const char *)msg);
    
        File out = (type == LOG_MESSAGE_TYPE_INFO) ? FileFromFd(1) : FileFromFd(2);
            return;
    
        StrAppendFmt(out, "DebugAllocator: {} live allocation(s):\n", (u64)self->live.length);
        MapForeachPairPtr(&self->live, key_ptr, val_ptr) {
            StrAppendFmt(out, "  leak: {x} ({} bytes)\n", (u64)(uintptr_t)*key_ptr, (u64)val_ptr->requested_size);
        StrAppendFmt(out, "DebugAllocator: {} live allocation(s):\n", (u64)self->live.length);
        MapForeachPairPtr(&self->live, key_ptr, val_ptr) {
            StrAppendFmt(out, "  leak: {x} ({} bytes)\n", (u64)(uintptr_t)*key_ptr, (u64)val_ptr->requested_size);
            if (val_ptr->alloc_trace_n > 0) {
                FormatStackTrace(out, val_ptr->alloc_trace, val_ptr->alloc_trace_n, ALLOCATOR_OF(&self->meta));
        do {                                                                                                               \
            Str b_ = StrInit();                                                                                            \
            StrAppendFmt(&b_, __VA_ARGS__);                                                                                 \
            ProcWriteToStdin((p), &b_);                                                                                    \
            StrDeinit(&b_);                                                                                                \
        do {                                                                                                               \
            Str b_ = StrInit();                                                                                            \
            StrAppendFmt(&b_, __VA_ARGS__);                                                                                 \
            StrPushBack(&b_, '\n');                                                                                        \
            ProcWriteToStdin((p), &b_);                                                                                    \
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_OBJ(j, writer);                                                                                             \
        } while (0)
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_ARR(j, arr, item, writer);                                                                                  \
        } while (0)
        do {                                                                                                               \
            i64 my_int = (i);                                                                                              \
            StrAppendFmt(&(j), "{}", my_int);                                                                               \
        } while (0)
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_INT(j, i);                                                                                                  \
        } while (0)
        do {                                                                                                               \
            f64 my_flt = (f);                                                                                              \
            StrAppendFmt(&(j), "{}", my_flt);                                                                               \
        } while (0)
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_FLT(j, f);                                                                                                  \
        } while (0)
    #define JW_STR(j, s)                                                                                                   \
        do {                                                                                                               \
            StrAppendFmt(&(j), "\"{}\"", (const char *)((s).length ? (s).data : ""));                                       \
        } while (0)
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_STR(j, s);                                                                                                  \
        } while (0)
    #define JW_BOOL(j, b)                                                                                                  \
        do {                                                                                                               \
            StrAppendFmt(&(j), "{}", (const char *)((b) ? "true" : "false"));                                               \
        } while (0)
                StrPushBack(&(j), ',');                                                                                    \
            }                                                                                                              \
            StrAppendFmt(&(j), "\"{}\":", (const char *)(k));                                                               \
            JW_BOOL(j, b);                                                                                                 \
        } while (0)
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            LogWrite(LOG_MESSAGE_TYPE_FATAL, __func__, __LINE__, m_.data);                                                 \
            StrDeinit(&m_);                                                                                                \
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            LogWrite(LOG_MESSAGE_TYPE_ERROR, __func__, __LINE__, m_.data);                                                 \
            StrDeinit(&m_);                                                                                                \
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            LogWrite(LOG_MESSAGE_TYPE_INFO, __func__, __LINE__, m_.data);                                                  \
            StrDeinit(&m_);                                                                                                \
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            Str syserr_;                                                                                                   \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
                StrError(sys_eno_, &syserr_);                                                                              \
                StrAppendFmt(&m_, " : {}", syserr_);                                                                        \
            });                                                                                                            \
            LogWrite(LOG_MESSAGE_TYPE_FATAL, __func__, __LINE__, m_.data);                                                 \
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            Str syserr_;                                                                                                   \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
                StrError(sys_eno_, &syserr_);                                                                              \
                StrAppendFmt(&m_, " : {}", syserr_);                                                                        \
            });                                                                                                            \
            LogWrite(LOG_MESSAGE_TYPE_ERROR, __func__, __LINE__, m_.data);                                                 \
            HeapAllocator log_alloc_ = HeapAllocatorInit();                                                                \
            Str           m_         = StrInit(&log_alloc_);                                                               \
            StrAppendFmt(&m_, __VA_ARGS__);                                                                                 \
            Str syserr_;                                                                                                   \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
            StrInitStack(syserr_, &log_alloc_, 256, {                                                                      \
                StrError(sys_eno_, &syserr_);                                                                              \
                StrAppendFmt(&m_, " : {}", syserr_);                                                                        \
            });                                                                                                            \
            LogWrite(LOG_MESSAGE_TYPE_INFO, __func__, __LINE__, m_.data);                                                  \
Last updated on