[pacman-dev] [PATCH 2/2] Add Query flag to list all files contained in a package in a tree format.

Bill Kolokithas freestyler7 at gmail.com
Wed Nov 6 20:07:58 EST 2013


My goal was to replicate the tree output format from gentoo's equery tool.
No support for differentiating output based on file types (symlink, FIFO etc).

Signed-off-by: Bill Kolokithas <kolokithas.b at gmail.com>
---
 src/pacman/package.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/pacman/package.h |  1 +
 src/pacman/pacman.c  |  2 +-
 src/pacman/query.c   |  4 ++-
 4 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/src/pacman/package.c b/src/pacman/package.c
index 1485889..949755a 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -334,6 +334,85 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet)
 	fflush(stdout);
 }

+/* Count character occurrences in a string
+ */
+static int count_char(char *s, char c)
+{
+	int count = 0;
+
+	for (; *s; s++)
+		if (*s == c)
+			count++;
+
+	return count;
+}
+
+/* List all files contained in a package in a tree format
+ */
+void dump_pkg_file_tree(alpm_pkg_t *pkg)
+{
+	const char *pkgname, *root, *prefix;
+	const alpm_file_t *file;
+	alpm_filelist_t *pkgfiles;
+	char *basename, filename[512], pool[128];
+	int len, isDir, num_spaces, dirdepth;
+	size_t i;
+
+	/* Fill our pool with spaces */
+	memset(pool, ' ', sizeof(pool));
+	pkgname  = alpm_pkg_get_name(pkg);
+	pkgfiles = alpm_pkg_get_files(pkg);
+	root     = alpm_option_get_root(config->handle);
+
+	printf("%s%s:%s\n", config->colstr.title, pkgname, config->colstr.nocolor);
+
+	for(i = 0; i < pkgfiles->count; i++) {
+		/* Duplicate the file name because we will alter it */
+		file = pkgfiles->files + i;
+		strncpy(filename, file->name, sizeof(filename));
+		/* Ensure string is always terminated */
+		filename[512 - 1] = '\0';
+
+		prefix   = "/";
+		len      = strlen(filename);
+		isDir    = filename[len - 1] == '/';
+		dirdepth = count_char(filename, '/');
+
+		/* Indent accordingly */
+		num_spaces = 1;
+		if(dirdepth == 2) {
+			num_spaces = 3;
+		} else if(dirdepth > 2) {
+			num_spaces = 3 * (dirdepth - 1);
+		}
+
+		/* Cut the trailing '/' so we can find the one before it */
+		if(isDir) {
+			filename[len - 1] = '\0';
+		} else {
+			/* Extra padding for files */
+			num_spaces += 3;
+		}
+
+		/* If no '/' is found, then it means we are on the top level so, we prepend the root */
+		basename = strrchr(filename, '/');
+		if(!basename) {
+			basename = filename;
+			prefix = root;
+		} else {
+			/* Skip the starting '/' char */
+			basename++;
+		}
+
+		if(isDir) {
+			printf("%.*s%s> %s%s%s\n", num_spaces, pool, config->colstr.title, prefix, basename, config->colstr.nocolor);
+		} else {
+			printf("%.*s%s+%s %s\n", num_spaces, pool, config->colstr.title, config->colstr.nocolor, basename);
+		}
+	}
+	fflush(stdout);
+}
+
 /* Display the changelog of a package
  */
 void dump_pkg_changelog(alpm_pkg_t *pkg)
diff --git a/src/pacman/package.h b/src/pacman/package.h
index 65eea87..58d58b5 100644
--- a/src/pacman/package.h
+++ b/src/pacman/package.h
@@ -26,6 +26,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra);

 void dump_pkg_backups(alpm_pkg_t *pkg);
 void dump_pkg_files(alpm_pkg_t *pkg, int quiet);
+void dump_pkg_file_tree(alpm_pkg_t *pkg);
 void dump_pkg_changelog(alpm_pkg_t *pkg);

 void print_installed(alpm_db_t *db_local, alpm_pkg_t *pkg);
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index e5d16fc..60e0f0d 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -525,7 +525,7 @@ static int parsearg_query(int opt)
 			break;
 		case OP_LIST:
 		case 'l':
-			config->op_q_list = 1;
+			(config->op_q_list)++;
 			break;
 		case OP_FOREIGN:
 		case 'm':
diff --git a/src/pacman/query.c b/src/pacman/query.c
index 8814307..d1a11d5 100644
--- a/src/pacman/query.c
+++ b/src/pacman/query.c
@@ -301,8 +301,10 @@ static int display(alpm_pkg_t *pkg)
 			dump_pkg_full(pkg, config->op_q_info > 1);
 		}
 	}
-	if(config->op_q_list) {
+	if(config->op_q_list == 1) {
 		dump_pkg_files(pkg, config->quiet);
+	} else if(config->op_q_list > 1) {
+		dump_pkg_file_tree(pkg);
 	}
 	if(config->op_q_changelog) {
 		dump_pkg_changelog(pkg);
--
1.8.4.2



More information about the pacman-dev mailing list