StrReadFmt

Table of Contents

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

NameDirectionDescription
inputinInput string to parse (must be null-terminated).
fmtstrinFormat 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)

    i8 i8_val = 0;
    z         = "-42";
    StrReadFmt(z, "{}", i8_val);
    success = success && (i8_val == -42);
    i16 i16_val = 0;
    z           = "-1234";
    StrReadFmt(z, "{}", i16_val);
    success = success && (i16_val == -1234);
    i32 i32_val = 0;
    z           = "-123456";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == -123456);
    i64 i64_val = 0;
    z           = "-1234567890";
    StrReadFmt(z, "{}", i64_val);
    success = success && (i64_val == -1234567890LL);
    u8 u8_val = 0;
    z         = "42";
    StrReadFmt(z, "{}", u8_val);
    success = success && (u8_val == 42);
    u16 u16_val = 0;
    z           = "1234";
    StrReadFmt(z, "{}", u16_val);
    success = success && (u16_val == 1234);
    u32 u32_val = 0;
    z           = "123456";
    StrReadFmt(z, "{}", u32_val);
    success = success && (u32_val == 123456);
    u64 u64_val = 0;
    z           = "1234567890";
    StrReadFmt(z, "{}", u64_val);
    success = success && (u64_val == 1234567890ULL);
    i8_val = 0;
    z      = "127";
    StrReadFmt(z, "{}", i8_val);
    success = success && (i8_val == 127);
    i8_val = 0;
    z      = "-128";
    StrReadFmt(z, "{}", i8_val);
    success = success && (i8_val == -128);
    u8_val = 0;
    z      = "255";
    StrReadFmt(z, "{}", u8_val);
    success = success && (u8_val == 255);
    u8_val = 0;
    z      = "0";
    StrReadFmt(z, "{}", u8_val);
    success = success && (u8_val == 0);
    i32_val = 0;
    z       = "000042";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == 42);
    i32_val = 0;
    z       = "-000042";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == -42);
    i32_val = 0;
    z       = "   42";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == 42);
    i32_val = 0;
    z       = "42   ";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == 42);
    i32_val = 0;
    z       = "  42  ";
    StrReadFmt(z, "{}", i32_val);
    success = success && (i32_val == 42);
    u32 val = 0;
    z       = "0xdeadbeef";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0xdeadbeef);
    val = 0;
    z   = "0xDEADBEEF";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0xDEADBEEF);
    val = 0;
    z   = "0x0";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0);
    val = 0;
    z   = "0xf";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0xf);
    val = 0;
    z   = "0xaBcDeF";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0xabcdef);
    i8 val = 0;
    z      = "0b101010";
    StrReadFmt(z, "{}", val);
    success = success && (val == 42);
    val = 0;
    z   = "0b0";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0);
    val = 0;
    z   = "0b1";
    StrReadFmt(z, "{}", val);
    success = success && (val == 1);
    i32 val = 0;
    z       = "0o755";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0755);
    val = 0;
    z   = "755";
    StrReadFmt(z, "{}", val);
    success = success && (val == 755);
    val = 0;
    z   = "0o0";
    StrReadFmt(z, "{}", val);
    success = success && (val == 0);
    val = 0;
    z   = "0o7";
    StrReadFmt(z, "{}", val);
    success = success && (val == 7);
    f32 f32_val = 0.0f;
    z           = "3.14159";
    StrReadFmt(z, "{}", f32_val);
    success = success && float_equals(f32_val, 3.14159f);
    f64 f64_val = 0.0;
    z           = "3.14159265359";
    StrReadFmt(z, "{}", f64_val);
    success = success && double_equals(f64_val, 3.14159265359);
    f64_val = 1.0;
    z       = "0.0";
    StrReadFmt(z, "{}", f64_val);
    success = success && double_equals(f64_val, 0.0);
    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
    f64_val = 0.0;
    z       = "42.0";
    StrReadFmt(z, "{}", f64_val);
    success = success && double_equals(f64_val, 42.0);
    f64_val = 0.0;
    z       = "0.42";
    StrReadFmt(z, "{}", f64_val);
    success = success && double_equals(f64_val, 0.42);
    f64 val = 0.0;
    z       = "1.23e4";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 12300.0);
    val = 0.0;
    z   = "1.23E4";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 12300.0);
    val = 0.0;
    z   = "1.23e+4";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 12300.0);
    val = 0.0;
    z   = "1.23e-4";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 0.000123);
    val = 0.0;
    z   = "1.0e0";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 1.0);
    val = 0.0;
    z   = "1.0E-0";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 1.0);
    val = 0.0;
    z   = "1.0e+0";
    StrReadFmt(z, "{}", val);
    success = success && double_equals(val, 1.0);
    Str s = StrInit();
    z     = "Hello";
    StrReadFmt(z, "{}", s);
    
    Str expected = StrInitFromZstr("Hello");
    // Test quoted string reading
    z = "\"Hello, World!\"";
    StrReadFmt(z, "{s}", s);
    
    expected = StrInitFromZstr("Hello, World!");
    Str name = StrInit();
    z        = "Count: 42, Name: Alice";
    StrReadFmt(z, "Count: {}, Name: {}", num, name);
    
    success = success && (num == 42);
    f64 val = 0.0;
    z       = "Value: 3.14, Name: Bob";
    StrReadFmt(z, "Value: {}, Name: {}", val, name);
    
    success = success && double_equals(val, 3.14);
    i32 num = 42;
    z       = "Count: forty-two";
    StrReadFmt(z, "Count: {}", num);
    success = success && (num == 42);
    num = 42;
    z   = "Count: abc";
    StrReadFmt(z, "Count: {}", num);
    success = success && (num == 42);
    i8 small = 42;
    z        = "Value: 1000";
    StrReadFmt(z, "Value: {}", small);
    success = success && (small == 42);
    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');
    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');
    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');
    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');
    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');
    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');
    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');
    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');
    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');
    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");
    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");
    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");
    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");
    u64_val = 0;
    z       = "MNOPQRST";
    StrReadFmt(z, "{c}", u64_val);
    bool u64_multi_pass = (ZstrCompareN((const char *)&u64_val, "MNOPQRST", 8) == 0);
    WriteFmt(
    i64_val = 0;
    z       = "UVWXYZab";
    StrReadFmt(z, "{c}", i64_val);
    bool i64_multi_pass = (ZstrCompareN((const char *)&i64_val, "UVWXYZab", 8) == 0);
    WriteFmt(
    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");
    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");
    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");
    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");
    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");
    Str str_val = StrInit();
    z           = "Hello";
    StrReadFmt(z, "{c}", str_val);
    Str  expected = StrInitFromZstr("Hello");
    bool str_pass = (StrCmp(&str_val, &expected) == 0);
    str_val = StrInit();
    z       = "\"World\"";
    StrReadFmt(z, "{cs}", str_val);
    expected             = StrInitFromZstr("World");
    bool quoted_str_pass = (StrCmp(&str_val, &expected) == 0);
    
    z = in;
    StrReadFmt(z, "{a}", result);
    
    WriteFmt("Test 1 - :a (lowercase)\n");
    
    z = in;
    StrReadFmt(z, "{as}", result);
    
    WriteFmt("Test 1.1 - :as (lowercase string single word)\n");
    
    z = in;
    StrReadFmt(z, "{A}", result);
    
    WriteFmt("Test 2 - :A (uppercase)\n");
    
    z = in;
    StrReadFmt(z, "{A} {A}", result1, result2);
    
    WriteFmt("Test 2 - :A (uppercase with split format)\n");
    
    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
    
    z = in;
    StrReadFmt(z, "{as}", result);
    
    WriteFmt("Test 3 - :a with quoted string\n");
    
    z = in;
    StrReadFmt(z, "{As}", result);
    
    WriteFmt("Test 4 - :A with mixed alphanumeric\n");
    
    z = in;
    StrReadFmt(z, "{c}", result);
    
    WriteFmt("Test 5 - :c (no case conversion)\n");
    BitVec bv1 = BitVecInit();
    z          = "10110";
    StrReadFmt(z, "{}", bv1);
    Str result1 = BitVecToStr(&bv1);
    success     = success && (ZstrCompare(result1.data, "10110") == 0);
    BitVec bv2 = BitVecInit();
    z          = "0xDEAD";
    StrReadFmt(z, "{}", bv2);
    u64 value2 = BitVecToInteger(&bv2);
    success    = success && (value2 == 0xDEAD);
    BitVec bv3 = BitVecInit();
    z          = "0o755";
    StrReadFmt(z, "{}", bv3);
    u64 value3 = BitVecToInteger(&bv3);
    success    = success && (value3 == 0755);
    BitVec bv4 = BitVecInit();
    z          = "   1101";
    StrReadFmt(z, "{}", bv4);
    Str result4 = BitVecToStr(&bv4);
    success     = success && (ZstrCompare(result4.data, "1101") == 0);
    BitVec bv5 = BitVecInit();
    z          = "0";
    StrReadFmt(z, "{}", bv5);
    Str result5 = BitVecToStr(&bv5);
    success     = success && (ZstrCompare(result5.data, "0") == 0);
    if (StrStartsWithZstr(line, "[.") && StrEndsWithZstr(line, "]")) {
    Str rule_name = StrInit();
    StrReadFmt(line->data, "[.{}]", rule_name);
    
    if (rule_name.length) {
    SysProcReadFromStdout((p), &b_);                                                                               \
    const char *in_ = b_.data;                                                                                     \
    StrReadFmt(in_, __VA_ARGS__);                                                                                  \
    StrDeinit(&b_);                                                                                                \
    } while (0)
    SysProcReadFromStderr((p), &b_);                                                                               \
    const char *in_ = b_.data;                                                                                     \
    StrReadFmt(in_, __VA_ARGS__);                                                                                  \
    StrDeinit(&b_);                                                                                                \
    } while (0)

Share :

Related Posts

StrWriteFmtInternal

StrWriteFmtInternal Description Print out a formatted string with rust-style placeholders to given string o.

Read More

FReadFmtInternal

FReadFmtInternal Description Read formatted data from file streams (stdin, or other file)

Read More

LOG_ERROR

LOG_ERROR Description Writes an error-level log message. …[in] : Format string and arguments following printf-style syntax.

Read More