2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
19 #include "repo_solv.h"
23 dump_attr(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv)
29 keyname = pool_id2str(repo->pool, key->name);
30 for (kvp = kv; (kvp = kvp->parent) != 0; indent += 2)
35 if (data && data->localpool)
36 kv->str = stringpool_id2str(&data->spool, kv->id);
38 kv->str = pool_dep2str(repo->pool, kv->id);
39 printf("%s: %s\n", keyname, kv->str);
41 case REPOKEY_TYPE_CONSTANTID:
42 printf("%s: %s\n", keyname, pool_dep2str(repo->pool, kv->id));
44 case REPOKEY_TYPE_IDARRAY:
46 printf("%s:\n%*s", keyname, indent, "");
47 if (data && data->localpool)
48 printf(" %s\n", stringpool_id2str(&data->spool, kv->id));
50 printf(" %s\n", pool_dep2str(repo->pool, kv->id));
52 case REPOKEY_TYPE_STR:
53 printf("%s: %s\n", keyname, kv->str);
55 case REPOKEY_TYPE_VOID:
56 printf("%s: (void)\n", keyname);
58 case REPOKEY_TYPE_CONSTANT:
59 printf("%s: %u\n", keyname, kv->num);
61 case REPOKEY_TYPE_NUM:
62 printf("%s: %llu\n", keyname, SOLV_KV_NUM64(kv));
64 case REPOKEY_TYPE_BINARY:
66 printf("%s: %02x..%02x len %u\n", keyname, (unsigned char)kv->str[0], (unsigned char)kv->str[kv->num - 1], kv->num);
68 printf("%s: len 0\n", keyname);
70 case REPOKEY_TYPE_DIRNUMNUMARRAY:
72 printf("%s:\n%*s", keyname, indent, "");
73 printf(" %s %u %u\n", repodata_dir2str(data, kv->id, 0), kv->num, kv->num2);
75 case REPOKEY_TYPE_DIRSTRARRAY:
77 printf("%s:\n%*s", keyname, indent, "");
78 printf(" %s\n", repodata_dir2str(data, kv->id, kv->str));
80 case REPOKEY_TYPE_FIXARRAY:
81 case REPOKEY_TYPE_FLEXARRAY:
83 printf("%s:\n", keyname);
88 if (solv_chksum_len(key->type))
90 printf("%s: %s (%s)\n", keyname, repodata_chk2str(data, key->type, (unsigned char *)kv->str), solv_chksum_type2str(key->type));
93 printf("%s: ?\n", keyname);
100 jsonstring(Pool *pool, const char *s)
103 const unsigned char *s1;
106 for (s1 = (const unsigned char *)s; *s1; s1++)
109 needed += *s1 == '\n' ? 2 : 6;
110 else if (*s1 == '\\' || *s1 == '\"')
115 r = rp = pool_alloctmpspace(pool, needed + 3);
117 for (s1 = (const unsigned char *)s; *s1; s1++)
133 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
135 *rp++ = (x < 10 ? '0' : 'a' - 10) + x;
137 else if (*s1 == '\\' || *s1 == '\"')
151 unsigned char *first;
157 dump_attr_json(Repo *repo, Repodata *data, Repokey *key, KeyValue *kv, struct cbdata *cbdata)
159 Pool *pool = repo->pool;
162 int indent = cbdata->baseindent;
167 keyname = pool_id2str(repo->pool, key->name);
168 for (kvp = kv; (kvp = kvp->parent) != 0; indent += 4)
170 if (cbdata->nfirst < depth + 1)
172 cbdata->first = solv_realloc(cbdata->first, depth + 16);
173 memset(cbdata->first + cbdata->nfirst, 0, depth + 16 - cbdata->nfirst);
174 cbdata->nfirst = depth + 16;
178 case REPOKEY_TYPE_IDARRAY:
179 case REPOKEY_TYPE_DIRNUMNUMARRAY:
180 case REPOKEY_TYPE_DIRSTRARRAY:
183 case REPOKEY_TYPE_FIXARRAY:
184 case REPOKEY_TYPE_FLEXARRAY:
190 if (!isarray || !kv->entry)
192 if (cbdata->first[depth])
194 printf("%*s%s: ", indent, "", jsonstring(pool, keyname));
195 cbdata->first[depth] = 1;
197 if (isarray == 1 && !kv->entry)
198 printf("[\n%*s", indent + 2, "");
199 else if (isarray == 1 && kv->entry)
200 printf("%*s", indent + 2, "");
203 case REPOKEY_TYPE_ID:
204 if (data && data->localpool)
205 str = stringpool_id2str(&data->spool, kv->id);
207 str = pool_dep2str(repo->pool, kv->id);
208 printf("%s", jsonstring(pool, str));
210 case REPOKEY_TYPE_CONSTANTID:
211 str = pool_dep2str(repo->pool, kv->id);
212 printf("%s", jsonstring(pool, str));
214 case REPOKEY_TYPE_IDARRAY:
215 if (data && data->localpool)
216 str = stringpool_id2str(&data->spool, kv->id);
218 str = pool_dep2str(repo->pool, kv->id);
219 printf("%s", jsonstring(pool, str));
221 case REPOKEY_TYPE_STR:
223 printf("%s", jsonstring(pool, str));
225 case REPOKEY_TYPE_VOID:
228 case REPOKEY_TYPE_CONSTANT:
229 printf("%u", kv->num);
231 case REPOKEY_TYPE_NUM:
232 printf("%llu", SOLV_KV_NUM64(kv));
234 case REPOKEY_TYPE_BINARY:
235 printf("\"<binary>\"");
237 case REPOKEY_TYPE_DIRNUMNUMARRAY:
239 printf("%*s \"dir\": %s,\n", indent, "", jsonstring(pool, repodata_dir2str(data, kv->id, 0)));
240 printf("%*s \"num1\": %u,\n", indent, "", kv->num);
241 printf("%*s \"num2\": %u\n", indent, "", kv->num2);
242 printf("%*s }", indent, "");
244 case REPOKEY_TYPE_DIRSTRARRAY:
245 printf("%s", jsonstring(pool, repodata_dir2str(data, kv->id, kv->str)));
247 case REPOKEY_TYPE_FIXARRAY:
248 case REPOKEY_TYPE_FLEXARRAY:
249 cbdata->first[depth + 1] = 0;
255 printf("\n%*s },\n", indent, "");
257 printf("\n%*s }\n", indent, "");
260 printf("%*s {\n", indent, "");
262 printf("%*s]", indent, "");
265 if (solv_chksum_len(key->type))
268 printf("%*s \"value\": %s,\n", indent, "", jsonstring(pool, repodata_chk2str(data, key->type, (unsigned char *)kv->str)));
269 printf("%*s \"type\": %s\n", indent, "", jsonstring(pool, solv_chksum_type2str(key->type)));
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);