Support for generating separate sub files and bugfixes in the reader
[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 #include "pool.h"
14 #include "repo_solv.h"
15 #if 0
16 #include "attr_store.h"
17 #include "attr_store_p.h"
18
19 static void
20 dump_attrs_1 (Attrstore *s, unsigned int entry)
21 {
22   attr_iterator ai;
23   FOR_ATTRS (s, entry, &ai)
24     {
25       fprintf (stdout, "%s:", id2str (s->pool, ai.name));
26       switch (ai.type)
27         {
28         case TYPE_ATTR_INT:
29           fprintf (stdout, "int  %u\n", ai.as_int);
30           break;
31         case TYPE_ATTR_CHUNK:
32           {
33             const char *str = attr_retrieve_blob (s, ai.as_chunk[0], ai.as_chunk[1]);
34             if (str)
35               fprintf (stdout, "blob %s\n", str);
36             else
37               fprintf (stdout, "blob %u+%u\n", ai.as_chunk[0], ai.as_chunk[1]);
38           }
39           break;
40         case TYPE_ATTR_STRING:
41           fprintf (stdout, "str  %s\n", ai.as_string);
42           break;
43         case TYPE_ATTR_INTLIST:
44           {
45             fprintf (stdout, "lint\n ");
46             while (1)
47               {
48                 int val;
49                 get_num (ai.as_numlist, val);
50                 fprintf (stdout, " %d", (val & 63) | ((val >> 1) & ~63));
51                 if (!(val & 64))
52                   break;
53               }
54             fprintf (stdout, "\n");
55             break;
56           }
57         case TYPE_ATTR_LOCALIDS:
58           {
59             fprintf (stdout, "lids");
60             while (1)
61               {
62                 Id val;
63                 get_num (ai.as_numlist, val);
64                 if (!val)
65                   break;
66                 fprintf (stdout, "\n  %s(%d)", localid2str (s, val), val);
67               }
68             fprintf (stdout, "\n");
69             break;
70           }
71         default:
72           fprintf (stdout, "\n");
73           break;
74         }
75     }
76 }
77
78 static void
79 dump_attrs (Repo *repo, unsigned int entry)
80 {
81   unsigned i;
82   for (i = 0; i < repo->nrepodata; i++)
83     {
84       Attrstore *s = repo->repodata[i].s;
85       if (s && entry < s->entries)
86         dump_attrs_1 (s, entry);
87     }
88 }
89 #endif
90
91 static void
92 dump_repodata (Repo *repo)
93 {
94   unsigned i;
95   Repodata *data;
96   if (repo->nrepodata == 0)
97     return;
98   printf("repo refers to %d subfiles:\n", repo->nrepodata);
99   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
100     {
101       unsigned int j;
102       printf("%s has %d keys", data->location ? data->location : "**EMBED**", data->nkeys);
103       for (j = 1; j < data->nkeys; j++)
104         printf("\n  %s", id2str(repo->pool, data->keys[j].name));
105       printf("\n");
106     }
107   printf("\n");
108 }
109
110 static void
111 printids(Repo *repo, char *kind, Offset ido)
112 {
113   Pool *pool = repo->pool;
114   Id id, *ids;
115   if (!ido)
116     return;
117   printf("%s:\n", kind);
118   ids = repo->idarraydata + ido;
119   while((id = *ids++) != 0)
120     printf("  %s\n", dep2str(pool, id));
121 }
122
123 static void
124 printdir(Repodata *data, Id dir)
125 {
126   Id comp;
127   Id parent = dirpool_parent(&data->dirpool, dir);
128   if (parent)
129     {
130       printdir(data, parent);
131       putchar('/');
132     }
133   comp = dirpool_compid(&data->dirpool, dir);
134   if (data->localpool)
135     printf("%s", stringpool_id2str(&data->spool, comp));
136   else
137     printf("%s", id2str(data->repo->pool, comp));
138 }
139
140 int
141 dump_repoattrs_cb(void *vcbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv)
142 {
143   const char *keyname;
144
145   keyname = id2str(data->repo->pool, key->name);
146   switch(key->type)
147     {
148     case TYPE_ID:
149       if (data->localpool)
150         kv->str = stringpool_id2str(&data->spool, kv->id);
151       else
152         kv->str = id2str(data->repo->pool, kv->id);
153       printf("%s: %s\n", keyname, kv->str);
154       break;
155     case TYPE_STR:
156       printf("%s: %s\n", keyname, kv->str);
157       break;
158     case TYPE_VOID:
159       printf("%s\n", keyname);
160       break;
161     case TYPE_NUM:
162     case TYPE_CONSTANT:
163       printf("%s: %d\n", keyname, kv->num);
164       break;
165     case TYPE_DIRNUMNUMARRAY:
166       printf("%s: ", keyname);
167       printdir(data, kv->id);
168       printf(" %d %d\n", kv->num, kv->num2);
169       break;
170     default:
171       printf("%s: ?\n", keyname);
172       break;
173     }
174   return 0;
175 }
176
177 void
178 dump_repoattrs(Repo *repo, Id p)
179 {
180   int i;
181   Repodata *data;
182   for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
183     {
184       if (data->state == REPODATA_STUB || data->state == REPODATA_ERROR)
185         continue;
186       if (p < data->start || p >= data->end)
187         continue;
188       repodata_search(data, p - data->start, 0, dump_repoattrs_cb, 0);
189     }
190 }
191
192 void
193 dump_some_attrs(Repo *repo, Solvable *s)
194 {
195   Id name = str2id (repo->pool, "summary", 0);
196   const char *summary = 0;
197   unsigned int medianr = -1, downloadsize = -1;
198   unsigned int time = -1;
199   if (name)
200     summary = repo_lookup_str (s, name);
201   if ((name = str2id (repo->pool, "medianr", 0)))
202     medianr = repo_lookup_num (s, name);
203   if ((name = str2id (repo->pool, "downloadsize", 0)))
204     downloadsize = repo_lookup_num (s, name);
205   if ((name = str2id (repo->pool, "time", 0)))
206     time = repo_lookup_num (s, name);
207
208   printf ("  XXX %d %d %u %s\n", medianr, downloadsize, time, summary);
209 }
210
211 static FILE *
212 loadcallback (Pool *pool, Repodata *data, void *vdata)
213 {
214   FILE *fp;
215   fprintf (stderr, "Loading SOLV file %s\n", data->location);
216   fp = fopen ("test.attr", "r");
217   return fp;
218 }
219
220 int main(int argc, char **argv)
221 {
222   Repo *repo;
223   Pool *pool;
224   int i, n;
225   Solvable *s;
226
227   if (argc != 1)
228     {
229       if (freopen(argv[1], "r", stdin) == 0)
230         {
231           perror(argv[1]);
232           exit(1);
233         }
234     }
235   pool = pool_create();
236   pool_setdebuglevel(pool, 1);
237   pool_setloadcallback(pool, loadcallback, 0);
238
239   repo = repo_create(pool, argc != 1 ? argv[1] : "<stdin>");
240   if (repo_add_solv(repo, stdin))
241     printf("could not read repository\n");
242   dump_repodata (repo);
243   printf("repo contains %d solvables\n", repo->nsolvables);
244   for (i = repo->start, n = 1; i < repo->end; i++)
245     {
246       s = pool->solvables + i;
247       if (s->repo != repo)
248         continue;
249       printf("\n");
250       printf("solvable %d:\n", n);
251       if (s->name || s->evr || s->arch)
252         printf("name: %s(%s) %s %s\n", id2str(pool, s->name) + s->kind, id2str(pool, s->name), id2str(pool, s->evr), id2str(pool, s->arch));
253       if (s->vendor)
254         printf("vendor: %s\n", id2str(pool, s->vendor));
255       printids(repo, "provides", s->provides);
256       printids(repo, "obsoletes", s->obsoletes);
257       printids(repo, "conflicts", s->conflicts);
258       printids(repo, "requires", s->requires);
259       printids(repo, "recommends", s->recommends);
260       printids(repo, "suggests", s->suggests);
261       printids(repo, "supplements", s->supplements);
262       printids(repo, "enhances", s->enhances);
263       printids(repo, "freshens", s->freshens);
264 #if 0
265       dump_attrs (repo, n - 1);
266 #endif
267       dump_repoattrs(repo, i);
268 #if 1
269       dump_some_attrs(repo, s);
270 #endif
271       n++;
272     }
273   pool_free(pool);
274   exit(0);
275 }