1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* 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"
static struct RichOpComp {
const char *n;
int l;
Id fl;
} RichOps[] = {
{ "and", 3, REL_AND },
{ "or", 2, REL_OR },
{ "if", 2, REL_COND },
{ "else", 4, 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_COND && 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;
}
|