diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2023-06-06 11:56:21 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2023-06-06 11:56:21 +0200 |
commit | e5a1983e4384a44e45486fb9a48bdba375a529b6 (patch) | |
tree | 6e84d9e43245b2d2c6aa2a6312b6281d744a7d24 /cooker/match.c | |
parent | 9c371d77e843163261d28e374f4ea7dab2e3f64d (diff) | |
download | seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar.gz seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar.bz2 seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar.lz seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar.xz seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.tar.zst seitan-e5a1983e4384a44e45486fb9a48bdba375a529b6.zip |
cooker: Draft quality: mknod/mknodat, sets of values with "in"
While at it:
- directly assign 'fd' in eater from install_filter()
- turn op_cmp into a description-style thing
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'cooker/match.c')
-rw-r--r-- | cooker/match.c | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/cooker/match.c b/cooker/match.c index c53a456..e9aed16 100644 --- a/cooker/match.c +++ b/cooker/match.c @@ -75,13 +75,15 @@ static struct gluten_offset arg_load(struct gluten_ctx *g, struct arg *a) */ static union value parse_field(struct gluten_ctx *g, struct gluten_offset offset, + enum op_cmp_type cmp, enum jump_type jump, int index, struct field *f, JSON_Value *jvalue) { - struct gluten_offset const_offset; + struct gluten_offset const_offset, mask_offset, data_offset; union value v = { .v_num = 0 }; struct field *f_inner; const char *tag_name; JSON_Object *tmp; + JSON_Array *set; JSON_Value *sel; if (f->name) @@ -96,6 +98,30 @@ static union value parse_field(struct gluten_ctx *g, jvalue = json_object_get_value(tmp, "value"); } + if (json_value_get_type(jvalue) == JSONObject && + (tmp = json_value_get_object(jvalue)) && + (set = json_object_get_array(tmp, "in"))) { + unsigned i, count = json_array_get_count(set); + + if (cmp != CMP_NE || jump != JUMP_NEXT_BLOCK) + die("unsupported nested set"); + + for (i = 0; i < count; i++) { + if (i == count - 1) { + cmp = CMP_NE; + jump = JUMP_NEXT_BLOCK; + } else { + cmp = CMP_EQ; + jump = JUMP_NEXT_ACTION; + } + + jvalue = json_array_get_value(set, i); + parse_field(g, offset, cmp, jump, index, f, jvalue); + } + + return v; /* No SELECT based on sets... of course */ + } + /* Nothing to match on: just store as reference */ if (!jvalue) return v; @@ -115,11 +141,41 @@ static union value parse_field(struct gluten_ctx *g, /* calculate mask first */ ; } - + /* Falls through */ v.v_num = value_get_num(f->desc.d_num, jvalue); const_offset = emit_data(g, f->type, 0, &v); - emit_cmp(g, CMP_NE, offset, const_offset, gluten_size[f->type], - JUMP_NEXT_BLOCK); + emit_cmp(g, cmp, offset, const_offset, gluten_size[f->type], + jump); + break; + case GNU_DEV_MAJOR: + /* +xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx +______________________ _____________ + */ + v.v_num = ((long long)0xfff << 44) | (0xfff << 8); + mask_offset = emit_data(g, U64, 0, &v); + + v.v_num = value_get_num(f->desc.d_num, jvalue); + v.v_num = (v.v_num & 0xfff) << 8 | (v.v_num & ~0xfff) << 32; + const_offset = emit_data(g, U64, 0, &v); + + data_offset = emit_mask(g, U64, offset, mask_offset); + emit_cmp_field(g, cmp, f, data_offset, const_offset, jump); + break; + case GNU_DEV_MINOR: + /* +xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + ____________________________ ________ + */ + v.v_num = 0xff | ((long long)0xffffff << 12); + mask_offset = emit_data(g, U64, 0, &v); + + v.v_num = value_get_num(f->desc.d_num, jvalue); + v.v_num = (v.v_num & 0xff) | (v.v_num & ~0xfff) << 12; + const_offset = emit_data(g, U64, 0, &v); + + data_offset = emit_mask(g, U64, offset, mask_offset); + emit_cmp_field(g, cmp, f, data_offset, const_offset, jump); break; case SELECT: f_inner = f->desc.d_select->field; @@ -131,11 +187,11 @@ static union value parse_field(struct gluten_ctx *g, sel = jvalue; } - v = parse_field(g, offset, index, f_inner, sel); + v = parse_field(g, offset, cmp, jump, index, f_inner, sel); f = select_field(g, index, f->desc.d_select, v); if (f) - parse_field(g, offset, index, f, jvalue); + parse_field(g, offset, cmp, jump, index, f, jvalue); break; case STRING: v.v_str = json_value_get_string(jvalue); @@ -155,7 +211,8 @@ static union value parse_field(struct gluten_ctx *g, if (!field_value) continue; - parse_field(g, offset, index, f_inner, field_value); + parse_field(g, offset, cmp, jump, index, f_inner, + field_value); } break; default: @@ -179,7 +236,7 @@ static void parse_arg(struct gluten_ctx *g, JSON_Value *jvalue, struct arg *a) offset = arg_load(g, a); - parse_field(g, offset, a->pos, &a->f, jvalue); + parse_field(g, offset, CMP_NE, JUMP_NEXT_BLOCK, a->pos, &a->f, jvalue); } /** |