1 |
commit: 3d00cad113975b02ece79892eb5f752d818aaa73 |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Mar 25 13:57:56 2018 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Mar 25 13:57:56 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=3d00cad1 |
7 |
|
8 |
qdepends_vdb_deep_cb: use atom matching when possible, bug #608960 |
9 |
|
10 |
When the argument is an atom-parsable thing, match whatever we find in |
11 |
the vdb as atom, such that version and range can be taken into account. |
12 |
|
13 |
Bug: https://bugs.gentoo.org/608960 |
14 |
|
15 |
qdepends.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++------------ |
16 |
1 file changed, 95 insertions(+), 23 deletions(-) |
17 |
|
18 |
diff --git a/qdepends.c b/qdepends.c |
19 |
index d5a8ef5..cd5e851 100644 |
20 |
--- a/qdepends.c |
21 |
+++ b/qdepends.c |
22 |
@@ -475,13 +475,17 @@ qdepends_vdb_deep_cb(q_vdb_pkg_ctx *pkg_ctx, void *priv) |
23 |
const char *pkgname = pkg_ctx->name; |
24 |
size_t len; |
25 |
char *ptr; |
26 |
- char buf[_Q_PATH_MAX]; |
27 |
+ char qbuf[_Q_PATH_MAX]; |
28 |
static char *depend, *use; |
29 |
static size_t depend_len, use_len; |
30 |
dep_node *dep_tree; |
31 |
int ret; |
32 |
regex_t preg; |
33 |
regmatch_t match; |
34 |
+ depend_atom *aq; |
35 |
+ depend_atom *as; |
36 |
+ depend_atom *ac; |
37 |
+ char firstmatch = 0; |
38 |
|
39 |
if (!q_vdb_pkg_eat(pkg_ctx, state->depend_file, &depend, &depend_len)) |
40 |
return 0; |
41 |
@@ -508,36 +512,104 @@ qdepends_vdb_deep_cb(q_vdb_pkg_ctx *pkg_ctx, void *priv) |
42 |
|
43 |
dep_prune_use(dep_tree, use); |
44 |
|
45 |
- ptr = dep_flatten_tree(dep_tree); |
46 |
+ if ((ptr = dep_flatten_tree(dep_tree)) == NULL) { |
47 |
+ dep_burn_tree(dep_tree); |
48 |
+ return 1; |
49 |
+ } |
50 |
|
51 |
- ret = -2; |
52 |
- if (ptr && wregcomp(&preg, state->query, REG_EXTENDED) == 0) |
53 |
- ret = regexec(&preg, ptr, 1, &match, 0); |
54 |
- if (ret > -2) |
55 |
- regfree(&preg); |
56 |
+ snprintf(qbuf, sizeof(qbuf), "%s/%s", catname, pkgname); |
57 |
+ as = atom_explode(qbuf); |
58 |
+ if (!as) { |
59 |
+ dep_burn_tree(dep_tree); |
60 |
+ return 1; |
61 |
+ } |
62 |
|
63 |
- if (ptr && ret == 0) { |
64 |
- if (qdep_name_only) { |
65 |
- depend_atom *atom = NULL; |
66 |
- snprintf(buf, sizeof(buf), "%s/%s", catname, pkgname); |
67 |
- if ((atom = atom_explode(buf)) != NULL) { |
68 |
- printf("%s%s/%s%s%s%c", BOLD, catname, BLUE, atom->PN, NORM, verbose ? ':' : '\n'); |
69 |
- atom_implode(atom); |
70 |
- } |
71 |
+ aq = atom_explode(state->query); |
72 |
+ if (!aq) { |
73 |
+ /* "fall" back to old behaviour of just performing an extended |
74 |
+ * regular expression match */ |
75 |
+ if (wregcomp(&preg, state->query, REG_EXTENDED) != 0) { |
76 |
+ dep_burn_tree(dep_tree); |
77 |
+ return 1; |
78 |
+ } |
79 |
+ } |
80 |
+ |
81 |
+ match.rm_eo = 0; |
82 |
+ firstmatch = 1; |
83 |
+ do { /* find all matches */ |
84 |
+ if (!aq) { |
85 |
+ ret = regexec(&preg, ptr + match.rm_eo, 1, &match, 0); |
86 |
} else { |
87 |
- printf("%s%s/%s%s%s%c", BOLD, catname, BLUE, pkgname, NORM, verbose ? ':' : '\n'); |
88 |
+ char *loc; |
89 |
+ ret = -1; |
90 |
+ snprintf(qbuf, sizeof(qbuf), "%s%s%s", |
91 |
+ aq->CATEGORY ? aq->CATEGORY : "", |
92 |
+ aq->CATEGORY ? "/" : "", |
93 |
+ aq->PN); |
94 |
+ if ((loc = strstr(ptr + match.rm_eo, qbuf)) != NULL) { |
95 |
+ ret = 0; |
96 |
+ match.rm_so = loc - ptr; |
97 |
+ match.rm_eo = match.rm_so + strlen(qbuf); |
98 |
+ } |
99 |
} |
100 |
- if (verbose) { |
101 |
- /* find the boundaries for this atom */ |
102 |
- while (match.rm_so > 0 && !isspace(ptr[match.rm_so - 1])) |
103 |
- match.rm_so--; |
104 |
- while (ptr[match.rm_eo] != '\0' && !isspace(ptr[match.rm_eo])) |
105 |
- match.rm_eo++; |
106 |
- printf(" %.*s\n", |
107 |
+ if (ret != 0) |
108 |
+ break; |
109 |
+ |
110 |
+ /* find the boundaries for matched atom */ |
111 |
+ while (match.rm_so > 0 && !isspace(ptr[match.rm_so - 1])) |
112 |
+ match.rm_so--; |
113 |
+ while (ptr[match.rm_eo] != '\0' && !isspace(ptr[match.rm_eo])) |
114 |
+ match.rm_eo++; |
115 |
+ |
116 |
+ snprintf(qbuf, sizeof(qbuf), "%.*s", |
117 |
(int)(match.rm_eo - match.rm_so), |
118 |
ptr + match.rm_so); |
119 |
+ ac = atom_explode(qbuf); |
120 |
+ |
121 |
+ ret = atom_compare(ac, aq); |
122 |
+ if (ret != EQUAL) { |
123 |
+ atom_implode(ac); |
124 |
+ break; |
125 |
+ } |
126 |
+ |
127 |
+ if (firstmatch == 1) { |
128 |
+ firstmatch = 0; |
129 |
+ printf("%s%s/%s%s%s%c", BOLD, catname, BLUE, |
130 |
+ qdep_name_only ? as->PN : pkgname, NORM, |
131 |
+ verbose ? ':' : '\n'); |
132 |
+ } |
133 |
+ |
134 |
+ if (verbose) { |
135 |
+ printf(" "); |
136 |
+ if (ac) { |
137 |
+ printf("%s", atom_op_str[ac->pfx_op]); |
138 |
+ if (ac->CATEGORY) |
139 |
+ printf("%s/", ac->CATEGORY); |
140 |
+ printf("%s", ac->P); |
141 |
+ if (ac->PR_int) |
142 |
+ printf("-r%i", ac->PR_int); |
143 |
+ printf("%s", atom_op_str[ac->sfx_op]); |
144 |
+ if (ac->SLOT) |
145 |
+ printf(":%s", ac->SLOT); |
146 |
+ atom_implode(ac); |
147 |
+ } else { |
148 |
+ printf("%s", qbuf); |
149 |
+ } |
150 |
+ } else { |
151 |
+ /* if not verbose, we don't care about any extra matches */ |
152 |
+ atom_implode(ac); |
153 |
+ break; |
154 |
} |
155 |
+ } while (1); |
156 |
+ if (verbose && firstmatch == 0) |
157 |
+ printf("\n"); |
158 |
+ |
159 |
+ if (!aq) { |
160 |
+ regfree(&preg); |
161 |
+ } else { |
162 |
+ atom_implode(aq); |
163 |
} |
164 |
+ atom_implode(as); |
165 |
dep_burn_tree(dep_tree); |
166 |
|
167 |
return 1; |