Signed-off-by: Florian Pritz <bluew...@xinu.at>
---
 doc/pacman.8.txt    |  4 +++
 src/pacman/conf.h   |  2 ++
 src/pacman/files.c  | 70 ++++++++++++++++++++++++++++++++++++++---------------
 src/pacman/pacman.c |  6 +++++
 4 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index a4dd1f0..8aff288 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -473,6 +473,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'.
+
 
 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 feda75d..33825df 100644
--- a/src/pacman/files.c
+++ b/src/pacman/files.c
@@ -27,6 +27,15 @@
 #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);
+       const char *root = alpm_option_get_root(config->handle);
+       for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) {
+               const alpm_file_t *file = pkgfiles->files + filenum;
+               printf("%s/%s %s %s%s\n", alpm_db_get_name(db), 
alpm_pkg_get_name(pkg),
+                               alpm_pkg_get_version(pkg), root, file->name);
+       }
+}
 
 static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) {
        int ret = 0;
@@ -59,13 +68,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));
+                                               }
                                        }
 
                                        found = 1;
@@ -137,19 +150,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);
                                                }
-                                               FREELIST(match);
                                        }
                                }
                        }
@@ -200,8 +222,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_pkg_files(pkg, config->quiet);
-                                       break;
+                                       if(config->op_f_machinereadable) {
+                                               dump_pkg_machinereadable(db, 
pkg);
+                                               // list all repos if not asked 
for a specific one
+                                               continue;
+                                       } else {
+                                               dump_pkg_files(pkg, 
config->quiet);
+                                               break;
+                                       }
                                }
                        }
                        if(!found) {
@@ -218,7 +246,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_pkg_files(pkg, config->quiet);
+                               if(config->op_f_machinereadable) {
+                                       dump_pkg_machinereadable(db, pkg);
+                               } else {
+                                       dump_pkg_files(pkg, config->quiet);
+                               }
                        }
                }
        }
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