1 diff -ur poldek-0.42.2-orig/capreq.h poldek-0.42.2/capreq.h
2 --- poldek-0.42.2-orig/capreq.h 2020-01-25 22:59:59.000000000 +0100
3 +++ poldek-0.42.2/capreq.h 2022-05-20 16:50:58.746605571 +0200
5 char _buff[0]; /* for evr, first byte is always '\0' */
8 +#define CAPREQ_BOOL_OP_AND (1 << 0)
9 +#define CAPREQ_BOOL_OP_OR (1 << 1)
10 +#define CAPREQ_BOOL_OP_IF (1 << 2)
11 +#define CAPREQ_BOOL_OP_UNLESS (1 << 3)
12 +#define CAPREQ_BOOL_OP_ELSE (1 << 4)
13 +#define CAPREQ_BOOL_OP_WITH (1 << 5)
14 +#define CAPREQ_BOOL_OP_WITHOUT (1 << 6)
17 + uint16_t op; // and, or, ir (else), with, without, unless (else)
19 + struct boolean_req* left; // left (and|or|with|without) right
20 + struct boolean_req* leftn; // left (if|unless) right (else leftn)
21 + struct boolean_req* right;
24 /* CAUTION: side effects! */
25 #define capreq_name(cr) (cr)->name
26 #define capreq_name_len(cr) (cr)->namelen
27 diff -ur poldek-0.42.2-orig/install3/requirements.c poldek-0.42.2/install3/requirements.c
28 --- poldek-0.42.2-orig/install3/requirements.c 2020-04-06 14:24:18.000000000 +0200
29 +++ poldek-0.42.2/install3/requirements.c 2022-05-20 17:05:57.456189112 +0200
34 -static int skip_boolean_dep(const struct capreq *cr) {
35 - if (capreq_is_boolean(cr)) {
36 - logn(LOGWARN, "%s: skipping boolean dependency (not supported yet)",
39 +static struct BooleanOpComp {
44 + { "and", 3, CAPREQ_BOOL_OP_AND },
45 + { "or", 2, CAPREQ_BOOL_OP_OR },
46 + { "if", 2, CAPREQ_BOOL_OP_IF },
47 + { "unless", 6, CAPREQ_BOOL_OP_UNLESS },
48 + { "with", 4, CAPREQ_BOOL_OP_WITH },
49 + { "without", 7, CAPREQ_BOOL_OP_WITHOUT },
53 +static struct capreq* parse_single_dep(char *req, int *len) {
54 + char *q, *cap, *name, *evr = NULL;
55 + int name_len, evr_len;
56 + struct capreq* cr = NULL;
59 + cap = q = strdup(req);
64 + DBGF("ltrim: %s", q);
66 + // look for the end of normal dep
69 + name_len = q - name;
70 + DBGF("to parse: %s, name: %s, name_len: %d", q, name, name_len);
73 + DBGF("ltrim: %s", q);
86 + DBGF("to parse: %s, op: %d", q, op);
89 + DBGF("ltrim: %s", q);
92 + while (*q != ' ' && *q != ')')
95 + DBGF("to parse: evr: %s, evr_len: %d", evr, evr_len);
97 + DBGF("to parse: %s", q);
100 + DBGF("ltrim: %s", q);
102 + *(name + name_len) = '\0';
103 + DBGF("name: %s, name_len: %d", name, name_len);
105 + *(evr + evr_len) = '\0';
106 + DBGF("evr: %s, evr_len: %d", evr, evr_len);
108 + cr = capreq_new_evr(NULL, name, evr, op, 0);
113 +static struct boolean_req* parse_boolean_dep(const char *strreq, uint16_t op, int* len) {
115 + struct boolean_req *breq;
117 + struct BooleanOpComp *o;
119 + cap = p = strdup(strreq);
120 + // boolean dep must start with '(' except if we're chaining 'and' or 'or'
121 + if (op != CAPREQ_BOOL_OP_AND && op != CAPREQ_BOOL_OP_OR) {
126 + DBGF("breq: %s", p);
127 + breq = malloc(sizeof(struct boolean_req));
128 + bzero(breq, sizeof(struct boolean_req));
132 + DBGF("breq ltrim: %s", p);
136 + breq->left = parse_boolean_dep(p, 0, &parsed_len);
138 + breq->req = parse_single_dep(p, &parsed_len);
140 + DBGF("breq to parse: %s", q);
147 + for (o = BooleanOps; o->n; o++)
148 + if (!strncmp(q, o->n, o->l))
152 + DBGF("fail no-op");
159 + breq->right = parse_boolean_dep(q, breq->op, &parsed_len);
161 + breq->right = malloc(sizeof(struct boolean_req));
162 + bzero(breq->right, sizeof(struct boolean_req));
163 + breq->right->req = parse_single_dep(q, &parsed_len);
172 + if (breq->op == CAPREQ_BOOL_OP_IF || breq->op == CAPREQ_BOOL_OP_UNLESS) {
173 + if (!strncmp(q, "else", 4)) {
178 + breq->leftn = parse_boolean_dep(q, breq->op, &parsed_len);
180 + breq->leftn = malloc(sizeof(struct boolean_req));
181 + bzero(breq->leftn, sizeof(struct boolean_req));
182 + breq->leftn->req = parse_single_dep(q, &parsed_len);
189 + if (*q != ')' && op != CAPREQ_BOOL_OP_AND && op != CAPREQ_BOOL_OP_OR) {
190 + DBGF("fail no closing paren");
205 +// i3pkg - package to be installed
206 +// req - dependency we are looking for
207 static int process_req(int indent, struct i3ctx *ictx,
208 struct i3pkg *i3pkg, const struct capreq *req)
214 +static int process_boolean_req(int indent, struct i3ctx *ictx,
215 + struct i3pkg *i3pkg, const struct boolean_req *breq)
219 + rcl = process_req(indent, ictx, i3pkg, breq->req);
221 + rcl = process_boolean_req(indent, ictx, i3pkg, breq->left);
223 + rcr = process_boolean_req(indent, ictx, i3pkg, breq->right);
226 + switch (breq->op) {
227 + case CAPREQ_BOOL_OP_AND:
228 + return (rcl > 0 && rcr > 0) ? 1 : -1;
229 + case CAPREQ_BOOL_OP_OR:
230 + return (rcl > 0 || rcr > 0) ? 1 : -1;
231 + case CAPREQ_BOOL_OP_IF:
235 + return process_boolean_req(indent, ictx, i3pkg, breq->leftn);
237 + case CAPREQ_BOOL_OP_UNLESS:
241 + return process_boolean_req(indent, ictx, i3pkg, breq->leftn);
243 + case CAPREQ_BOOL_OP_WITH:
244 + // TODO: check that both deps are stisfied by the same package
245 + return (rcl > 0 && rcr > 0) ? 1 : -1;
246 + case CAPREQ_BOOL_OP_WITHOUT:
247 + // TODO: check that both deps are stisfied by the same package
248 + return (rcl > 0 && rcr <= 0) ? 1 : -1;
255 static tn_array *with_suggests(int indent, struct i3ctx *ictx, struct pkg *pkg)
258 struct pkg *oldpkg = NULL;
259 char *autochoice = NULL; /* testing only */
261 + struct boolean_req* breq;
263 if (pkg->sugs == NULL)
267 //trace(indent, "%d) suggested %s", i, reqstr);
269 - if (skip_boolean_dep(req))
270 + if (capreq_is_boolean(req)) {
271 + logn(LOGWARN, "%s: skipping boolean dependency (weak deps not supported yet)",
274 + // breq = parse_boolean_dep(capreq_name(req), 0, NULL);
275 + // process_boolean_req(indent, ictx, i3pkg, breq);
279 if (iset_provides(ictx->inset, req)) {
280 trace(indent, "- %s: already marked", reqstr);
282 const struct capreq *req = NULL;
283 unsigned itflags = PKG_ITER_REQIN;
284 int nerrors = 0, backtrack = 0;
285 + struct boolean_req* breq;
289 @@ -806,10 +1007,16 @@
290 while ((req = pkg_req_iter_get(it))) {
293 - if (skip_boolean_dep(req))
295 + if (capreq_is_boolean(req)) {
296 + msgn_i(1, indent, "%s required by %s",
297 + capreq_stra(req), pkg->name ? pkg->name : "(null)");
298 + breq = parse_boolean_dep(capreq_name(req), 0, NULL);
299 + rc = process_boolean_req(indent + 2, ictx, i3pkg, breq);
301 + rc = process_req(indent, ictx, i3pkg, req);
304 - if ((rc = process_req(indent, ictx, i3pkg, req)) <= 0) {