1
0
mirror of https://github.com/openSUSE/libsolv.git synced 2026-02-05 12:45:46 +01:00

add parser for rpm rich deps

This is work in progress, the rpm format may still change. Also,
THEN/ELSE ops are not yet supported.
This commit is contained in:
Michael Schroeder
2015-01-14 13:07:58 +01:00
parent 001152b744
commit 434eaa3a26
6 changed files with 207 additions and 13 deletions

View File

@@ -43,6 +43,11 @@ IF (ENABLE_SUSEREPO)
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)

138
ext/pool_parserpmrichdep.c Normal file
View File

@@ -0,0 +1,138 @@
/*
* 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;
}

View File

@@ -0,0 +1,15 @@
/*
* 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

View File

@@ -47,6 +47,9 @@
#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 */
@@ -147,6 +150,7 @@
#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)
@@ -404,7 +408,6 @@ setutf8string(Repodata *repodata, Id handle, Id tag, const char *str)
repodata_set_str(repodata, handle, tag, str);
}
/*
* strong: 0: ignore strongness
* 1: filter to strong
@@ -512,6 +515,7 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
ida = repo->idarraydata + olddeps;
for (i = 0; ; i++)
{
Id id;
if (i == nc)
{
if (haspre != 1)
@@ -532,9 +536,21 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
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;
@@ -542,15 +558,13 @@ makedeps(Pool *pool, Repo *repo, RpmHead *rpmhead, int tagn, int tagv, int tagf,
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;

View File

@@ -19,7 +19,9 @@
#include "tools_util.h"
#include "repo_rpmmd.h"
#include "chksum.h"
#ifdef ENABLE_COMPLEX_DEPS
#include "pool_parserpmrichdep.h"
#endif
enum state {
STATE_START,
@@ -466,7 +468,7 @@ static char *flagtab[] = {
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;
@@ -496,10 +498,18 @@ adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, const char **atts
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);
@@ -508,10 +518,8 @@ adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, const char **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

View File

@@ -18,6 +18,9 @@
#include "chksum.h"
#include "tools_util.h"
#include "repo_susetags.h"
#ifdef ENABLE_COMPLEX_DEPS
#include "pool_parserpmrichdep.h"
#endif
struct datashare {
Id name;
@@ -87,6 +90,17 @@ adddep(Pool *pool, struct parsedata *pd, unsigned int olddeps, char *line, Id ma
/* 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, ? */