repo_susetags.h repo_zyppdb.h)
ENDIF (ENABLE_SUSEREPO)
+IF (ENABLE_COMPLEX_DEPS AND (ENABLE_SUSEREPO OR ENABLE_RPMMD OR ENABLE_RPMDB))
+ SET (libsolvext_SRCS ${libsolvext_SRCS}
+ pool_parserpmrichdep.c)
+ENDIF (ENABLE_COMPLEX_DEPS AND (ENABLE_SUSEREPO OR ENABLE_RPMMD OR ENABLE_RPMDB))
+
IF (SUSE)
SET (libsolvext_SRCS ${libsolvext_SRCS}
repo_autopattern.c)
--- /dev/null
+/*
+ * Copyright (c) 2015, SUSE Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/* this is used by repo_rpmmd, repo_rpmdb, and repo_susetags */
+
+#include <stdio.h>
+
+#include "pool.h"
+#include "pool_parserpmrichdep.h"
+
+#define REL_THEN 0
+#define REL_ELSE 0
+
+static struct RichOpComp {
+ const char *n;
+ int l;
+ Id fl;
+} RichOps[] = {
+ { "&&", 2, REL_AND },
+ { "&", 1, REL_AND },
+ { "AND", 3, REL_AND },
+ { "||", 2, REL_OR },
+ { "|", 1, REL_OR },
+ { "OR", 2, REL_OR },
+ { "IF", 2, REL_COND },
+ { "THEN", 4, REL_THEN },
+ { "?", 1, REL_THEN },
+ { "ELSE", 4, REL_ELSE },
+ { ":", 1, REL_ELSE },
+ { NULL, 0, 0},
+};
+
+static Id
+parseRichDep(Pool *pool, const char **depp, Id chainfl)
+{
+ const char *p = *depp;
+ const char *n;
+ Id id, evr;
+ int fl, bl;
+ struct RichOpComp *op;
+
+ if (!chainfl && *p++ != '(')
+ return 0;
+ while (*p == ' ')
+ p++;
+ if (*p == ')')
+ return 0;
+ if (*p == '(')
+ {
+ id = parseRichDep(pool, &p, 0);
+ if (!id)
+ return 0;
+ }
+ else
+ {
+ n = p;
+ bl = 0;
+ while (*p && !(*p == ' ' || *p == ',' || (*p == ')' && bl-- <= 0)))
+ if (*p++ == '(')
+ bl++;
+ if (n == p)
+ return 0;
+ id = pool_strn2id(pool, n, p - n, 1);
+ while (*p == ' ')
+ p++;
+ if (*p)
+ {
+ fl = 0;
+ for (;; p++)
+ {
+ if (*p == '<')
+ fl |= REL_LT;
+ else if (*p == '=')
+ fl |= REL_EQ;
+ else if (*p == '>')
+ fl |= REL_GT;
+ else
+ break;
+ }
+ if (fl)
+ {
+ while (*p == ' ')
+ p++;
+ n = p;
+ bl = 0;
+ while (*p && !(*p == ' ' || *p == ',' || (*p == ')' && bl-- <= 0)))
+ if (*p++ == '(')
+ bl++;
+ if (p - n > 2 && n[0] == '0' && n[1] == ':')
+ n += 2; /* strip zero epoch */
+ if (n == p)
+ return 0;
+ id = pool_rel2id(pool, id, pool_strn2id(pool, n, p - n, 1), fl, 1);
+ }
+ }
+ }
+ while (*p == ' ')
+ p++;
+ if (!*p)
+ return 0;
+ if (*p == ')')
+ {
+ *depp = p + 1;
+ return id;
+ }
+ n = p;
+ while (*p && *p != ' ')
+ p++;
+ for (op = RichOps; op->n; op++)
+ if (p - n == op->l && !strncmp(n, op->n, op->l))
+ break;
+ fl = op->fl;
+ if (!fl)
+ return 0;
+ if (chainfl == REL_THEN && fl == REL_ELSE)
+ chainfl = 0;
+ if (chainfl && fl != chainfl)
+ return 0;
+ evr = parseRichDep(pool, &p, fl);
+ if (!evr)
+ return 0;
+ *depp = p;
+ return pool_rel2id(pool, id, evr, fl, 1);
+}
+
+Id
+pool_parserpmrichdep(Pool *pool, const char *dep)
+{
+ Id id = parseRichDep(pool, &dep, 0);
+ if (id && *dep)
+ id = 0;
+ return id;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2014, SUSE Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+#ifndef POOL_PARSERPMRICHDEP_H
+#define POOL_PARSERPMRICHDEP_H
+
+#include "pool.h"
+
+extern Id pool_parserpmrichdep(Pool *pool, const char *dep);
+
+#endif
#include "chksum.h"
#include "repo_rpmdb.h"
#include "repo_solv.h"
+#ifdef ENABLE_COMPLEX_DEPS
+#include "pool_parserpmrichdep.h"
+#endif
/* 3: added triggers */
/* 4: fixed triggers */
#define DEP_STRONG (1 << 27)
#define DEP_PRE_IN ((1 << 6) | (1 << 9) | (1 << 10))
#define DEP_PRE_UN ((1 << 6) | (1 << 11) | (1 << 12))
+#define DEP_RICH (1 << 29)
#define FILEFLAG_GHOST (1 << 6)
repodata_set_str(repodata, handle, tag, str);
}
-
/*
* strong: 0: ignore strongness
* 1: filter to strong
ida = repo->idarraydata + olddeps;
for (i = 0; ; i++)
{
+ Id id;
if (i == nc)
{
if (haspre != 1)
if ((flags & RPM_ADD_NO_RPMLIBREQS) != 0)
if (!strncmp(n[i], "rpmlib(", 7))
continue;
+#ifdef ENABLE_COMPLEX_DEPS
+ if ((flags & (DEP_RICH | DEP_LESS | DEP_EQUAL | DEP_GREATER)) == DEP_RICH && n[i][0] == '(')
+ {
+ id = pool_parserpmrichdep(pool, n[i]);
+ if (id)
+ *ida++ = id;
+ else
+ cc--;
+ continue;
+ }
+#endif
+ id = pool_str2id(pool, n[i], 1);
if (f[i] & (DEP_LESS|DEP_GREATER|DEP_EQUAL))
{
- Id name, evr;
+ Id evr;
int fl = 0;
if ((f[i] & DEP_LESS) != 0)
fl |= REL_LT;
fl |= REL_EQ;
if ((f[i] & DEP_GREATER) != 0)
fl |= REL_GT;
- name = pool_str2id(pool, n[i], 1);
if (v[i][0] == '0' && v[i][1] == ':' && v[i][2])
evr = pool_str2id(pool, v[i] + 2, 1);
else
evr = pool_str2id(pool, v[i], 1);
- *ida++ = pool_rel2id(pool, name, evr, fl, 1);
+ id = pool_rel2id(pool, id, evr, fl, 1);
}
- else
- *ida++ = pool_str2id(pool, n[i], 1);
+ *ida++ = id;
}
*ida++ = 0;
repo->idarraysize += cc + 1;
#include "tools_util.h"
#include "repo_rpmmd.h"
#include "chksum.h"
-
+#ifdef ENABLE_COMPLEX_DEPS
+#include "pool_parserpmrichdep.h"
+#endif
enum state {
STATE_START,
static unsigned int
adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, const char **atts, int isreq)
{
- Id id, name, marker;
+ Id id, marker;
const char *n, *f, *k;
const char **a;
pd->acontent = l + 256;
}
sprintf(pd->content, "%s:%s", k, n);
- name = pool_str2id(pool, pd->content, 1);
+ id = pool_str2id(pool, pd->content, 1);
+ }
+#ifdef ENABLE_COMPLEX_DEPS
+ else if (!f && n[0] == '(')
+ {
+ id = pool_parserpmrichdep(pool, n);
+ if (!id)
+ return olddeps;
}
+#endif
else
- name = pool_str2id(pool, (char *)n, 1);
+ id = pool_str2id(pool, (char *)n, 1);
if (f)
{
Id evr = makeevr_atts(pool, pd, atts);
if (!strcmp(f, flagtab[flags]))
break;
flags = flags < 6 ? flags + 1 : 0;
- id = pool_rel2id(pool, name, evr, flags, 1);
+ id = pool_rel2id(pool, id, evr, flags, 1);
}
- else
- id = name;
#if 0
fprintf(stderr, "new dep %s\n", pool_dep2str(pool, id));
#endif
#include "chksum.h"
#include "tools_util.h"
#include "repo_susetags.h"
+#ifdef ENABLE_COMPLEX_DEPS
+#include "pool_parserpmrichdep.h"
+#endif
struct datashare {
Id name;
/* A file dependency. Do not try to parse it */
id = pool_str2id(pool, line + 6, 1);
}
+#ifdef ENABLE_COMPLEX_DEPS
+ else if (line[6] == '(')
+ {
+ id = pool_parserpmrichdep(pool, line + 6);
+ if (!id)
+ {
+ pd->ret = pool_error(pool, -1, "susetags: line %d: bad dependency: '%s'\n", pd->lineno, line);
+ return olddeps;
+ }
+ }
+#endif
else
{
i = split(line + 6, sp, 4); /* name, <op>, evr, ? */