Skip to content

Commit 68efa9c

Browse files
committed
WIP: json
1 parent c165de7 commit 68efa9c

File tree

9 files changed

+298
-21
lines changed

9 files changed

+298
-21
lines changed

bin/xbps-query/defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int ownedby(struct xbps_handle *, const char *, bool, bool);
5555
int list_manual_pkgs(struct xbps_handle *, xbps_object_t, const char *, void *, bool *);
5656
int list_orphans(struct xbps_handle *, const char *);
5757
int list_pkgs_pkgdb(struct xbps_handle *);
58-
int list_pkgdb(struct xbps_handle *, int (*filter)(xbps_object_t), const char *format);
58+
int list_pkgdb(struct xbps_handle *, int (*filter)(xbps_object_t), const char *format, int json);
5959

6060
int repo_list(struct xbps_handle *);
6161

bin/xbps-query/list.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include "defs.h"
3838
#include "xbps.h"
39+
#include "xbps/json.h"
3940

4041
struct length_max_cb {
4142
const char *key;
@@ -135,6 +136,7 @@ list_pkgs_pkgdb(struct xbps_handle *xhp)
135136

136137
struct list_pkgdb_cb {
137138
struct xbps_fmt *fmt;
139+
struct xbps_json_printer *json;
138140
int (*filter)(xbps_object_t obj);
139141
};
140142

@@ -153,23 +155,33 @@ list_pkgdb_cb(struct xbps_handle *xhp UNUSED, xbps_object_t obj,
153155
return 0;
154156
}
155157

156-
r = xbps_fmt_dictionary(ctx->fmt, obj, stdout);
157-
if (r < 0)
158-
return r;
159-
return 0;
158+
if (ctx->fmt) {
159+
r = xbps_fmt_dictionary(ctx->fmt, obj, stdout);
160+
} else if (ctx->json) {
161+
r = xbps_json_print_xbps_object(ctx->json, obj);
162+
} else {
163+
r = -ENOTSUP;
164+
}
165+
return r;
160166
}
161167

