From b185b057674387ca58511d722af8d4cfe8acc6a8 Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 30 Nov 2010 16:27:55 -0500 Subject: Implement searching. Why am I rewriting pacman? --- Makefile | 3 ++ config.mk | 2 +- expac.c | 104 ++++++++++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 74 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 393e17f..dc99f05 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ OBJ = ${SRC:.c=.o} all: expac +35: + ${MAKE} PMCHECK=-D_HAVE_ALPM_FIND_SATISFIER all + .c.o: ${CC} -c ${CFLAGS} $< diff --git a/config.mk b/config.mk index a1ed858..d358463 100644 --- a/config.mk +++ b/config.mk @@ -3,6 +3,6 @@ VERSION = $(shell git describe --always) # compiler flags CC = c99 -CPPFLAGS = -DVERSION=\"${VERSION}\" +CPPFLAGS = -DVERSION=\"${VERSION}\" ${PMCHECK} CFLAGS += -g -pedantic -Wall -Wextra ${CPPFLAGS} LDFLAGS += -lalpm diff --git a/expac.c b/expac.c index 1e84d85..feecdbc 100644 --- a/expac.c +++ b/expac.c @@ -7,13 +7,15 @@ #include #include #include +#include #define FORMAT_TOKENS "BCDEFGLNOPRSabdfiklmnoprsuv%" #define ESCAPE_TOKENS "\"\\abefnrtv" alpm_list_t *dblist = NULL, *targets = NULL; pmdb_t *db_local; -int verbose = 0; +bool verbose = false; +bool search = false; const char *format = NULL; const char *timefmt = NULL; const char *listdelim = NULL; @@ -132,6 +134,7 @@ static void usage(void) { " Options:\n" " -Q, --local search local DB (default)\n" " -S, --sync search sync DBs\n\n" + " -s, --search search for matching strings\n" " -d, --delim separator used between packages (default: \"\\n\")\n" " -l, --listdelim separator used between list elements (default: \" \")\n" " -t, --timefmt date format passed to strftime (default: \"%%c\")\n\n" @@ -148,12 +151,13 @@ static int parse_options(int argc, char *argv[]) { {"help", no_argument, 0, 'h'}, {"local", no_argument, 0, 'Q'}, {"sync", no_argument, 0, 'S'}, + {"search", no_argument, 0, 's'}, {"timefmt", required_argument, 0, 't'}, {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0} }; - while (-1 != (opt = getopt_long(argc, argv, "l:d:hf:QSt:v", opts, &option_index))) { + while (-1 != (opt = getopt_long(argc, argv, "l:d:hf:QSst:v", opts, &option_index))) { switch (opt) { case 'S': if (dblist) { @@ -178,11 +182,14 @@ static int parse_options(int argc, char *argv[]) { case 'h': usage(); return(1); + case 's': + search = true; + break; case 't': timefmt = optarg; break; case 'v': - verbose = 1; + verbose = true; break; case '?': @@ -292,35 +299,9 @@ static void print_time(time_t timestamp) { printf("%s", buffer); } -static int print_pkg(alpm_list_t *dblist, const char *p, const char *format) { - alpm_list_t *i; - pmpkg_t *pkg; +static int print_pkg(pmpkg_t *pkg, const char *format) { const char *f; - char *repo, *pkgname; - - pkgname = repo = (char*)p; - if (strchr(pkgname, '/')) { - strsep(&pkgname, "/"); - } else { - repo = NULL; - } - - for (i = dblist; i; i = alpm_list_next(i)) { - pkg = alpm_db_get_pkg(alpm_list_getdata(i), pkgname); - if (repo && strcmp(repo, alpm_db_get_name(alpm_list_getdata(i))) != 0) { - continue; - } - if (pkg) { - break; - } - } - - if (!pkg) { - if (verbose) { - fprintf(stderr, "error: package `%s' not found\n", pkgname); - } - return(1); - } + assert(pkg); for (f = format; *f != '\0'; f++) { bool shortdeps = false; @@ -446,9 +427,55 @@ int verify_format_string(const char *format) { return(0); } +alpm_list_t *resolve_pkg(alpm_list_t *targets) { + char *pkgname, *reponame; + alpm_list_t *t, *r, *ret = NULL; + + if (search) { + for (r = dblist; r; r = alpm_list_next(r)) { + ret = alpm_list_join(ret, alpm_db_search(alpm_list_getdata(r), targets)); + } + } else { + for (t = targets; t; t = alpm_list_next(t)) { + pkgname = alpm_list_getdata(t); + if (strchr(pkgname, '/')) { + strsep(&pkgname, "/"); + } else { + reponame = NULL; + } + + for (r = dblist; r; r = alpm_list_next(r)) { + pmpkg_t *pkg; + + pkg = alpm_db_get_pkg(alpm_list_getdata(r), pkgname); + +#ifdef _HAVE_ALPM_FIND_SATISFIER + if (!pkg) { + pkg = alpm_find_satisfier(alpm_db_get_pkgcache(alpm_list_getdata(r)), pkgname); + } +#endif + + if (reponame && strcmp(reponame, alpm_db_get_name(alpm_list_getdata(r))) != 0) { + continue; + } + if (!pkg) { + if (verbose) { + fprintf(stderr, "error: package `%s' not found\n", pkgname); + } + continue; + } + + ret = alpm_list_add(ret, pkg); + } + } + } + + return(ret); +} + int main(int argc, char *argv[]) { int ret = 0, freelist = 0; - alpm_list_t *i; + alpm_list_t *results, *i; ret = alpm_init(); if (ret != 0) { @@ -473,11 +500,20 @@ int main(int argc, char *argv[]) { return(1); } - for (i = targets; i; i = alpm_list_next(i)) { - ret += print_pkg(dblist, alpm_list_getdata(i), format); + results = resolve_pkg(targets); + if (!results) { + ret = 1; + goto finish; + } + + for (i = results; i; i = alpm_list_next(i)) { + pmpkg_t *pkg = alpm_list_getdata(i); + ret += print_pkg(pkg, format); } ret = !!ret; /* clamp to zero/one */ + alpm_list_free(results); + if (freelist) { alpm_list_free(dblist); } -- cgit v1.2.3-70-g09d2