StrReadFmt
- Macro
- October 8, 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.
Info
The new input
value after a successful read will be in [input
, input + len(input)
]
Note
Provided input string must be an assignable l-value. The macro automatically updates given input string to new parse position after a successful parse. If parse fails, the input string pointers does not change.
Warning
Do not free given input after use. Pointer value is changed after successful read. It can be like (input) + 1
or (input + 1233493783847394)
which are invalid pointers to be called FREE
upon. Not providing an assingable input (first parameter) will result in undefined behavior. If you’re lucky you’ll get a segfault.
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 . |
Usage example (from documentation)
struct {i32 id; Str name} ParseInput(const char* i, const char** o) {
const char* p = i; // create a new variable to pass the pointer
i32 id; Str name = StrInit();
StrReadFmt(p, "Person id = {} and name = {}", id, name);
*o = p; // position after parsed input
}
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
Io.Read.c:53
:
i8 i8_val = 0;
z = "-42";
StrReadFmt(z, "{}", i8_val);
success = success && (i8_val == -42);
- In
Io.Read.c:58
:
i16 i16_val = 0;
z = "-1234";
StrReadFmt(z, "{}", i16_val);
success = success && (i16_val == -1234);
- In
Io.Read.c:63
:
i32 i32_val = 0;
z = "-123456";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == -123456);
- In
Io.Read.c:68
:
i64 i64_val = 0;
z = "-1234567890";
StrReadFmt(z, "{}", i64_val);
success = success && (i64_val == -1234567890LL);
- In
Io.Read.c:74
:
u8 u8_val = 0;
z = "42";
StrReadFmt(z, "{}", u8_val);
success = success && (u8_val == 42);
- In
Io.Read.c:79
:
u16 u16_val = 0;
z = "1234";
StrReadFmt(z, "{}", u16_val);
success = success && (u16_val == 1234);
- In
Io.Read.c:84
:
u32 u32_val = 0;
z = "123456";
StrReadFmt(z, "{}", u32_val);
success = success && (u32_val == 123456);
- In
Io.Read.c:89
:
u64 u64_val = 0;
z = "1234567890";
StrReadFmt(z, "{}", u64_val);
success = success && (u64_val == 1234567890ULL);
- In
Io.Read.c:95
:
i8_val = 0;
z = "127";
StrReadFmt(z, "{}", i8_val);
success = success && (i8_val == 127);
- In
Io.Read.c:100
:
i8_val = 0;
z = "-128";
StrReadFmt(z, "{}", i8_val);
success = success && (i8_val == -128);
- In
Io.Read.c:105
:
u8_val = 0;
z = "255";
StrReadFmt(z, "{}", u8_val);
success = success && (u8_val == 255);
- In
Io.Read.c:110
:
u8_val = 0;
z = "0";
StrReadFmt(z, "{}", u8_val);
success = success && (u8_val == 0);
- In
Io.Read.c:116
:
i32_val = 0;
z = "000042";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:121
:
i32_val = 0;
z = "-000042";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == -42);
- In
Io.Read.c:127
:
i32_val = 0;
z = " 42";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:132
:
i32_val = 0;
z = "42 ";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:137
:
i32_val = 0;
z = " 42 ";
StrReadFmt(z, "{}", i32_val);
success = success && (i32_val == 42);
- In
Io.Read.c:153
:
u32 val = 0;
z = "0xdeadbeef";
StrReadFmt(z, "{}", val);
success = success && (val == 0xdeadbeef);
- In
Io.Read.c:158
:
val = 0;
z = "0xDEADBEEF";
StrReadFmt(z, "{}", val);
success = success && (val == 0xDEADBEEF);
- In
Io.Read.c:164
:
val = 0;
z = "0x0";
StrReadFmt(z, "{}", val);
success = success && (val == 0);
- In
Io.Read.c:169
:
val = 0;
z = "0xf";
StrReadFmt(z, "{}", val);
success = success && (val == 0xf);
- In
Io.Read.c:174
:
val = 0;
z = "0xaBcDeF";
StrReadFmt(z, "{}", val);
success = success && (val == 0xabcdef);
- In
Io.Read.c:190
:
i8 val = 0;
z = "0b101010";
StrReadFmt(z, "{}", val);
success = success && (val == 42);
- In
Io.Read.c:196
:
val = 0;
z = "0b0";
StrReadFmt(z, "{}", val);
success = success && (val == 0);
- In
Io.Read.c:201
:
val = 0;
z = "0b1";
StrReadFmt(z, "{}", val);
success = success && (val == 1);
- In
Io.Read.c:217
:
i32 val = 0;
z = "0o755";
StrReadFmt(z, "{}", val);
success = success && (val == 0755);
- In
Io.Read.c:222
:
val = 0;
z = "755";
StrReadFmt(z, "{}", val);
success = success && (val == 755);
- In
Io.Read.c:228
:
val = 0;
z = "0o0";
StrReadFmt(z, "{}", val);
success = success && (val == 0);
- In
Io.Read.c:233
:
val = 0;
z = "0o7";
StrReadFmt(z, "{}", val);
success = success && (val == 7);
- In
Io.Read.c:250
:
f32 f32_val = 0.0f;
z = "3.14159";
StrReadFmt(z, "{}", f32_val);
success = success && float_equals(f32_val, 3.14159f);
- In
Io.Read.c:255
:
f64 f64_val = 0.0;
z = "3.14159265359";
StrReadFmt(z, "{}", f64_val);
success = success && double_equals(f64_val, 3.14159265359);
- In
Io.Read.c:261
:
f64_val = 1.0;
z = "0.0";
StrReadFmt(z, "{}", f64_val);
success = success && double_equals(f64_val, 0.0);
- In
Io.Read.c:266
:
f64_val = 1.0;
z = "-0.0";
StrReadFmt(z, "{}", 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:273
:
f64_val = 0.0;
z = "42.0";
StrReadFmt(z, "{}", f64_val);
success = success && double_equals(f64_val, 42.0);
- In
Io.Read.c:278
:
f64_val = 0.0;
z = "0.42";
StrReadFmt(z, "{}", f64_val);
success = success && double_equals(f64_val, 0.42);
- In
Io.Read.c:294
:
f64 val = 0.0;
z = "1.23e4";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:299
:
val = 0.0;
z = "1.23E4";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:304
:
val = 0.0;
z = "1.23e+4";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 12300.0);
- In
Io.Read.c:309
:
val = 0.0;
z = "1.23e-4";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 0.000123);
- In
Io.Read.c:315
:
val = 0.0;
z = "1.0e0";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:320
:
val = 0.0;
z = "1.0E-0";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:325
:
val = 0.0;
z = "1.0e+0";
StrReadFmt(z, "{}", val);
success = success && double_equals(val, 1.0);
- In
Io.Read.c:342
:
Str s = StrInit();
z = "Hello";
StrReadFmt(z, "{}", s);
Str expected = StrInitFromZstr("Hello");
- In
Io.Read.c:351
:
// Test quoted string reading
z = "\"Hello, World!\"";
StrReadFmt(z, "{s}", s);
expected = StrInitFromZstr("Hello, World!");
- In
Io.Read.c:373
:
Str name = StrInit();
z = "Count: 42, Name: Alice";
StrReadFmt(z, "Count: {}, Name: {}", num, name);
success = success && (num == 42);
- In
Io.Read.c:385
:
f64 val = 0.0;
z = "Value: 3.14, Name: Bob";
StrReadFmt(z, "Value: {}, Name: {}", val, name);
success = success && double_equals(val, 3.14);
- In
Io.Read.c:412
:
i32 num = 42;
z = "Count: forty-two";
StrReadFmt(z, "Count: {}", num);
success = success && (num == 42);
- In
Io.Read.c:418
:
num = 42;
z = "Count: abc";
StrReadFmt(z, "Count: {}", num);
success = success && (num == 42);
- In
Io.Read.c:424
:
i8 small = 42;
z = "Value: 1000";
StrReadFmt(z, "Value: {}", small);
success = success && (small == 42);
- In
Io.Read.c:441
:
u8 u8_val = 0;
z = "A";
StrReadFmt(z, "{c}", u8_val);
WriteFmt("u8_val = {}, expected = {}, pass = {}\n", u8_val, 'A', (u8_val == 'A') ? "true" : "false");
success = success && (u8_val == 'A');
- In
Io.Read.c:447
:
u8_val = 0;
z = "z";
StrReadFmt(z, "{c}", u8_val);
WriteFmt("u8_val = {}, expected = {}, pass = {}\n", u8_val, 'z', (u8_val == 'z') ? "true" : "false");
success = success && (u8_val == 'z');
- In
Io.Read.c:454
:
i8 i8_val = 0;
z = "B";
StrReadFmt(z, "{c}", i8_val);
WriteFmt("i8_val = {}, expected = {}, pass = {}\n", i8_val, 'B', (i8_val == 'B') ? "true" : "false");
success = success && (i8_val == 'B');
- In
Io.Read.c:460
:
i16 i16_val = 0;
z = "C";
StrReadFmt(z, "{c}", i16_val);
WriteFmt("i16_val = {}, expected = {}, pass = {}\n", i16_val, 'C', (i16_val == 'C') ? "true" : "false");
success = success && (i16_val == 'C');
- In
Io.Read.c:466
:
i32 i32_val = 0;
z = "D";
StrReadFmt(z, "{c}", i32_val);
WriteFmt("i32_val = {}, expected = {}, pass = {}\n", i32_val, 'D', (i32_val == 'D') ? "true" : "false");
success = success && (i32_val == 'D');
- In
Io.Read.c:472
:
i64 i64_val = 0;
z = "E";
StrReadFmt(z, "{c}", i64_val);
WriteFmt("i64_val = {}, expected = {}, pass = {}\n", i64_val, 'E', (i64_val == 'E') ? "true" : "false");
success = success && (i64_val == 'E');
- In
Io.Read.c:479
:
u16 u16_val = 0;
z = "F";
StrReadFmt(z, "{c}", u16_val);
WriteFmt("u16_val = {}, expected = {}, pass = {}\n", u16_val, 'F', (u16_val == 'F') ? "true" : "false");
success = success && (u16_val == 'F');
- In
Io.Read.c:485
:
u32 u32_val = 0;
z = "G";
StrReadFmt(z, "{c}", u32_val);
WriteFmt("u32_val = {}, expected = {}, pass = {}\n", u32_val, 'G', (u32_val == 'G') ? "true" : "false");
success = success && (u32_val == 'G');
- In
Io.Read.c:491
:
u64 u64_val = 0;
z = "H";
StrReadFmt(z, "{c}", u64_val);
WriteFmt("u64_val = {}, expected = {}, pass = {}\n", u64_val, 'H', (u64_val == 'H') ? "true" : "false");
success = success && (u64_val == 'H');
- In
Io.Read.c:498
:
u16_val = 0;
z = "AB";
StrReadFmt(z, "{c}", u16_val);
bool u16_multi_pass = (ZstrCompareN((const char *)&u16_val, "AB", 2) == 0);
WriteFmt("u16_val multi-char test: comparing memory with 'AB', pass = {}\n", u16_multi_pass ? "true" : "false");
- In
Io.Read.c:512
:
i16_val = 0;
z = "CD";
StrReadFmt(z, "{c}", i16_val);
bool i16_multi_pass = (ZstrCompareN((const char *)&i16_val, "CD", 2) == 0);
WriteFmt("i16_val multi-char test: comparing memory with 'CD', pass = {}\n", i16_multi_pass ? "true" : "false");
- In
Io.Read.c:519
:
u32_val = 0;
z = "EFGH";
StrReadFmt(z, "{c}", u32_val);
bool u32_multi_pass = (ZstrCompareN((const char *)&u32_val, "EFGH", 4) == 0);
WriteFmt("u32_val multi-char test: comparing memory with 'EFGH', pass = {}\n", u32_multi_pass ? "true" : "false");
- In
Io.Read.c:526
:
i32_val = 0;
z = "IJKL";
StrReadFmt(z, "{c}", i32_val);
bool i32_multi_pass = (ZstrCompareN((const char *)&i32_val, "IJKL", 4) == 0);
WriteFmt("i32_val multi-char test: comparing memory with 'IJKL', pass = {}\n", i32_multi_pass ? "true" : "false");
- In
Io.Read.c:533
:
u64_val = 0;
z = "MNOPQRST";
StrReadFmt(z, "{c}", u64_val);
bool u64_multi_pass = (ZstrCompareN((const char *)&u64_val, "MNOPQRST", 8) == 0);
WriteFmt(
- In
Io.Read.c:543
:
i64_val = 0;
z = "UVWXYZab";
StrReadFmt(z, "{c}", i64_val);
bool i64_multi_pass = (ZstrCompareN((const char *)&i64_val, "UVWXYZab", 8) == 0);
WriteFmt(
- In
Io.Read.c:553
:
f32 f32_val = 0.0f;
z = "A";
StrReadFmt(z, "{c}", f32_val);
bool f32_pass = (f32_val == (f32)'A');
WriteFmt("f32_val = {}, expected = {}, pass = {}\n", f32_val, (f32)'A', f32_pass ? "true" : "false");
- In
Io.Read.c:560
:
f64 f64_val = 0.0;
z = "B";
StrReadFmt(z, "{c}", f64_val);
bool f64_pass = (f64_val == (f64)'B');
WriteFmt("f64_val = {}, expected = {}, pass = {}\n", f64_val, (f64)'B', f64_pass ? "true" : "false");
- In
Io.Read.c:567
:
u8_val = 0;
z = "~";
StrReadFmt(z, "{c}", u8_val);
bool tilde_pass = (u8_val == '~');
WriteFmt("u8_val = {}, expected = {} (~), pass = {}\n", u8_val, '~', tilde_pass ? "true" : "false");
- In
Io.Read.c:574
:
u32_val = 0;
z = "XY";
StrReadFmt(z, "{c}", u32_val);
bool xy_pass = (ZstrCompareN((const char *)&u32_val, "XY", 2) == 0);
WriteFmt("u32_val partial test: comparing memory with 'XY', pass = {}\n", xy_pass ? "true" : "false");
- In
Io.Read.c:581
:
u64_val = 0;
z = "abc";
StrReadFmt(z, "{c}", u64_val);
bool abc_pass = (ZstrCompareN((const char *)&u64_val, "abc", 3) == 0);
WriteFmt("u64_val partial test: comparing memory with 'abc', pass = {}\n", abc_pass ? "true" : "false");
- In
Io.Read.c:588
:
Str str_val = StrInit();
z = "Hello";
StrReadFmt(z, "{c}", str_val);
Str expected = StrInitFromZstr("Hello");
bool str_pass = (StrCmp(&str_val, &expected) == 0);
- In
Io.Read.c:598
:
str_val = StrInit();
z = "\"World\"";
StrReadFmt(z, "{cs}", str_val);
expected = StrInitFromZstr("World");
bool quoted_str_pass = (StrCmp(&str_val, &expected) == 0);
- In
Io.Read.c:624
:
z = in;
StrReadFmt(z, "{a}", result);
WriteFmt("Test 1 - :a (lowercase)\n");
- In
Io.Read.c:649
:
z = in;
StrReadFmt(z, "{as}", result);
WriteFmt("Test 1.1 - :as (lowercase string single word)\n");
- In
Io.Read.c:674
:
z = in;
StrReadFmt(z, "{A}", result);
WriteFmt("Test 2 - :A (uppercase)\n");
- In
Io.Read.c:700
:
z = in;
StrReadFmt(z, "{A} {A}", result1, result2);
WriteFmt("Test 2 - :A (uppercase with split format)\n");
- In
Io.Read.c:721
:
z = in;
StrReadFmt(z, "{As}{A}", result1, result2);
// result1 must consume first word only
// result2 must consume the space after hello and then everything after it
- In
Io.Read.c:743
:
z = in;
StrReadFmt(z, "{as}", result);
WriteFmt("Test 3 - :a with quoted string\n");
- In
Io.Read.c:768
:
z = in;
StrReadFmt(z, "{As}", result);
WriteFmt("Test 4 - :A with mixed alphanumeric\n");
- In
Io.Read.c:793
:
z = in;
StrReadFmt(z, "{c}", result);
WriteFmt("Test 5 - :c (no case conversion)\n");
- In
Io.Read.c:827
:
BitVec bv1 = BitVecInit();
z = "10110";
StrReadFmt(z, "{}", bv1);
Str result1 = BitVecToStr(&bv1);
success = success && (ZstrCompare(result1.data, "10110") == 0);
- In
Io.Read.c:841
:
BitVec bv2 = BitVecInit();
z = "0xDEAD";
StrReadFmt(z, "{}", bv2);
u64 value2 = BitVecToInteger(&bv2);
success = success && (value2 == 0xDEAD);
- In
Io.Read.c:850
:
BitVec bv3 = BitVecInit();
z = "0o755";
StrReadFmt(z, "{}", bv3);
u64 value3 = BitVecToInteger(&bv3);
success = success && (value3 == 0755);
- In
Io.Read.c:859
:
BitVec bv4 = BitVecInit();
z = " 1101";
StrReadFmt(z, "{}", bv4);
Str result4 = BitVecToStr(&bv4);
success = success && (ZstrCompare(result4.data, "1101") == 0);
- In
Io.Read.c:873
:
BitVec bv5 = BitVecInit();
z = "0";
StrReadFmt(z, "{}", bv5);
Str result5 = BitVecToStr(&bv5);
success = success && (ZstrCompare(result5.data, "0") == 0);
- In
Main.c:12
:
if (StrStartsWithZstr(line, "[.") && StrEndsWithZstr(line, "]")) {
Str rule_name = StrInit();
StrReadFmt(line->data, "[.{}]", rule_name);
if (rule_name.length) {
- In
Proc.h:168
:
SysProcReadFromStdout((p), &b_); \
const char *in_ = b_.data; \
StrReadFmt(in_, __VA_ARGS__); \
StrDeinit(&b_); \
} while (0)
- In
Proc.h:177
:
SysProcReadFromStderr((p), &b_); \
const char *in_ = b_.data; \
StrReadFmt(in_, __VA_ARGS__); \
StrDeinit(&b_); \
} while (0)