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:
@@ -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
138
ext/pool_parserpmrichdep.c
Normal 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;
|
||||
}
|
||||
|
||||
15
ext/pool_parserpmrichdep.h
Normal file
15
ext/pool_parserpmrichdep.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ? */
|
||||
|
||||
Reference in New Issue
Block a user