2424 */
2525
2626#include <sys/types.h>
27- #include <stdio.h>
27+
28+ #include <assert.h>
29+ #include <errno.h>
30+ #include <inttypes.h>
31+ #include <limits.h>
2832#include <stdbool.h>
33+ #include <stdio.h>
2934#include <stdlib.h>
30- #include <errno.h>
3135#include <string.h>
32- #include <assert.h>
3336
3437#include "defs.h"
38+ #include "xbps.h"
39+
40+ struct length_max_cb {
41+ const char * key ;
42+ int max ;
43+ };
44+
45+ static int
46+ length_max_cb (struct xbps_handle * xhp UNUSED , xbps_object_t obj ,
47+ const char * key UNUSED , void * arg , bool * loop_done UNUSED )
48+ {
49+ struct length_max_cb * ctx = arg ;
50+ const char * s = NULL ;
51+ size_t len ;
52+
53+ if (!xbps_dictionary_get_cstring_nocopy (obj , ctx -> key , & s ))
54+ return - errno ;
55+
56+ len = strlen (s );
57+ if (len > INT_MAX )
58+ return - ERANGE ;
59+ if ((int )len > ctx -> max )
60+ ctx -> max = len ;
61+
62+ return 0 ;
63+ }
3564
3665struct list_pkgver_cb {
37- unsigned int pkgver_len ;
66+ unsigned int pkgver_align ;
3867 unsigned int maxcols ;
39- char * linebuf ;
68+ char * buf ;
69+ struct xbps_fmt * fmt ;
4070};
4171
42- int
43- list_pkgs_in_dict (struct xbps_handle * xhp UNUSED ,
72+ static int
73+ list_pkgs_pkgdb_cb (struct xbps_handle * xhp UNUSED ,
4474 xbps_object_t obj ,
4575 const char * key UNUSED ,
4676 void * arg ,
4777 bool * loop_done UNUSED )
4878{
49- struct list_pkgver_cb * lpc = arg ;
79+ struct list_pkgver_cb * ctx = arg ;
5080 const char * pkgver = NULL , * short_desc = NULL , * state_str = NULL ;
5181 unsigned int len ;
5282 pkg_state_t state ;
@@ -58,127 +88,151 @@ list_pkgs_in_dict(struct xbps_handle *xhp UNUSED,
5888
5989 xbps_pkg_state_dictionary (obj , & state );
6090
61- if (state == XBPS_PKG_STATE_INSTALLED )
62- state_str = "ii" ;
63- else if (state == XBPS_PKG_STATE_UNPACKED )
64- state_str = "uu" ;
65- else if (state == XBPS_PKG_STATE_HALF_REMOVED )
66- state_str = "hr" ;
67- else
68- state_str = "??" ;
69-
70- if (lpc -> linebuf == NULL ) {
71- printf ("%s %-*s %s\n" ,
72- state_str ,
73- lpc -> pkgver_len , pkgver ,
74- short_desc );
91+ switch (state ) {
92+ case XBPS_PKG_STATE_INSTALLED : state_str = "ii" ; break ;
93+ case XBPS_PKG_STATE_UNPACKED : state_str = "uu" ; break ;
94+ case XBPS_PKG_STATE_HALF_REMOVED : state_str = "hr" ; break ;
95+ case XBPS_PKG_STATE_BROKEN : state_str = "br" ; break ;
96+ case XBPS_PKG_STATE_NOT_INSTALLED : state_str = "??" ; break ;
97+ }
98+
99+ if (!ctx -> buf ) {
100+ printf ("%s %-*s %s\n" , state_str , ctx -> pkgver_align , pkgver ,
101+ short_desc );
75102 return 0 ;
76103 }
77104
78- len = snprintf (lpc -> linebuf , lpc -> maxcols , "%s %-*s %s" ,
79- state_str ,
80- lpc -> pkgver_len , pkgver ,
81- short_desc );
82105 /* add ellipsis if the line was truncated */
83- if (len >= lpc -> maxcols && lpc -> maxcols > 4 ) {
84- for (unsigned int j = 0 ; j < 3 ; j ++ )
85- lpc -> linebuf [lpc -> maxcols - j - 1 ] = '.' ;
86- lpc -> linebuf [lpc -> maxcols ] = '\0' ;
87- }
88- puts (lpc -> linebuf );
106+ len = snprintf (ctx -> buf , ctx -> maxcols , "%s %-*s %s\n" , state_str ,
107+ ctx -> pkgver_align , pkgver , short_desc );
108+ if (len >= ctx -> maxcols && ctx -> maxcols > sizeof ("..." ))
109+ memcpy (ctx -> buf + ctx -> maxcols - sizeof ("..." ), "..." , sizeof ("..." ));
110+ fputs (ctx -> buf , stdout );
89111
90112 return 0 ;
91113}
92114
93115int
94- list_manual_pkgs (struct xbps_handle * xhp UNUSED ,
95- xbps_object_t obj ,
96- const char * key UNUSED ,
97- void * arg UNUSED ,
98- bool * loop_done UNUSED )
116+ list_pkgs_pkgdb (struct xbps_handle * xhp )
99117{
100- const char * pkgver = NULL ;
101- bool automatic = false ;
118+ struct length_max_cb longest = {. key = "pkgver" } ;
119+ struct list_pkgver_cb lpc = { 0 } ;
102120
103- xbps_dictionary_get_bool (obj , "automatic-install" , & automatic );
104- if (automatic == false) {
105- xbps_dictionary_get_cstring_nocopy (obj , "pkgver" , & pkgver );
106- puts (pkgver );
121+ int r = xbps_pkgdb_foreach_cb_multi (xhp , length_max_cb , & longest );
122+ if (r < 0 )
123+ return r ;
124+
125+ lpc .pkgver_align = longest .max ;
126+ lpc .maxcols = get_maxcols ();
127+ if (lpc .maxcols > 0 ) {
128+ lpc .buf = malloc (lpc .maxcols );
129+ if (!lpc .buf )
130+ return - errno ;
107131 }
108132
109- return 0 ;
133+ return xbps_pkgdb_foreach_cb ( xhp , list_pkgs_pkgdb_cb , & lpc ) ;
110134}
111135
112- int
113- list_hold_pkgs (struct xbps_handle * xhp UNUSED ,
114- xbps_object_t obj ,
115- const char * key UNUSED ,
116- void * arg UNUSED ,
117- bool * loop_done UNUSED )
118- {
119- const char * pkgver = NULL ;
136+ struct list_pkgdb_cb {
137+ struct xbps_fmt * fmt ;
138+ int (* filter )(xbps_object_t obj );
139+ };
120140
121- if (xbps_dictionary_get (obj , "hold" )) {
122- xbps_dictionary_get_cstring_nocopy (obj , "pkgver" , & pkgver );
123- puts (pkgver );
141+ static int
142+ list_pkgdb_cb (struct xbps_handle * xhp UNUSED , xbps_object_t obj ,
143+ const char * key UNUSED , void * arg , bool * loop_done UNUSED )
144+ {
145+ struct list_pkgdb_cb * ctx = arg ;
146+ int r ;
147+
148+ if (ctx -> filter ) {
149+ r = ctx -> filter (obj );
150+ if (r < 0 )
151+ return r ;
152+ if (r == 0 )
153+ return 0 ;
124154 }
125155
156+ r = xbps_fmt_dictionary (ctx -> fmt , obj , stdout );
157+ if (r < 0 )
158+ return r ;
126159 return 0 ;
127160}
128161
129162int
130- list_repolock_pkgs (struct xbps_handle * xhp UNUSED ,
131- xbps_object_t obj ,
132- const char * key UNUSED ,
133- void * arg UNUSED ,
134- bool * loop_done UNUSED )
163+ list_pkgdb (struct xbps_handle * xhp , int (* filter )(xbps_object_t ), const char * format )
135164{
136- const char * pkgver = NULL ;
137-
138- if (xbps_dictionary_get (obj , "repolock" )) {
139- xbps_dictionary_get_cstring_nocopy (obj , "pkgver" , & pkgver );
140- puts (pkgver );
165+ struct list_pkgdb_cb ctx = {.filter = filter };
166+ int r ;
167+
168+ ctx .fmt = xbps_fmt_parse (format );
169+ if (!ctx .fmt ) {
170+ r = - errno ;
171+ xbps_error_printf ("failed to parse format: %s\n" , strerror (- r ));
172+ return r ;
141173 }
142-
143- return 0 ;
174+ r = xbps_pkgdb_foreach_cb (xhp , list_pkgdb_cb , & ctx );
175+ xbps_fmt_free (ctx .fmt );
176+ return r ;
144177}
145178
146179int
147- list_orphans (struct xbps_handle * xhp )
180+ list_manual_pkgs (struct xbps_handle * xhp UNUSED ,
181+ xbps_object_t obj ,
182+ const char * key UNUSED ,
183+ void * arg UNUSED ,
184+ bool * loop_done UNUSED )
148185{
149- xbps_array_t orphans ;
150186 const char * pkgver = NULL ;
187+ bool automatic = false;
151188
152- orphans = xbps_find_pkg_orphans (xhp , NULL );
153- if (orphans == NULL )
154- return EINVAL ;
155-
156- for (unsigned int i = 0 ; i < xbps_array_count (orphans ); i ++ ) {
157- xbps_dictionary_get_cstring_nocopy (xbps_array_get (orphans , i ),
158- "pkgver" , & pkgver );
189+ xbps_dictionary_get_bool (obj , "automatic-install" , & automatic );
190+ if (automatic == false) {
191+ xbps_dictionary_get_cstring_nocopy (obj , "pkgver" , & pkgver );
159192 puts (pkgver );
160193 }
161194
162195 return 0 ;
163196}
164197
165198int
166- list_pkgs_pkgdb (struct xbps_handle * xhp )
199+ list_orphans (struct xbps_handle * xhp , const char * format )
167200{
168- struct list_pkgver_cb lpc ;
201+ xbps_array_t orphans ;
202+ struct xbps_fmt * fmt ;
203+ int r = 0 ;
204+
205+ fmt = xbps_fmt_parse (format );
206+ if (!fmt ) {
207+ r = - errno ;
208+ xbps_error_printf ("failed to parse format: %s\n" , strerror (- r ));
209+ return r ;
210+ }
169211
170- lpc .pkgver_len = find_longest_pkgver (xhp , NULL );
171- lpc .maxcols = get_maxcols ();
172- lpc .linebuf = NULL ;
173- if (lpc .maxcols > 0 ) {
174- lpc .linebuf = malloc (lpc .maxcols );
175- if (lpc .linebuf == NULL )
176- exit (1 );
212+ orphans = xbps_find_pkg_orphans (xhp , NULL );
213+ if (!orphans ) {
214+ r = - errno ;
215+ xbps_error_printf ("failed to find orphans: %s\n" , strerror (- r ));
216+ goto err ;
177217 }
178218
179- return xbps_pkgdb_foreach_cb (xhp , list_pkgs_in_dict , & lpc );
219+ for (unsigned int i = 0 ; i < xbps_array_count (orphans ); i ++ ) {
220+ xbps_object_t obj = xbps_array_get (orphans , i );
221+ if (!obj )
222+ return - errno ;
223+ r = xbps_fmt_dictionary (fmt , obj , stdout );
224+ if (r < 0 )
225+ goto err ;
226+ }
227+ err :
228+ xbps_fmt_free (fmt );
229+ return r ;
180230}
181231
232+ #ifndef __UNCONST
233+ #define __UNCONST (a ) ((void *)(uintptr_t)(const void *)(a))
234+ #endif
235+
182236static void
183237repo_list_uri (struct xbps_repo * repo )
184238{
@@ -230,50 +284,3 @@ repo_list(struct xbps_handle *xhp)
230284 }
231285 return 0 ;
232286}
233-
234- struct fflongest {
235- xbps_dictionary_t d ;
236- unsigned int len ;
237- };
238-
239- static int
240- _find_longest_pkgver_cb (struct xbps_handle * xhp UNUSED ,
241- xbps_object_t obj ,
242- const char * key UNUSED ,
243- void * arg ,
244- bool * loop_done UNUSED )
245- {
246- struct fflongest * ffl = arg ;
247- const char * pkgver = NULL ;
248- unsigned int len ;
249-
250- xbps_dictionary_get_cstring_nocopy (obj , "pkgver" , & pkgver );
251- len = strlen (pkgver );
252- if (ffl -> len == 0 || len > ffl -> len )
253- ffl -> len = len ;
254-
255- return 0 ;
256- }
257-
258- unsigned int
259- find_longest_pkgver (struct xbps_handle * xhp , xbps_object_t o )
260- {
261- struct fflongest ffl ;
262-
263- ffl .d = o ;
264- ffl .len = 0 ;
265-
266- if (xbps_object_type (o ) == XBPS_TYPE_DICTIONARY ) {
267- xbps_array_t array ;
268-
269- array = xbps_dictionary_all_keys (o );
270- (void )xbps_array_foreach_cb_multi (xhp , array , o ,
271- _find_longest_pkgver_cb , & ffl );
272- xbps_object_release (array );
273- } else {
274- (void )xbps_pkgdb_foreach_cb_multi (xhp ,
275- _find_longest_pkgver_cb , & ffl );
276- }
277-
278- return ffl .len ;
279- }
0 commit comments