[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
Thu Nov 7 14:49:23 EST 2013


For long filelists it's not so practical, i agree.
Well, your call if you want to keep any patch. :)


On Thu, Nov 7, 2013 at 6:51 AM, Allan McRae <allan at archlinux.org> wrote:
> 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