From fd9ff672b0010650297e645c4fd1bd1cc320e3ef Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Thu, 18 Jun 2015 19:27:51 +1000 Subject: Add regex search option to sync database file searching e.g. pacman -Fsx kcm.*print.*\.so Signed-off-by: Allan McRae --- src/pacman/conf.h | 3 +++ src/pacman/files.c | 28 ++++++++++++++++++++++------ src/pacman/pacman.c | 12 ++++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 84b5a253..3fff9008 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -88,6 +88,8 @@ typedef struct __config_t { unsigned short op_s_search; unsigned short op_s_upgrade; + unsigned short op_f_regex; + unsigned short group; unsigned short noask; unsigned int ask; @@ -187,6 +189,7 @@ enum { OP_ROOT, OP_RECURSIVE, OP_SEARCH, + OP_REGEX, OP_UNREQUIRED, OP_UPGRADES, OP_SYSUPGRADE, diff --git a/src/pacman/files.c b/src/pacman/files.c index fc06ae7d..5156e466 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -19,6 +19,7 @@ #include #include +#include /* pacman */ #include "pacman.h" @@ -83,24 +84,33 @@ notfound: return 0; } -static int files_search(alpm_list_t *syncs, alpm_list_t *targets) { +static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { int ret = 0; alpm_list_t *t; const colstr_t *colstr = &config->colstr; for(t = targets; t; t = alpm_list_next(t)) { - char *filename = NULL; + char *targ = NULL; alpm_list_t *s; int found = 0; + regex_t reg; - if((filename = strdup(t->data)) == NULL) { + if((targ = strdup(t->data)) == NULL) { goto notfound; } + if(regex) { + if(regcomp(®, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { + /* TODO: error message */ + goto notfound; + } + } + for(s = syncs; s; s = alpm_list_next(s)) { alpm_list_t *p; alpm_db_t *repo = s->data; alpm_list_t *packages = alpm_db_get_pkgcache(repo); + int m; for(p = packages; p; p = alpm_list_next(p)) { size_t f = 0; @@ -112,7 +122,12 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets) { while(f < files->count) { c = strrchr(files->files[f].name, '/'); if(c && *(c + 1)) { - if(strcmp(c + 1, filename) == 0) { + if(regex) { + m = regexec(®, (c + 1), 0, 0, 0); + } else { + m = strcmp(c + 1, targ); + } + if(m == 0) { match = alpm_list_add(match, strdup(files->files[f].name)); found = 1; } @@ -138,7 +153,8 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets) { } } } - free(filename); + + free(targ); notfound: if(!found) { @@ -219,7 +235,7 @@ int pacman_files(alpm_list_t *targets) /* search for a file */ if(config->op_s_search) { - return files_search(files_dbs, targets); + return files_search(files_dbs, targets, config->op_f_regex); } /* get a listing of files in sync DBs */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 951d628c..c680067c 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -177,7 +177,8 @@ static void usage(int op, const char * const myname) } else if(op == PM_OP_FILES) { addlist(_(" -l, --list list the files owned by the queried package\n")); addlist(_(" -o, --owns query the package that owns \n")); - addlist(_(" -s, --search search package file names for matching strings\n")); + addlist(_(" -s, --search search package file names for matching strings\n")); + 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")); } @@ -787,6 +788,10 @@ static int parsearg_files(int opt) case 'y': (config->op_s_sync)++; break; + case OP_REGEX: + case 'x': + config->op_f_regex = 1; + break; case OP_QUIET: case 'q': config->quiet = 1; @@ -802,8 +807,10 @@ static void checkargs_files(void) if(config->op_q_owns) { invalid_opt(config->op_q_list, "--owns", "--list"); invalid_opt(config->op_q_search, "--owns", "--search"); + invalid_opt(config->op_f_regex, "--owns", "--regex"); } else if(config->op_q_list) { invalid_opt(config->op_q_search, "--list", "--search"); + invalid_opt(config->op_f_regex, "--list", "--regex"); } } @@ -899,7 +906,7 @@ static int parseargs(int argc, char *argv[]) int opt; int option_index = 0; int result; - const char *optstring = "DFQRSTUVb:cdefghiklmnopqr:stuvwy"; + const char *optstring = "DFQRSTUVb:cdefghiklmnopqr:stuvwxy"; static const struct option opts[] = { {"database", no_argument, 0, 'D'}, @@ -933,6 +940,7 @@ static int parseargs(int argc, char *argv[]) {"root", required_argument, 0, OP_ROOT}, {"recursive", no_argument, 0, OP_RECURSIVE}, {"search", no_argument, 0, OP_SEARCH}, + {"regex", no_argument, 0, OP_REGEX}, {"unrequired", no_argument, 0, OP_UNREQUIRED}, {"upgrades", no_argument, 0, OP_UPGRADES}, {"sysupgrade", no_argument, 0, OP_SYSUPGRADE}, -- cgit v1.2.3-70-g09d2