7906c85c449e9ff68583a6c7aba0e891cbf085bc
[platform/upstream/libsolv.git] / tools / dumpsolv.c
1 /*
2  * Copyright (c) 2007, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12
13 static int with_attr = 0;
14
15 #include "pool.h"
16 #include "repo_solv.h"
17
18 static void
19 dump_repodata (Repo *repo)
20 {
21   unsigned i;
22   Repodata *data;
23   if (repo->nrepodata == 0)
24     return;
25   printf("repo refers to %d subfiles:\n", repo->nrepodata);
26   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
27     {
28       unsigned int j;
29       printf("%s has %d keys", data->location ? data->location : "**EMBED**", data->nkeys);
30       for (j = 1; j < data->nkeys; j++)
31         printf("\n  %s (type %d size %d storage %d)", id2str(repo->pool, data->keys[j].name), data->keys[j].type, data->keys[j].size, data->keys[j].storage);
32       printf("\n");
33     }
34   printf("\n");
35 }
36
37 static void
38 printids(Repo *repo, char *kind, Offset ido)
39 {
40   Pool *pool = repo->pool;
41   Id id, *ids;
42   if (!ido)
43     return;
44   printf("%s:\n", kind);
45   ids = repo->idarraydata + ido;
46   while((id = *ids++) != 0)
47     printf("  %s\n", dep2str(pool, id));
48 }
49
50 static void
51 printdir(Repodata *data, Id dir)
52 {
53   Id comp;
54   Id parent = dirpool_parent(&data->dirpool, dir);
55   if (parent)
56     {
57       printdir(data, parent);
58       putchar('/');
59     }
60   comp = dirpool_compid(&data->dirpool, dir);
61   if (data->localpool)
62     printf("%s", stringpool_id2str(&data->spool, comp));
63   else
64     printf("%s", id2str(data->repo->pool, comp));
65 }
66
67 int
68 dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
69 {
70   const char *keyname;
71
72   keyname = id2str(data->repo->pool, key->name);
73   switch(key->type)
74     {
75     case TYPE_ID:
76       if (data->localpool)
77         kv->str = stringpool_id2str(&data->spool, kv->id);
78       else
79         kv->str = id2str(data->repo->pool, kv->id);
80       printf("%s: %s\n", keyname, kv->str);
81       break;
82     case TYPE_STR:
83       printf("%s: %s\n", keyname, kv->str);
84       break;
85     case TYPE_VOID:
86       printf("%s\n", keyname);
87       break;
88     case TYPE_NUM:
89     case TYPE_CONSTANT:
90       printf("%s: %d\n", keyname, kv->num);
91       break;
92     case TYPE_DIRNUMNUMARRAY:
93       printf("%s: ", keyname);
94       printdir(data, kv->id);
95       printf(" %d %d\n", kv->num, kv->num2);
96       break;
97     case TYPE_DIRSTRARRAY:
98       printf("%s: ", keyname);
99       printdir(data, kv->id);
100       printf("/%s\n", kv->str);
101       break;
102     default:
103       printf("%s: ?\n", keyname);
104       break;
105     }
106   return 0;
107 }
108
109 /*
110  * dump all attributes for Id <p>
111  */
112
113 void
114 dump_repoattrs(Repo *repo, Id p)
115 {
116 #if 1
117   repo_search(repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE, dump_repoattrs_cb, 0);
118 #else
119   Dataiterator di;
120   dataiterator_init(&di, repo, p, 0, 0, SEARCH_NO_STORAGE_SOLVABLE);
121   while (dataiterator_step(&di))
122     dump_repoattrs_cb(0, repo->pool->solvables + di.solvid, di.data, di.key,
123                       &di.kv);
124 #endif
125 }
126
127 #if 0
128 void
129 dump_some_attrs(Repo *repo, Solvable *s)
130 {
131   Id name = str2id (repo->pool, "summary", 0);
132   const char *summary = 0;
133   unsigned int medianr = -1, downloadsize = -1;
134   unsigned int time = -1;
135   if (name)
136     summary = repo_lookup_str (s, name);
137   if ((name = str2id (repo->pool, "medianr", 0)))
138     medianr = repo_lookup_num (s, name);
139   if ((name = str2id (repo->pool, "downloadsize", 0)))
140     downloadsize = repo_lookup_num (s, name);
141   if ((name = str2id (repo->pool, "time", 0)))
142     time = repo_lookup_num (s, name);
143
144   printf ("  XXX %d %d %u %s\n", medianr, downloadsize, time, summary);
145 }
146 #endif
147
148
149 static FILE *
150 loadcallback (Pool *pool, Repodata *data, void *vdata)
151 {
152   FILE *fp = 0;
153   if (data->location && with_attr)
154     {
155       fprintf (stderr, "Loading SOLV file %s\n", data->location);
156       fp = fopen (data->location, "r");
157       if (!fp)
158         perror(data->location);
159     }
160   return fp;
161 }
162
163
164 static void
165 usage( const char *err )
166 {
167   if (err)
168     fprintf (stderr, "\n** Error:\n  %s\n", err);
169   fprintf( stderr, "\nUsage:\n"
170            "dumpsolv [-a] [<solvfile>]\n"
171            "  -a  read attributes.\n"
172            );
173   exit(0);
174 }
175
176 #if 0
177 static void
178 tryme (Repo *repo, Id p, Id keyname, const char *match, int flags)
179 {
180   Dataiterator di;
181   dataiterator_init(&di, repo, p, keyname, match, flags);
182   while (dataiterator_step(&di))
183     {
184       switch (di.key->type)
185         {
186           case TYPE_ID:
187           case TYPE_IDARRAY:
188               if (di.data && di.data->localpool)
189                 di.kv.str = stringpool_id2str(&di.data->spool, di.kv.id);
190               else
191                 di.kv.str = id2str(repo->pool, di.kv.id);
192               break;
193           case TYPE_STR:
194           case TYPE_DIRSTRARRAY:
195               break;
196           default:
197               di.kv.str = 0;
198         }
199       fprintf (stdout, "found: %d:%s %d %s %d %d %d\n",
200                di.solvid,
201                id2str(repo->pool, di.key->name),
202                di.kv.id,
203                di.kv.str, di.kv.num, di.kv.num2, di.kv.eof);
204     }
205 }
206 #endif
207
208 int main(int argc, char **argv)
209 {
210   Repo *repo;
211   Pool *pool;
212   int i, n;
213   Solvable *s;
214   
215   argv++;
216   argc--;
217   while (argc--)
218     {
219       const char *s = argv[0];
220       if (*s++ == '-')
221         while (*s)
222           switch (*s++)
223             {
224               case 'h': usage(NULL); break;
225               case 'a': with_attr = 1; break;
226               default : break;
227             }
228       else
229         {
230           if (freopen (argv[0], "r", stdin) == 0)
231             {
232               perror(argv[0]);
233               exit(1);
234             }
235           break;
236         }
237       argv++;
238     }
239
240   pool = pool_create();
241   pool_setdebuglevel(pool, 1);
242   pool_setloadcallback(pool, loadcallback, 0);
243
244   repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
245   if (repo_add_solv(repo, stdin))
246     printf("could not read repository\n");
247   dump_repodata (repo);
248   printf("repo contains %d solvables\n", repo->nsolvables);
249   for (i = repo->start, n = 1; i < repo->end; i++)
250     {
251       s = pool->solvables + i;
252       if (s->repo != repo)
253         continue;
254       printf("\n");
255       printf("solvable %d:\n", n);
256       if (s->name || s->evr || s->arch)
257         printf("name: %s %s %s\n", id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
258       if (s->vendor)
259         printf("vendor: %s\n", id2str(pool, s->vendor));
260       printids(repo, "provides", s->provides);
261       printids(repo, "obsoletes", s->obsoletes);
262       printids(repo, "conflicts", s->conflicts);
263       printids(repo, "requires", s->requires);
264       printids(repo, "recommends", s->recommends);
265       printids(repo, "suggests", s->suggests);
266       printids(repo, "supplements", s->supplements);
267       printids(repo, "enhances", s->enhances);
268       printids(repo, "freshens", s->freshens);
269       if (repo->rpmdbid)
270         printf("rpmdbid: %u\n", repo->rpmdbid[i - repo->start]);
271 #if 0
272       dump_attrs (repo, n - 1);
273 #endif
274       dump_repoattrs(repo, i);
275 #if 0
276       dump_some_attrs(repo, s);
277 #endif
278       n++;
279     }
280 #if 0
281   tryme(repo, 0, str2id (repo->pool, "medianr", 0), 0, 0);
282   printf("\n");
283   tryme(repo, 0, 0, 0, 0);
284   printf("\n");
285   tryme(repo, 0, 0, "*y*e*", SEARCH_GLOB);
286 #endif
287   pool_free(pool);
288   exit(0);
289 }