END_TEST #define make_str(x) #x START_TEST(Reading_invalid_piref_fails) { const char* data[] = { "0, 0]", "[0 0]", "[0, 0", "[0, -1]", "[-1, 0]", "[0, " make_str(KQT_PAT_INSTANCES_MAX) "]", "[" make_str(KQT_PATTERNS_MAX) ", 0]", }; for (size_t i = 0; i < arr_size(data); ++i) { Streader* sr = init_with_cstr(data[i]); Pat_inst_ref* result = PAT_INST_REF_AUTO; fail_if(Streader_read_piref(sr, result), "Streader accepted `%s` as a valid pattern instance reference", data[i]); } }
END_TEST START_TEST(Read_valid_piref) { static const struct { const char* data; const Pat_inst_ref expected; } pirefs[] = { { "[0, 0]", { 0, 0 } }, { "[2,5]", { 2, 5 } }, { " [2,5]", { 2, 5 } }, { "[ 2,5]", { 2, 5 } }, { "[2 ,5]", { 2, 5 } }, { "[2, 5]", { 2, 5 } }, { "[2,5 ]", { 2, 5 } }, { "[0, 1023]", { 0, KQT_PAT_INSTANCES_MAX - 1 } }, { "[1023, 0]", { KQT_PATTERNS_MAX - 1, 0 } }, { "[1023, 1023]", { KQT_PATTERNS_MAX - 1, KQT_PAT_INSTANCES_MAX - 1 } }, }; for (size_t i = 0; i < arr_size(pirefs); ++i) { char data[128] = ""; sprintf(data, "%s x", pirefs[i].data); Streader* sr = init_with_cstr(data); Pat_inst_ref* result = PAT_INST_REF_AUTO; fail_if(!Streader_read_piref(sr, result), "Could not read pattern instance refernce " PRIpi " from `%s`: %s", PRIVALpi(pirefs[i].expected), data, Streader_get_error_desc(sr)); fail_if(Pat_inst_ref_cmp(result, &pirefs[i].expected) != 0, "Streader stored " PRIpi " instead of " PRIpi " when reading `%s`", PRIVALpi(*result), PRIVALpi(pirefs[i].expected), data); fail_if(!Streader_match_char(sr, 'x'), "Streader did not consume pattern instance from `%s` correctly", data); } }
static bool read_piref(Streader* sr, int32_t index, void* userdata) { rassert(sr != NULL); rassert(userdata != NULL); Order_list* ol = userdata; // Read the Pattern instance reference Pat_inst_ref* p = PAT_INST_REF_AUTO; if (!Streader_read_piref(sr, p)) return false; // Check if the Pattern instance is already used Index_mapping* key = INDEX_MAPPING_AUTO; key->p = *p; key->ol_index = index; if (AAtree_contains(ol->index_map, key)) { Streader_set_error( sr, "Duplicate occurrence of pattern instance" " [%" PRId16 ", %" PRId16 "]", p->pat, p->inst); return false; } // Add the reference to our containers if (!Vector_append(ol->pat_insts, p)) { Streader_set_memory_error( sr, "Could not allocate memory for order list"); return false; } Index_mapping* im = new_Index_mapping(key); if (im == NULL || !AAtree_ins(ol->index_map, im)) { memory_free(im); Streader_set_memory_error( sr, "Could not allocate memory for order list"); return false; } return true; }
bool Streader_readf(Streader* sr, const char* format, ...) { rassert(sr != NULL); rassert(format != NULL); va_list args; va_start(args, format); while (!Streader_is_error_set(sr) && *format != '\0') { if (*format == '%') { // Conversion characters ++format; switch (*format) { case 'n': { Streader_read_null(sr); } break; case 'b': { bool* dest = va_arg(args, bool*); Streader_read_bool(sr, dest); } break; case 'i': { int64_t* dest = va_arg(args, int64_t*); Streader_read_int(sr, dest); } break; case 'f': { double* dest = va_arg(args, double*); Streader_read_float(sr, dest); } break; case 's': { Streader_readf_str_info info = va_arg(args, Streader_readf_str_info); rassert(info.guard == Streader_readf_str_guard); const int64_t max_bytes = info.max_bytes; char* dest = info.dest; Streader_read_string(sr, max_bytes, dest); } break; case 't': { Tstamp* dest = va_arg(args, Tstamp*); Streader_read_tstamp(sr, dest); } break; case 'p': { Pat_inst_ref* dest = va_arg(args, Pat_inst_ref*); Streader_read_piref(sr, dest); } break; case 'l': { List_item_reader* ir = va_arg(args, List_item_reader*); void* userdata = va_arg(args, void*); Streader_read_list(sr, ir, userdata); } break; case 'd': { Dict_item_reader* ir = va_arg(args, Dict_item_reader*); void* userdata = va_arg(args, void*); Streader_read_dict(sr, ir, userdata); } break; case '%': { Streader_match_char(sr, '%'); } break; default: rassert(false); } } else { // Characters to be matched if (!isspace(*format))