Skip to content

Commit ad9bcef

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 ad9bcef

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

bin/xbps-create/main.c

Lines changed: 91 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,87 @@ 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+
{
241+
xbps_dictionary_t d;
242+
char *key, *valstr, *rem = NULL;
243+
uint64_t val = 0;
244+
bool alloc = false;
245+
246+
if ((d = xbps_dictionary_get(pkg_propsd, prop)) == NULL) {
247+
d = xbps_dictionary_create();
248+
if (d == NULL)
249+
die("xbps_dictionary_create");
250+
alloc = true;
251+
}
252+
253+
key = strdup(keyval);
254+
if (key == NULL)
255+
die("strdup");
256+
valstr = strchr(key, delim);
257+
*valstr = '\0';
258+
valstr = valstr + 1;
259+
assert(valstr);
260+
261+
if (validate_key && !validate_key(key)) {
262+
diex("%s: invalid key: %s", prop, key);
263+
}
264+
265+
if (validate_val && !validate_val(valstr)) {
266+
diex("%s: invalid value for key `%s': %s", prop, key, valstr);
267+
}
268+
269+
val = strtoull(valstr, &rem, 10);
270+
if (errno != 0)
271+
die("%s: %s: invalid integer: %s", prop, key, valstr);
272+
else if (valstr == rem || (valstr && *rem != 0))
273+
diex("%s: %s: invalid integer: %s", prop, key, valstr);
274+
275+
xbps_dictionary_set_uint64(d, key, val);
276+
xbps_dictionary_set(pkg_propsd, prop, d);
277+
if (alloc) {
278+
xbps_object_release(d);
279+
}
280+
}
281+
282+
static void
283+
process_dict(const char *key, const char *val, const char delim,
284+
void (*process_item)(const char *, const char *, const char,
285+
bool (*)(const char *), bool (*)(const char *)),
286+
bool (*validate_key)(const char *), bool (*validate_val)(const char *))
287+
{
288+
char *args, *p = NULL, *saveptr = NULL;
289+
290+
assert(key);
291+
292+
if (val == NULL)
293+
return;
294+
295+
args = strdup(val);
296+
if (args == NULL)
297+
die("strdup");
298+
299+
if (strchr(args, ' ') == NULL) {
300+
process_item(key, args, delim, validate_key, validate_val);
301+
goto out;
302+
}
303+
304+
for ((p = strtok_r(args, " ", &saveptr)); p;
305+
(p = strtok_r(NULL, " ", &saveptr))) {
306+
char *buf;
307+
buf = strdup(p);
308+
assert(buf);
309+
process_item(key, buf, delim, validate_key, validate_val);
310+
free(buf);
311+
}
312+
313+
out:
314+
free(args);
315+
}
316+
233317
static void
234318
process_one_alternative(const char *altgrname, const char *val)
235319
{
@@ -863,6 +947,7 @@ main(int argc, char **argv)
863947
{ "pkgver", required_argument, NULL, 'n' },
864948
{ "preserve", no_argument, NULL, 'p' },
865949
{ "provides", required_argument, NULL, 'P' },
950+
{ "provides-priority", required_argument, NULL, '6' },
866951
{ "quiet", no_argument, NULL, 'q' },
867952
{ "replaces", required_argument, NULL, 'R' },
868953
{ "reverts", required_argument, NULL, 'r' },
@@ -883,6 +968,7 @@ main(int argc, char **argv)
883968
const char *arch, *config_files, *mutable_files, *version, *changelog;
884969
const char *buildopts, *shlib_provides, *shlib_requires, *alternatives;
885970
const char *compression, *tags = NULL, *srcrevs = NULL, *sourcepkg = NULL;
971+
const char *provides_priority = NULL;
886972
char pkgname[XBPS_NAME_SIZE], *binpkg, *tname, *p, cwd[PATH_MAX-1];
887973
bool quiet = false, preserve = false;
888974
int c, pkg_fd;
@@ -982,6 +1068,9 @@ main(int argc, char **argv)
9821068
case '5':
9831069
sourcepkg = optarg;
9841070
break;
1071+
case '6':
1072+
provides_priority = optarg;
1073+
break;
9851074
case '?':
9861075
default:
9871076
usage(true);
@@ -1070,6 +1159,7 @@ main(int argc, char **argv)
10701159
process_array("conf_files", config_files, NULL);
10711160
process_array("conflicts", conflicts, NULL);
10721161
process_array("provides", provides, validate_pkgver);
1162+
process_dict("provides-priority", provides_priority, ',', process_keyval_uint64, validate_pkgver, NULL);
10731163
process_array("replaces", replaces, NULL);
10741164
process_array("reverts", reverts, NULL);
10751165
process_array("shlib-provides", shlib_provides, NULL);

0 commit comments

Comments
 (0)