]> git.pld-linux.org Git - packages/poldek.git/blame - boolean-deps.patch
Release 19 (by relup.sh)
[packages/poldek.git] / boolean-deps.patch
CommitLineData
28d3fe2c
JR
1diff -ur poldek-0.42.2/capreq.h poldek-0.42.2-boolean-deps/capreq.h
2--- poldek-0.42.2/capreq.h 2020-01-25 22:59:59.000000000 +0100
3+++ poldek-0.42.2-boolean-deps/capreq.h 2022-06-08 20:48:12.797280673 +0200
2d94f8f7
JR
4@@ -58,6 +58,22 @@
5 char _buff[0]; /* for evr, first byte is always '\0' */
6 };
7
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)
15+
16+struct boolean_req {
17+ uint16_t op; // and, or, ir (else), with, without, unless (else)
18+ struct capreq* req;
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;
22+};
23+
24 /* CAUTION: side effects! */
25 #define capreq_name(cr) (cr)->name
26 #define capreq_name_len(cr) (cr)->namelen
28d3fe2c
JR
27diff -ur poldek-0.42.2/install3/requirements.c poldek-0.42.2-boolean-deps/install3/requirements.c
28--- poldek-0.42.2/install3/requirements.c 2020-04-06 14:24:18.000000000 +0200
29+++ poldek-0.42.2-boolean-deps/install3/requirements.c 2022-06-08 20:48:12.797280673 +0200
2d94f8f7
JR
30@@ -16,13 +16,163 @@
31
32 #include "ictx.h"
33
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)",
37- capreq_stra(cr));
38- return 1;
39+static struct BooleanOpComp {
40+ const char *n;
41+ int l;
42+ uint16_t op;
43+} BooleanOps[] = {
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 },
50+ { NULL, 0, 0},
51+};
52+
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;
57+ uint16_t op;
58+
59+ cap = q = strdup(req);
60+ DBGF("dep: %s", q);
61+ // skip whitespace
62+ while (*q == ' ')
63+ q++;
64+ DBGF("ltrim: %s", q);
65+ name = q;
66+ // look for the end of normal dep
67+ while (*q != ' ')
68+ q++;
69+ name_len = q - name;
70+ DBGF("to parse: %s, name: %s, name_len: %d", q, name, name_len);
71+ while (*q == ' ')
72+ q++;
73+ DBGF("ltrim: %s", q);
74+ op = 0;
75+ while (*q != ' ') {
76+ if (*q == '<')
77+ op |= REL_LT;
78+ else if (*q == '=')
79+ op |= REL_EQ;
80+ else if (*q == '>')
81+ op |= REL_GT;
82+ else
83+ break;
84+ q++;
85+ }
86+ DBGF("to parse: %s, op: %d", q, op);
87+ while (*q == ' ')
88+ q++;
89+ DBGF("ltrim: %s", q);
90+ if (op) {
91+ evr = q;
92+ while (*q != ' ' && *q != ')')
93+ q++;
94+ evr_len = q - evr;
95+ DBGF("to parse: evr: %s, evr_len: %d", evr, evr_len);
96+ }
97+ DBGF("to parse: %s", q);
98+ while (*q == ' ')
99+ q++;
100+ DBGF("ltrim: %s", q);
101+ *len = q - cap;
102+ *(name + name_len) = '\0';
103+ DBGF("name: %s, name_len: %d", name, name_len);
104+ if (evr) {
105+ *(evr + evr_len) = '\0';
106+ DBGF("evr: %s, evr_len: %d", evr, evr_len);
107+ }
108+ cr = capreq_new_evr(NULL, name, evr, op, 0);
109+ free(cap);
110+ return cr;
111+}
112+
113+static struct boolean_req* parse_boolean_dep(const char *strreq, uint16_t op, int* len) {
114+ char *p, *q, *cap;
115+ struct boolean_req *breq;
116+ int parsed_len;
117+ struct BooleanOpComp *o;
118+
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) {
122+ if (*p != '(')
123+ return NULL;
124+ p++;
125+ }
126+ DBGF("breq: %s", p);
127+ breq = malloc(sizeof(struct boolean_req));
128+ bzero(breq, sizeof(struct boolean_req));
129+ // skip whitespace
130+ while (*p == ' ')
131+ p++;
132+ DBGF("breq ltrim: %s", p);
133+ // nested dep
134+ q = p;
135+ if (*p == '(')
136+ breq->left = parse_boolean_dep(p, 0, &parsed_len);
137+ else
138+ breq->req = parse_single_dep(p, &parsed_len);
139+ q += parsed_len;
140+ DBGF("breq to parse: %s", q);
141+ if (*q == ')') {
142+ if (len)
143+ *len = q - cap;
144+ return breq;
28d3fe2c
JR
145 }
146- return 0;
2d94f8f7
JR
147+
148+ for (o = BooleanOps; o->n; o++)
149+ if (!strncmp(q, o->n, o->l))
150+ break;
151+ breq->op = o->op;
152+ if (!breq->op) {
153+ DBGF("fail no-op");
154+ return NULL;
155+ }
156+ q += o->l;
157+ while (*q == ' ')
158+ q++;
159+ if (*q == '(')
160+ breq->right = parse_boolean_dep(q, breq->op, &parsed_len);
161+ else {
162+ breq->right = malloc(sizeof(struct boolean_req));
163+ bzero(breq->right, sizeof(struct boolean_req));
164+ breq->right->req = parse_single_dep(q, &parsed_len);
165+ }
166+ q += parsed_len;
167+ if (*q == ')') {
168+ if (len)
169+ *len = q - cap;
170+ return breq;
171+ }
172+
173+ if (breq->op == CAPREQ_BOOL_OP_IF || breq->op == CAPREQ_BOOL_OP_UNLESS) {
174+ if (!strncmp(q, "else", 4)) {
175+ q += 4;
176+ while (*q == ' ')
177+ q++;
178+ if (*q == '(')
179+ breq->leftn = parse_boolean_dep(q, breq->op, &parsed_len);
180+ else {
181+ breq->leftn = malloc(sizeof(struct boolean_req));
182+ bzero(breq->leftn, sizeof(struct boolean_req));
183+ breq->leftn->req = parse_single_dep(q, &parsed_len);
184+ }
185+ }
28d3fe2c 186+ }
2d94f8f7
JR
187+ while (*q == ' ')
188+ q++;
189+ if (*q != ')' && op != CAPREQ_BOOL_OP_AND && op != CAPREQ_BOOL_OP_OR) {
190+ DBGF("fail no closing paren");
191+ return NULL;
192+ }
193+
194+ if (len)
195+ *len = q - cap;
196+ return breq;
197 }
198
199 static
28d3fe2c 200@@ -553,8 +703,11 @@
2d94f8f7
JR
201
202 }
203
204+
205+// i3pkg - package to be installed
206+// req - dependency we are looking for
207 static int process_req(int indent, struct i3ctx *ictx,
28d3fe2c
JR
208- struct i3pkg *i3pkg, const struct capreq *req)
209+ struct i3pkg *i3pkg, const struct capreq *req, int boolean)
2d94f8f7 210 {
28d3fe2c
JR
211 struct poldek_ts *ts = ictx->ts; /* just for short */
212 struct pkg *pkg, *tomark = NULL;
213@@ -644,7 +797,8 @@
214 else
215 errfmt = _("%s: req %s not found");
216
217- i3_error(ictx, pkg, I3ERR_NOTFOUND, errfmt, pkg_id(pkg), strreq);
218+ if (boolean == 0)
219+ i3_error(ictx, pkg, I3ERR_NOTFOUND, errfmt, pkg_id(pkg), strreq);
220 rc = 0;
221
222 l_end:
223@@ -653,6 +807,49 @@
2d94f8f7
JR
224 return rc;
225 }
226
227+static int process_boolean_req(int indent, struct i3ctx *ictx,
228+ struct i3pkg *i3pkg, const struct boolean_req *breq)
229+{
230+ int rcl, rcr, rce;
231+ if (breq->req)
28d3fe2c 232+ rcl = process_req(indent, ictx, i3pkg, breq->req, 1);
2d94f8f7
JR
233+ else
234+ rcl = process_boolean_req(indent, ictx, i3pkg, breq->left);
c6ad8d0d
JR
235+ if (breq->op != CAPREQ_BOOL_OP_OR)
236+ if (breq->right)
237+ rcr = process_boolean_req(indent, ictx, i3pkg, breq->right);
238+ else
239+ return rcl;
2d94f8f7
JR
240+ switch (breq->op) {
241+ case CAPREQ_BOOL_OP_AND:
242+ return (rcl > 0 && rcr > 0) ? 1 : -1;
243+ case CAPREQ_BOOL_OP_OR:
c6ad8d0d
JR
244+ if (rcl <= 0 && breq->right)
245+ return process_boolean_req(indent, ictx, i3pkg, breq->right);
246+ return rcl;
2d94f8f7
JR
247+ case CAPREQ_BOOL_OP_IF:
248+ if (rcr > 0)
249+ return rcl;
250+ if (breq->leftn)
251+ return process_boolean_req(indent, ictx, i3pkg, breq->leftn);
c6ad8d0d 252+ return 1;
2d94f8f7
JR
253+ case CAPREQ_BOOL_OP_UNLESS:
254+ if (rcr <= 0)
255+ return rcl;
256+ if (breq->leftn)
257+ return process_boolean_req(indent, ictx, i3pkg, breq->leftn);
c6ad8d0d 258+ return 1;
2d94f8f7
JR
259+ case CAPREQ_BOOL_OP_WITH:
260+ // TODO: check that both deps are stisfied by the same package
261+ return (rcl > 0 && rcr > 0) ? 1 : -1;
262+ case CAPREQ_BOOL_OP_WITHOUT:
263+ // TODO: check that both deps are stisfied by the same package
264+ return (rcl > 0 && rcr <= 0) ? 1 : -1;
265+ default:
266+ return -1;
267+ }
268+ return -1;
269+}
270
271 static tn_array *with_suggests(int indent, struct i3ctx *ictx, struct pkg *pkg)
272 {
28d3fe2c 273@@ -660,6 +857,7 @@
2d94f8f7
JR
274 struct pkg *oldpkg = NULL;
275 char *autochoice = NULL; /* testing only */
276 int i;
277+ struct boolean_req* breq;
278
279 if (pkg->sugs == NULL)
280 return NULL;
28d3fe2c 281@@ -693,8 +891,14 @@
2d94f8f7
JR
282
283 //trace(indent, "%d) suggested %s", i, reqstr);
284
285- if (skip_boolean_dep(req))
286+ if (capreq_is_boolean(req)) {
287+ logn(LOGWARN, "%s: skipping boolean dependency (weak deps not supported yet)",
288+ capreq_stra(req));
289+ // TODO
290+ // breq = parse_boolean_dep(capreq_name(req), 0, NULL);
291+ // process_boolean_req(indent, ictx, i3pkg, breq);
292 continue;
293+ }
294
295 if (iset_provides(ictx->inset, req)) {
296 trace(indent, "- %s: already marked", reqstr);
28d3fe2c 297@@ -791,6 +995,7 @@
2d94f8f7
JR
298 const struct capreq *req = NULL;
299 unsigned itflags = PKG_ITER_REQIN;
300 int nerrors = 0, backtrack = 0;
301+ struct boolean_req* breq;
302
303 pkg = i3pkg->pkg;
304 n_assert(pkg);
28d3fe2c 305@@ -806,10 +1011,18 @@
2d94f8f7
JR
306 while ((req = pkg_req_iter_get(it))) {
307 int rc;
308
309- if (skip_boolean_dep(req))
310- continue;
311+ if (capreq_is_boolean(req)) {
312+ msgn_i(1, indent, "%s required by %s",
313+ capreq_stra(req), pkg->name ? pkg->name : "(null)");
314+ breq = parse_boolean_dep(capreq_name(req), 0, NULL);
315+ rc = process_boolean_req(indent + 2, ictx, i3pkg, breq);
28d3fe2c
JR
316+ if (rc <= 0)
317+ i3_error(ictx, i3pkg->pkg, I3ERR_NOTFOUND, _("%s: req %s not found"), pkg_id(i3pkg->pkg), capreq_stra(req));
2d94f8f7 318+ } else {
28d3fe2c 319+ rc = process_req(indent, ictx, i3pkg, req, 0);
2d94f8f7
JR
320+ }
321
322- if ((rc = process_req(indent, ictx, i3pkg, req)) <= 0) {
323+ if (rc <= 0) {
324 nerrors++;
325 if (rc < 0) {
326 backtrack = 1;
28d3fe2c
JR
327@@ -836,7 +1049,7 @@
328
329 req = n_array_nth(suggests, i);
330
331- if ((rc = process_req(indent, ictx, i3pkg, req)) <= 0) {
332+ if ((rc = process_req(indent, ictx, i3pkg, req, 0)) <= 0) {
333 nerrors++;
334 if (rc < 0) {
335 backtrack = 1;
This page took 0.240311 seconds and 4 git commands to generate.