[pacman-dev] [PATCH] pactree: show tree vertical "limbs"

andrew.gregory.8 at gmail.com andrew.gregory.8 at gmail.com
Mon Jul 2 18:02:42 EDT 2012


From: Andrew Gregory <andrew.gregory.8 at gmail.com>

Showing vertical limbs makes the tree easier to follow.

Old:            New:
|--pkg          |--pkg
   |--dep1         |--dep1
      |--dep2      |  |--dep2
   |--dep3         |--dep3

Signed-off-by: Andrew Gregory <andrew.gregory.8 at gmail.com>
---
 src/util/pactree.c | 105 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 83 insertions(+), 22 deletions(-)

diff --git a/src/util/pactree.c b/src/util/pactree.c
index aa02c80..2fafd6d 100644
--- a/src/util/pactree.c
+++ b/src/util/pactree.c
@@ -27,11 +27,18 @@
 
 #define LINE_MAX     512
 
+typedef struct tdepth {
+	struct tdepth *prev;
+	struct tdepth *next;
+	int level;
+} tdepth;
+
 /* output */
 struct graph_style {
 	const char *provides;
 	const char *tip1;
 	const char *tip2;
+	const char *limb;
 	int indent;
 };
 
@@ -39,6 +46,7 @@ static struct graph_style graph_default = {
 	" provides",
 	"|--",
 	"+--",
+	"|",
 	3
 };
 
@@ -46,6 +54,7 @@ static struct graph_style graph_linear = {
 	"",
 	"",
 	"",
+	"",
 	0
 };
 
@@ -292,28 +301,36 @@ static void cleanup(void)
 }
 
 /* pkg provides provision */
-static void print_text(const char *pkg, const char *provision, int depth)
+static void print_text(const char *pkg, const char *provision, tdepth *depth)
 {
-	int indent_sz = (depth + 1) * style->indent;
-
 	if(!pkg && !provision) {
 		/* not much we can do */
 		return;
 	}
 
+	/* print limbs */
+	while(depth->prev)
+		depth = depth->prev;
+	int level = 0;
+	printf("%s", color->branch1);
+	while(depth->next){
+		printf("%*s%-*s", style->indent * (depth->level - level), "",
+				style->indent, style->limb);
+		level = depth->level + 1;
+		depth = depth->next;
+	}
+	printf("%*s", style->indent * (depth->level - level), "");
+
+	/* print tip */
 	if(!pkg && provision) {
-		/* we failed to resolve provision */
-		printf("%s%*s%s%s%s [unresolvable]%s\n", color->branch1, indent_sz,
-				style->tip1, color->leaf1, provision, color->branch1, color->off);
+		printf("%s%s%s%s [unresolvable]%s\n", style->tip1,  color->leaf1,
+				provision, color->branch1, color->off);
 	} else if(provision && strcmp(pkg, provision) != 0) {
-		/* pkg provides provision */
-		printf("%s%*s%s%s%s%s %s%s%s\n", color->branch2, indent_sz, style->tip2,
-				color->leaf1, pkg, color->leaf2, style->provides, color->leaf1, provision,
+		printf("%s%s%s%s%s %s%s%s\n", style->tip2, color->leaf1, pkg,
+				color->leaf2, style->provides, color->leaf1, provision,
 				color->off);
 	} else {
-		/* pkg is a normal package */
-		printf("%s%*s%s%s%s\n", color->branch1, indent_sz, style->tip1, color->leaf1,
-				pkg, color->off);
+		printf("%s%s%s%s\n", style->tip1, color->leaf1, pkg, color->off);
 	}
 }
 
@@ -331,7 +348,7 @@ static void print_graph(const char *parentname, const char *pkgname, const char
 }
 
 /* parent depends on dep which is satisfied by pkg */
-static void print(const char *parentname, const char *pkgname, const char *depname, int depth)
+static void print(const char *parentname, const char *pkgname, const char *depname, tdepth *depth)
 {
 	if(graphviz) {
 		print_graph(parentname, pkgname, depname);
@@ -347,7 +364,12 @@ static void print_start(const char *pkgname, const char *provname)
 				"node [style=filled, color=green];\n"
 				" \"START\" -> \"%s\";\n", pkgname);
 	} else {
-		print_text(pkgname, provname, 0);
+		tdepth d = {
+			NULL,
+			NULL,
+			0
+		};
+		print_text(pkgname, provname, &d);
 	}
 }
 
@@ -375,11 +397,11 @@ static alpm_pkg_t *get_pkg_from_dbs(alpm_list_t *dbs, const char *needle) {
 /**
  * walk dependencies in reverse, showing packages which require the target
  */
-static void walk_reverse_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
+static void walk_reverse_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, tdepth *depth)
 {
 	alpm_list_t *required_by, *i;
 
-	if(!pkg || ((max_depth >= 0) && (depth == max_depth + 1))) {
+	if(!pkg || ((max_depth >= 0) && (depth->level > max_depth))) {
 		return;
 	}
 
@@ -397,7 +419,24 @@ static void walk_reverse_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
 			}
 		} else {
 			print(alpm_pkg_get_name(pkg), pkgname, NULL, depth);
-			walk_reverse_deps(dblist, get_pkg_from_dbs(dblist, pkgname), depth + 1);
+			tdepth d = {
+				depth,
+				NULL,
+				depth->level + 1
+			};
+			depth->next = &d;
+			/* last dep, cut off the limb here */
+			if(!alpm_list_next(i)){
+				if(depth->prev){
+					depth->prev->next = &d;
+					d.prev = depth->prev;
+					depth = &d;
+				} else {
+					d.prev = NULL;
+				}
+			}
+			walk_reverse_deps(dblist, get_pkg_from_dbs(dblist, pkgname), &d);
+			depth->next = NULL;
 		}
 	}
 
@@ -407,11 +446,11 @@ static void walk_reverse_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
 /**
  * walk dependencies, showing dependencies of the target
  */
-static void walk_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
+static void walk_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, tdepth *depth)
 {
 	alpm_list_t *i;
 
-	if((max_depth >= 0) && (depth == max_depth + 1)) {
+	if((max_depth >= 0) && (depth->level > max_depth)) {
 		return;
 	}
 
@@ -432,7 +471,24 @@ static void walk_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, int depth)
 				}
 			} else {
 				print(alpm_pkg_get_name(pkg), provname, depend->name, depth);
-				walk_deps(dblist, provider, depth + 1);
+				tdepth d = {
+					depth,
+					NULL,
+					depth->level + 1
+				};
+				depth->next = &d;
+				/* last dep, cut off the limb here */
+				if(!alpm_list_next(i)){
+					if(depth->prev){
+						depth->prev->next = &d;
+						d.prev = depth->prev;
+						depth = &d;
+					} else {
+						d.prev = NULL;
+					}
+				}
+				walk_deps(dblist, provider, &d);
+				depth->next = NULL;
 			}
 		} else {
 			/* unresolvable package */
@@ -486,10 +542,15 @@ int main(int argc, char *argv[])
 
 	print_start(alpm_pkg_get_name(pkg), target_name);
 
+	tdepth d = {
+		NULL,
+		NULL,
+		1
+	};
 	if(reverse) {
-		walk_reverse_deps(dblist, pkg, 1);
+		walk_reverse_deps(dblist, pkg, &d);
 	} else {
-		walk_deps(dblist, pkg, 1);
+		walk_deps(dblist, pkg, &d);
 	}
 
 	print_end();
-- 
1.7.11.1



More information about the pacman-dev mailing list