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_SHA256:
56 printf("%s: %s (%s)\n", keyname, repodata_chk2str(data, key->type, (unsigned char *)kv->str), pool_id2str(repo->pool, key->type));
58 case REPOKEY_TYPE_VOID:
59 printf("%s: (void)\n", keyname);
61 case REPOKEY_TYPE_U32:
62 case REPOKEY_TYPE_CONSTANT:
63 printf("%s: %u\n", keyname, kv->num);
65 case REPOKEY_TYPE_NUM:
66 printf("%s: %llu\n", keyname, SOLV_KV_NUM64(kv));
68 case REPOKEY_TYPE_BINARY:
70 printf("%s: %02x..%02x len %u\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num);
72 printf("%s: len 0\n", keyname);
74 case REPOKEY_TYPE_DIRNUMNUMARRAY:
76 printf("%s:\n%*s", keyname, indent, "");
77 printf(" %s %u %u\n", repodata_dir2str(data, kv->id, 0), kv->num, kv->num2);
79 case REPOKEY_TYPE_DIRSTRARRAY:
81 printf("%s:\n%*s", keyname, indent, "");
82 printf(" %s\n", repodata_dir2str(data, kv->id, kv->str));
84 case REPOKEY_TYPE_FIXARRAY:
85 case REPOKEY_TYPE_FLEXARRAY:
87 printf("%s:\n", keyname);
92 printf("%s: ?\n", keyname);
99 jsonstring(Pool *pool, const char *s)
102 const unsigned char *s1;
105 for (s1 = (const unsigned char *)s; *s1; s1++)
108 needed += *s1 == '\n' ? 2 : 6;
109 else if (*s1 == '\\' || *s1 == '\"')
114 r = rp = pool_alloctmpspace(pool, needed + 3);
116 for (s1 = (const unsigned char *)s; *s1; s1++)
132 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
134 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
136 else if (*s1 == '\\' || *s1 == '\"')
150 unsigned char *first;
156 dump_attr_json(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv, struct cbdata *cbdata)
158 Pool *pool = repo->pool;
161 int indent = cbdata->baseindent;
166 keyname = pool_id2str(repo->pool, key->name);
167 for (kvp = kv; (kvp = kvp->parent) != 0; indent += 4)
169 if (cbdata->nfirst < depth + 1)
171 cbdata->first = solv_realloc(cbdata->first, depth + 16);
172 memset(cbdata->first + cbdata->nfirst, 0, depth + 16 - cbdata->nfirst);
173 cbdata->nfirst = depth + 16;
177 case REPOKEY_TYPE_IDARRAY:
178 case REPOKEY_TYPE_DIRNUMNUMARRAY:
179 case REPOKEY_TYPE_DIRSTRARRAY:
182 case REPOKEY_TYPE_FIXARRAY:
183 case REPOKEY_TYPE_FLEXARRAY:
189 if (!isarray || !kv->entry)
191 if (cbdata->first[depth])
193 printf("%*s%s: ", indent, "", jsonstring(pool, keyname));
194 cbdata->first[depth] = 1;
196 if (isarray == 1 && !kv->entry)
197 printf("[\n%*s", indent + 2, "");
198 else if (isarray == 1 && kv->entry)
199 printf("%*s", indent + 2, "");
202 case REPOKEY_TYPE_ID:
203 if (data && data->localpool)
204 str = stringpool_id2str(&data->spool, kv->id);
206 str = pool_dep2str(repo->pool, kv->id);
207 printf("%s", jsonstring(pool, str));
209 case REPOKEY_TYPE_CONSTANTID:
210 str = pool_dep2str(repo->pool, kv->id);
211 printf("%s", jsonstring(pool, str));
213 case REPOKEY_TYPE_IDARRAY:
214 if (data && data->localpool)
215 str = stringpool_id2str(&data->spool, kv->id);
217 str = pool_dep2str(repo->pool, kv->id);
218 printf("%s", jsonstring(pool, str));
220 case REPOKEY_TYPE_STR:
222 printf("%s", jsonstring(pool, str));
224 case REPOKEY_TYPE_MD5:
225 case REPOKEY_TYPE_SHA1:
226 case REPOKEY_TYPE_SHA256:
228 printf("%*s \"value\": %s,\n", indent, "", jsonstring(pool, repodata_chk2str(data, key->type, (unsigned char *)kv->str)));
229 printf("%*s \"type\": %s\n", indent, "", jsonstring(pool, pool_id2str(repo->pool, key->type)));
230 printf("%*s}", indent, "");
232 case REPOKEY_TYPE_VOID:
235 case REPOKEY_TYPE_U32:
236 case REPOKEY_TYPE_CONSTANT:
237 printf("%u", kv->num);
239 case REPOKEY_TYPE_NUM:
240 printf("%llu", SOLV_KV_NUM64(kv));
242 case REPOKEY_TYPE_BINARY:
243 printf("\"<binary>\"");
245 case REPOKEY_TYPE_DIRNUMNUMARRAY:
247 printf("%*s \"dir\": %s,\n", indent, "", jsonstring(pool, repodata_dir2str(data, kv->id, 0)));
248 printf("%*s \"num1\": %u,\n", indent, "", kv->num);
249 printf("%*s \"num2\": %u\n", indent, "", kv->num2);
250 printf("%*s }", indent, "");
252 case REPOKEY_TYPE_DIRSTRARRAY:
253 printf("%s", jsonstring(pool, repodata_dir2str(data, kv->id, kv->str)));
255 case REPOKEY_TYPE_FIXARRAY:
256 case REPOKEY_TYPE_FLEXARRAY:
257 cbdata->first[depth + 1] = 0;
263 printf("\n%*s },\n", indent, "");
265 printf("\n%*s }\n", indent, "");
268 printf("%*s {\n", indent, "");
270 printf("%*s]", indent, "");
281 printf("\n%*s]", indent, "");
287 dump_repodata_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
289 if (key->name == REPOSITORY_SOLVABLES)
290 return SEARCH_NEXT_SOLVABLE;
292 return dump_attr(data->repo, data, key, kv);
294 return dump_attr_json(data->repo, data, key, kv, vcbdata);
298 dump_repodata(Repo *repo)
302 if (repo->nrepodata == 0)
304 printf("repo contains %d repodata sections:\n", repo->nrepodata - 1);
305 FOR_REPODATAS(repo, i, data)
308 printf("\nrepodata %d has %d keys, %d schemata\n", i, data->nkeys - 1, data->nschemata - 1);
309 for (j = 1; j < data->nkeys; j++)
310 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);
312 printf(" localpool has %d strings, size is %d\n", data->spool.nstrings, data->spool.sstrings);
313 if (data->dirpool.ndirs)
314 printf(" localpool has %d directories\n", data->dirpool.ndirs);
316 repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repodata_cb, 0);
322 dump_repodata_json(Repo *repo, struct cbdata *cbdata)
326 if (repo->nrepodata == 0)
328 cbdata->baseindent = 6;
329 FOR_REPODATAS(repo, i, data)
330 repodata_search(data, SOLVID_META, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB, dump_repodata_cb, cbdata);
334 * dump all attributes for Id <p>
338 dump_solvable(Repo *repo, Id p, struct cbdata *cbdata)
341 dataiterator_init(&di, repo->pool, repo, p, 0, 0, SEARCH_ARRAYSENTINEL|SEARCH_SUB);
342 if (cbdata && cbdata->first)
343 cbdata->first[0] = 0;
345 cbdata->baseindent = 10;
346 while (dataiterator_step(&di))
349 dump_attr(repo, di.data, di.key, &di.kv);
351 dump_attr_json(repo, di.data, di.key, &di.kv, cbdata);
353 dataiterator_free(&di);
357 loadcallback(Pool *pool, Repodata *data, void *vdata)
361 const char *location;
363 location = repodata_lookup_str(data, SOLVID_META, REPOSITORY_LOCATION);
364 if (!location || !with_attr)
366 fprintf(stderr, "[Loading SOLV file %s]\n", location);
367 fp = fopen (location, "r");
373 r = repo_add_solv(data->repo, fp, REPO_USE_LOADING|REPO_LOCALPOOL);
382 fprintf( stderr, "\nUsage:\n"
383 "dumpsolv [-a] [-j] [<solvfile>]\n"
384 " -a read attributes.\n"
385 " -j dump json format.\n"
390 int main(int argc, char **argv)
397 pool = pool_create();
398 pool_setloadcallback(pool, loadcallback, 0);
400 while ((c = getopt(argc, argv, "haj")) >= 0)
419 pool_setdebuglevel(pool, 1);
421 pool->debugmask |= SOLV_DEBUG_TO_STDERR;
422 for (; optind < argc; optind++)
424 if (freopen(argv[optind], "r", stdin) == 0)
426 perror(argv[optind]);
429 repo = repo_create(pool, argv[optind]);
430 if (repo_add_solv(repo, stdin, 0))
432 fprintf(stderr, "could not read repository: %s\n", pool_errstr(pool));
438 repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
439 if (repo_add_solv(repo, stdin, 0))
441 fprintf(stderr, "could not read repository: %s\n", pool_errstr(pool));
449 struct cbdata cbdata;
451 memset(&cbdata, 0, sizeof(cbdata));
453 printf(" \"repositories\": [\n");
464 dump_repodata_json(repo, &cbdata);
467 printf(" \"solvables\": [\n");
468 FOR_REPO_SOLVABLES(repo, i, s)
474 dump_solvable(repo, i, &cbdata);
484 solv_free(cbdata.first);
488 printf("pool contains %d strings, %d rels, string size is %d\n", pool->ss.nstrings, pool->nrels, pool->ss.sstrings);
493 printf("repo %d contains %d solvables\n", j, repo->nsolvables);
494 printf("repo start: %d end: %d\n", repo->start, repo->end);
495 FOR_REPO_SOLVABLES(repo, i, s)
499 printf("solvable %d (%d):\n", n, i);
500 dump_solvable(repo, i, 0);