#include "solverdebug.h"
#include "chksum.h"
#include "testcase.h"
+#include "selection.h"
#include "solv_xfopen.h"
#define DISABLE_JOIN2
{ SOLVER_ERASE, "erase" },
{ SOLVER_UPDATE, "update" },
{ SOLVER_WEAKENDEPS, "weakendeps" },
- { SOLVER_NOOBSOLETES, "noobsoletes" },
+ { SOLVER_MULTIVERSION, "multiversion" },
+ { SOLVER_MULTIVERSION, "noobsoletes" }, /* old name */
{ SOLVER_LOCK, "lock" },
{ SOLVER_DISTUPGRADE, "distupgrade" },
{ SOLVER_VERIFY, "verify" },
{ POOL_FLAG_OBSOLETEUSESPROVIDES, "obsoleteusesprovides", 0 },
{ POOL_FLAG_IMPLICITOBSOLETEUSESPROVIDES, "implicitobsoleteusesprovides", 0 },
{ POOL_FLAG_OBSOLETEUSESCOLORS, "obsoleteusescolors", 0 },
+ { POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS, "implicitobsoleteusescolors", 0 },
{ POOL_FLAG_NOINSTALLEDOBSOLETES, "noinstalledobsoletes", 0 },
{ POOL_FLAG_HAVEDISTEPOCH, "havedistepoch", 0 },
+ { POOL_FLAG_NOOBSOLETESMULTIVERSION, "noobsoletesmultiversion", 0 },
+ { POOL_FLAG_ADDFILEPROVIDESFILTERED, "addfileprovidesfiltered", 0 },
{ 0, 0, 0 }
};
{ DISTTYPE_RPM, "rpm" },
{ DISTTYPE_DEB, "deb" },
{ DISTTYPE_ARCH, "arch" },
- { 0, 0 },
+ { DISTTYPE_HAIKU, "haiku" },
+ { 0, 0 }
+};
+
+static struct selflags2str {
+ Id flag;
+ const char *str;
+} selflags2str[] = {
+ { SELECTION_NAME, "name" },
+ { SELECTION_PROVIDES, "provides" },
+ { SELECTION_FILELIST, "filelist" },
+ { SELECTION_CANON, "canon" },
+ { SELECTION_DOTARCH, "dotarch" },
+ { SELECTION_REL, "rel" },
+ { SELECTION_INSTALLED_ONLY, "installedonly" },
+ { SELECTION_GLOB, "glob" },
+ { SELECTION_FLAT, "flat" },
+ { SELECTION_NOCASE, "nocase" },
+ { SELECTION_SOURCE_ONLY, "sourceonly" },
+ { SELECTION_WITH_SOURCE, "withsource" },
+ { 0, 0 }
};
+
typedef struct strqueue {
char **str;
int nstr;
return 1;
}
-Id
-testcase_str2dep(Pool *pool, char *s)
+static Id
+testcase_str2dep_simple(Pool *pool, const char **sp)
{
- char *n, *a;
- Id id;
+ const char *s = *sp;
+ const char *n, *a;
+ Id id, evr;
int flags;
- if ((n = strchr(s, '|')) != 0)
- {
- id = testcase_str2dep(pool, n + 1);
- *n = 0;
- id = pool_rel2id(pool, testcase_str2dep(pool, s), id, REL_OR, 1);
- *n = '|';
- return id;
- }
while (*s == ' ' || *s == '\t')
s++;
n = s;
{
while (*s && *s != ')')
s++;
+ continue;
}
- else
- s++;
+ s++;
}
if ((a = strchr(n, '.')) != 0 && a + 1 < s && s[-1] != ')')
{
else
id = pool_strn2id(pool, n, s - n, 1);
}
+ else if (s - n > 4 && s[-4] == ':' && !strncmp(s - 4, ":any", 4))
+ {
+ id = pool_strn2id(pool, n, s - n - 4, 1);
+ id = pool_rel2id(pool, id, ARCH_ANY, REL_MULTIARCH, 1);
+ }
else
id = pool_strn2id(pool, n, s - n, 1);
if (!*s)
- return id;
+ {
+ *sp = s;
+ return id;
+ }
while (*s == ' ' || *s == '\t')
s++;
flags = 0;
+ if (*s == '!' && s[1] == '=') /* support != as synonym for <> */
+ {
+ flags = REL_LT | REL_GT;
+ s += 2;
+ }
for (;;s++)
- {
+ {
if (*s == '<')
- flags |= REL_LT;
+ flags |= REL_LT;
else if (*s == '=')
- flags |= REL_EQ;
+ flags |= REL_EQ;
else if (*s == '>')
- flags |= REL_GT;
+ flags |= REL_GT;
else
- break;
+ break;
}
if (!flags)
- return id;
+ {
+ *sp = s;
+ return id;
+ }
while (*s == ' ' || *s == '\t')
s++;
n = s;
while (*s && *s != ' ' && *s != '\t')
s++;
- return pool_rel2id(pool, id, pool_strn2id(pool, n, s - n, 1), flags, 1);
+ evr = pool_strn2id(pool, n, s - n, 1);
+ if (*s == ' ' && !strcmp(s, " compat >= "))
+ {
+ s += 11;
+ while (*s == ' ' || *s == '\t')
+ s++;
+ n = s;
+ while (*s && *s != ' ' && *s != '\t')
+ s++;
+ evr = pool_rel2id(pool, evr, pool_strn2id(pool, n, s - n, 1), REL_COMPAT, 1);
+ }
+ *sp = s;
+ return pool_rel2id(pool, id, evr, flags, 1);
+}
+
+static Id
+testcase_str2dep_complex(Pool *pool, const char **sp)
+{
+ const char *s = *sp;
+ Id id;
+ id = testcase_str2dep_simple(pool, &s);
+ if (*s == '|')
+ {
+ s++;
+ id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_OR, 1);
+ }
+ else if (*s == '&')
+ {
+ s++;
+ id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_AND, 1);
+ }
+ else if (*s == 'I' && s[1] == 'F' && (s[2] == ' ' || s[2] == '\t'))
+ {
+ s += 2;
+ id = pool_rel2id(pool, id, testcase_str2dep_complex(pool, &s), REL_COND, 1);
+ }
+ *sp = s;
+ return id;
+}
+
+Id
+testcase_str2dep(Pool *pool, const char *s)
+{
+ return testcase_str2dep_complex(pool, &s);
}
const char *
n = pool_id2str(pool, s->name);
e = pool_id2str(pool, s->evr);
a = pool_id2str(pool, s->arch);
- str = pool_alloctmpspace(pool, strlen(n) + strlen(e) + strlen(a) + 3);
- sprintf(str, "%s-%s.%s", n, e, a);
+ str = pool_alloctmpspace(pool, strlen(n) + strlen(e) + strlen(a) + 3);
+ sprintf(str, "%s-%s.%s", n, e, a);
if (!s->repo)
return pool_tmpappend(pool, str, "@", 0);
if (s->repo->name)
return ret;
}
+static int
+str2selflags(Pool *pool, char *s) /* modifies the string! */
+{
+ int i, selflags = 0;
+ while (s)
+ {
+ char *se = strchr(s, ',');
+ if (se)
+ *se++ = 0;
+ for (i = 0; selflags2str[i].str; i++)
+ if (!strcmp(s, selflags2str[i].str))
+ {
+ selflags |= selflags2str[i].flag;
+ break;
+ }
+ if (!selflags2str[i].str)
+ pool_debug(pool, SOLV_ERROR, "str2job: unknown selection flag '%s'\n", s);
+ s = se;
+ }
+ return selflags;
+}
+
+static int
+str2jobflags(Pool *pool, char *s) /* modifies the string */
+{
+ int i, jobflags = 0;
+ while (s)
+ {
+ char *se = strchr(s, ',');
+ if (se)
+ *se++ = 0;
+ for (i = 0; jobflags2str[i].str; i++)
+ if (!strcmp(s, jobflags2str[i].str))
+ {
+ jobflags |= jobflags2str[i].flag;
+ break;
+ }
+ if (!jobflags2str[i].str)
+ pool_debug(pool, SOLV_ERROR, "str2job: unknown job flag '%s'\n", s);
+ s = se;
+ }
+ return jobflags;
+}
+
Id
testcase_str2job(Pool *pool, const char *str, Id *whatp)
{
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
for (i = 0; job2str[i].str; i++)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown job '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
job = job2str[i].job;
+ what = 0;
if (npieces > 3)
{
char *flags = pieces[npieces - 1];
- char *nf;
if (*flags == '[' && flags[strlen(flags) - 1] == ']')
{
npieces--;
flags++;
- flags[strlen(flags) - 1] = ',';
- while (*flags)
- {
- for (nf = flags; *nf != ','; nf++)
- ;
- *nf++ = 0;
- for (i = 0; jobflags2str[i].str; i++)
- if (!strcmp(flags, jobflags2str[i].str))
- break;
- if (!jobflags2str[i].str)
- {
- pool_debug(pool, SOLV_ERROR, "str2job: unknown jobflags in '%s'\n", str);
- solv_free(pieces);
- return 0;
- }
- job |= jobflags2str[i].flag;
- flags = nf;
- }
+ flags[strlen(flags) - 1] = 0;
+ job |= str2jobflags(pool, flags);
}
}
if (!strcmp(pieces[1], "pkg"))
{
pool_debug(pool, SOLV_ERROR, "str2job: bad pkg selector in '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
job |= SOLVER_SOLVABLE;
what = testcase_str2solvid(pool, pieces[2]);
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[2]);
solv_free(pieces);
- return 0;
+ return -1;
}
}
else if (!strcmp(pieces[1], "name") || !strcmp(pieces[1], "provides"))
pool_debug(pool, SOLV_ERROR, "str2job: unknown package '%s'\n", pieces[i]);
queue_free(&q);
solv_free(pieces);
- return 0;
+ return -1;
}
queue_push(&q, p);
}
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
repo = testcase_str2repo(pool, pieces[2]);
if (!repo)
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown repo '%s'\n", pieces[2]);
solv_free(pieces);
- return 0;
+ return -1;
}
job |= SOLVER_SOLVABLE_REPO;
what = repo->repoid;
{
pool_debug(pool, SOLV_ERROR, "str2job: bad line '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
job |= SOLVER_SOLVABLE_ALL;
what = 0;
{
pool_debug(pool, SOLV_ERROR, "str2job: unknown selection in '%s'\n", str);
solv_free(pieces);
- return 0;
+ return -1;
}
*whatp = what;
solv_free(pieces);
return job;
}
+int
+addselectionjob(Pool *pool, char **pieces, int npieces, Queue *jobqueue)
+{
+ Id job;
+ int i, r;
+ int selflags;
+ Queue sel;
+
+ for (i = 0; job2str[i].str; i++)
+ if (!strcmp(pieces[0], job2str[i].str))
+ break;
+ if (!job2str[i].str)
+ {
+ pool_debug(pool, SOLV_ERROR, "selstr2job: unknown job '%s'\n", pieces[0]);
+ return -1;
+ }
+ job = job2str[i].job;
+ if (npieces > 3)
+ {
+ char *flags = pieces[npieces - 1];
+ if (*flags == '[' && flags[strlen(flags) - 1] == ']')
+ {
+ npieces--;
+ flags++;
+ flags[strlen(flags) - 1] = 0;
+ job |= str2jobflags(pool, flags);
+ }
+ }
+ if (npieces < 4)
+ {
+ pool_debug(pool, SOLV_ERROR, "selstr2job: no selection flags\n");
+ return -1;
+ }
+ selflags = str2selflags(pool, pieces[3]);
+ queue_init(&sel);
+ r = selection_make(pool, &sel, pieces[2], selflags);
+ for (i = 0; i < sel.count; i += 2)
+ queue_push2(jobqueue, job | sel.elements[i], sel.elements[i + 1]);
+ queue_free(&sel);
+ return r;
+}
+
static void
writedeps(Repo *repo, FILE *fp, const char *tag, Id key, Solvable *s, Offset off)
{
if (nfilelist)
{
int l;
- Id did;
- for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1)
+ Id did;
+ for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1)
{
char *p = strrchr(filelist + l, '/');
- if (!p)
+ if (!p)
continue;
- *p++ = 0;
+ *p++ = 0;
did = repodata_str2dir(data, filelist + l, 1);
- p[-1] = '/';
+ p[-1] = '/';
if (!did)
did = repodata_str2dir(data, "/", 1);
repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, did, p);
linep += strlen(linep);
if (linep == line || linep[-1] != '\n')
continue;
- *--linep = 0;
+ linep[-1] = 0;
linep = line + intag;
if (intag)
{
Strqueue sq;
Queue q;
int i;
- void *chk;
+ Chksum *chk;
const unsigned char *md5;
int md5l;
const char *s;
{
Strqueue sq;
Queue q;
- void *chk;
+ Chksum *chk;
const unsigned char *md5;
int i, md5l;
const char *s;
testcase_solutionid(Solver *solv, Id problem, Id solution)
{
Id intid;
- void *chk;
+ Chksum *chk;
const unsigned char *md5;
int md5l;
const char *s;
pool_debug(solv->pool, SOLV_ERROR, "testcase_write: write error\n");
solv_free(result);
strqueue_free(&sq);
+ fclose(fp);
return 0;
}
if (fclose(fp))
{
pool_debug(solv->pool, SOLV_ERROR, "testcase_write: write error\n");
strqueue_free(&sq);
+ fclose(fp);
return 0;
}
if (fclose(fp))
char *result = solv_malloc(1024);
char *rp = result;
int resultl = 1024;
-
+
for (;;)
{
size_t rl;
char *result = solv_malloc(1024);
char *rp = result;
int resultl = 1024;
-
+
for (;;)
{
size_t rl;
return result;
}
+static int
+str2resultflags(Pool *pool, char *s) /* modifies the string! */
+{
+ int i, resultflags = 0;
+ while (s)
+ {
+ char *se = strchr(s, ',');
+ if (se)
+ *se++ = 0;
+ for (i = 0; resultflags2str[i].str; i++)
+ if (!strcmp(s, resultflags2str[i].str))
+ {
+ resultflags |= resultflags2str[i].flag;
+ break;
+ }
+ if (!resultflags2str[i].str)
+ pool_debug(pool, SOLV_ERROR, "result: unknown flag '%s'\n", s);
+ s = se;
+ }
+ return resultflags;
+}
+
Solver *
testcase_read(Pool *pool, FILE *fp, char *testcase, Queue *job, char **resultp, int *resultflagsp)
{
repo_add_solv(repo, rfp, 0);
fclose(rfp);
}
+#if 0
+ else if (!strcmp(repotype, "helix"))
+ {
+ extern int repo_add_helix(Repo *repo, FILE *fp, int flags);
+ repo_add_helix(repo, rfp, 0);
+ fclose(rfp);
+ }
+#endif
else
{
fclose(rfp);
pool_debug(pool, SOLV_ERROR, "testcase_read: system: cannot change disttype to '%s'\n", pieces[2]);
#endif
}
- if (strcmp(pieces[1], "unset") != 0)
- pool_setarch(pool, pieces[1]);
- else
+ if (strcmp(pieces[1], "unset") == 0)
pool_setarch(pool, 0);
+ else if (pieces[1][0] == ':')
+ pool_setarchpolicy(pool, pieces[1] + 1);
+ else
+ pool_setarch(pool, pieces[1]);
if (npieces > 3)
{
Repo *repo = testcase_str2repo(pool, pieces[3]);
pool_createwhatprovides(pool);
prepared = 1;
}
+ if (npieces >= 3 && !strcmp(pieces[2], "selection"))
+ {
+ addselectionjob(pool, pieces + 1, npieces - 1, job);
+ continue;
+ }
/* rejoin */
for (sp = pieces[1]; sp < pieces[npieces - 1]; sp++)
if (*sp == 0)
}
else if (!strcmp(pieces[0], "result") && npieces > 2)
{
- const char *rdata;
char *result = 0;
- int resultflags = 0;
- char *s = pieces[1];
- int i;
- while (s)
- {
- char *se = strchr(s, ',');
- if (se)
- *se++ = 0;
- for (i = 0; resultflags2str[i].str; i++)
- if (!strcmp(s, resultflags2str[i].str))
- {
- resultflags |= resultflags2str[i].flag;
- break;
- }
- if (!resultflags2str[i].str)
- pool_debug(pool, SOLV_ERROR, "result: unknown flag '%s'\n", s);
- s = se;
- }
-
- rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0);
+ int resultflags = str2resultflags(pool, pieces[1]);
+ const char *rdata = pool_tmpjoin(pool, testcasedir, pieces[2], 0);
if (!strcmp(pieces[2], "<inline>"))
result = read_inline_file(fp, &buf, &bufp, &bufl);
else