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

Allan McRae allan at archlinux.org
Wed Nov 6 23:51:10 EST 2013


On 07/11/13 11:07, Bill Kolokithas wrote:
> 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>

For those that have no idea of what that output looks like, take a look
at [1].

I'm not sure what the gain is here.   Testing it out with glibc, I was
required to scroll up five screens before seeing the parent directory
name and all the way to the top to see it was in /usr.

[1]
https://wiki.gentoo.org/wiki/Gentoolkit#Listing_Files_Installed_by_a_Package_with_files_.28f.29

A

> ---
>  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