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 <[email protected]>
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 > > > >
