StrInitFromZstr

Table of Contents

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

NameDirectionDescription
zstrinPointer 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)

    }
    
    direntry.name = StrInitFromZstr(findFileData.cFileName); // Copy file name
    VecPushBack(&dc, direntry);
    } while (FindNextFile(hFind, &findFileData) != 0);
    char* env_var = getenv(name);
    if (env_var) {
    *value = StrInitFromZstr(env_var);
    return value;
    }
    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;
    }
    // Last resort fallback
    LOG_ERROR("Could not determine executable path, using fallback");
    *exe_path = StrInitFromZstr("unknown_executable");
    return exe_path;
    #endif
    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    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\"]}"
    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); });
    
    // 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);
    // 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 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);
    printf("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, "
    
    // 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 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);
    printf("Testing StrSwapCharAt\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Swap 'H' and 'o'
    printf("Testing StrResize\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Initial length should be 5
    printf("Testing StrClear\n");
    
    Str s = StrInitFromZstr("Hello, World!");
    
    // Initial length should be 13
    printf("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
    printf("Testing StrInsertCharAt\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Insert a character in the middle
    printf("Testing StrInsertCstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Insert a string in the middle
    printf("Testing StrInsertZstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Insert a string in the middle
    printf("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
    printf("Testing StrPushCstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Push a string at position 2
    printf("Testing StrPushZstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Push a string at position 2
    printf("Testing StrPushBackCstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Push a string at the back
    printf("Testing StrPushBackZstr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Push a string at the back
    printf("Testing StrPushFrontCstr\n");
    
    Str s = StrInitFromZstr("World");
    
    // Push a string at the front
    printf("Testing StrPushFrontZstr\n");
    
    Str s = StrInitFromZstr("World");
    
    // Push a string at the front
    printf("Testing StrPushBack\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Push characters at the back
    printf("Testing StrPushFront\n");
    
    Str s = StrInitFromZstr("World");
    
    // Push characters at the front
    printf("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)
    printf("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)
    printf("Testing StrMerge\n");
    
    Str s1 = StrInitFromZstr("Hello");
    Str s2 = StrInitFromZstr(" World");
    
    Str s1 = StrInitFromZstr("Hello");
    Str s2 = StrInitFromZstr(" World");
    
    // Merge s2 into s1
    printf("Testing StrAppendf\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Append formatted string
    printf("Testing StrPopBack\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Pop a character from the back
    printf("Testing StrPopFront\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Pop a character from the front
    printf("Testing StrRemove\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Remove a character from the middle
    printf("Testing StrRemoveRange\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Create a buffer to store the removed characters
    printf("Testing StrDeleteLastChar\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Delete the last character
    printf("Testing StrDelete\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Delete a character from the middle
    printf("Testing StrDeleteRange\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Delete a range of characters
    printf("Testing StrForeachInRangeIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Hello World!"); // 12 characters
    
    // Use StrForeachInRangeIdx which captures the 'end' parameter at the start
    printf("Testing StrForeachInRangeIdx with character deletion where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Programming"); // 11 characters
    
    // Use StrForeachInRangeIdx with a fixed range that will become invalid
    printf("Testing StrForeachReverseIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Beautiful Weather"); // 17 characters
    
    // StrForeachReverseIdx (VecForeachReverseIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
    printf("Testing StrForeachPtrIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Programming Test"); // 16 characters
    
    // StrForeachPtrIdx (VecForeachPtrIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
    printf("Testing StrForeachReversePtrIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Excellent Example"); // 17 characters
    
    // StrForeachReversePtrIdx (VecForeachPtrReverseIdx) has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
    printf("Testing StrForeachPtrInRangeIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Comprehensive Testing Framework"); // 32 characters
    
    // Use StrForeachPtrInRangeIdx with a fixed range that becomes invalid when we modify the string
    printf("Testing basic StrForeachIdx where idx goes out of bounds (should crash)\n");
    
    Str s = StrInitFromZstr("Testing Basic"); // 13 characters
    
    // Basic StrForeachIdx (VecForeachIdx) now has explicit bounds checking: if ((idx) >= (v)->length) LOG_FATAL(...)
    
    // 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)
    printf("Testing StrForeachIdx\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character with its index
    printf("Testing StrForeachReverseIdx\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character in reverse with its index
    printf("Testing StrForeachPtrIdx\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character pointer with its index
    printf("Testing StrForeachReversePtrIdx\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character pointer in reverse with its index
    printf("Testing StrForeach\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character
    printf("Testing StrForeachReverse\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character in reverse
    printf("Testing StrForeachPtr\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character pointer
    printf("Testing StrForeachPtrReverse\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Build a new string by iterating through each character pointer in reverse
    printf("Testing StrForeachInRangeIdx\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Build a new string by iterating through a range of characters with indices
    printf("Testing StrForeachInRange\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Build a new string by iterating through a range of characters
    printf("Testing StrForeachPtrInRangeIdx\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Build a new string by iterating through a range of character pointers with indices
    printf("Testing StrForeachPtrInRange\n");
    
    Str s = StrInitFromZstr("Hello World");
    
    // Build a new string by iterating through a range of character pointers
    printf("Testing StrFirst\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Get the first character
    printf("Testing StrLast\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Get the last character
    printf("Testing StrBegin\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Get a pointer to the first character using StrBegin
    printf("Testing StrEnd\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Get a pointer to one past the last character using StrEnd
    printf("Testing StrCharAt\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Access characters at different indices
    printf("Testing StrCharPtrAt\n");
    
    Str s = StrInitFromZstr("Hello");
    
    // Access character pointers at different indices
    // Test StrInitFromZstr function
    bool test_str_init_from_zstr(void) {
    printf("Testing StrInitFromZstr\n");
    
    const char* test_str = "Hello, World!";
    
    const char* test_str = "Hello, World!";
    Str         s        = StrInitFromZstr(test_str);
    
    // Validate the string
    printf("Testing StrInitFromStr\n");
    
    Str src = StrInitFromZstr("Hello, World!");
    Str dst = StrInitFromStr(&src);
    printf("Testing StrDup\n");
    
    Str src = StrInitFromZstr("Hello, World!");
    Str dst = StrDup(&src);
    printf("Testing StrInitCopy\n");
    
    Str src = StrInitFromZstr("Hello, World!");
    Str dst = StrInit();
    printf("Testing StrDeinit\n");
    
    Str s = StrInitFromZstr("Hello, World!");
    
    // Validate the string before deinit
    StrReadFmt("Hello", "{}", s);
    
    Str expected = StrInitFromZstr("Hello");
    success      = success && (StrCmp(&s, &expected) == 0);
    StrDeinit(&expected);
    StrReadFmt("\"Hello, World!\"", "{}", 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);
    StrReadFmt("Hello", "{c}", str_val);
    
    Str  expected = StrInitFromZstr("Hello");
    bool str_pass = (StrCmp(&str_val, &expected) == 0);
    printf("str_val test: comparing with 'Hello', pass = %s\n", str_pass ? "true" : "false");
    StrReadFmt("\"World\"", "{c}", str_val);
    
    expected             = StrInitFromZstr("World");
    bool quoted_str_pass = (StrCmp(&str_val, &expected) == 0);
    printf("quoted str_val test: comparing with 'World', pass = %s\n", quoted_str_pass ? "true" : "false");
    
    // Should read "hello" (stops at first space)
    Str  expected   = StrInitFromZstr("hello");
    bool test1_pass = (StrCmp(&result, &expected) == 0);
    printf("Expected: 'hello', Pass: %s\n\n", test1_pass ? "true" : "false");
    
    // Should read "HELLO" (stops at first space)
    Str  expected   = StrInitFromZstr("HELLO");
    bool test2_pass = (StrCmp(&result, &expected) == 0);
    printf("Expected: 'HELLO', Pass: %s\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);
    printf("Expected: 'mixed case', Pass: %s\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);
    printf("Expected: 'ABC123XYZ', Pass: %s\n\n", test4_pass ? "true" : "false");
    
    // Should read "Hello" (stops at first space, no case conversion)
    Str  expected   = StrInitFromZstr("Hello");
    bool test5_pass = (StrCmp(&result, &expected) == 0);
    printf("Expected: 'Hello', Pass: %s\n\n", test5_pass ? "true" : "false");
    printf("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
    printf("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
    printf("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, "*");

Share :