aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2015-11-26 02:58:21 -0500
committerMike Frysinger <vapier@gentoo.org>2015-11-26 02:58:21 -0500
commita30baf6e2163eb4ed4dd6c9b5beee2473c775377 (patch)
tree3cee4d44d8f22fb4b8ddacfb9e0591670ec48ee5 /qdepends.c
parentqatom: add a --format flag for controlling output (diff)
downloadportage-utils-a30baf6e2163eb4ed4dd6c9b5beee2473c775377.tar.gz
portage-utils-a30baf6e2163eb4ed4dd6c9b5beee2473c775377.tar.bz2
portage-utils-a30baf6e2163eb4ed4dd6c9b5beee2473c775377.zip
qdepends: rework dep tree flattening
By leveraging stpcpy, we don't need to call strlen at all, or update the length of the buffer we've written to. Instead, make the func recursive and pass around the start of the buffer that is ready to accept more data. While we're here, increase the static buffer to 1MiB. Some packages (e.g. qemu) are larger than the 8KiB we have which causes corruption/crashes. There's no way we'd exceed 1MiB! </last-words>
Diffstat (limited to 'qdepends.c')
-rw-r--r--qdepends.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/qdepends.c b/qdepends.c
index bcdeaa55..5ded84b1 100644
--- a/qdepends.c
+++ b/qdepends.c
@@ -70,7 +70,6 @@ _q_static void _dep_print_tree(FILE *fp, const dep_node *root, size_t space);
void dep_burn_tree(dep_node *root);
char *dep_flatten_tree(const dep_node *root);
_q_static void _dep_attach(dep_node *root, dep_node *attach_me, int type);
-_q_static void _dep_flatten_tree(const dep_node *root, char *buf, size_t *pos);
_q_static void _dep_burn_node(dep_node *node);
int qdepends_main_vdb(const char *depend_file, int argc, char **argv);
int qdepends_vdb_deep(const char *depend_file, const char *query);
@@ -352,33 +351,33 @@ _q_static void dep_prune_use(dep_node *root, const char *use)
if (root->children) dep_prune_use(root->children, use);
}
-void _dep_flatten_tree(const dep_node *root, char *buf, size_t *pos)
+_q_static char *
+_dep_flatten_tree(const dep_node *root, char *buf)
{
if (root->type == DEP_NULL) goto this_node_sucks;
if (root->type == DEP_NORM) {
- size_t len = strlen(root->info);
- memcpy(buf + *pos, root->info, len);
- *pos += len+1;
- buf[*pos-1] = ' ';
+ buf[0] = ' ';
+ buf = stpcpy(buf + 1, root->info);
}
- if (root->children) _dep_flatten_tree(root->children, buf, pos);
+ if (root->children)
+ buf = _dep_flatten_tree(root->children, buf);
this_node_sucks:
- if (root->neighbor) _dep_flatten_tree(root->neighbor, buf, pos);
+ if (root->neighbor)
+ buf = _dep_flatten_tree(root->neighbor, buf);
+ return buf;
}
char *dep_flatten_tree(const dep_node *root)
{
- static char flat[8192];
- size_t pos = 0;
- _dep_flatten_tree(root, flat, &pos);
- if (pos == 0) {
+ static char flat[1024 * 1024];
+ char *buf = _dep_flatten_tree(root, flat);
+ if (buf == flat) {
/* all the nodes were squashed ... for example:
* USE=-selinux RDEPEND="selinux? ( sys-libs/libselinux )"
*/
return NULL;
}
- flat[pos-1] = '\0';
- return flat;
+ return flat + 1;
}
struct qdepends_opt_state {