aboutgitcodelistschat:MatrixIRC
path: root/cooker/match.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2023-06-06 11:56:21 +0200
committerStefano Brivio <sbrivio@redhat.com>2023-06-06 11:56:21 +0200
commite5a1983e4384a44e45486fb9a48bdba375a529b6 (patch)
tree6e84d9e43245b2d2c6aa2a6312b6281d744a7d24 /cooker/match.c
parent9c371d77e843163261d28e374f4ea7dab2e3f64d (diff)
downloadseitan-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.c73
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);
}
/**