summaryrefslogtreecommitdiff
path: root/src/pool.h
blob: 1ae3b11ad941c9c203dc43d79ccd1e8f61482cbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
/*
 * Copyright (c) 2007, Novell Inc.
 *
 * This program is licensed under the BSD license, read LICENSE.BSD
 * for further information
 */

/*
 * pool.h
 *
 */

#ifndef LIBSOLV_POOL_H
#define LIBSOLV_POOL_H

#include <stdio.h>

#include "solvversion.h"
#include "pooltypes.h"
#include "poolid.h"
#include "solvable.h"
#include "bitmap.h"
#include "queue.h"
#include "strpool.h"

/* well known ids */
#include "knownid.h"

#ifdef __cplusplus
extern "C" {
#endif

/* well known solvable */
#define SYSTEMSOLVABLE		1


/*----------------------------------------------- */

struct _Repo;
struct _Repodata;
struct _Repokey;
struct _KeyValue;

typedef struct _Datapos {
  struct _Repo *repo;
  Id solvid;
  Id repodataid;
  Id schema;
  Id dp;
} Datapos;


#ifdef LIBSOLV_INTERNAL

/* how many strings to maintain (round robin) */
#define POOL_TMPSPACEBUF 16

struct _Pool_tmpspace {
  char *buf[POOL_TMPSPACEBUF];
  int   len[POOL_TMPSPACEBUF];
  int   n;
};

#endif

struct _Pool {
  void *appdata;		/* application private pointer */

  struct _Stringpool ss;

  Reldep *rels;			/* table of rels: Id -> Reldep */
  int nrels;			/* number of unique rels */

  struct _Repo **repos;
  int nrepos;			/* repos allocated */
  int urepos;			/* repos in use */

  struct _Repo *installed; 	/* packages considered installed */

  Solvable *solvables;
  int nsolvables;		/* solvables allocated */

  const char **languages;
  int nlanguages;

  /* package manager type, deb/rpm */
  int disttype;

  Id *id2arch;			/* map arch ids to scores */
  unsigned char *id2color;	/* map arch ids to colors */
  Id lastarch;			/* last valid entry in id2arch/id2color */

  Queue vendormap;		/* map vendor to vendorclasses mask */
  const char **vendorclasses;	/* vendor equivalence classes */

  /* providers data, as two-step indirect list
   * whatprovides[Id] -> Offset into whatprovidesdata for name
   * whatprovidesdata[Offset] -> 0-terminated list of solvables providing Id
   */
  Offset *whatprovides;		/* Offset to providers of a specific name, Id -> Offset  */
  Offset *whatprovides_rel;	/* Offset to providers of a specific relation, Id -> Offset  */

  Id *whatprovidesdata;		/* Ids of solvable providing Id */
  Offset whatprovidesdataoff;	/* next free slot within whatprovidesdata */
  int whatprovidesdataleft;	/* number of 'free slots' within whatprovidesdata */

  /* If nonzero, then consider only the solvables with Ids set in this
     bitmap for solving.  If zero, consider all solvables.  */
  Map *considered;

  /* callback for REL_NAMESPACE dependencies handled by the application  */
  Id (*nscallback)(struct _Pool *, void *data, Id name, Id evr);
  void *nscallbackdata;

  /* debug mask and callback */
  int  debugmask;
  void (*debugcallback)(struct _Pool *, void *data, int type, const char *str);
  void *debugcallbackdata;

  /* load callback */
  int (*loadcallback)(struct _Pool *, struct _Repodata *, void *);
  void *loadcallbackdata;

  /* search position */
  Datapos pos;

  Queue pooljobs;		/* fixed jobs, like USERINSTALLED/MULTIVERSION */

#ifdef LIBSOLV_INTERNAL
  /* flags to tell the library how the installed package manager works */
  int promoteepoch;		/* true: missing epoch is replaced by epoch of dependency   */
  int havedistepoch;		/* true: thr release part in the evr may contain a distepoch suffix */
  int obsoleteusesprovides;	/* true: obsoletes are matched against provides, not names */
  int implicitobsoleteusesprovides;	/* true: implicit obsoletes due to same name are matched against provides, not names */
  int obsoleteusescolors;	/* true: obsoletes check arch color */
  int implicitobsoleteusescolors;	/* true: implicit obsoletes check arch color */
  int noinstalledobsoletes;	/* true: ignore obsoletes of installed packages */
  int forbidselfconflicts;	/* true: packages which conflict with itself are not installable */
  int noobsoletesmultiversion;	/* true: obsoletes are ignored for multiversion installs */

  Id noarchid;			/* ARCH_NOARCH, ARCH_ALL, ARCH_ANY, ... */

  /* hash for rel unification */
  Hashtable relhashtbl;		/* hashtable: (name,evr,op)Hash -> Id */
  Hashval relhashmask;

  Id *languagecache;
  int languagecacheother;

  /* our tmp space string space */
  struct _Pool_tmpspace tmpspace;

  char *errstr;			/* last error string */
  int errstra;			/* allocated space for errstr */

  char *rootdir;

  int (*custom_vendorcheck)(struct _Pool *, Solvable *, Solvable *);

  int addfileprovidesfiltered;	/* 1: only use filtered file list for addfileprovides */
  int addedfileprovides;	/* true: application called addfileprovides */
  Queue lazywhatprovidesq;	/* queue to store old whatprovides offsets */
  int nowhatprovidesaux;	/* don't allocate and use the whatprovides aux helper */
  Offset *whatprovidesaux;
  Offset whatprovidesauxoff;
  Id *whatprovidesauxdata;
  Offset whatprovidesauxdataoff;

#endif
};

#define DISTTYPE_RPM	0
#define DISTTYPE_DEB	1
#define DISTTYPE_ARCH   2
#define DISTTYPE_HAIKU  3

#define SOLV_FATAL			(1<<0)
#define SOLV_ERROR			(1<<1)
#define SOLV_WARN			(1<<2)
#define SOLV_DEBUG_STATS		(1<<3)
#define SOLV_DEBUG_RULE_CREATION	(1<<4)
#define SOLV_DEBUG_PROPAGATE		(1<<5)
#define SOLV_DEBUG_ANALYZE		(1<<6)
#define SOLV_DEBUG_UNSOLVABLE		(1<<7)
#define SOLV_DEBUG_SOLUTIONS		(1<<8)
#define SOLV_DEBUG_POLICY		(1<<9)
#define SOLV_DEBUG_RESULT		(1<<10)
#define SOLV_DEBUG_JOB			(1<<11)
#define SOLV_DEBUG_SOLVER		(1<<12)
#define SOLV_DEBUG_TRANSACTION		(1<<13)

#define SOLV_DEBUG_TO_STDERR		(1<<30)

#define POOL_FLAG_PROMOTEEPOCH				1
#define POOL_FLAG_FORBIDSELFCONFLICTS			2
#define POOL_FLAG_OBSOLETEUSESPROVIDES			3
#define POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES		4
#define POOL_FLAG_OBSOLETEUSESCOLORS			5
#define POOL_FLAG_NOINSTALLEDOBSOLETES			6
#define POOL_FLAG_HAVEDISTEPOCH				7
#define POOL_FLAG_NOOBSOLETESMULTIVERSION		8
#define POOL_FLAG_ADDFILEPROVIDESFILTERED		9
#define POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS		10
#define POOL_FLAG_NOWHATPROVIDESAUX			11

/* ----------------------------------------------- */


/* mark dependencies with relation by setting bit31 */

#define MAKERELDEP(id) ((id) | 0x80000000)
#define ISRELDEP(id) (((id) & 0x80000000) != 0)
#define GETRELID(id) ((id) ^ 0x80000000)				/* returns Id */
#define GETRELDEP(pool, id) ((pool)->rels + ((id) ^ 0x80000000))	/* returns Reldep* */

#define REL_GT		1
#define REL_EQ		2
#define REL_LT		4

#define REL_AND		16
#define REL_OR		17
#define REL_WITH	18
#define REL_NAMESPACE	19
#define REL_ARCH	20
#define REL_FILECONFLICT	21
#define REL_COND	22
#define REL_COMPAT	23
#define REL_KIND	24	/* for filters only */
#define REL_MULTIARCH	25	/* debian multiarch annotation */
#define REL_ELSE	26	/* only as evr part of REL_COND */

#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(x)
#endif

extern Pool *pool_create(void);
extern void pool_free(Pool *pool);
extern void pool_freeallrepos(Pool *pool, int reuseids);

extern void pool_setdebuglevel(Pool *pool, int level);
extern int  pool_setdisttype(Pool *pool, int disttype);
extern int  pool_set_flag(Pool *pool, int flag, int value);
extern int  pool_get_flag(Pool *pool, int flag);

extern void pool_debug(Pool *pool, int type, const char *format, ...) __attribute__((format(printf, 3, 4)));
extern void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct _Pool *, void *data, int type, const char *str), void *debugcallbackdata);
extern void pool_setdebugmask(Pool *pool, int mask);
extern void pool_setloadcallback(Pool *pool, int (*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata);
extern void pool_setnamespacecallback(Pool *pool, Id (*cb)(struct _Pool *, void *, Id, Id), void *nscbdata);
extern void pool_flush_namespaceproviders(Pool *pool, Id ns, Id evr);

extern void pool_set_custom_vendorcheck(Pool *pool, int (*vendorcheck)(struct _Pool *, Solvable *, Solvable *));


extern char *pool_alloctmpspace(Pool *pool, int len);
extern void  pool_freetmpspace(Pool *pool, const char *space);
extern char *pool_tmpjoin(Pool *pool, const char *str1, const char *str2, const char *str3);
extern char *pool_tmpappend(Pool *pool, const char *str1, const char *str2, const char *str3);
extern const char *pool_bin2hex(Pool *pool, const unsigned char *buf, int len);

extern void pool_set_installed(Pool *pool, struct _Repo *repo);

extern int  pool_error(Pool *pool, int ret, const char *format, ...) __attribute__((format(printf, 3, 4)));
extern char *pool_errstr(Pool *pool);

extern void pool_set_rootdir(Pool *pool, const char *rootdir);
extern const char *pool_get_rootdir(Pool *pool);
extern char *pool_prepend_rootdir(Pool *pool, const char *dir);
extern const char *pool_prepend_rootdir_tmp(Pool *pool, const char *dir);

/**
 * Solvable management
 */
extern Id pool_add_solvable(Pool *pool);
extern Id pool_add_solvable_block(Pool *pool, int count);

extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
static inline Solvable *pool_id2solvable(const Pool *pool, Id p)
{
  return pool->solvables + p;
}

extern const char *pool_solvable2str(Pool *pool, Solvable *s);
static inline const char *pool_solvid2str(Pool *pool, Id p)
{
  return pool_solvable2str(pool, pool->solvables + p);
}

void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);

int pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr);
int pool_match_dep(Pool *pool, Id d1, Id d2);

/* semi private, used in pool_match_nevr */
int pool_match_nevr_rel(Pool *pool, Solvable *s, Id d);

static inline int pool_match_nevr(Pool *pool, Solvable *s, Id d)
{
  if (!ISRELDEP(d))
    return d == s->name;
  else
    return pool_match_nevr_rel(pool, s, d);
}


/**
 * Prepares a pool for solving
 */
extern void pool_createwhatprovides(Pool *pool);
extern void pool_addfileprovides(Pool *pool);
extern void pool_addfileprovides_queue(Pool *pool, Queue *idq, Queue *idqinst);
extern void pool_freewhatprovides(Pool *pool);
extern Id pool_queuetowhatprovides(Pool *pool, Queue *q);
extern Id pool_ids2whatprovides(Pool *pool, Id *ids, int count);
extern Id pool_searchlazywhatprovidesq(Pool *pool, Id d);

extern Id pool_addrelproviders(Pool *pool, Id d);

static inline Id pool_whatprovides(Pool *pool, Id d)
{
  if (!ISRELDEP(d))
    {
      if (pool->whatprovides[d])
	return pool->whatprovides[d];
    }
  else
    {
      Id v = GETRELID(d);
      if (pool->whatprovides_rel[v])
	return pool->whatprovides_rel[v];
    }
  return pool_addrelproviders(pool, d);
}

