2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
17 #include "repo_solv.h"
21 dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
27 keyname = pool_id2str(repo->pool, key->name);
28 for (kvp = kv; (kvp = kvp->parent) != 0; indent += 2)
33 if (data && data->localpool)
34 kv->str = stringpool_id2str(&data->spool, kv->id);
36 kv->str = pool_dep2str(repo->pool, kv->id);
37 printf("%s: %s\n", keyname, kv->str);
39 case REPOKEY_TYPE_CONSTANTID:
40 printf("%s: %s\n", keyname, pool_dep2str(repo->pool, kv->id));
42 case REPOKEY_TYPE_IDARRAY:
44 printf("%s:\n%*s", keyname, indent, "");
45 if (data && data->localpool)
46 printf(" %s\n", stringpool_id2str(&data->spool, kv->id));
48 printf(" %s\n", pool_dep2str(repo->pool, kv->id));
50 case REPOKEY_TYPE_STR:
51 printf("%s: %s\n", keyname, kv->str);
53 case REPOKEY_TYPE_MD5:
54 case REPOKEY_TYPE_SHA1:
55 case REPOKEY_TYPE_SHA224:
56 case REPOKEY_TYPE_SHA256:
57 case REPOKEY_TYPE_SHA384:
58 case REPOKEY_TYPE_SHA512:
59 printf("%s: %s (%s)\n", keyname, repodata_chk2str(data, key->type, (unsigned char *)kv->str), pool_id2str(repo->pool, key->type));
61 case REPOKEY_TYPE_VOID:
62 printf("%s: (void)\n", keyname);
64 case REPOKEY_TYPE_U32:
65 case REPOKEY_TYPE_CONSTANT:
66 printf("%s: %u\n", keyname, kv->num);
68 case REPOKEY_TYPE_NUM:
69 printf("%s: %llu\n", keyname, SOLV_KV_NUM64(kv));
71 case REPOKEY_TYPE_BINARY:
73 printf("%s: %02x..%02x len %u\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num);
75 printf("%s: len 0\n", keyname);
77 case REPOKEY_TYPE_DIRNUMNUMARRAY:
79 printf("%s:\n%*s", keyname, indent, "");
80 printf(" %s %u %u\n", repodata_dir2str(data, kv->id, 0), kv->num, kv->num2);
82 case REPOKEY_TYPE_DIRSTRARRAY:
84 printf("%s:\n%*s", keyname, indent, "");
85 printf(" %s\n", repodata_dir2str(data, kv->id, kv->str));
87 case REPOKEY_TYPE_FIXARRAY:
88 case REPOKEY_TYPE_FLEXARRAY:
90 printf("%s:\n", keyname);
95 printf("%s: ?\n", keyname);
102 jsonstring(Pool *pool, const char *s)
105 const unsigned char *s1;
108 for (s1 = (const unsigned char *)s; *s1; s1++)
111 needed += *s1 == '\n' ? 2 : 6;
112 else if (*s1 == '\\' || *s1 == '\"')
117 r = rp = pool_alloctmpspace(pool, needed + 3);
119 for (s1 = (const unsigned char *)s; *s1; s1++)
135 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
137 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
139 else if (*s1 == '\\' || *s1 == '\"')
153 unsigned char *first;
159 dump_attr_json(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv, struct cbdata *cbdata)
161 Pool *pool = repo->pool;
164 int indent = cbdata->baseindent;
169 keyname = pool_id2str(repo->pool, key->name);
170 for (kvp = kv; (kvp = kvp->parent) != 0; indent += 4)
172 if (cbdata->nfirst < depth + 1)
174 cbdata->first = solv_realloc(cbdata->first, depth + 16);
175 memset(cbdata->first + cbdata->nfirst, 0, depth + 16 - cbdata->nfirst);
176 cbdata->nfirst = depth + 16;
180 case REPOKEY_TYPE_IDARRAY:
181 case REPOKEY_TYPE_DIRNUMNUMARRAY:
182 case REPOKEY_TYPE_DIRSTRARRAY:
185 case REPOKEY_TYPE_FIXARRAY:
186 case REPOKEY_TYPE_FLEXARRAY:
192 if (!isarray || !kv->entry)
194 if (cbdata->first[depth])
196 printf("%*s%s: ", indent, "", jsonstring(pool, keyname));
197 cbdata->first[depth] = 1;
199 if (isarray == 1 && !kv->entry)
200 printf("[\n%*s", indent + 2, "");
201 else if (isarray == 1 && kv->entry)
202 printf("%*s", indent + 2, "");
205 case REPOKEY_TYPE_ID:
206 if (data && data->localpool)
207 str = stringpool_id2str(&data->spool, kv->id);
209 str = pool_dep2str(repo->pool, kv->id);
210 printf("%s", jsonstring(pool, str));
212 case REPOKEY_TYPE_CONSTANTID:
213 str = pool_dep2str(repo->pool, kv->id);
214 printf("%s", jsonstring(pool, str));
216 case REPOKEY_TYPE_IDARRAY:
217 if (data && data->localpool)
218 str = stringpool_id2str(&data->spool, kv->id);
220 str = pool_dep2str(repo->pool, kv->id);
221 printf("%s", jsonstring(pool, str));
223 case REPOKEY_TYPE_STR:
225 printf("%s", jsonstring(pool, str));
227 case REPOKEY_TYPE_MD5:
228 case REPOKEY_TYPE_SHA1:
229 case REPOKEY_TYPE_SHA224:
230 case REPOKEY_TYPE_SHA256:
231 case REPOKEY_TYPE_SHA384:
232 case REPOKEY_TYPE_SHA512:
234 printf("%*s \"value\": %s,\n", indent, "", jsonstring(pool, repodata_chk2str(data, key->type, (unsigned char *)kv->str)));
235 printf("%*s \"type\": %s\n", indent, "", jsonstring(pool, pool_id2str(repo->pool, key->type)));
236 printf("%*s}", indent, "");
238 case REPOKEY_TYPE_VOID:
241 case REPOKEY_TYPE_U32:
242 case REPOKEY_TYPE_CONSTANT:
243 printf("%u", kv->num);
245 case REPOKEY_TYPE_NUM:
246 printf("%llu", SOLV_KV_NUM64(kv));
248 case REPOKEY_TYPE_BINARY:
249 printf("\"<binary>\"");
251 case REPOKEY_TYPE_DIRNUMNUMARRAY:
253 printf("%*s \"dir\": %s,\n", indent, "", jsonstring(pool, repodata_dir2str(data, kv->id, 0)));
254 printf("%*s \"num1\": %u,\n", indent, "", kv->num);
255 printf("%*s \"num2\": %u\n", indent, "", kv->num2);
256 printf("%*s }", indent, "");
258 case REPOKEY_TYPE_DIRSTRARRAY:
259 printf("%s", jsonstring(pool, repodata_dir2str(data, kv->id, kv->str)));
261 case REPOKEY_TYPE_FIXARRAY:
262 case REPOKEY_TYPE_FLEXARRAY:
263 cbdata->first[depth + 1] = 0;
269 printf("\n%*s },\n", indent, "");
271 printf("\n%*s }\n", indent, "");
274 printf("%*s {\n", indent, "");
276 printf("%*s]", indent, "");
287 printf("\n%*s]", indent, "");
293 dump_repodata_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
295 if (key->name == REPOSITORY_SOLVABLES)
296 return SEARCH_NEXT_SOLVABLE;
298 return dump_attr(data->repo, data, key, kv);
300 return dump_attr_json(data->repo, data, key, kv, vcbdata);
304 dump_repodata(Repo *repo)
308 if (repo->nrepodata == 0)
310 printf("repo contains %d repodata sections:\n", repo->nrepodata - 1);
311 FOR_REPODATAS(repo, i, data)
314 printf("\nrepodata %d has %d keys, %d schemata\n", i, data->nkeys - 1, data->nschemata - 1);
315 for (j = 1; j < data->nkeys; j++)
316 printf(" %s (type %s size %d storage %d)\n", pool_id2str(repo->pool, data->keys[j].name), pool_id2str(repo->pool, data->keys[j].type), data->keys[j].size, data->keys[j].storage);
318 printf(" localpool has %d strings, size is %d\n", data->spool.nstrings, data->spool.sstrings);
319 if (data->dirpool.ndirs)
320 printf(" localpool has %d directories\n", data->dirpool.ndirs);
322 repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repodata_cb, 0);
328 dump_repodata_json(Repo *repo, struct cbdata *cbdata)
332 if (repo->nrepodata == 0)
334 cbdata->baseindent = 6;
335 FOR_REPODATAS(repo, i, data)
336 repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repodata_cb, cbdata);
340 * dump all attributes for Id <p>
344 dump_solvable(Repo *repo, Id p, struct cbdata *cbdata)
347 dataiterator_init(&di, repo->pool, repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB);
348 if (cbdata && cbdata->first)
349 cbdata->first[0] = 0;
351 cbdata->baseindent = 10;
352 while (dataiterator_step(&di))
355 dump_attr(repo, di.data, di.key, &di.kv);
357 dump_attr_json(repo, di.data, di.key, &di.kv, cbdata);
359 dataiterator_free(&di);
363 loadcallback(Pool *pool, Repodata *data, void *vdata)
367 const char *location;
369 location = repodata_lookup_str(data, SOLVID_META, REPOSITORY_LOCATION);
370 if (!location || !with_attr)
372 fprintf(stderr, "[Loading SOLV file %s]\n", location);
373 fp = fopen (location, "r");
379 r = repo_add_solv(data->repo, fp, REPO_USE_LOADING|REPO_LOCALPOOL);
388 fprintf( stderr, "\nUsage:\n"
389 "dumpsolv [-a] [-j] [<solvfile>]\n"
390 " -a read attributes.\n"
391 " -j dump json format.\n"
396 int main(int argc, char **argv)
403 pool = pool_create();
404 pool_setloadcallback(pool, loadcallback, 0);
406 while ((c = getopt(argc, argv, "haj")) >= 0)
425 pool_setdebuglevel(pool, 1);
427 pool->debugmask |= SOLV_DEBUG_TO_STDERR;
428 for (; optind < argc; optind++)
430 if (freopen(argv[optind], "r", stdin) == 0)
432 perror(argv[optind]);
435 repo = repo_create(pool, argv[optind]);
436 if (repo_add_solv(repo, stdin, 0))
438 fprintf(stderr, "could not read repository: %s\n", pool_errstr(pool));
444 repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
445 if (repo_add_solv(repo, stdin, 0))
447 fprintf(stderr, "could not read repository: %s\n", pool_errstr(pool));
455 struct cbdata cbdata;
457 memset(&cbdata, 0, sizeof(cbdata));
459 printf(" \"repositories\": [\n");
470 dump_repodata_json(repo, &cbdata);
473 printf(" \"solvables\": [\n");
474 FOR_REPO_SOLVABLES(repo, i, s)
480 dump_solvable(repo, i, &cbdata);
490 solv_free(cbdata.first);
494 printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
499 printf("repo %d contains %d solvables\n", j, repo->nsolvables);
500 printf("repo start: %d end: %d\n", repo->start, repo->end);
501 FOR_REPO_SOLVABLES(repo, i, s)
505 printf("solvable %d (%d):\n", n, i);
506 dump_solvable(repo, i, 0);