|
Packit Service |
ff689b |
/*
|
|
Packit Service |
ff689b |
* Copyright (c) 2015, SUSE Inc.
|
|
Packit Service |
ff689b |
*
|
|
Packit Service |
ff689b |
* This program is licensed under the BSD license, read LICENSE.BSD
|
|
Packit Service |
ff689b |
* for further information
|
|
Packit Service |
ff689b |
*/
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
/* this is used by repo_rpmmd, repo_rpmdb, and repo_susetags */
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
#include <stdio.h>
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
#include "pool.h"
|
|
Packit Service |
ff689b |
#include "pool_parserpmrichdep.h"
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
static struct RichOpComp {
|
|
Packit Service |
ff689b |
const char *n;
|
|
Packit Service |
ff689b |
int l;
|
|
Packit Service |
ff689b |
Id fl;
|
|
Packit Service |
ff689b |
} RichOps[] = {
|
|
Packit Service |
ff689b |
{ "and", 3, REL_AND },
|
|
Packit Service |
ff689b |
{ "or", 2, REL_OR },
|
|
Packit Service |
ff689b |
{ "if", 2, REL_COND },
|
|
Packit Service |
ff689b |
{ "unless", 6, REL_UNLESS },
|
|
Packit Service |
ff689b |
{ "else", 4, REL_ELSE },
|
|
Packit Service |
ff689b |
{ "with", 4, REL_WITH },
|
|
Packit Service |
ff689b |
{ "without", 7, REL_WITHOUT },
|
|
Packit Service |
ff689b |
{ NULL, 0, 0},
|
|
Packit Service |
ff689b |
};
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
static inline const char *
|
|
Packit Service |
ff689b |
skipnonwhite(const char *p)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
int bl = 0;
|
|
Packit Service |
ff689b |
while (*p && !(*p == ' ' || *p == ',' || (*p == ')' && bl-- <= 0)))
|
|
Packit Service |
ff689b |
if (*p++ == '(')
|
|
Packit Service |
ff689b |
bl++;
|
|
Packit Service |
ff689b |
return p;
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
static Id
|
|
Packit Service |
ff689b |
parseRichDep(Pool *pool, const char **depp, Id chainfl)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
const char *p = *depp;
|
|
Packit Service |
ff689b |
const char *n;
|
|
Packit Service |
ff689b |
Id id, evr;
|
|
Packit Service |
ff689b |
int fl;
|
|
Packit Service |
ff689b |
struct RichOpComp *op;
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
if (!chainfl && *p++ != '(')
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
while (*p == ' ')
|
|
Packit Service |
ff689b |
p++;
|
|
Packit Service |
ff689b |
if (*p == ')')
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
if (*p == '(')
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
id = parseRichDep(pool, &p, 0);
|
|
Packit Service |
ff689b |
if (!id)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
else
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
n = p;
|
|
Packit Service |
ff689b |
p = skipnonwhite(p);
|
|
Packit Service |
ff689b |
if (n == p)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
id = pool_strn2id(pool, n, p - n, 1);
|
|
Packit Service |
ff689b |
while (*p == ' ')
|
|
Packit Service |
ff689b |
p++;
|
|
Packit Service |
ff689b |
if (*p)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
fl = 0;
|
|
Packit Service |
ff689b |
for (;; p++)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
if (*p == '<')
|
|
Packit Service |
ff689b |
fl |= REL_LT;
|
|
Packit Service |
ff689b |
else if (*p == '=')
|
|
Packit Service |
ff689b |
fl |= REL_EQ;
|
|
Packit Service |
ff689b |
else if (*p == '>')
|
|
Packit Service |
ff689b |
fl |= REL_GT;
|
|
Packit Service |
ff689b |
else
|
|
Packit Service |
ff689b |
break;
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
if (fl)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
while (*p == ' ')
|
|
Packit Service |
ff689b |
p++;
|
|
Packit Service |
ff689b |
n = p;
|
|
Packit Service |
ff689b |
p = skipnonwhite(p);
|
|
Packit Service |
ff689b |
if (p - n > 2 && n[0] == '0' && n[1] == ':')
|
|
Packit Service |
ff689b |
n += 2; /* strip zero epoch */
|
|
Packit Service |
ff689b |
if (n == p)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
id = pool_rel2id(pool, id, pool_strn2id(pool, n, p - n, 1), fl, 1);
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
while (*p == ' ')
|
|
Packit Service |
ff689b |
p++;
|
|
Packit Service |
ff689b |
if (!*p)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
if (*p == ')')
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
*depp = p + 1;
|
|
Packit Service |
ff689b |
return id;
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
n = p;
|
|
Packit Service |
ff689b |
while (*p && *p != ' ')
|
|
Packit Service |
ff689b |
p++;
|
|
Packit Service |
ff689b |
for (op = RichOps; op->n; op++)
|
|
Packit Service |
ff689b |
if (p - n == op->l && !strncmp(n, op->n, op->l))
|
|
Packit Service |
ff689b |
break;
|
|
Packit Service |
ff689b |
fl = op->fl;
|
|
Packit Service |
ff689b |
if (!fl)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
if ((chainfl == REL_COND || chainfl == REL_UNLESS) && fl == REL_ELSE)
|
|
Packit Service |
ff689b |
chainfl = 0;
|
|
Packit Service |
ff689b |
if (chainfl && fl != chainfl)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
evr = parseRichDep(pool, &p, fl);
|
|
Packit Service |
ff689b |
if (!evr)
|
|
Packit Service |
ff689b |
return 0;
|
|
Packit Service |
ff689b |
*depp = p;
|
|
Packit Service |
ff689b |
return pool_rel2id(pool, id, evr, fl, 1);
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
|
|
Packit Service |
ff689b |
Id
|
|
Packit Service |
ff689b |
pool_parserpmrichdep(Pool *pool, const char *dep)
|
|
Packit Service |
ff689b |
{
|
|
Packit Service |
ff689b |
Id id = parseRichDep(pool, &dep, 0);
|
|
Packit Service |
ff689b |
if (id && *dep)
|
|
Packit Service |
ff689b |
id = 0;
|
|
Packit Service |
ff689b |
return id;
|
|
Packit Service |
ff689b |
}
|
|
Packit Service |
ff689b |
|