Skip to content
StrInitFromZstr

StrInitFromZstr

StrInitFromZstr

Description

Initializes a Str object from a null-terminated C-style string (zstr). This macro calculates the length of zstr using strlen and then calls StrInitFromCstr to create the Str object.

Parameters

Name Direction Description
zstr in Pointer to the null-terminated C-style string to initialize from.

Success

Returns a newly created Str object with its data field pointing to a newly allocated memory containing a copy of zstr. The length and capacity fields are set to the length of zstr. copy_init and copy_deinit are set to NULL, and alignment is set to 1.

Failure

Returns a Str object with data set to NULL if memory allocation using strndup (called internally by StrInitFromCstr) fails. In such a case, length and capacity will likely be uninitialized or zero. It’s crucial to check the data field for NULL after using this macro to handle potential memory allocation errors.

Usage example (Cross-references)

Usage examples (Cross-references)
                    if (zstr) {
                        StrDeinit(str);
                        *str = StrInitFromZstr(zstr);
                        free(zstr);
                    }
        char *env_var = getenv(name);
        if (env_var) {
            *value = StrInitFromZstr(env_var);
            return value;
        }
        strerror_r(eno, buf, 1023);
    #endif
        *err_str = StrInitFromZstr(buf);
        return err_str;
    }
    
        if (FloatIsZero(value)) {
            return StrInitFromZstr("0");
        }
    
        if (IntIsZero(value)) {
            return StrInitFromZstr("0");
        }
        }
    
        lookup = StrInitFromZstr(key);
        value  = map_get_value_ptr(
            GENERIC_MAP(cfg),
            return NULL;
        }
        *exe_path = StrInitFromZstr(buffer);
        return exe_path;
    #else
        if (len != -1) {
            buffer[len] = '\0';
            *exe_path   = StrInitFromZstr(buffer);
            return exe_path;
        }
        u32 bsize = sizeof(buffer);
        if (_NSGetExecutablePath(buffer, &bsize) == 0) {
            *exe_path = StrInitFromZstr(buffer);
            return exe_path;
        }
            }
    
            direntry.name = StrInitFromZstr(findFileData.cFileName); // Copy file name
            VecPushBack(&dc, direntry);
        } while (FindNextFile(hFind, &findFileData) != 0);
    static bool test_kvconfig_basic_parse(void) {
        KvConfig cfg = KvConfigInit();
        Str      src = StrInitFromZstr(
            "host = localhost\n"
                 "port = 8080\n"
    static bool test_kvconfig_comments_quotes_and_duplicates(void) {
        KvConfig cfg = KvConfigInit();
        Str      src = StrInitFromZstr(
            "# comment line\n"
                 "path = \"/srv/my app\"   # keep spaces in quotes\n"
    static bool test_kvconfig_get_returns_copy(void) {
        KvConfig cfg         = KvConfigInit();
        Str      src         = StrInitFromZstr("host = localhost\n");
        StrIter  input       = StrIterFromStr(src);
        Str      host_copy   = StrInit();
    static bool test_kvconfig_numeric_and_bool_accessors(void) {
        KvConfig cfg = KvConfigInit();
        Str      src = StrInitFromZstr(
            "workers = 16\n"
                 "pi = 3.14159\n"
    static bool test_kvconfig_invalid_line_fails(void) {
        KvConfig cfg = KvConfigInit();
        Str      src = StrInitFromZstr(
            "valid = yes\n"
                 "broken line\n"
    // Helper function to compare JSON output (removes whitespace for comparison)
    bool compare_json_output(const Str *output, const char *expected) {
        Str expected_str   = StrInitFromZstr(expected);
        Str output_clean   = StrInit();
        Str expected_clean = StrInit();
            Str status;
        } data = {
            {123, {StrInitFromZstr("Alice"), 30}},
            StrInitFromZstr("active")
        };
        } data = {
            {123, {StrInitFromZstr("Alice"), 30}},
            StrInitFromZstr("active")
        };
            } company;
        } data = {
            {{{StrInitFromZstr("John"), 25, 150000.0}}, StrInitFromZstr("TechCorp")}
        };
        Str  json    = StrInit();
    
        ApiResponse response = {true, StrInitFromZstr("Success"), VecInitWithDeepCopy(NULL, AnnSymbolDeinit)};
    
        // Add sample data
        // Add sample data
        AnnSymbol sym             = {0};
        sym.analysis_name         = StrInitFromZstr("test_analysis");
        sym.function_name         = StrInitFromZstr("main_func");
        sym.sha256                = StrInitFromZstr("abc123");
        AnnSymbol sym             = {0};
        sym.analysis_name         = StrInitFromZstr("test_analysis");
        sym.function_name         = StrInitFromZstr("main_func");
        sym.sha256                = StrInitFromZstr("abc123");
        sym.function_mangled_name = StrInitFromZstr("_Z4main");
        sym.analysis_name         = StrInitFromZstr("test_analysis");
        sym.function_name         = StrInitFromZstr("main_func");
        sym.sha256                = StrInitFromZstr("abc123");
        sym.function_mangled_name = StrInitFromZstr("_Z4main");
        sym.source_function_id    = 12345;
        sym.function_name         = StrInitFromZstr("main_func");
        sym.sha256                = StrInitFromZstr("abc123");
        sym.function_mangled_name = StrInitFromZstr("_Z4main");
        sym.source_function_id    = 12345;
        sym.target_function_id    = 67890;
        Vec(FunctionInfo) functions = VecInitWithDeepCopy(NULL, FunctionInfoDeinit);
    
        FunctionInfo func1 = {12345, StrInitFromZstr("test_func"), 1024, 4096};
        FunctionInfo func2 = {54321, StrInitFromZstr("helper_func"), 512, 8192};
        VecPushBack(&functions, func1);
    
        FunctionInfo func1 = {12345, StrInitFromZstr("test_func"), 1024, 4096};
        FunctionInfo func2 = {54321, StrInitFromZstr("helper_func"), 512, 8192};
        VecPushBack(&functions, func1);
        VecPushBack(&functions, func2);
        SearchResult result = {0};
        result.binary_id    = 888;
        result.binary_name  = StrInitFromZstr("test_binary");
        result.analysis_id  = 999;
        result.sha256       = StrInitFromZstr("abc123");
        result.binary_name  = StrInitFromZstr("test_binary");
        result.analysis_id  = 999;
        result.sha256       = StrInitFromZstr("abc123");
        result.tags         = VecInitWithDeepCopyT(result.tags, NULL, StrDeinit);
    
        // Create strings and push them properly
        Str tag1 = StrInitFromZstr("malware");
        Str tag2 = StrInitFromZstr("x86");
        // Create strings and push them properly
        Str tag1 = StrInitFromZstr("malware");
        Str tag2 = StrInitFromZstr("x86");
    
        VecPushBack(&result.tags, tag1);
        VecPushBack(&result.tags, tag2);
    
        result.created_at = StrInitFromZstr("2024-04-01");
        result.model_id   = 12345;
        result.model_name = StrInitFromZstr("test_model");
        result.created_at = StrInitFromZstr("2024-04-01");
        result.model_id   = 12345;
        result.model_name = StrInitFromZstr("test_model");
        result.owned_by   = StrInitFromZstr("user1");
        result.model_id   = 12345;
        result.model_name = StrInitFromZstr("test_model");
        result.owned_by   = StrInitFromZstr("user1");
    
        JW_OBJ(json, {
    
        AnnSymbol sym1             = {0};
        sym1.analysis_name         = StrInitFromZstr("analysis1");
        sym1.function_name         = StrInitFromZstr("func1");
        sym1.sha256                = StrInitFromZstr("hash1");
        AnnSymbol sym1             = {0};
        sym1.analysis_name         = StrInitFromZstr("analysis1");
        sym1.function_name         = StrInitFromZstr("func1");
        sym1.sha256                = StrInitFromZstr("hash1");
        sym1.function_mangled_name = StrInitFromZstr("_Z5func1");
        sym1.analysis_name         = StrInitFromZstr("analysis1");
        sym1.function_name         = StrInitFromZstr("func1");
        sym1.sha256                = StrInitFromZstr("hash1");
        sym1.function_mangled_name = StrInitFromZstr("_Z5func1");
        sym1.source_function_id    = 111;
        sym1.function_name         = StrInitFromZstr("func1");
        sym1.sha256                = StrInitFromZstr("hash1");
        sym1.function_mangled_name = StrInitFromZstr("_Z5func1");
        sym1.source_function_id    = 111;
        sym1.target_function_id    = 222;
    
        AnnSymbol sym2             = {0};
        sym2.analysis_name         = StrInitFromZstr("analysis2");
        sym2.function_name         = StrInitFromZstr("func2");
        sym2.sha256                = StrInitFromZstr("hash2");
        AnnSymbol sym2             = {0};
        sym2.analysis_name         = StrInitFromZstr("analysis2");
        sym2.function_name         = StrInitFromZstr("func2");
        sym2.sha256                = StrInitFromZstr("hash2");
        sym2.function_mangled_name = StrInitFromZstr("_Z5func2");
        sym2.analysis_name         = StrInitFromZstr("analysis2");
        sym2.function_name         = StrInitFromZstr("func2");
        sym2.sha256                = StrInitFromZstr("hash2");
        sym2.function_mangled_name = StrInitFromZstr("_Z5func2");
        sym2.source_function_id    = 333;
        sym2.function_name         = StrInitFromZstr("func2");
        sym2.sha256                = StrInitFromZstr("hash2");
        sym2.function_mangled_name = StrInitFromZstr("_Z5func2");
        sym2.source_function_id    = 333;
        sym2.target_function_id    = 444;
    
        // Create strings for the nested structure
        Str deep_message = StrInitFromZstr("deep");
        Str test_name    = StrInitFromZstr("test");
        // Create strings for the nested structure
        Str deep_message = StrInitFromZstr("deep");
        Str test_name    = StrInitFromZstr("test");
    
        JW_OBJ(json, {
    
        // Create strings and push them properly
        Str str1 = StrInitFromZstr("a");
        Str str2 = StrInitFromZstr("b");
        Str str3 = StrInitFromZstr("c");
        // Create strings and push them properly
        Str str1 = StrInitFromZstr("a");
        Str str2 = StrInitFromZstr("b");
        Str str3 = StrInitFromZstr("c");
        Str str1 = StrInitFromZstr("a");
        Str str2 = StrInitFromZstr("b");
        Str str3 = StrInitFromZstr("c");
    
        VecPushBack(&strings, str1);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"name\": \"Alice\", \"city\": \"New York\"}");
        StrIter si      = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"count\": 42, \"score\": 95.5, \"year\": 2024}");
        StrIter si      = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"enabled\": true, \"visible\": false}");
        StrIter si      = StrIterFromStr(json);
        bool success = true;
        Str  json =
            StrInitFromZstr("{\"id\": 1001, \"name\": \"Bob\", \"age\": 25, \"is_active\": true, \"salary\": 50000.0}");
        StrIter si = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"debug_mode\": false, \"timeout\": 30, \"log_level\": \"INFO\"}");
        StrIter si      = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"languages\": [\"C\", \"Python\", \"Rust\"]}");
        StrIter si      = StrIterFromStr(json);
        bool success = true;
        Str  json =
            StrInitFromZstr("{\"user\": {\"name\": \"Charlie\", \"email\": \"charlie@example.com\"}, \"active\": true}");
        StrIter si = StrIterFromStr(json);
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"id\": 12345, \"name\": \"Laptop\", \"price\": 999.99, \"tags\": [\"electronics\", \"computers\", "
                "\"portable\"]}"
        WriteFmt("Testing basic iterator functionality\n");
    
        Str     json = StrInitFromZstr("{\"test\": \"value\"}");
        StrIter si   = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"id\": 12345, \"name\": \"test\", \"active\": true, \"score\": 98.5}");
        StrIter si      = StrIterFromStr(json);
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"user\": {\"id\": 123, \"profile\": {\"name\": \"Alice\", \"age\": 30}}, \"status\": \"active\"}"
        );
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"company\": {\"departments\": {\"engineering\": {\"head\": \"John\", \"count\": 25, \"budget\": 150000.0}}, "
                "\"name\": \"TechCorp\"}}"
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"functions\": {\"12345\": {\"67890\": {\"distance\": 0.85, \"name\": \"main\"}}, \"54321\": {\"98765\": "
                "{\"distance\": 0.92, \"name\": \"helper\"}}}}"
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"status\": true, \"message\": \"Success\", \"data\": {\"12345\": {\"67890\": {\"distance\": 0.85, "
                "\"nearest_neighbor_analysis_id\": 999, \"nearest_neighbor_binary_id\": 888, "
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"id\": 12345, \"name\": \"test_func\", \"size\": 1024, \"vaddr\": 4096}");
        StrIter si      = StrIterFromStr(json);
    
        bool    success = true;
        Str     json    = StrInitFromZstr("{\"id\": 54321, \"name\": \"test_model\"}");
        StrIter si      = StrIterFromStr(json);
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"binary_id\": 888, \"binary_name\": \"test_binary\", \"analysis_id\": 999, \"sha256\": \"abc123\", "
                "\"created_at\": \"2024-04-01\", \"model_id\": 12345, \"model_name\": \"test_model\", \"owned_by\": \"user1\"}"
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"status\": true, \"message\": \"Success\", \"data\": {\"12345\": {\"67890\": {\"distance\": 0.85, "
                "\"nearest_neighbor_analysis_id\": 999, \"nearest_neighbor_binary_id\": 888, "
    
        bool success = true;
        Str  json    = StrInitFromZstr(
            "{\"status\": true, \"message\": \"Success\", \"data\": {\"12345\": {\"67890\": {\"distance\": 0.85, "
                "\"nearest_neighbor_analysis_id\": 999, \"nearest_neighbor_binary_id\": 888, "
    bool compare_json_output(const Str *output, const char *expected) {
        // Create a copy of expected without spaces for comparison
        Str expected_str   = StrInitFromZstr(expected);
        Str output_clean   = StrInit();
        Str expected_clean = StrInit();
    
        // Note: These are the actual characters, not escape sequences
        Str path    = StrInitFromZstr("C:\\Program Files\\App");
        Str message = StrInitFromZstr("Hello, \"World\"!");
        Str data    = StrInitFromZstr("line1\nline2\ttab");
        // Note: These are the actual characters, not escape sequences
        Str path    = StrInitFromZstr("C:\\Program Files\\App");
        Str message = StrInitFromZstr("Hello, \"World\"!");
        Str data    = StrInitFromZstr("line1\nline2\ttab");
        Str path    = StrInitFromZstr("C:\\Program Files\\App");
        Str message = StrInitFromZstr("Hello, \"World\"!");
        Str data    = StrInitFromZstr("line1\nline2\ttab");
    
        JW_OBJ(json, {
    
        // These contain actual special characters that should be escaped
        Str quotes    = StrInitFromZstr("\"quotes\"");
        Str backslash = StrInitFromZstr("\\");
        Str newline   = StrInitFromZstr("\n");
        // These contain actual special characters that should be escaped
        Str quotes    = StrInitFromZstr("\"quotes\"");
        Str backslash = StrInitFromZstr("\\");
        Str newline   = StrInitFromZstr("\n");
        Str tab       = StrInitFromZstr("\t");
        Str quotes    = StrInitFromZstr("\"quotes\"");
        Str backslash = StrInitFromZstr("\\");
        Str newline   = StrInitFromZstr("\n");
        Str tab       = StrInitFromZstr("\t");
        Str backslash = StrInitFromZstr("\\");
        Str newline   = StrInitFromZstr("\n");
        Str tab       = StrInitFromZstr("\t");
    
        JW_OBJ(json, {
    
        // Single string
        Str single_str = StrInitFromZstr("hello");
        JW_OBJ(json2, { JW_STR_KV(json2, "text", single_str); });
    bool compare_json_output(const Str *output, const char *expected) {
        // Create a copy of expected without spaces for comparison
        Str expected_str   = StrInitFromZstr(expected);
        Str output_clean   = StrInit();
        Str expected_clean = StrInit();
        Str  json    = StrInit();
    
        Str name = StrInitFromZstr("Alice");
        Str city = StrInitFromZstr("New York");
    
        Str name = StrInitFromZstr("Alice");
        Str city = StrInitFromZstr("New York");
    
        JW_OBJ(json, {
        Str  json    = StrInit();
    
        Person person = {1001, StrInitFromZstr("Bob"), 25, true, 50000.0};
    
        JW_OBJ(json, {
        Str  json    = StrInit();
    
        Config config = {false, 30, StrInitFromZstr("INFO")};
    
        JW_OBJ(json, {
    
        // Create strings and push them properly
        Str lang1 = StrInitFromZstr("C");
        Str lang2 = StrInitFromZstr("Python");
        Str lang3 = StrInitFromZstr("Rust");
        // Create strings and push them properly
        Str lang1 = StrInitFromZstr("C");
        Str lang2 = StrInitFromZstr("Python");
        Str lang3 = StrInitFromZstr("Rust");
        Str lang1 = StrInitFromZstr("C");
        Str lang2 = StrInitFromZstr("Python");
        Str lang3 = StrInitFromZstr("Rust");
    
        VecPushBack(&languages, lang1);
            bool active;
        } data = {
            {StrInitFromZstr("Charlie"), StrInitFromZstr("charlie@example.com")},
            true
        };
        SimpleProduct product = {0};
        product.id            = 12345;
        product.name          = StrInitFromZstr("Laptop");
        product.price         = 999.99;
        product.tags          = VecInitWithDeepCopyT(product.tags, NULL, StrDeinit);
    
        // Create strings and push them properly
        Str tag1 = StrInitFromZstr("electronics");
        Str tag2 = StrInitFromZstr("computers");
        Str tag3 = StrInitFromZstr("portable");
        // Create strings and push them properly
        Str tag1 = StrInitFromZstr("electronics");
        Str tag2 = StrInitFromZstr("computers");
        Str tag3 = StrInitFromZstr("portable");
        Str tag1 = StrInitFromZstr("electronics");
        Str tag2 = StrInitFromZstr("computers");
        Str tag3 = StrInitFromZstr("portable");
    
        VecPushBack(&product.tags, tag1);
            bool enabled;
            Str  message;
        } original = {42, 25.5, true, StrInitFromZstr("hello world")};
    
        // Write to JSON
        } original = {
            StrInit(),
            StrInitFromZstr("hello"),
            StrInitFromZstr("hello world with spaces"),
            StrInitFromZstr("special: !@#$%^&*()")
            StrInit(),
            StrInitFromZstr("hello"),
            StrInitFromZstr("hello world with spaces"),
            StrInitFromZstr("special: !@#$%^&*()")
        };
            StrInitFromZstr("hello"),
            StrInitFromZstr("hello world with spaces"),
            StrInitFromZstr("special: !@#$%^&*()")
        };
    
        // Create strings and push them properly
        Str str1 = StrInitFromZstr("first");
        Str str2 = StrInitFromZstr("second");
        Str str3 = StrInitFromZstr("");
        // Create strings and push them properly
        Str str1 = StrInitFromZstr("first");
        Str str2 = StrInitFromZstr("second");
        Str str3 = StrInitFromZstr("");
        Str str4 = StrInitFromZstr("last");
        Str str1 = StrInitFromZstr("first");
        Str str2 = StrInitFromZstr("second");
        Str str3 = StrInitFromZstr("");
        Str str4 = StrInitFromZstr("last");
        Str str2 = StrInitFromZstr("second");
        Str str3 = StrInitFromZstr("");
        Str str4 = StrInitFromZstr("last");
    
        VecPushBack(&original_strings, str1);
    
        // Original data
        TestPerson original_person = {12345, StrInitFromZstr("John Doe"), 30, true, 75000.50};
    
        // Write to JSON
        ComplexData original    = {0};
        original.user.id        = 999;
        original.user.name      = StrInitFromZstr("Complex User");
        original.user.age       = 25;
        original.user.is_active = true;
        original.config.debug_mode = false;
        original.config.timeout    = 30;
        original.config.log_level  = StrInitFromZstr("INFO");
        original.config.features   = VecInitWithDeepCopyT(original.config.features, NULL, StrDeinit);
    
        // Create strings and push them properly
        Str feature1 = StrInitFromZstr("auth");
        Str feature2 = StrInitFromZstr("logging");
        // Create strings and push them properly
        Str feature1 = StrInitFromZstr("auth");
        Str feature2 = StrInitFromZstr("logging");
    
        VecPushBack(&original.config.features, feature1);
    
        // Test completely empty object
        Str     json1 = StrInitFromZstr("{}");
        StrIter si1   = StrIterFromStr(json1);
    
        // Test empty object with whitespace
        Str     json2 = StrInitFromZstr("  {   }  ");
        StrIter si2   = StrIterFromStr(json2);
    
        // Test completely empty array
        Str     json1 = StrInitFromZstr("{\"items\":[]}");
        StrIter si1   = StrIterFromStr(json1);
    
        // Test empty array with whitespace
        Str     json2 = StrInitFromZstr("{\"data\": [  ] }");
        StrIter si2   = StrIterFromStr(json2);
        bool success = true;
    
        Str     json = StrInitFromZstr("{\"name\":\"\",\"description\":\"\"}");
        StrIter si   = StrIterFromStr(json);
        bool success = true;
    
        Str     json = StrInitFromZstr("{\"temp\":-25,\"balance\":-1000.50,\"delta\":-0.001}");
        StrIter si   = StrIterFromStr(json);
        bool success = true;
    
        Str json = StrInitFromZstr(
            "{\"big_int\":9223372036854775807,\"big_float\":1.7976931348623157e+308,\"small_float\":2.2250738585072014e-"
            "308}"
        bool success = true;
    
        Str     json = StrInitFromZstr("{\"int_zero\":0,\"float_zero\":0.0,\"bool_false\":false}");
        StrIter si   = StrIterFromStr(json);
    
        // Test with various special characters that might be problematic
        Str json = StrInitFromZstr(
            "{\"path\":\"C:\\\\Program Files\\\\App\",\"message\":\"Hello, "
            "\\\"World\\\"!\",\"data\":\"line1\\nline2\\ttab\"}"
    
        Str json =
            StrInitFromZstr("{\"escaped\":\"\\\"quotes\\\"\",\"backslash\":\"\\\\\",\"newline\":\"\\n\",\"tab\":\"\\t\"}");
        StrIter si = StrIterFromStr(json);
    
        // Test with lots of different whitespace patterns
        Str     json = StrInitFromZstr("  {\n\t\"name\"  :  \"test\"  ,\n  \"value\": 42\t,\"flag\"\n:\ntrue\n}\t");
        StrIter si   = StrIterFromStr(json);
        bool success = true;
    
        Str     json = StrInitFromZstr("{\"outer\":{},\"list\":[],\"deep\":{\"inner\":{}}}");
        StrIter si   = StrIterFromStr(json);
        bool success = true;
    
        Str     json = StrInitFromZstr("{\"empty_obj\":{},\"filled_obj\":{\"x\":1},\"empty_arr\":[],\"filled_arr\":[1,2]}");
        StrIter si   = StrIterFromStr(json);
    
        // Using smaller values that are safer to work with
        Str     json = StrInitFromZstr("{\"max_int\":2147483647,\"min_int\":-2147483648,\"one\":1,\"minus_one\":-1}");
        StrIter si   = StrIterFromStr(json);
        bool success = true;
    
        Str json   = StrInitFromZstr("{\"tiny\":0.000001,\"huge\":999999.999999,\"zero\":0.0,\"negative_tiny\":-0.000001}");
        StrIter si = StrIterFromStr(json);
        WriteFmt("Testing StrInsertCharAt\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Insert a character in the middle
        WriteFmt("Testing StrInsertCstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Insert a string in the middle
        WriteFmt("Testing StrInsertZstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Insert a string in the middle
        WriteFmt("Testing StrInsert\n");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        // Insert s2 into s1 in the middle
        WriteFmt("Testing StrPushCstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Push a string at position 2
        WriteFmt("Testing StrPushZstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Push a string at position 2
        WriteFmt("Testing StrPushBackCstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Push a string at the back
        WriteFmt("Testing StrPushBackZstr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Push a string at the back
        WriteFmt("Testing StrPushFrontCstr\n");
    
        Str s = StrInitFromZstr("World");
    
        // Push a string at the front
        WriteFmt("Testing StrPushFrontZstr\n");
    
        Str s = StrInitFromZstr("World");
    
        // Push a string at the front
        WriteFmt("Testing StrPushBack\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Push characters at the back
        WriteFmt("Testing StrPushFront\n");
    
        Str s = StrInitFromZstr("World");
    
        // Push characters at the front
        WriteFmt("Testing StrMergeL\n");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        // Merge s2 into s1 (L-value semantics)
        WriteFmt("Testing StrMergeR\n");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        // Merge s2 into s1 (R-value semantics)
        WriteFmt("Testing StrMerge\n");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr(" World");
    
        // Merge s2 into s1
        WriteFmt("Testing StrAppendf\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Append formatted string
        StrReadFmt(z, "{}", s);
    
        Str expected = StrInitFromZstr("Hello");
        success      = success && (StrCmp(&s, &expected) == 0);
        StrDeinit(&expected);
        StrReadFmt(z, "{s}", s);
    
        expected = StrInitFromZstr("Hello, World!");
        success  = success && (StrCmp(&s, &expected) == 0);
        StrDeinit(&expected);
        success = success && (num == 42);
    
        Str expected = StrInitFromZstr("Alice");
        success      = success && (StrCmp(&name, &expected) == 0);
        StrDeinit(&expected);
        success = success && double_equals(val, 3.14);
    
        expected = StrInitFromZstr("Bob");
        success  = success && (StrCmp(&name, &expected) == 0);
        StrDeinit(&expected);
        z           = "Hello";
        StrReadFmt(z, "{c}", str_val);
        Str  expected = StrInitFromZstr("Hello");
        bool str_pass = (StrCmp(&str_val, &expected) == 0);
        WriteFmt("str_val test: comparing with 'Hello', pass = {}\n", str_pass ? "true" : "false");
        z       = "\"World\"";
        StrReadFmt(z, "{cs}", str_val);
        expected             = StrInitFromZstr("World");
        bool quoted_str_pass = (StrCmp(&str_val, &expected) == 0);
        WriteFmt("quoted str_val test: comparing with 'World', pass = {}\n", quoted_str_pass ? "true" : "false");
    
            // Should read "hello" (stops at first space)
            Str  expected   = StrInitFromZstr("hello world");
            bool test1_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'hello', Pass: {}\n\n", test1_pass ? "true" : "false");
    
            // Should read "hello" (stops at first space)
            Str  expected   = StrInitFromZstr("hello");
            bool test1_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'hello', Pass: {}\n\n", test1_pass ? "true" : "false");
    
            // Should read "HELLO" (stops at first space)
            Str  expected   = StrInitFromZstr("HELLO WORLD");
            bool test2_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'HELLO', Pass: {}\n\n", test2_pass ? "true" : "false");
    
            // Should read "mixed case" (converts the entire quoted string)
            Str  expected   = StrInitFromZstr("mixed case");
            bool test3_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'mixed case', Pass: {}\n\n", test3_pass ? "true" : "false");
    
            // Should read "ABC123XYZ" (only letters are converted, numbers unchanged)
            Str  expected   = StrInitFromZstr("ABC123XYZ");
            bool test4_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'ABC123XYZ', Pass: {}\n\n", test4_pass ? "true" : "false");
    
            // Should read "Hello" (stops at first space, no case conversion)
            Str  expected   = StrInitFromZstr("Hello World");
            bool test5_pass = (StrCmp(&result, &expected) == 0);
            WriteFmt("Expected: 'Hello World', Pass: {}\n\n", test5_pass ? "true" : "false");
    
        // Add some strings
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr("World");
        // Add some strings
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr("World");
    
        VecPushBack(&sv, s1);
    
        // Test Str object
        Str s = StrInitFromZstr("World");
        StrWriteFmt(&output, "{}", s);
        success = success && (ZstrCompare(output.data, "World") == 0);
    
        // Test with Str object
        Str s = StrInitFromZstr("MiXeD CaSe");
    
        // Test with :c (preserve case)
        WriteFmt("Testing StrForeachIdx\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character with its index
        WriteFmt("Testing StrForeachReverseIdx\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character in reverse with its index
        WriteFmt("Testing StrForeachPtrIdx\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character pointer with its index
        WriteFmt("Testing StrForeachReversePtrIdx\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character pointer in reverse with its index
        WriteFmt("Testing StrForeach\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character
        WriteFmt("Testing StrForeachReverse\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character in reverse
        WriteFmt("Testing StrForeachPtr\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character pointer
        WriteFmt("Testing StrForeachPtrReverse\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Build a new string by iterating through each character pointer in reverse
        WriteFmt("Testing StrForeachInRangeIdx\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Build a new string by iterating through a range of characters with indices
        WriteFmt("Testing StrForeachInRange\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Build a new string by iterating through a range of characters
        WriteFmt("Testing StrForeachPtrInRangeIdx\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Build a new string by iterating through a range of character pointers with indices
        WriteFmt("Testing StrForeachPtrInRange\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Build a new string by iterating through a range of character pointers
        WriteFmt("Testing StrForeachInRangeIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Hello World!"); // 12 characters
    
        // Use StrForeachInRangeIdx which captures the 'end' parameter at the start
        WriteFmt("Testing StrForeachInRangeIdx with character deletion where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Programming"); // 11 characters
    
        // Use StrForeachInRangeIdx with a fixed range that will become invalid
        WriteFmt("Testing StrForeachReverseIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Beautiful Weather"); // 17 characters
    
        // StrForeachReverseIdx (VecForeachReverseIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
        WriteFmt("Testing StrForeachPtrIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Programming Test"); // 16 characters
    
        // StrForeachPtrIdx (VecForeachPtrIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
        WriteFmt("Testing StrForeachReversePtrIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Excellent Example"); // 17 characters
    
        // StrForeachReversePtrIdx (VecForeachPtrReverseIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
        WriteFmt("Testing StrForeachPtrInRangeIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Comprehensive Testing Framework"); // 31 characters
    
        // Use StrForeachPtrInRangeIdx with a fixed range that becomes invalid when we modify the string
        WriteFmt("Testing basic StrForeachIdx where idx goes out of bounds\n");
    
        Str s = StrInitFromZstr("Testing Basic"); // 13 characters
    
        // Basic StrForeachIdx (VecForeachIdx) now has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
    
        // Test decimal conversion
        Str  s       = StrInitFromZstr("12345");
        u64  value   = 0;
        bool success = StrToU64(&s, &value, NULL);
        // Test hexadecimal conversion with explicit base
        StrDeinit(&s);
        s                     = StrInitFromZstr("ABCD"); // No 0x prefix when base is explicitly 16
        StrParseConfig config = {.base = 16};
        success               = StrToU64(&s, &value, &config);
        // Test hexadecimal conversion (auto-detect base with 0)
        StrDeinit(&s);
        s       = StrInitFromZstr("0xABCD");
        success = StrToU64(&s, &value, NULL);
        result  = result && (success && value == 0xABCD);
        // Test binary conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("0b101010");
        success = StrToU64(&s, &value, NULL);
        result  = result && (success && value == 42);
        // Test octal conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("0o52");
        success = StrToU64(&s, &value, NULL);
        result  = result && (success && value == 42);
        // Test zero
        StrDeinit(&s);
        s       = StrInitFromZstr("0");
        success = StrToU64(&s, &value, NULL);
        result  = result && (success && value == 0);
        // Test invalid input
        StrDeinit(&s);
        s       = StrInitFromZstr("not a number");
        success = StrToU64(&s, &value, NULL);
        result  = result && (!success);
        // Test negative number (should fail for unsigned)
        StrDeinit(&s);
        s       = StrInitFromZstr("-123");
        success = StrToU64(&s, &value, NULL);
        result  = result && (!success);
    
        // Test positive decimal conversion
        Str  s       = StrInitFromZstr("12345");
        i64  value   = 0;
        bool success = StrToI64(&s, &value, NULL);
        // Test negative decimal conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("-12345");
        success = StrToI64(&s, &value, NULL);
        result  = result && (success && value == -12345);
        // Test hexadecimal conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("0xABCD");
        success = StrToI64(&s, &value, NULL);
        result  = result && (success && value == 0xABCD);
        // Test binary conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("0b101010");
        success = StrToI64(&s, &value, NULL);
        result  = result && (success && value == 42);
        // Test zero
        StrDeinit(&s);
        s       = StrInitFromZstr("0");
        success = StrToI64(&s, &value, NULL);
        result  = result && (success && value == 0);
        // Test invalid input
        StrDeinit(&s);
        s       = StrInitFromZstr("not a number");
        success = StrToI64(&s, &value, NULL);
        result  = result && (!success);
    
        // Test integer conversion
        Str  s       = StrInitFromZstr("123");
        f64  value   = 0.0;
        bool success = StrToF64(&s, &value, NULL);
        // Test fractional conversion
        StrDeinit(&s);
        s       = StrInitFromZstr("123.456");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && fabs(value - 123.456) < 0.0001);
        // Test negative number
        StrDeinit(&s);
        s       = StrInitFromZstr("-123.456");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && fabs(value - (-123.456)) < 0.0001);
        // Test scientific notation
        StrDeinit(&s);
        s       = StrInitFromZstr("1.23e2");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && fabs(value - 123.0) < 0.0001);
        // Test zero
        StrDeinit(&s);
        s       = StrInitFromZstr("0");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && fabs(value) < 0.0001);
        // Test infinity
        StrDeinit(&s);
        s       = StrInitFromZstr("inf");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && isinf(value) && value > 0);
        // Test negative infinity
        StrDeinit(&s);
        s       = StrInitFromZstr("-inf");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && isinf(value) && value < 0);
        // Test NaN
        StrDeinit(&s);
        s       = StrInitFromZstr("nan");
        success = StrToF64(&s, &value, NULL);
        result  = result && (success && isnan(value));
        // Test invalid input
        StrDeinit(&s);
        s       = StrInitFromZstr("not a number");
        success = StrToF64(&s, &value, NULL);
        result  = result && (!success);
    
        for (size_t i = 0; i < sizeof(prefix_tests) / sizeof(prefix_tests[0]); i++) {
            Str            test_str = StrInitFromZstr(prefix_tests[i].input);
            u64            value    = 0;
            StrParseConfig config   = {.base = prefix_tests[i].base};
        strcpy(long_number, "12345678901234567890123456789012345678901234567890");
    
        Str  long_str   = StrInitFromZstr(long_number);
        u64  long_value = 0;
        bool success    = StrToU64(&long_str, &long_value, NULL);
        WriteFmt("Testing StrSwapCharAt\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Swap 'H' and 'o'
        WriteFmt("Testing StrResize\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Initial length should be 5
        WriteFmt("Testing StrClear\n");
    
        Str s = StrInitFromZstr("Hello, World!");
    
        // Initial length should be 13
        WriteFmt("Testing StrReverse\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Reverse the string
        // Test with an even-length string
        StrDeinit(&s);
        s = StrInitFromZstr("abcd");
    
        // Reverse the string
        // Test with a single-character string
        StrDeinit(&s);
        s = StrInitFromZstr("a");
    
        // Reverse the string
        WriteFmt("Testing StrCmp and StrCmpCstr\n");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr("Hello");
        Str s3 = StrInitFromZstr("World");
    
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr("Hello");
        Str s3 = StrInitFromZstr("World");
        Str s4 = StrInitFromZstr("Hello World");
        Str s1 = StrInitFromZstr("Hello");
        Str s2 = StrInitFromZstr("Hello");
        Str s3 = StrInitFromZstr("World");
        Str s4 = StrInitFromZstr("Hello World");
        Str s2 = StrInitFromZstr("Hello");
        Str s3 = StrInitFromZstr("World");
        Str s4 = StrInitFromZstr("Hello World");
    
        // Test StrCmp with equal strings
        WriteFmt("Testing StrFindStr, StrFindZstr, and StrFindCstr\n");
    
        Str haystack = StrInitFromZstr("Hello World");
        Str needle1  = StrInitFromZstr("World");
        Str needle2  = StrInitFromZstr("Hello");
    
        Str haystack = StrInitFromZstr("Hello World");
        Str needle1  = StrInitFromZstr("World");
        Str needle2  = StrInitFromZstr("Hello");
        Str needle3  = StrInitFromZstr("NotFound");
        Str haystack = StrInitFromZstr("Hello World");
        Str needle1  = StrInitFromZstr("World");
        Str needle2  = StrInitFromZstr("Hello");
        Str needle3  = StrInitFromZstr("NotFound");
        Str needle1  = StrInitFromZstr("World");
        Str needle2  = StrInitFromZstr("Hello");
        Str needle3  = StrInitFromZstr("NotFound");
    
        // Test StrFindStr with match at end
        WriteFmt("Testing StrStartsWith and StrEndsWith variants\n");
    
        Str s      = StrInitFromZstr("Hello World");
        Str prefix = StrInitFromZstr("Hello");
        Str suffix = StrInitFromZstr("World");
    
        Str s      = StrInitFromZstr("Hello World");
        Str prefix = StrInitFromZstr("Hello");
        Str suffix = StrInitFromZstr("World");
        Str s      = StrInitFromZstr("Hello World");
        Str prefix = StrInitFromZstr("Hello");
        Str suffix = StrInitFromZstr("World");
    
        // Test StrStartsWith
    
        // Test StrReplaceZstr
        Str s1 = StrInitFromZstr("Hello World");
        StrReplaceZstr(&s1, "World", "Universe", 1);
        bool result = (ZstrCompare(s1.data, "Hello Universe") == 0);
        // Test multiple replacements
        StrDeinit(&s1);
        s1 = StrInitFromZstr("Hello Hello Hello");
        StrReplaceZstr(&s1, "Hello", "Hi", 2);
        result = result && (ZstrCompare(s1.data, "Hi Hi Hello") == 0);
        // Test StrReplaceCstr - use the full "World" string instead of just "Wo"
        StrDeinit(&s1);
        s1 = StrInitFromZstr("Hello World");
        StrReplaceCstr(&s1, "World", 5, "Universe", 8, 1);
        result = result && (ZstrCompare(s1.data, "Hello Universe") == 0);
        // Test StrReplace
        StrDeinit(&s1);
        s1          = StrInitFromZstr("Hello World");
        Str find    = StrInitFromZstr("World");
        Str replace = StrInitFromZstr("Universe");
        StrDeinit(&s1);
        s1          = StrInitFromZstr("Hello World");
        Str find    = StrInitFromZstr("World");
        Str replace = StrInitFromZstr("Universe");
        StrReplace(&s1, &find, &replace, 1);
        s1          = StrInitFromZstr("Hello World");
        Str find    = StrInitFromZstr("World");
        Str replace = StrInitFromZstr("Universe");
        StrReplace(&s1, &find, &replace, 1);
        result = result && (ZstrCompare(s1.data, "Hello Universe") == 0);
    
        // Test StrSplit
        Str  s     = StrInitFromZstr("Hello,World,Test");
        Strs split = StrSplit(&s, ",");
    
        // Test StrLStrip
        Str  s1       = StrInitFromZstr("  Hello  ");
        Str  stripped = StrLStrip(&s1, NULL);
        bool result   = (ZstrCompare(stripped.data, "Hello  ") == 0);
        // Test with custom strip characters
        StrDeinit(&s1);
        s1 = StrInitFromZstr("***Hello***");
    
        stripped = StrLStrip(&s1, "*");
        WriteFmt("Testing StrFirst\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Get the first character
        WriteFmt("Testing StrLast\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Get the last character
        WriteFmt("Testing StrBegin\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Get a pointer to the first character using StrBegin
        WriteFmt("Testing StrEnd\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Get a pointer to one past the last character using StrEnd
        WriteFmt("Testing StrCharAt\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Access characters at different indices
        WriteFmt("Testing StrCharPtrAt\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Access character pointers at different indices
    // Test StrInitFromZstr function
    bool test_str_init_from_zstr(void) {
        WriteFmt("Testing StrInitFromZstr\n");
    
        const char *test_str = "Hello, World!";
    
        const char *test_str = "Hello, World!";
        Str         s        = StrInitFromZstr(test_str);
    
        // Validate the string
        WriteFmt("Testing StrInitFromStr\n");
    
        Str src = StrInitFromZstr("Hello, World!");
        Str dst = StrInitFromStr(&src);
        WriteFmt("Testing StrDup\n");
    
        Str src = StrInitFromZstr("Hello, World!");
        Str dst = StrDup(&src);
        WriteFmt("Testing StrInitCopy\n");
    
        Str src = StrInitFromZstr("Hello, World!");
        Str dst = StrInit();
        WriteFmt("Testing StrDeinit\n");
    
        Str s = StrInitFromZstr("Hello, World!");
    
        // Validate the string before deinit
        WriteFmt("Testing StrPopBack\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Pop a character from the back
        WriteFmt("Testing StrPopFront\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Pop a character from the front
        WriteFmt("Testing StrRemove\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Remove a character from the middle
        WriteFmt("Testing StrRemoveRange\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Create a buffer to store the removed characters
        WriteFmt("Testing StrDeleteLastChar\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Delete the last character
        WriteFmt("Testing StrDelete\n");
    
        Str s = StrInitFromZstr("Hello");
    
        // Delete a character from the middle
        WriteFmt("Testing StrDeleteRange\n");
    
        Str s = StrInitFromZstr("Hello World");
    
        // Delete a range of characters
Last updated on