Skip to content

Commit 56be05c

Browse files
committed
bin/xbps-create: add support for recording provides priority
Specified as a space-separated array of comma-separated keys and values that record the priority which xbps should give to a virtual package a package provides. Keys are pkgvers, and values are positive integers. Higher values will be given a higher priority, and missing entries will be given a priority of 0 by default. This is implemented as a generic function with validation and parsing callbacks so it can be used for other properties that are dictionaries.
1 parent a634e82 commit 56be05c

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

bin/xbps-create/main.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <stdbool.h>
4141
#include <stdio.h>
4242
#include <stdlib.h>
43+
#include <stdint.h>
4344
#include <string.h>
4445
#include <strings.h>
4546
#include <unistd.h>
@@ -100,7 +101,7 @@ usage(bool fail)
100101
" e.g: '/usr/lib/foo /usr/bin/blah')\n"
101102
" -m, --maintainer Maintainer\n"
102103
" -n, --pkgver Package name/version tuple (e.g `foo-1.0_1')\n"
103-
" -P, --provides Provides (blank separated list, e.g: 'foo-9999 blah-1.0')\n"
104+
" -P, --provides Provides (blank separated list, e.g: 'foo-9999_1 blah-1.0_1')\n"
104105
" -p, --preserve Enable package preserve boolean\n"
105106
" -q, --quiet Work silently\n"
106107
" -R, --replaces Replaces (blank separated list, e.g: 'foo>=1.0 blah<2.0')\n"
@@ -118,6 +119,8 @@ usage(bool fail)
118119
" e.g 'libfoo.so.1 libblah.so.2')\n"
119120
" --shlib-requires List of required shared libraries (blank separated list,\n"
120121
" e.g 'libfoo.so.1 libblah.so.2')\n\n"
122+
" --provides-priority Provides with explicit priority (blank separated list,\n"
123+
" e.g: 'foo-9999_1,100 blah-1.0_1,0')\n"
121124
"NOTE:\n"
122125
" At least three flags are required: architecture, pkgver and desc.\n\n"
123126
"EXAMPLE:\n"
@@ -230,6 +233,85 @@ process_array(const char *key, const char *val, bool (*validate)(const char *s))
230233
xbps_object_release(array);
231234
}
232235

236+
static void
237+
process_keyval_uint64(const char *prop, const char *keyval, const char delim,
238+
bool (*validate_key)(const char *),
239+
bool (*validate_val)(const char *)) {
240+
xbps_dictionary_t d;
241+
char *key, *valstr, *rem = NULL;
242+
uint64_t val = 0;
243+
bool alloc = false;
244+
245+
if ((d = xbps_dictionary_get(pkg_propsd, prop)) == NULL) {
246+
d = xbps_dictionary_create();
247+
if (d == NULL)
248+
die("xbps_dictionary_create");
249+
alloc = true;
250+
}
251+
252+
key = strdup(keyval);
253+
if (key == NULL)
254+
die("strdup");
255+
valstr = strchr(key, delim);
256+
*valstr = '\0';
257+
valstr = valstr + 1;
258+
assert(valstr);
259+
260+
if (validate_key && !validate_key(key)) {
261+
diex("%s: invalid key: %s", prop, key);
262+
}
263+
264+
if (validate_val && !validate_val(valstr)) {
265+
diex("%s: invalid value for key `%s': %s", prop, key, valstr);
266+
}
267+
268+
val = strtoull(valstr, &rem, 10);
269+
if (errno != 0)
270+
die("%s: %s: invalid integer: %s", prop, key, valstr);
271+
else if (valstr == rem || (valstr && *rem != 0))
272+
diex("%s: %s: invalid integer: %s", prop, key, valstr);
273+
274+
xbps_dictionary_set_uint64(d, key, val);
275+
xbps_dictionary_set(pkg_propsd, prop, d);
276+
if (alloc) {
277+
xbps_object_release(d);
278+
}
279+
}
280+
281+
static void
282+
process_dict(const char *key, const char *val, const char delim,
283+
void (*process_item)(const char *, const char *, const char,
284+
bool (*)(const char *), bool (*)(const char *)),
285+
bool (*validate_key)(const char *), bool (*validate_val)(const char *)) {
286+
char *args, *p = NULL, *saveptr = NULL;
287+
288+
assert(key);
289+
290+
if (val == NULL)
291+
return;
292+
293+
args = strdup(val);
294+
if (args == NULL)
295+
die("strdup");
296+
297+
if (strchr(args, ' ') == NULL) {
298+
process_item(key, args, delim, validate_key, validate_val);
299+
goto out;
300+
}
301+
302+
for ((p = strtok_r(args, " ", &saveptr)); p;
303+
(p = strtok_r(NULL, " ", &saveptr))) {
304+
char *buf;
305+
buf = strdup(p);
306+
assert(buf);
307+
process_item(key, buf, delim, validate_key, validate_val);
308+
free(buf);
309+
}
310+
311+
out:
312+
free(args);
313+
}
314+
233315
static void
234316
process_one_alternative(const char *altgrname, const char *val)
235317
{
@@ -863,6 +945,7 @@ main(int argc, char **argv)
863945
{ "pkgver", required_argument, NULL, 'n' },
864946
{ "preserve", no_argument, NULL, 'p' },
865947
{ "provides", required_argument, NULL, 'P' },
948+
{ "provides-priority", required_argument, NULL, '6' },
866949
{ "quiet", no_argument, NULL, 'q' },
867950
{ "replaces", required_argument, NULL, 'R' },
868951
{ "reverts", required_argument, NULL, 'r' },
@@ -883,6 +966,7 @@ main(int argc, char **argv)
883966
const char *arch, *config_files, *mutable_files, *version, *changelog;
884967
const char *buildopts, *shlib_provides, *shlib_requires, *alternatives;
885968
const char *compression, *tags = NULL, *srcrevs = NULL, *sourcepkg = NULL;
969+
const char *provides_priority = NULL;
886970
char pkgname[XBPS_NAME_SIZE], *binpkg, *tname, *p, cwd[PATH_MAX-1];
887971
bool quiet = false, preserve = false;
888972
int c, pkg_fd;
@@ -982,6 +1066,9 @@ main(int argc, char **argv)
9821066
case '5':
9831067
sourcepkg = optarg;
9841068
break;
1069+
case '6':
1070+
provides_priority = optarg;
1071+
break;
9851072
case '?':
9861073
default:
9871074
usage(true);
@@ -1070,6 +1157,7 @@ main(int argc, char **argv)
10701157
process_array("conf_files", config_files, NULL);
10711158
process_array("conflicts", conflicts, NULL);
10721159
process_array("provides", provides, validate_pkgver);
1160+
process_dict("provides-priority", provides_priority, ',', process_keyval_uint64, validate_pkgver, NULL);
10731161
process_array("replaces", replaces, NULL);
10741162
process_array("reverts", reverts, NULL);
10751163
process_array("shlib-provides", shlib_provides, NULL);

0 commit comments

Comments
 (0)