StrInitFromZstr
- Macro
- August 22, 2025
Table of Contents
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)
- In
Sys.c:141
:
}
direntry.name = StrInitFromZstr(findFileData.cFileName); // Copy file name
VecPushBack(&dc, direntry);
} while (FindNextFile(hFind, &findFileData) != 0);
- In
Sys.c:295
:
char* env_var = getenv(name);
if (env_var) {
*value = StrInitFromZstr(env_var);
return value;
}
- In
Sys.c:323
:
return NULL;
}
*exe_path = StrInitFromZstr(buffer);
return exe_path;
#else
- In
Sys.c:332
:
if (len != -1) {
buffer[len] = '\0';
*exe_path = StrInitFromZstr(buffer);
return exe_path;
}
- In
Sys.c:341
:
u32 bsize = sizeof(buffer);
if (_NSGetExecutablePath(buffer, &bsize) == 0) {
*exe_path = StrInitFromZstr(buffer);
return exe_path;
}
- In
Sys.c:348
:
// 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);
- In
Read.Simple.c:62
:
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);
- In
RoundTrip.c:96
:
bool enabled;
Str message;
} original = {42, 25.5, true, StrInitFromZstr("hello world")};
// Write to JSON
- In
RoundTrip.c:292
:
} original = {
StrInit(),
StrInitFromZstr("hello"),
StrInitFromZstr("hello world with spaces"),
StrInitFromZstr("special: !@#$%^&*()")
- In
RoundTrip.c:293
:
StrInit(),
StrInitFromZstr("hello"),
StrInitFromZstr("hello world with spaces"),
StrInitFromZstr("special: !@#$%^&*()")
};
- In
RoundTrip.c:294
:
StrInitFromZstr("hello"),
StrInitFromZstr("hello world with spaces"),
StrInitFromZstr("special: !@#$%^&*()")
};
- In
RoundTrip.c:362
:
// Create strings and push them properly
Str str1 = StrInitFromZstr("first");
Str str2 = StrInitFromZstr("second");
Str str3 = StrInitFromZstr("");
- In
RoundTrip.c:363
:
// Create strings and push them properly
Str str1 = StrInitFromZstr("first");
Str str2 = StrInitFromZstr("second");
Str str3 = StrInitFromZstr("");
Str str4 = StrInitFromZstr("last");
- In
RoundTrip.c:364
:
Str str1 = StrInitFromZstr("first");
Str str2 = StrInitFromZstr("second");
Str str3 = StrInitFromZstr("");
Str str4 = StrInitFromZstr("last");
- In
RoundTrip.c:365
:
Str str2 = StrInitFromZstr("second");
Str str3 = StrInitFromZstr("");
Str str4 = StrInitFromZstr("last");
VecPushBack(&original_strings, str1);
- In
RoundTrip.c:455
:
// Original data
TestPerson original_person = {12345, StrInitFromZstr("John Doe"), 30, true, 75000.50};
// Write to JSON
- In
RoundTrip.c:507
:
ComplexData original = {0};
original.user.id = 999;
original.user.name = StrInitFromZstr("Complex User");
original.user.age = 25;
original.user.is_active = true;
- In
RoundTrip.c:514
:
original.config.debug_mode = false;
original.config.timeout = 30;
original.config.log_level = StrInitFromZstr("INFO");
original.config.features = VecInitWithDeepCopyT(original.config.features, NULL, StrDeinit);
- In
RoundTrip.c:518
:
// Create strings and push them properly
Str feature1 = StrInitFromZstr("auth");
Str feature2 = StrInitFromZstr("logging");
- In
RoundTrip.c:519
:
// 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, "
- In
Str.Type.c:48
:
// Add some strings
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr("World");
- In
Str.Type.c:49
:
// 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);
- In
Str.Memory.c:46
:
printf("Testing StrSwapCharAt\n");
Str s = StrInitFromZstr("Hello");
// Swap 'H' and 'o'
- In
Str.Memory.c:68
:
printf("Testing StrResize\n");
Str s = StrInitFromZstr("Hello");
// Initial length should be 5
- In
Str.Memory.c:119
:
printf("Testing StrClear\n");
Str s = StrInitFromZstr("Hello, World!");
// Initial length should be 13
- In
Str.Memory.c:141
:
printf("Testing StrReverse\n");
Str s = StrInitFromZstr("Hello");
// Reverse the string
- In
Str.Memory.c:151
:
// Test with an even-length string
StrDeinit(&s);
s = StrInitFromZstr("abcd");
// Reverse the string
- In
Str.Memory.c:161
:
// Test with a single-character string
StrDeinit(&s);
s = StrInitFromZstr("a");
// Reverse the string
- In
Str.Insert.c:32
:
printf("Testing StrInsertCharAt\n");
Str s = StrInitFromZstr("Hello");
// Insert a character in the middle
- In
Str.Insert.c:60
:
printf("Testing StrInsertCstr\n");
Str s = StrInitFromZstr("Hello");
// Insert a string in the middle
- In
Str.Insert.c:76
:
printf("Testing StrInsertZstr\n");
Str s = StrInitFromZstr("Hello");
// Insert a string in the middle
- In
Str.Insert.c:92
:
printf("Testing StrInsert\n");
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
- In
Str.Insert.c:93
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
// Insert s2 into s1 in the middle
- In
Str.Insert.c:110
:
printf("Testing StrPushCstr\n");
Str s = StrInitFromZstr("Hello");
// Push a string at position 2
- In
Str.Insert.c:126
:
printf("Testing StrPushZstr\n");
Str s = StrInitFromZstr("Hello");
// Push a string at position 2
- In
Str.Insert.c:142
:
printf("Testing StrPushBackCstr\n");
Str s = StrInitFromZstr("Hello");
// Push a string at the back
- In
Str.Insert.c:158
:
printf("Testing StrPushBackZstr\n");
Str s = StrInitFromZstr("Hello");
// Push a string at the back
- In
Str.Insert.c:174
:
printf("Testing StrPushFrontCstr\n");
Str s = StrInitFromZstr("World");
// Push a string at the front
- In
Str.Insert.c:190
:
printf("Testing StrPushFrontZstr\n");
Str s = StrInitFromZstr("World");
// Push a string at the front
- In
Str.Insert.c:206
:
printf("Testing StrPushBack\n");
Str s = StrInitFromZstr("Hello");
// Push characters at the back
- In
Str.Insert.c:227
:
printf("Testing StrPushFront\n");
Str s = StrInitFromZstr("World");
// Push characters at the front
- In
Str.Insert.c:248
:
printf("Testing StrMergeL\n");
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
- In
Str.Insert.c:249
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
// Merge s2 into s1 (L-value semantics)
- In
Str.Insert.c:273
:
printf("Testing StrMergeR\n");
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
- In
Str.Insert.c:274
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
// Merge s2 into s1 (R-value semantics)
- In
Str.Insert.c:294
:
printf("Testing StrMerge\n");
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
- In
Str.Insert.c:295
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr(" World");
// Merge s2 into s1
- In
Str.Insert.c:315
:
printf("Testing StrAppendf\n");
Str s = StrInitFromZstr("Hello");
// Append formatted string
- In
Str.Remove.c:23
:
printf("Testing StrPopBack\n");
Str s = StrInitFromZstr("Hello");
// Pop a character from the back
- In
Str.Remove.c:47
:
printf("Testing StrPopFront\n");
Str s = StrInitFromZstr("Hello");
// Pop a character from the front
- In
Str.Remove.c:71
:
printf("Testing StrRemove\n");
Str s = StrInitFromZstr("Hello");
// Remove a character from the middle
- In
Str.Remove.c:95
:
printf("Testing StrRemoveRange\n");
Str s = StrInitFromZstr("Hello World");
// Create a buffer to store the removed characters
- In
Str.Remove.c:122
:
printf("Testing StrDeleteLastChar\n");
Str s = StrInitFromZstr("Hello");
// Delete the last character
- In
Str.Remove.c:144
:
printf("Testing StrDelete\n");
Str s = StrInitFromZstr("Hello");
// Delete a character from the middle
- In
Str.Remove.c:166
:
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(...)
- In
Io.Write.c:92
:
// Test Str object
Str s = StrInitFromZstr("World");
StrWriteFmt(&output, "{}", s);
success = success && (ZstrCompare(output.data, "World") == 0);
- In
Io.Write.c:380
:
// 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
- In
Str.Access.c:22
:
printf("Testing StrFirst\n");
Str s = StrInitFromZstr("Hello");
// Get the first character
- In
Str.Access.c:38
:
printf("Testing StrLast\n");
Str s = StrInitFromZstr("Hello");
// Get the last character
- In
Str.Access.c:54
:
printf("Testing StrBegin\n");
Str s = StrInitFromZstr("Hello");
// Get a pointer to the first character using StrBegin
- In
Str.Access.c:70
:
printf("Testing StrEnd\n");
Str s = StrInitFromZstr("Hello");
// Get a pointer to one past the last character using StrEnd
- In
Str.Access.c:86
:
printf("Testing StrCharAt\n");
Str s = StrInitFromZstr("Hello");
// Access characters at different indices
- In
Str.Access.c:107
:
printf("Testing StrCharPtrAt\n");
Str s = StrInitFromZstr("Hello");
// Access character pointers at different indices
- In
Str.Init.c:58
:
// Test StrInitFromZstr function
bool test_str_init_from_zstr(void) {
printf("Testing StrInitFromZstr\n");
const char* test_str = "Hello, World!";
- In
Str.Init.c:61
:
const char* test_str = "Hello, World!";
Str s = StrInitFromZstr(test_str);
// Validate the string
- In
Str.Init.c:77
:
printf("Testing StrInitFromStr\n");
Str src = StrInitFromZstr("Hello, World!");
Str dst = StrInitFromStr(&src);
- In
Str.Init.c:96
:
printf("Testing StrDup\n");
Str src = StrInitFromZstr("Hello, World!");
Str dst = StrDup(&src);
- In
Str.Init.c:166
:
printf("Testing StrInitCopy\n");
Str src = StrInitFromZstr("Hello, World!");
Str dst = StrInit();
- In
Str.Init.c:188
:
printf("Testing StrDeinit\n");
Str s = StrInitFromZstr("Hello, World!");
// Validate the string before deinit
- In
Io.Read.c:287
:
StrReadFmt("Hello", "{}", s);
Str expected = StrInitFromZstr("Hello");
success = success && (StrCmp(&s, &expected) == 0);
StrDeinit(&expected);
- In
Io.Read.c:295
:
StrReadFmt("\"Hello, World!\"", "{}", s);
expected = StrInitFromZstr("Hello, World!");
success = success && (StrCmp(&s, &expected) == 0);
StrDeinit(&expected);
- In
Io.Read.c:316
:
success = success && (num == 42);
Str expected = StrInitFromZstr("Alice");
success = success && (StrCmp(&name, &expected) == 0);
StrDeinit(&expected);
- In
Io.Read.c:327
:
success = success && double_equals(val, 3.14);
expected = StrInitFromZstr("Bob");
success = success && (StrCmp(&name, &expected) == 0);
StrDeinit(&expected);
- In
Io.Read.c:505
:
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");
- In
Io.Read.c:516
:
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");
- In
Io.Read.c:548
:
// 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");
- In
Io.Read.c:572
:
// 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");
- In
Io.Read.c:596
:
// 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");
- In
Io.Read.c:620
:
// 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");
- In
Io.Read.c:644
:
// 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");
- In
Str.Ops.c:23
:
printf("Testing StrCmp and StrCmpCstr\n");
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr("Hello");
Str s3 = StrInitFromZstr("World");
- In
Str.Ops.c:24
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr("Hello");
Str s3 = StrInitFromZstr("World");
Str s4 = StrInitFromZstr("Hello World");
- In
Str.Ops.c:25
:
Str s1 = StrInitFromZstr("Hello");
Str s2 = StrInitFromZstr("Hello");
Str s3 = StrInitFromZstr("World");
Str s4 = StrInitFromZstr("Hello World");
- In
Str.Ops.c:26
:
Str s2 = StrInitFromZstr("Hello");
Str s3 = StrInitFromZstr("World");
Str s4 = StrInitFromZstr("Hello World");
// Test StrCmp with equal strings
- In
Str.Ops.c:58
:
printf("Testing StrFindStr, StrFindZstr, and StrFindCstr\n");
Str haystack = StrInitFromZstr("Hello World");
Str needle1 = StrInitFromZstr("World");
Str needle2 = StrInitFromZstr("Hello");
- In
Str.Ops.c:59
:
Str haystack = StrInitFromZstr("Hello World");
Str needle1 = StrInitFromZstr("World");
Str needle2 = StrInitFromZstr("Hello");
Str needle3 = StrInitFromZstr("NotFound");
- In
Str.Ops.c:60
:
Str haystack = StrInitFromZstr("Hello World");
Str needle1 = StrInitFromZstr("World");
Str needle2 = StrInitFromZstr("Hello");
Str needle3 = StrInitFromZstr("NotFound");
- In
Str.Ops.c:61
:
Str needle1 = StrInitFromZstr("World");
Str needle2 = StrInitFromZstr("Hello");
Str needle3 = StrInitFromZstr("NotFound");
// Test StrFindStr with match at end
- In
Str.Ops.c:94
:
printf("Testing StrStartsWith and StrEndsWith variants\n");
Str s = StrInitFromZstr("Hello World");
Str prefix = StrInitFromZstr("Hello");
Str suffix = StrInitFromZstr("World");
- In
Str.Ops.c:95
:
Str s = StrInitFromZstr("Hello World");
Str prefix = StrInitFromZstr("Hello");
Str suffix = StrInitFromZstr("World");
- In
Str.Ops.c:96
:
Str s = StrInitFromZstr("Hello World");
Str prefix = StrInitFromZstr("Hello");
Str suffix = StrInitFromZstr("World");
// Test StrStartsWith
- In
Str.Ops.c:131
:
// Test StrReplaceZstr
Str s1 = StrInitFromZstr("Hello World");
StrReplaceZstr(&s1, "World", "Universe", 1);
bool result = (ZstrCompare(s1.data, "Hello Universe") == 0);
- In
Str.Ops.c:137
:
// Test multiple replacements
StrDeinit(&s1);
s1 = StrInitFromZstr("Hello Hello Hello");
StrReplaceZstr(&s1, "Hello", "Hi", 2);
result = result && (ZstrCompare(s1.data, "Hi Hi Hello") == 0);
- In
Str.Ops.c:143
:
// 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);
- In
Str.Ops.c:149
:
// Test StrReplace
StrDeinit(&s1);
s1 = StrInitFromZstr("Hello World");
Str find = StrInitFromZstr("World");
Str replace = StrInitFromZstr("Universe");
- In
Str.Ops.c:150
:
StrDeinit(&s1);
s1 = StrInitFromZstr("Hello World");
Str find = StrInitFromZstr("World");
Str replace = StrInitFromZstr("Universe");
StrReplace(&s1, &find, &replace, 1);
- In
Str.Ops.c:151
:
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);
- In
Str.Ops.c:166
:
// Test StrSplit
Str s = StrInitFromZstr("Hello,World,Test");
Strs split = StrSplit(&s, ",");
- In
Str.Ops.c:212
:
// Test StrLStrip
Str s1 = StrInitFromZstr(" Hello ");
Str stripped = StrLStrip(&s1, NULL);
bool result = (ZstrCompare(stripped.data, "Hello ") == 0);
- In
Str.Ops.c:229
:
// Test with custom strip characters
StrDeinit(&s1);
s1 = StrInitFromZstr("***Hello***");
stripped = StrLStrip(&s1, "*");