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+
233315static void
234316process_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