static inline Id *pool_whatprovides_ptr(Pool *pool, Id d)
{
  Id off = pool_whatprovides(pool, d);
  return pool->whatprovidesdata + off;
}

void pool_whatmatchesdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker);
void pool_whatcontainsdep(Pool *pool, Id keyname, Id dep, Queue *q, int marker);

/* search the pool. the following filters are available:
 *   p     - search just this solvable
 *   key   - search only this key
 *   match - key must match this string
 */
void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);

void pool_clear_pos(Pool *pool);

/* lookup functions */
const char *pool_lookup_str(Pool *pool, Id entry, Id keyname);
Id pool_lookup_id(Pool *pool, Id entry, Id keyname);
unsigned long long pool_lookup_num(Pool *pool, Id entry, Id keyname, unsigned long long notfound);
int pool_lookup_void(Pool *pool, Id entry, Id keyname);
const unsigned char *pool_lookup_bin_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
int pool_lookup_idarray(Pool *pool, Id entry, Id keyname, Queue *q);
const char *pool_lookup_checksum(Pool *pool, Id entry, Id keyname, Id *typep);
const char *pool_lookup_deltalocation(Pool *pool, Id entry, unsigned int *medianrp);


#define DUCHANGES_ONLYADD	1

typedef struct _DUChanges {
  const char *path;
  int kbytes;
  int files;
  int flags;
} DUChanges;


void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);
void pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps);
int  pool_calc_installsizechange(Pool *pool, Map *installedmap);

void pool_add_fileconflicts_deps(Pool *pool, Queue *conflicts);



/* loop over all providers of d */
#define FOR_PROVIDES(v, vp, d) 						\
  for (vp = pool_whatprovides(pool, d) ; (v = pool->whatprovidesdata[vp++]) != 0; )

/* loop over all repositories */
#define FOR_REPOS(repoid, r)						\
  for (repoid = 1; repoid < pool->nrepos; repoid++)			\
    if ((r = pool->repos[repoid]) == 0)					\
      continue;								\
    else

#define FOR_POOL_SOLVABLES(p)						\
  for (p = 2; p < pool->nsolvables; p++)				\
    if (pool->solvables[p].repo == 0)					\
      continue;								\
    else

#ifdef ENABLE_COMPS
#define ISCONDDEP(id) (ISRELDEP(id) && (GETRELDEP(pool, id))->flags == REL_COND)
#define MODIFYCONDDEP(id, tst) do { Reldep *condrd = GETRELDEP(pool, id); Id condp, condpp; FOR_PROVIDES(condrd->evr, condp, condpp) if (tst) break; id = condp ? condrd->name : 0;} while(0)
#endif

#define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
#define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)

/* weird suse stuff */
void pool_trivial_installable_multiversionmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *multiversionmap);
void pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res);

#ifdef __cplusplus
}
#endif


#endif /* LIBSOLV_POOL_H */