StrReadFmt
- Macro
- August 22, 2025
Table of Contents
StrReadFmt
StrReadFmt
Description
Parse input string according to format string with rust-style placeholders, extracting values into provided arguments. This is a macro wrapper around StrReadFmtInternal.
Parameters
Name | Direction | Description |
---|---|---|
input | in | Input string to parse (must be null-terminated). |
fmtstr | in | Format string with {} placeholders (must be null-terminated). argument should be a modifiable l-value wrapped with &variable . |
Success
Returns a const char*
pointing to the beginning of the unparsed portion of the input
string after successful parsing.
Failure
Failure occurs within StrReadFmtInternal
. Refer to its documentation for details on failure behavior (typically logs error messages and does not return).
Usage example (Cross-references)
- In
Main.c:12
:
if (StrStartsWithZstr(line, "[.") && StrEndsWithZstr(line, "]")) {
Str rule_name = StrInit();
StrReadFmt(line->data, "[.{}]", rule_name);
if (rule_name.length) {
- In
Io.Read.c:50
:
// Test signed integers
i8 i8_val = 0;
StrReadFmt("-42", "{}", i8_val);
success = success && (i8_val == -42);
- In
Io.Read.c:54
:
i16 i16_val = 0;
StrReadFmt("-1234", "{}", i16_val);
success = success && (i16_val == -1234);
- In
Io.Read.c:58
:
i32 i32_val = 0;
StrReadFmt("-123456", "{}", i32_val);
success = success && (i32_val == -123456);
- In
Io.Read.c:62
:
i64 i64_val = 0;
StrReadFmt("-1234567890", "{}", i64_val);
success = success && (i64_val == -1234567890LL);
- In
Io.Read.c:67
:
// Test unsigned integers
u8 u8_val = 0;
StrReadFmt("42", "{}", u8_val);
success = success && (u8_val == 42);
- In
Io.Read.c:71
:
u16 u16_val = 0;
StrReadFmt("1234", "{}", u16_val);
success = success && (u16_val == 1234);
- In
Io.Read.c:75
:
u32 u32_val = 0;
StrReadFmt("123456", "{}", u32_val);
success = success && (u32_val == 123456);
- In
Io.Read.c:79
:
u64 u64_val = 0;
StrReadFmt("1234567890", "{}", u64_val);
success = success && (u64_val == 1234567890ULL);
- In
Io.Read.c:84
:
// Test edge cases
i8_val = 0;
StrReadFmt("127", "{}", i8_val);
success = success && (i8_val == 127);
- In
Io.Read.c:88
:
i8_val = 0;
StrReadFmt("-128", "{}", i8_val);
success = success && (i8_val == -128);
- In
Io.Read.c:92
:
u8_val = 0;
StrReadFmt("255", "{}", u8_val);
success = success && (u8_val == 255);
- In
Io.Read.c:96
:
u8_val = 0;
StrReadFmt("0", "{}", u8_val);
success = success && (u8_val == 0);
- In
Io.Read.c:101
:
// Test leading zeros
i32_val = 0;
StrReadFmt("000042", "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:105
:
i32_val = 0;
StrReadFmt("-000042", "{}", i32_val);
success = success && (i32_val == -42);
- In
Io.Read.c:110
:
// Test whitespace handling
i32_val = 0;
StrReadFmt(" 42", "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:114
:
i32_val = 0;
StrReadFmt("42 ", "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:118
:
i32_val = 0;
StrReadFmt(" 42 ", "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:131
:
u32 val = 0;
StrReadFmt("0xdeadbeef", "{}", val);
success = success && (val == 0xdeadbeef);
- In
Io.Read.c:135
:
val = 0;
StrReadFmt("0xDEADBEEF", "{}", val);
success = success && (val == 0xDEADBEEF);
- In
Io.Read.c:140
:
// Test hex edge cases
val = 0;
StrReadFmt("0x0", "{}", val);
success = success && (val == 0);
- In
Io.Read.c:144
:
val = 0;
StrReadFmt("0xf", "{}", val);
success = success && (val == 0xf);
- In
Io.Read.c:148
:
val = 0;
StrReadFmt("0xaBcDeF", "{}", val);
success = success && (val == 0xabcdef);
- In
Io.Read.c:161
:
i8 val = 0;
StrReadFmt("0b101010", "{}", val);
success = success && (val == 42);
- In
Io.Read.c:166
:
// Test binary edge cases
val = 0;
StrReadFmt("0b0", "{}", val);
success = success && (val == 0);
- In
Io.Read.c:170
:
val = 0;
StrReadFmt("0b1", "{}", val);
success = success && (val == 1);
- In
Io.Read.c:183
:
i32 val = 0;
StrReadFmt("0o755", "{}", val);
success = success && (val == 0755);
- In
Io.Read.c:187
:
val = 0;
StrReadFmt("755", "{}", val);
success = success && (val == 755);
- In
Io.Read.c:192
:
// Test octal edge cases
val = 0;
StrReadFmt("0o0", "{}", val);
success = success && (val == 0);
- In
Io.Read.c:196
:
val = 0;
StrReadFmt("0o7", "{}", val);
success = success && (val == 7);
- In
Io.Read.c:210
:
// Test basic float values
f32 f32_val = 0.0f;
StrReadFmt("3.14159", "{}", f32_val);
success = success && float_equals(f32_val, 3.14159f);
- In
Io.Read.c:214
:
f64 f64_val = 0.0;
StrReadFmt("3.14159265359", "{}", f64_val);
success = success && double_equals(f64_val, 3.14159265359);
- In
Io.Read.c:219
:
// Test float edge cases
f64_val = 1.0;
StrReadFmt("0.0", "{}", f64_val);
success = success && double_equals(f64_val, 0.0);
- In
Io.Read.c:223
:
f64_val = 1.0;
StrReadFmt("-0.0", "{}", f64_val);
// Special case for -0.0 which compares equal to 0.0 but has different bit pattern
// We'll just check if it's close to zero
- In
Io.Read.c:229
:
f64_val = 0.0;
StrReadFmt("42.0", "{}", f64_val);
success = success && double_equals(f64_val, 42.0);
- In
Io.Read.c:233
:
f64_val = 0.0;
StrReadFmt("0.42", "{}", f64_val);
success = success && double_equals(f64_val, 0.42);
- In
Io.Read.c:246
:
f64 val = 0.0;
StrReadFmt("1.23e4", "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:250
:
val = 0.0;
StrReadFmt("1.23E4", "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:254
:
val = 0.0;
StrReadFmt("1.23e+4", "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:258
:
val = 0.0;
StrReadFmt("1.23e-4", "{}", val);
success = success && double_equals(val, 0.000123);
- In
Io.Read.c:263
:
// Test scientific notation edge cases
val = 0.0;
StrReadFmt("1.0e0", "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:267
:
val = 0.0;
StrReadFmt("1.0E-0", "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:271
:
val = 0.0;
StrReadFmt("1.0e+0", "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:285
:
// Test basic string reading
Str s = StrInit();
StrReadFmt("Hello", "{}", s);
Str expected = StrInitFromZstr("Hello");
- In
Io.Read.c:293
:
// Test quoted string reading
StrReadFmt("\"Hello, World!\"", "{}", s);
expected = StrInitFromZstr("Hello, World!");
- In
Io.Read.c:312
:
i32 num = 0;
Str name = StrInit();
StrReadFmt("Count: 42, Name: Alice", "Count: {}, Name: {}", num, name);
success = success && (num == 42);
- In
Io.Read.c:323
:
// Test with different order
f64 val = 0.0;
StrReadFmt("Value: 3.14, Name: Bob", "Value: {}, Name: {}", val, name);
success = success && double_equals(val, 3.14);
- In
Io.Read.c:347
:
// Test mismatched format
i32 num = 42;
StrReadFmt("Count: forty-two", "Count: {}", num);
// The value should remain unchanged since the parsing should fail
success = success && (num == 42);
- In
Io.Read.c:353
:
// Test invalid integer
num = 42;
StrReadFmt("Count: abc", "Count: {}", num);
success = success && (num == 42);
- In
Io.Read.c:358
:
// Test overflow
i8 small = 42;
StrReadFmt("Value: 1000", "Value: {}", small);
success = success && (small == 42);
- In
Io.Read.c:372
:
// Test reading single character into u8
u8 u8_val = 0;
StrReadFmt("A", "{c}", u8_val);
printf("u8_val = %d, expected = %d, pass = %s\n", u8_val, 'A', (u8_val == 'A') ? "true" : "false");
success = success && (u8_val == 'A');
- In
Io.Read.c:377
:
u8_val = 0;
StrReadFmt("z", "{c}", u8_val);
printf("u8_val = %d, expected = %d, pass = %s\n", u8_val, 'z', (u8_val == 'z') ? "true" : "false");
success = success && (u8_val == 'z');
- In
Io.Read.c:383
:
// Test reading single character into signed integers
i8 i8_val = 0;
StrReadFmt("B", "{c}", i8_val);
printf("i8_val = %d, expected = %d, pass = %s\n", i8_val, 'B', (i8_val == 'B') ? "true" : "false");
success = success && (i8_val == 'B');
- In
Io.Read.c:388
:
i16 i16_val = 0;
StrReadFmt("C", "{c}", i16_val);
printf("i16_val = %d, expected = %d, pass = %s\n", i16_val, 'C', (i16_val == 'C') ? "true" : "false");
success = success && (i16_val == 'C');
- In
Io.Read.c:393
:
i32 i32_val = 0;
StrReadFmt("D", "{c}", i32_val);
printf("i32_val = %d, expected = %d, pass = %s\n", i32_val, 'D', (i32_val == 'D') ? "true" : "false");
success = success && (i32_val == 'D');
- In
Io.Read.c:398
:
i64 i64_val = 0;
StrReadFmt("E", "{c}", i64_val);
printf("i64_val = %lld, expected = %d, pass = %s\n", i64_val, 'E', (i64_val == 'E') ? "true" : "false");
success = success && (i64_val == 'E');
- In
Io.Read.c:404
:
// Test reading single character into unsigned integers
u16 u16_val = 0;
StrReadFmt("F", "{c}", u16_val);
printf("u16_val = %d, expected = %d, pass = %s\n", u16_val, 'F', (u16_val == 'F') ? "true" : "false");
success = success && (u16_val == 'F');
- In
Io.Read.c:409
:
u32 u32_val = 0;
StrReadFmt("G", "{c}", u32_val);
printf("u32_val = %d, expected = %d, pass = %s\n", u32_val, 'G', (u32_val == 'G') ? "true" : "false");
success = success && (u32_val == 'G');
- In
Io.Read.c:414
:
u64 u64_val = 0;
StrReadFmt("H", "{c}", u64_val);
printf("u64_val = %llu, expected = %d, pass = %s\n", u64_val, 'H', (u64_val == 'H') ? "true" : "false");
success = success && (u64_val == 'H');
- In
Io.Read.c:421
:
// For u16, read 2 characters
u16_val = 0;
StrReadFmt("AB", "{c}", u16_val);
bool u16_multi_pass = (ZstrCompareN((const char*)&u16_val, "AB", 2) == 0);
printf("u16_val multi-char test: comparing memory with 'AB', pass = %s\n", u16_multi_pass ? "true" : "false");
- In
Io.Read.c:435
:
// For i16, read 2 characters
i16_val = 0;
StrReadFmt("CD", "{c}", i16_val);
bool i16_multi_pass = (ZstrCompareN((const char*)&i16_val, "CD", 2) == 0);
printf("i16_val multi-char test: comparing memory with 'CD', pass = %s\n", i16_multi_pass ? "true" : "false");
- In
Io.Read.c:442
:
// For u32, read up to 4 characters
u32_val = 0;
StrReadFmt("EFGH", "{c}", u32_val);
bool u32_multi_pass = (ZstrCompareN((const char*)&u32_val, "EFGH", 4) == 0);
printf("u32_val multi-char test: comparing memory with 'EFGH', pass = %s\n", u32_multi_pass ? "true" : "false");
- In
Io.Read.c:449
:
// For i32, read up to 4 characters
i32_val = 0;
StrReadFmt("IJKL", "{c}", i32_val);
bool i32_multi_pass = (ZstrCompareN((const char*)&i32_val, "IJKL", 4) == 0);
printf("i32_val multi-char test: comparing memory with 'IJKL', pass = %s\n", i32_multi_pass ? "true" : "false");
- In
Io.Read.c:456
:
// For u64, read up to 8 characters
u64_val = 0;
StrReadFmt("MNOPQRST", "{c}", u64_val);
bool u64_multi_pass = (ZstrCompareN((const char*)&u64_val, "MNOPQRST", 8) == 0);
printf("u64_val multi-char test: comparing memory with 'MNOPQRST', pass = %s\n", u64_multi_pass ? "true" : "false");
- In
Io.Read.c:463
:
// For i64, read up to 8 characters
i64_val = 0;
StrReadFmt("UVWXYZab", "{c}", i64_val);
bool i64_multi_pass = (ZstrCompareN((const char*)&i64_val, "UVWXYZab", 8) == 0);
printf("i64_val multi-char test: comparing memory with 'UVWXYZab', pass = %s\n", i64_multi_pass ? "true" : "false");
- In
Io.Read.c:470
:
// Test reading characters into float types (should interpret as character ordinals)
f32 f32_val = 0.0f;
StrReadFmt("A", "{c}", f32_val);
bool f32_pass = (f32_val == (f32)'A');
printf("f32_val = %f, expected = %f, pass = %s\n", f32_val, (f32)'A', f32_pass ? "true" : "false");
- In
Io.Read.c:476
:
f64 f64_val = 0.0;
StrReadFmt("B", "{c}", f64_val);
bool f64_pass = (f64_val == (f64)'B');
printf("f64_val = %f, expected = %f, pass = %s\n", f64_val, (f64)'B', f64_pass ? "true" : "false");
- In
Io.Read.c:483
:
// Test with high ASCII characters
u8_val = 0;
StrReadFmt("~", "{c}", u8_val);
bool tilde_pass = (u8_val == '~');
printf("u8_val = %d, expected = %d (~), pass = %s\n", u8_val, '~', tilde_pass ? "true" : "false");
- In
Io.Read.c:490
:
// Test partial reads for larger types with fewer characters
u32_val = 0;
StrReadFmt("XY", "{c}", u32_val);
bool xy_pass = (ZstrCompareN((const char*)&u32_val, "XY", 2) == 0);
printf("u32_val partial test: comparing memory with 'XY', pass = %s\n", xy_pass ? "true" : "false");
- In
Io.Read.c:496
:
u64_val = 0;
StrReadFmt("abc", "{c}", u64_val);
bool abc_pass = (ZstrCompareN((const char*)&u64_val, "abc", 3) == 0);
printf("u64_val partial test: comparing memory with 'abc', pass = %s\n", abc_pass ? "true" : "false");
- In
Io.Read.c:503
:
// Test that :c has no effect on string types (should work like regular string reading)
Str str_val = StrInit();
StrReadFmt("Hello", "{c}", str_val);
Str expected = StrInitFromZstr("Hello");
- In
Io.Read.c:514
:
// Test :c with quoted strings (should work like regular string reading)
str_val = StrInit();
StrReadFmt("\"World\"", "{c}", str_val);
expected = StrInitFromZstr("World");
- In
Io.Read.c:538
:
const char* input = "Hello World";
StrReadFmt(input, "{a}", result);
printf("Test 1 - :a (lowercase)\n");
- In
Io.Read.c:562
:
const char* input = "hello world";
StrReadFmt(input, "{A}", result);
printf("Test 2 - :A (uppercase)\n");
- In
Io.Read.c:586
:
const char* input = "\"MiXeD CaSe\"";
StrReadFmt(input, "{a}", result);
printf("Test 3 - :a with quoted string\n");
- In
Io.Read.c:610
:
const char* input = "\"abc123XYZ\"";
StrReadFmt(input, "{A}", result);
printf("Test 4 - :A with mixed alphanumeric\n");
- In
Io.Read.c:634
:
const char* input = "Hello World";
StrReadFmt(input, "{c}", result);
printf("Test 5 - :c (no case conversion)\n");
- In
Io.Read.c:665
:
// Test 1: Reading binary string
BitVec bv1 = BitVecInit();
StrReadFmt("10110", "{}", bv1);
Str result1 = BitVecToStr(&bv1);
success = success && (ZstrCompare(result1.data, "10110") == 0);
- In
Io.Read.c:679
:
// Test 2: Reading hex format
BitVec bv2 = BitVecInit();
StrReadFmt("0xDEAD", "{}", bv2);
u64 value2 = BitVecToInteger(&bv2);
success = success && (value2 == 0xDEAD);
- In
Io.Read.c:687
:
// Test 3: Reading octal format
BitVec bv3 = BitVecInit();
StrReadFmt("0o755", "{}", bv3);
u64 value3 = BitVecToInteger(&bv3);
success = success && (value3 == 0755);
- In
Io.Read.c:695
:
// Test 4: Reading with whitespace
BitVec bv4 = BitVecInit();
StrReadFmt(" 1101", "{}", bv4);
Str result4 = BitVecToStr(&bv4);
success = success && (ZstrCompare(result4.data, "1101") == 0);
- In
Io.Read.c:709
:
// Test 5: Reading zero values
BitVec bv5 = BitVecInit();
StrReadFmt("0", "{}", bv5);
Str result5 = BitVecToStr(&bv5);
success = success && (ZstrCompare(result5.data, "0") == 0);