00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <stdio.h>
00017
00018 #include "pool.h"
00019 #include "poolid.h"
00020 #include "poolid_private.h"
00021 #include "util.h"
00022
00023
00024
00025
00026 Id
00027 str2id(Pool *pool, const char *str, int create)
00028 {
00029 int oldnstrings = pool->ss.nstrings;
00030 Id id = stringpool_str2id(&pool->ss, str, create);
00031 if (create && pool->whatprovides && oldnstrings != pool->ss.nstrings && (id & WHATPROVIDES_BLOCK) == 0)
00032 {
00033
00034 pool->whatprovides = sat_realloc(pool->whatprovides, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
00035 memset(pool->whatprovides + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
00036 }
00037 return id;
00038 }
00039
00040 Id
00041 strn2id(Pool *pool, const char *str, unsigned int len, int create)
00042 {
00043 int oldnstrings = pool->ss.nstrings;
00044 Id id = stringpool_strn2id(&pool->ss, str, len, create);
00045 if (create && pool->whatprovides && oldnstrings != pool->ss.nstrings && (id & WHATPROVIDES_BLOCK) == 0)
00046 {
00047
00048 pool->whatprovides = sat_realloc(pool->whatprovides, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
00049 memset(pool->whatprovides + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
00050 }
00051 return id;
00052 }
00053
00054 Id
00055 rel2id(Pool *pool, Id name, Id evr, int flags, int create)
00056 {
00057 Hashval h;
00058 unsigned int hh;
00059 Hashmask hashmask;
00060 int i;
00061 Id id;
00062 Hashtable hashtbl;
00063 Reldep *ran;
00064
00065 hashmask = pool->relhashmask;
00066 hashtbl = pool->relhashtbl;
00067 ran = pool->rels;
00068
00069
00070 if (pool->nrels * 2 > hashmask)
00071 {
00072 sat_free(pool->relhashtbl);
00073 pool->relhashmask = hashmask = mkmask(pool->nrels + REL_BLOCK);
00074 pool->relhashtbl = hashtbl = sat_calloc(hashmask + 1, sizeof(Id));
00075
00076 for (i = 1; i < pool->nrels; i++)
00077 {
00078 h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
00079 hh = HASHCHAIN_START;
00080 while (hashtbl[h])
00081 h = HASHCHAIN_NEXT(h, hh, hashmask);
00082 hashtbl[h] = i;
00083 }
00084 }
00085
00086
00087 h = relhash(name, evr, flags) & hashmask;
00088 hh = HASHCHAIN_START;
00089 while ((id = hashtbl[h]) != 0)
00090 {
00091 if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
00092 break;
00093 h = HASHCHAIN_NEXT(h, hh, hashmask);
00094 }
00095 if (id)
00096 return MAKERELDEP(id);
00097
00098 if (!create)
00099 return ID_NULL;
00100
00101 id = pool->nrels++;
00102
00103 pool->rels = sat_extend(pool->rels, id, 1, sizeof(Reldep), REL_BLOCK);
00104 hashtbl[h] = id;
00105 ran = pool->rels + id;
00106 ran->name = name;
00107 ran->evr = evr;
00108 ran->flags = flags;
00109
00110
00111 if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
00112 {
00113 pool->whatprovides_rel = sat_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset));
00114 memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
00115 }
00116 return MAKERELDEP(id);
00117 }
00118
00119
00120
00121
00122
00123 const char *
00124 id2str(const Pool *pool, Id id)
00125 {
00126 if (ISRELDEP(id))
00127 {
00128 Reldep *rd = GETRELDEP(pool, id);
00129 if (ISRELDEP(rd->name))
00130 return "REL";
00131 return pool->ss.stringspace + pool->ss.strings[rd->name];
00132 }
00133 return pool->ss.stringspace + pool->ss.strings[id];
00134 }
00135
00136 static const char *rels[] = {
00137 " ! ",
00138 #ifndef DEBIAN_SEMANTICS
00139 " > ",
00140 #else
00141 " >> ",
00142 #endif
00143 " = ",
00144 " >= ",
00145 #ifndef DEBIAN_SEMANTICS
00146 " < ",
00147 #else
00148 " << ",
00149 #endif
00150 " <> ",
00151 " <= ",
00152 " <=> "
00153 };
00154
00155
00156
00157 const char *
00158 id2rel(const Pool *pool, Id id)
00159 {
00160 Reldep *rd;
00161 if (!ISRELDEP(id))
00162 return "";
00163 rd = GETRELDEP(pool, id);
00164 switch (rd->flags)
00165 {
00166 case 0: case 1: case 2: case 3:
00167 case 4: case 5: case 6: case 7:
00168 return rels[rd->flags & 7];
00169 case REL_AND:
00170 return " & ";
00171 case REL_OR:
00172 return " | ";
00173 case REL_WITH:
00174 return " + ";
00175 case REL_NAMESPACE:
00176 return " NAMESPACE ";
00177 case REL_ARCH:
00178 return ".";
00179 case REL_FILECONFLICT:
00180 return " FILECONFLICT ";
00181 default:
00182 break;
00183 }
00184 return " ??? ";
00185 }
00186
00187
00188
00189
00190 const char *
00191 id2evr(const Pool *pool, Id id)
00192 {
00193 Reldep *rd;
00194 if (!ISRELDEP(id))
00195 return "";
00196 rd = GETRELDEP(pool, id);
00197 if (ISRELDEP(rd->evr))
00198 return "(REL)";
00199 return pool->ss.stringspace + pool->ss.strings[rd->evr];
00200 }
00201
00202 static int
00203 dep2strlen(const Pool *pool, Id id)
00204 {
00205 int l = 0;
00206
00207 while (ISRELDEP(id))
00208 {
00209 Reldep *rd = GETRELDEP(pool, id);
00210
00211 l += 2 + dep2strlen(pool, rd->name) + strlen(id2rel(pool, id));
00212 id = rd->evr;
00213 }
00214 return l + strlen(pool->ss.stringspace + pool->ss.strings[id]);
00215 }
00216
00217 static void
00218 dep2strcpy(const Pool *pool, char *p, Id id, int oldrel)
00219 {
00220 while (ISRELDEP(id))
00221 {
00222 Reldep *rd = GETRELDEP(pool, id);
00223 if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH)
00224 if (rd->flags == REL_AND || rd->flags == REL_OR || rd->flags == REL_WITH)
00225 if (oldrel != rd->flags)
00226 {
00227 *p++ = '(';
00228 dep2strcpy(pool, p, rd->name, rd->flags);
00229 p += strlen(p);
00230 strcpy(p, id2rel(pool, id));
00231 p += strlen(p);
00232 dep2strcpy(pool, p, rd->evr, rd->flags);
00233 strcat(p, ")");
00234 return;
00235 }
00236 dep2strcpy(pool, p, rd->name, rd->flags);
00237 p += strlen(p);
00238 if (rd->flags == REL_NAMESPACE)
00239 {
00240 *p++ = '(';
00241 dep2strcpy(pool, p, rd->evr, rd->flags);
00242 strcat(p, ")");
00243 return;
00244 }
00245 if (rd->flags == REL_FILECONFLICT)
00246 {
00247 *p = 0;
00248 return;
00249 }
00250 strcpy(p, id2rel(pool, id));
00251 p += strlen(p);
00252 id = rd->evr;
00253 oldrel = rd->flags;
00254 }
00255 strcpy(p, pool->ss.stringspace + pool->ss.strings[id]);
00256 }
00257
00258 const char *
00259 dep2str(Pool *pool, Id id)
00260 {
00261 char *p;
00262 if (!ISRELDEP(id))
00263 return pool->ss.stringspace + pool->ss.strings[id];
00264 p = pool_alloctmpspace(pool, dep2strlen(pool, id) + 1);
00265 dep2strcpy(pool, p, id, 0);
00266 return p;
00267 }
00268
00269 void
00270 pool_shrink_strings(Pool *pool)
00271 {
00272 stringpool_shrink(&pool->ss);
00273 }
00274
00275 void
00276 pool_shrink_rels(Pool *pool)
00277 {
00278 pool->rels = sat_extend_resize(pool->rels, pool->nrels, sizeof(Reldep), REL_BLOCK);
00279 }
00280
00281
00282
00283 void
00284 pool_freeidhashes(Pool *pool)
00285 {
00286 stringpool_freehash(&pool->ss);
00287 pool->relhashtbl = sat_free(pool->relhashtbl);
00288 pool->relhashmask = 0;
00289 }
00290
00291