On 10/25/15 at 05:07pm, Florian Pritz wrote:
> Signed-off-by: Florian Pritz <[email protected]>
> ---
> 
> v2:
>  - Always output paths without leading slash
> 
>  doc/pacman.8.txt    |  4 ++++
>  src/pacman/conf.h   |  2 ++
>  src/pacman/files.c  | 69 
> ++++++++++++++++++++++++++++++++++++++---------------
>  src/pacman/pacman.c |  6 +++++
>  4 files changed, 62 insertions(+), 19 deletions(-)
> 
> diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
> index 38b8bb7..1f11cf3 100644
> --- a/doc/pacman.8.txt
> +++ b/doc/pacman.8.txt
> @@ -477,6 +477,10 @@ The '--list', '--search' and '--owns' options are 
> exclusive and can not be combi
>  *-o <file>, \--owns<file>*::
>       Search for packages that own a particular file.
>  
> +*--machinereadable*::
> +     Use a machine readable output format for '--list', '--search' and
> +     '--owns'. The format is 'repository/pkgname pkgver path'.

Spaces are not really reliable field separators.  Every single field
being printed is allowed to contain spaces by alpm/pacman.

>  Handling Config Files[[HCF]]
>  ----------------------------
> diff --git a/src/pacman/conf.h b/src/pacman/conf.h
> index 3fff900..1760b07 100644
> --- a/src/pacman/conf.h
> +++ b/src/pacman/conf.h
> @@ -89,6 +89,7 @@ typedef struct __config_t {
>       unsigned short op_s_upgrade;
>  
>       unsigned short op_f_regex;
> +     unsigned short op_f_machinereadable;
>  
>       unsigned short group;
>       unsigned short noask;
> @@ -190,6 +191,7 @@ enum {
>       OP_RECURSIVE,
>       OP_SEARCH,
>       OP_REGEX,
> +     OP_MACHINEREADABLE,
>       OP_UNREQUIRED,
>       OP_UPGRADES,
>       OP_SYSUPGRADE,
> diff --git a/src/pacman/files.c b/src/pacman/files.c
> index 31ce9e0..b21503a 100644
> --- a/src/pacman/files.c
> +++ b/src/pacman/files.c
> @@ -27,6 +27,14 @@
>  #include "conf.h"
>  #include "package.h"
>  
> +static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg) {
> +     alpm_filelist_t *pkgfiles = alpm_pkg_get_files(pkg);
> +     for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) {
> +             const alpm_file_t *file = pkgfiles->files + filenum;
> +             printf("%s/%s %s %s\n", alpm_db_get_name(db), 
> alpm_pkg_get_name(pkg),
> +                             alpm_pkg_get_version(pkg), file->name);
> +     }
> +}
>  
>  static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) {
>       int ret = 0;
> @@ -59,13 +67,17 @@ static int files_fileowner(alpm_list_t *syncs, 
> alpm_list_t *targets) {
>                               alpm_filelist_t *files = 
> alpm_pkg_get_files(pkg);
>  
>                               if(alpm_filelist_contains(files, f)) {
> -
> -                                     if(!config->quiet) {
> -                                             printf(_("%s is owned by %s/%s 
> %s\n"), f,
> -                                                             
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
> -                                                             
> alpm_pkg_get_version(pkg));
> +                                     if(config->op_f_machinereadable) {
> +                                             printf("%s/%s %s %s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
> +                                                             
> alpm_pkg_get_version(pkg), f);
>                                       } else {
> -                                             printf("%s/%s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
> +                                             if(!config->quiet) {
> +                                                     printf(_("%s is owned 
> by %s/%s %s\n"), f,
> +                                                                     
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
> +                                                                     
> alpm_pkg_get_version(pkg));
> +                                             } else {
> +                                                     printf("%s/%s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
> +                                             }

No need to nest this if, make it part of the outer conditional.

>                                       }
>  
>                                       found = 1;
> @@ -137,19 +149,28 @@ static int files_search(alpm_list_t *syncs, alpm_list_t 
> *targets, int regex) {
>                               }
>  
>                               if(match != NULL) {
> -                                     if(config->quiet) {
> -                                             printf("%s/%s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
> -                                     } else {
> +                                     if(config->op_f_machinereadable) {
>                                               alpm_list_t *ml;
> -                                             printf("%s%s/%s%s %s%s%s\n", 
> colstr->repo, alpm_db_get_name(repo),
> -                                                     colstr->title, 
> alpm_pkg_get_name(pkg),
> -                                                     colstr->version, 
> alpm_pkg_get_version(pkg), colstr->nocolor);
> -
>                                               for(ml = match; ml; ml = 
> alpm_list_next(ml)) {
> -                                                     c = ml->data;
> -                                                     printf("    %s\n", c);
> +                                                     char *filename = 
> ml->data;
> +                                                     printf("%s/%s %s %s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg),
> +                                                                     
> alpm_pkg_get_version(pkg), filename);
> +                                             }
> +                                     } else {
> +                                             if(config->quiet) {
> +                                                     printf("%s/%s\n", 
> alpm_db_get_name(repo), alpm_pkg_get_name(pkg));
> +                                             } else {
> +                                                     alpm_list_t *ml;
> +                                                     printf("%s%s/%s%s 
> %s%s%s\n", colstr->repo, alpm_db_get_name(repo),
> +                                                             colstr->title, 
> alpm_pkg_get_name(pkg),
> +                                                             
> colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor);
> +
> +                                                     for(ml = match; ml; ml 
> = alpm_list_next(ml)) {
> +                                                             c = ml->data;
> +                                                             printf("    
> %s\n", c);
> +                                                     }
> +                                                     FREELIST(match);
>                                               }

Same for this one.

> -                                             FREELIST(match);

match needs to be free'd any time it's not NULL, this needs to be
moved to the outer block.

>                                       }
>                               }
>                       }
> @@ -222,8 +243,14 @@ static int files_list(alpm_list_t *syncs, alpm_list_t 
> *targets) {
>  
>                               if((pkg = alpm_db_get_pkg(db, targ)) != NULL) {
>                                       found = 1;
> -                                     dump_file_list(pkg);
> -                                     break;
> +                                     if(config->op_f_machinereadable) {
> +                                             dump_pkg_machinereadable(db, 
> pkg);
> +                                             // list all repos if not asked 
> for a specific one

I don't like having the machine readable format printing a different
set of packages than the normal format.

> +                                             continue;

Unnecessary continue.

> +                                     } else {
> +                                             dump_file_list(pkg);
> +                                             break;
> +                                     }
>                               }
>                       }
>                       if(!found) {
> @@ -240,7 +267,11 @@ static int files_list(alpm_list_t *syncs, alpm_list_t 
> *targets) {
>  
>                       for(j = alpm_db_get_pkgcache(db); j; j = 
> alpm_list_next(j)) {
>                               alpm_pkg_t *pkg = j->data;
> -                             dump_file_list(pkg);
> +                             if(config->op_f_machinereadable) {
> +                                     dump_pkg_machinereadable(db, pkg);
> +                             } else {
> +                                     dump_file_list(pkg);
> +                             }
>                       }
>               }
>       }
> diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> index c680067..0bb1b39 100644
> --- a/src/pacman/pacman.c
> +++ b/src/pacman/pacman.c
> @@ -181,6 +181,8 @@ static void usage(int op, const char * const myname)
>                       addlist(_("  -x, --regex          enable searching 
> using regular expressions\n"));
>                       addlist(_("  -y, --refresh        download fresh 
> package databases from the server\n"
>                                 "                       (-yy to force a 
> refresh even if up to date)\n"));
> +                     addlist(_("      --machinereadable\n"
> +                               "                       produce 
> machine-readable output\n"));
>               }
>               switch(op) {
>                       case PM_OP_SYNC:
> @@ -792,6 +794,9 @@ static int parsearg_files(int opt)
>               case 'x':
>                       config->op_f_regex = 1;
>                       break;
> +             case OP_MACHINEREADABLE:
> +                     config->op_f_machinereadable = 1;
> +                     break;
>               case OP_QUIET:
>               case 'q':
>                       config->quiet = 1;
> @@ -941,6 +946,7 @@ static int parseargs(int argc, char *argv[])
>               {"recursive",  no_argument,       0, OP_RECURSIVE},
>               {"search",     no_argument,       0, OP_SEARCH},
>               {"regex",      no_argument,       0, OP_REGEX},
> +             {"machinereadable",      no_argument,       0, 
> OP_MACHINEREADABLE},
>               {"unrequired", no_argument,       0, OP_UNREQUIRED},
>               {"upgrades",   no_argument,       0, OP_UPGRADES},
>               {"sysupgrade", no_argument,       0, OP_SYSUPGRADE},
> -- 
> 2.6.2

Reply via email to