162168
int
163-
list_pkgdb(struct xbps_handle *xhp, int (*filter)(xbps_object_t), const char *format)
169+
list_pkgdb(struct xbps_handle *xhp, int (*filter)(xbps_object_t), const char *format, int json)
164170
{
165171
struct list_pkgdb_cb ctx = {.filter = filter};
172+
struct xbps_json_printer pr = {0};
166173
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;
174+
if (json > 0) {
175+
pr.indent = (json-1) * 2;
176+
pr.file = stdout;
177+
ctx.json = &pr;
178+
} else if (format) {
179+
ctx.fmt = xbps_fmt_parse(format);
180+
if (!ctx.fmt) {
181+
r = -errno;
182+
xbps_error_printf("failed to parse format: %s\n", strerror(-r));
183+
return r;
184+
}
173185
}
174186
r = xbps_pkgdb_foreach_cb(xhp, list_pkgdb_cb, &ctx);
175187
xbps_fmt_free(ctx.fmt);

bin/xbps-query/main.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <xbps.h>
3434

3535
#include "defs.h"
36+
#include "xbps.h"
37+
#include "xbps/json.h"
3638

3739
static void __attribute__((noreturn))
3840
usage(bool fail)
@@ -100,7 +102,7 @@ filter_repolock(xbps_object_t obj)
100102
int
101103
main(int argc, char **argv)
102104
{
103-
const char *shortopts = "C:c:dF:f:hHiLlMmOo:p:Rr:s:S:VvX:x:";
105+
const char *shortopts = "C:c:dF:f:hHiJLlMmOo:p:Rr:s:S:VvX:x:";
104106
const struct option longopts[] = {
105107
{ "config", required_argument, NULL, 'C' },
106108
{ "cachedir", required_argument, NULL, 'c' },
@@ -137,6 +139,7 @@ main(int argc, char **argv)
137139
bool list_pkgs, list_repos, orphans, own, list_repolock;
138140
bool list_manual, list_hold, show_prop, show_files, show_deps, show_rdeps;
139141
bool show, pkg_search, regex, repo_mode, opmode, fulldeptree;
142+
int json = 0;
140143

141144
rootdir = cachedir = confdir = props = pkg = catfile = format = NULL;
142145
flags = rv = c = 0;
@@ -165,6 +168,9 @@ main(int argc, char **argv)
165168
case 'F':
166169
format = optarg;
167170
break;
171+
case 'J':
172+
json++;
173+
break;
168174
case 'H':
169175
list_hold = opmode = true;
170176
break;
@@ -286,20 +292,21 @@ main(int argc, char **argv)
286292
rv = repo_list(&xh);
287293

288294
} else if (list_hold) {
289-
rv = list_pkgdb(&xh, filter_hold, format ? format : "{pkgver}\n") < 0;
295+
rv = list_pkgdb(&xh, filter_hold, format ? format : "{pkgver}\n", json) < 0;
290296

291297
} else if (list_repolock) {
292-
rv = list_pkgdb(&xh, filter_repolock, format ? format : "{pkgver}\n") < 0;
298+
rv = list_pkgdb(&xh, filter_repolock, format ? format : "{pkgver}\n", json) < 0;
293299

294300
} else if (list_manual) {
295-
rv = list_pkgdb(&xh, filter_manual, format ? format : "{pkgver}\n") < 0;
301+
rv = list_pkgdb(&xh, filter_manual, format ? format : "{pkgver}\n", json) < 0;
296302

297303
} else if (list_pkgs) {
298304
/* list available pkgs */
299-
if (format)
300-
rv = list_pkgdb(&xh, NULL, format);
301-
else
305+
if (format || json > 0) {
306+
rv = list_pkgdb(&xh, NULL, format, json);
307+
} else {
302308
rv = list_pkgs_pkgdb(&xh);
309+
}
303310

304311
} else if (orphans) {
305312
/* list pkg orphans */

include/xbps/json.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* SPDX-FileCopyrightText: Copyright 2023 Duncan Overbruck <[email protected]> */
2+
/* SPDX-License-Identifier: BSD-2-Clause */
3+
#ifndef _XBPS_JSON_H_
4+
#define _XBPS_JSON_H_
5+
6+
#include <stdio.h>
7+
#include <stdint.h>
8+
9+
#include <xbps/xbps_array.h>
10+
#include <xbps/xbps_bool.h>
11+
#include <xbps/xbps_dictionary.h>
12+
#include <xbps/xbps_number.h>
13+
#include <xbps/xbps_object.h>
14+
#include <xbps/xbps_string.h>
15+
16+
struct xbps_json_printer {
17+
FILE *file;
18+
unsigned depth;
19+
uint8_t indent;
20+
bool compact;
21+
};
22+
23+
24+
int xbps_json_printf(struct xbps_json_printer *p, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
25+
int xbps_json_print_escape(struct xbps_json_printer *p, const char *s);
26+
int xbps_json_print_quote(struct xbps_json_printer *p, const char *s);
27+
int xbps_json_print_bool(struct xbps_json_printer *p, bool b);
28+
29+
30+
int xbps_json_print_xbps_string(struct xbps_json_printer *p, xbps_string_t str);
31+
int xbps_json_print_xbps_number(struct xbps_json_printer *p, xbps_number_t num);
32+
int xbps_json_print_xbps_boolean(struct xbps_json_printer *p, xbps_bool_t b);
33+
int xbps_json_print_xbps_array(struct xbps_json_printer *p, xbps_array_t array);
34+
int xbps_json_print_xbps_dictionary(struct xbps_json_printer *p, xbps_dictionary_t dict);
35+
int xbps_json_print_xbps_object(struct xbps_json_printer *p, xbps_object_t obj);
36+
37+
#endif /* !_XBPS_JSON_H_ */

lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ OBJS += plist_remove.o plist_fetch.o util.o util_path.o util_hash.o
5151
OBJS += repo.o repo_sync.o
5252
OBJS += rpool.o cb_util.o proplib_wrapper.o
5353
OBJS += package_alternatives.o
54-
OBJS += conf.o log.o format.o
54+
OBJS += conf.o log.o format.o json.o
5555
OBJS += $(EXTOBJS) $(COMPAT_OBJS)
5656
# unnecessary unless pkgdb format changes
5757
# OBJS += pkgdb_conversion.o

lib/format.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <stdlib.h>
2929
#include <string.h>
3030

31+
#include "xbps/json.h"
3132
#include "xbps_api_impl.h"
3233
#include "compat.h"
3334

@@ -283,7 +284,7 @@ parse_default(const char **pos, struct xbps_fmt *fmt, struct strbuf *buf,
283284
}
284285

285286
struct xbps_fmt_conv {
286-
enum { HUMANIZE = 1, STRMODE } type;
287+
enum { HUMANIZE = 1, STRMODE, JSON } type;
287288
union {
288289
struct humanize {
289290
unsigned width : 8;
@@ -361,6 +362,10 @@ parse_conversion(const char **pos, struct xbps_fmt *fmt, struct xbps_fmt_conv *c
361362
fmt->conv->type = HUMANIZE;
362363
*pos += sizeof("humanize");
363364
return parse_humanize(pos, &fmt->conv->humanize);
365+
} else if (strncmp(*pos + 1, "json", sizeof("json") - 1) == 0) {
366+
fmt->conv->type = JSON;
367+
*pos += sizeof("json");
368+
return 0;
364369
}
365370
return -EINVAL;
366371
}
@@ -641,6 +646,12 @@ int
641646
xbps_fmt_print_string(const struct xbps_fmt *fmt, const char *str, size_t len, FILE *fp)
642647
{
643648
const struct xbps_fmt_spec *spec = fmt->spec;
649+
650+
if (fmt->conv && fmt->conv->type == JSON) {
651+
struct xbps_json_printer pr = {.file = fp};
652+
return xbps_json_print_quote(&pr, str);
653+
}
654+
644655
if (len == 0)
645656
len = strlen(str);
646657
if (spec && spec->align == '>' && spec->width > (unsigned)len) {
@@ -700,6 +711,7 @@ xbps_fmt_print_number(const struct xbps_fmt *fmt, int64_t d, FILE *fp)
700711
switch (fmt->conv->type) {
701712
case HUMANIZE: return humanize(&fmt->conv->humanize, fmt, d, fp);
702713
case STRMODE: return tostrmode(fmt, d, fp);
714+
case JSON: break;
703715
}
704716
}
705717
if (spec) {
@@ -732,6 +744,10 @@ xbps_fmt_print_number(const struct xbps_fmt *fmt, int64_t d, FILE *fp)
732744
int
733745
xbps_fmt_print_object(const struct xbps_fmt *fmt, xbps_object_t obj, FILE *fp)
734746
{
747+
if (fmt->conv && fmt->conv->type == JSON) {
748+
struct xbps_json_printer pr = {.file = fp};
749+
return xbps_json_print_xbps_object(&pr, obj);
750+
}
735751
switch (xbps_object_type(obj)) {
736752
case XBPS_TYPE_BOOL:
737753
return xbps_fmt_print_string(fmt, xbps_bool_true(obj) ? "true" : "false", 0, fp);

0 commit comments

Comments
 (0)