1 |
commit: a30baf6e2163eb4ed4dd6c9b5beee2473c775377 |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Nov 26 07:58:21 2015 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Nov 26 07:58:21 2015 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=a30baf6e |
7 |
|
8 |
qdepends: rework dep tree flattening |
9 |
|
10 |
By leveraging stpcpy, we don't need to call strlen at all, or update the |
11 |
length of the buffer we've written to. Instead, make the func recursive |
12 |
and pass around the start of the buffer that is ready to accept more data. |
13 |
|
14 |
While we're here, increase the static buffer to 1MiB. Some packages (e.g. |
15 |
qemu) are larger than the 8KiB we have which causes corruption/crashes. |
16 |
There's no way we'd exceed 1MiB! </last-words> |
17 |
|
18 |
qdepends.c | 27 +++++++++++++-------------- |
19 |
1 file changed, 13 insertions(+), 14 deletions(-) |
20 |
|
21 |
diff --git a/qdepends.c b/qdepends.c |
22 |
index bcdeaa5..5ded84b 100644 |
23 |
--- a/qdepends.c |
24 |
+++ b/qdepends.c |
25 |
@@ -70,7 +70,6 @@ _q_static void _dep_print_tree(FILE *fp, const dep_node *root, size_t space); |
26 |
void dep_burn_tree(dep_node *root); |
27 |
char *dep_flatten_tree(const dep_node *root); |
28 |
_q_static void _dep_attach(dep_node *root, dep_node *attach_me, int type); |
29 |
-_q_static void _dep_flatten_tree(const dep_node *root, char *buf, size_t *pos); |
30 |
_q_static void _dep_burn_node(dep_node *node); |
31 |
int qdepends_main_vdb(const char *depend_file, int argc, char **argv); |
32 |
int qdepends_vdb_deep(const char *depend_file, const char *query); |
33 |
@@ -352,33 +351,33 @@ _q_static void dep_prune_use(dep_node *root, const char *use) |
34 |
if (root->children) dep_prune_use(root->children, use); |
35 |
} |
36 |
|
37 |
-void _dep_flatten_tree(const dep_node *root, char *buf, size_t *pos) |
38 |
+_q_static char * |
39 |
+_dep_flatten_tree(const dep_node *root, char *buf) |
40 |
{ |
41 |
if (root->type == DEP_NULL) goto this_node_sucks; |
42 |
if (root->type == DEP_NORM) { |
43 |
- size_t len = strlen(root->info); |
44 |
- memcpy(buf + *pos, root->info, len); |
45 |
- *pos += len+1; |
46 |
- buf[*pos-1] = ' '; |
47 |
+ buf[0] = ' '; |
48 |
+ buf = stpcpy(buf + 1, root->info); |
49 |
} |
50 |
- if (root->children) _dep_flatten_tree(root->children, buf, pos); |
51 |
+ if (root->children) |
52 |
+ buf = _dep_flatten_tree(root->children, buf); |
53 |
this_node_sucks: |
54 |
- if (root->neighbor) _dep_flatten_tree(root->neighbor, buf, pos); |
55 |
+ if (root->neighbor) |
56 |
+ buf = _dep_flatten_tree(root->neighbor, buf); |
57 |
+ return buf; |
58 |
} |
59 |
|
60 |
char *dep_flatten_tree(const dep_node *root) |
61 |
{ |
62 |
- static char flat[8192]; |
63 |
- size_t pos = 0; |
64 |
- _dep_flatten_tree(root, flat, &pos); |
65 |
- if (pos == 0) { |
66 |
+ static char flat[1024 * 1024]; |
67 |
+ char *buf = _dep_flatten_tree(root, flat); |
68 |
+ if (buf == flat) { |
69 |
/* all the nodes were squashed ... for example: |
70 |
* USE=-selinux RDEPEND="selinux? ( sys-libs/libselinux )" |
71 |
*/ |
72 |
return NULL; |
73 |
} |
74 |
- flat[pos-1] = '\0'; |
75 |
- return flat; |
76 |
+ return flat + 1; |
77 |
} |
78 |
|
79 |
struct qdepends_opt_state { |