Skip to content

Commit 8b4daae

Browse files
committed
bin/xbps-query: add -F/--format flag
1 parent 0cf4db7 commit 8b4daae

File tree

3 files changed

+182
-152
lines changed

3 files changed

+182
-152
lines changed

bin/xbps-query/defs.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,10 @@ int repo_show_pkg_namedesc(struct xbps_handle *, xbps_object_t, void *,
5252
int ownedby(struct xbps_handle *, const char *, bool, bool);
5353

5454
/* From list.c */
55-
unsigned int find_longest_pkgver(struct xbps_handle *, xbps_object_t);
56-
57-
int list_pkgs_in_dict(struct xbps_handle *, xbps_object_t, const char *, void *, bool *);
5855
int list_manual_pkgs(struct xbps_handle *, xbps_object_t, const char *, void *, bool *);
59-
int list_hold_pkgs(struct xbps_handle *, xbps_object_t, const char *, void *, bool *);
60-
int list_repolock_pkgs(struct xbps_handle *, xbps_object_t, const char *, void *, bool *);
61-
int list_orphans(struct xbps_handle *);
56+
int list_orphans(struct xbps_handle *, const char *);
6257
int list_pkgs_pkgdb(struct xbps_handle *);
58+
int list_pkgdb(struct xbps_handle *, int (*filter)(xbps_object_t), const char *format);
6359

6460
int repo_list(struct xbps_handle *);
6561

bin/xbps-query/list.c

Lines changed: 140 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,59 @@
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

3665
struct 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

93115
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)
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

129162
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)
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

146179
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)
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

165198
int
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+
182236
static void
183237
repo_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

Comments
 (0)