24
24
*/
25
25
26
26
#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>
28
32
#include <stdbool.h>
33
+ #include <stdio.h>
29
34
#include <stdlib.h>
30
- #include <errno.h>
31
35
#include <string.h>
32
- #include <assert.h>
33
36
34
37
#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
+ }
35
64
36
65
struct list_pkgver_cb {
37
- unsigned int pkgver_len ;
66
+ unsigned int pkgver_align ;
38
67
unsigned int maxcols ;
39
- char * linebuf ;
68
+ char * buf ;
69
+ struct xbps_fmt * fmt ;
40
70
};
41
71
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 ,
44
74
xbps_object_t obj ,
45
75
const char * key UNUSED ,
46
76
void * arg ,
47
77
bool * loop_done UNUSED )
48
78
{
49
- struct list_pkgver_cb * lpc = arg ;
79
+ struct list_pkgver_cb * ctx = arg ;
50
80
const char * pkgver = NULL , * short_desc = NULL , * state_str = NULL ;
51
81
unsigned int len ;
52
82
pkg_state_t state ;
@@ -58,127 +88,151 @@ list_pkgs_in_dict(struct xbps_handle *xhp UNUSED,
58
88
59
89
xbps_pkg_state_dictionary (obj , & state );
60
90
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 );
75
102
return 0 ;
76
103
}
77
104
78
- len = snprintf (lpc -> linebuf , lpc -> maxcols , "%s %-*s %s" ,
79
- state_str ,
80
- lpc -> pkgver_len , pkgver ,
81
- short_desc );
82
105
/* 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 );
89
111
90
112
return 0 ;
91
113
}
92
114
93
115
int
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 )
99
117
{
100
- const char * pkgver = NULL ;
101
- bool automatic = false ;
118
+ struct length_max_cb longest = {. key = "pkgver" } ;
119
+ struct list_pkgver_cb lpc = { 0 } ;
102
120
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 ;
107
131
}
108
132
109
- return 0 ;
133
+ return xbps_pkgdb_foreach_cb ( xhp , list_pkgs_pkgdb_cb , & lpc ) ;
110
134
}
111
135
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
+ };
120
140
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 ;
124
154
}
125
155
156
+ r = xbps_fmt_dictionary (ctx -> fmt , obj , stdout );
157
+ if (r < 0 )
158
+ return r ;
126
159
return 0 ;
127
160
}
128
161
129
162
int
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 )
135
164
{
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 ;
141
173
}
142
-
143
- return 0 ;
174
+ r = xbps_pkgdb_foreach_cb (xhp , list_pkgdb_cb , & ctx );
175
+ xbps_fmt_free (ctx .fmt );
176
+ return r ;
144
177
}
145
178
146
179
int
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 )
148
185
{
149
- xbps_array_t orphans ;
150
186
const char * pkgver = NULL ;
187
+ bool automatic = false;
151
188
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 );
159
192
puts (pkgver );
160
193
}
161
194
162
195
return 0 ;
163
196
}
164
197
165
198
int
166
- list_pkgs_pkgdb (struct xbps_handle * xhp )
199
+ list_orphans (struct xbps_handle * xhp , const char * format )
167
200
{
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
+ }
169
211
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 ;
177
217
}
178
218
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 ;
180
230
}
181
231
232
+ #ifndef __UNCONST
233
+ #define __UNCONST (a ) ((void *)(uintptr_t)(const void *)(a))
234
+ #endif
235
+
182
236
static void
183
237
repo_list_uri (struct xbps_repo * repo )
184
238
{
@@ -230,50 +284,3 @@ repo_list(struct xbps_handle *xhp)
230
284
}
231
285
return 0 ;
232
286
}
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