summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2014-11-16 16:51:30 -0500
committerDave Reisner <dreisner@archlinux.org>2014-11-16 16:54:30 -0500
commitc16a1cea13c70e9c40a8db82d561e71bd04f404f (patch)
tree1adf263ea9a8b1d7b2f84d0e858571a4888606f2
parent13145a3957ac029fc5e3f538f676c0075255822d (diff)
downloadexpac-c16a1cea13c70e9c40a8db82d561e71bd04f404f.tar.xz
Reorg a bit, introduce a control struct
-rw-r--r--.gitignore5
-rw-r--r--.ycm_extra_conf.py85
-rw-r--r--Makefile9
-rw-r--r--conf.c182
-rw-r--r--conf.h15
-rw-r--r--expac.c439
-rw-r--r--expac.h23
-rw-r--r--util.h14
8 files changed, 464 insertions, 308 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4ebba7c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.o
+.*.swp
+expac
+expac.1
+.ycm_extra_conf.pyc
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
new file mode 100644
index 0000000..6ba1cca
--- /dev/null
+++ b/.ycm_extra_conf.py
@@ -0,0 +1,85 @@
+import os
+import ycm_core
+from clang_helpers import PrepareClangFlags
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = ''
+
+# These are the compilation flags that will be used in case there's no
+# compilation database set.
+flags = [
+'-Wall',
+'-Wextra',
+'-Werror',
+'-Wno-long-long',
+'-Wno-variadic-macros',
+'-fexceptions',
+'-DNDEBUG',
+'-D_GNU_SOURCE',
+'-DUSE_CLANG_COMPLETER',
+'-std=c99',
+'-DVERSION="1"',
+]
+
+if compilation_database_folder:
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
+
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
+ if not working_directory:
+ return flags
+ new_flags = []
+ make_next_absolute = False
+ path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith( '/' ):
+ new_flag = os.path.join( working_directory, flag )
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith( path_flag ):
+ path = flag[ len( path_flag ): ]
+ new_flag = path_flag + os.path.join( working_directory, path )
+ break
+
+ if new_flag:
+ new_flags.append( new_flag )
+ return new_flags
+
+
+def FlagsForFile( filename ):
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = database.GetCompilationInfoForFile( filename )
+ final_flags = PrepareClangFlags(
+ MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_ ),
+ filename )
+
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }
diff --git a/Makefile b/Makefile
index 85b47a9..d585e4f 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,13 @@ LDLIBS = -lalpm
DISTFILES = expac.c README.pod
+expac_SOURCES = \
+ expac.c \
+ conf.c conf.h \
+ util.h
+
+expac: $(expac_SOURCES)
+
all: expac doc
doc: expac.1
@@ -30,6 +37,6 @@ dist: clean
rm -rf expac-$(VERSION)
clean:
- $(RM) expac.o expac expac.1
+ $(RM) *.o expac expac.1
.PHONY: all clean dist doc install doc
diff --git a/conf.c b/conf.c
new file mode 100644
index 0000000..5aedc6e
--- /dev/null
+++ b/conf.c
@@ -0,0 +1,182 @@
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "conf.h"
+#include "util.h"
+
+static size_t strtrim(char *str) {
+ char *left = str, *right;
+
+ if (!str || *str == '\0') {
+ return 0;
+ }
+
+ while (isspace((unsigned char)*left)) {
+ left++;
+ }
+ if (left != str) {
+ memmove(str, left, (strlen(left) + 1));
+ left = str;
+ }
+
+ if (*str == '\0') {
+ return 0;
+ }
+
+ right = strchr(str, '\0') - 1;
+ while (isspace((unsigned char)*right)) {
+ right--;
+ }
+ *++right = '\0';
+
+ return right - left;
+}
+
+int is_section(const char *s, int n) {
+ return s[0] == '[' && s[n-1] == ']';
+}
+
+static int config_add_repo(config_t *config, char *reponame) {
+ /* first time setup */
+ if (config->repos == NULL) {
+ config->repos = calloc(10, sizeof(char*));
+ if (config->repos == NULL) {
+ return -ENOMEM;
+ }
+
+ config->size = 0;
+ config->capacity = 10;
+ }
+
+ /* grow when needed */
+ if (config->size == config->capacity) {
+ void *ptr;
+
+ ptr = realloc(config->repos, config->capacity * 2.5 * sizeof(char*));
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+
+ config->repos = ptr;
+ }
+
+ config->repos[config->size] = strdup(reponame);
+ ++config->size;
+
+ return 0;
+}
+
+static int parse_one_file(config_t *config, const char *filename, char **section);
+
+static int parse_include(config_t *config, const char *include, char **section) {
+ _cleanup_(globfreep) glob_t globbuf = {};
+
+ if (glob(include, GLOB_NOCHECK, NULL, &globbuf) != 0) {
+ fprintf(stderr, "warning: globbing failed on '%s': out of memory\n",
+ include);
+ return -ENOMEM;
+ }
+
+ for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
+ int r;
+ r = parse_one_file(config, globbuf.gl_pathv[i], section);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static char *split_keyval(char *line, const char *sep) {
+ strsep(&line, sep);
+ return line;
+}
+
+static int parse_one_file(config_t *config, const char *filename, char **section) {
+ _cleanup_(fclosep) FILE *fp = NULL;
+ _cleanup_free_ char *line = NULL;
+ size_t n = 0;
+ int in_options = 0;
+
+ if (*section)
+ in_options = strcmp(*section, "options") == 0;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ return -errno;
+
+ for (;;) {
+ ssize_t len;
+
+ errno = 0;
+ len = getline(&line, &n, fp);
+ if (len < 0) {
+ if (errno != 0)
+ return -errno;
+
+ /* EOF */
+ break;
+ }
+
+ len = strtrim(line);
+ if (len == 0 || line[0] == '#')
+ continue;
+
+ if (is_section(line, len)) {
+ free(*section);
+ *section = strndup(&line[1], len - 2);
+ if (*section == NULL)
+ return -ENOMEM;
+
+ in_options = strcmp(*section, "options") == 0;
+ if (!in_options) {
+ int r;
+
+ r = config_add_repo(config, *section);
+ if (r < 0)
+ return r;
+
+ }
+ continue;
+ }
+
+ if (in_options && memchr(line, '=', len)) {
+ char *val;
+
+ val = split_keyval(line, "=");
+ strtrim(line);
+
+ if (strcmp(line, "Include") == 0) {
+ int k;
+
+ strtrim(val);
+
+ k = parse_include(config, val, section);
+ if (k < 0)
+ return k;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void config_reset(config_t *config) {
+ if (config == NULL)
+ return;
+
+ for (int i = 0; i < config->size; ++i)
+ free(config->repos[i]);
+
+ free(config->repos);
+}
+
+int config_parse(config_t *config, const char *filename) {
+ _cleanup_free_ char *section = NULL;
+
+ return parse_one_file(config, filename, &section);
+}
+
+/* vim: set et ts=2 sw=2: */
diff --git a/conf.h b/conf.h
new file mode 100644
index 0000000..1ce6a17
--- /dev/null
+++ b/conf.h
@@ -0,0 +1,15 @@
+#ifndef _CONF_H
+#define _CONF_H
+
+typedef struct config_t {
+ char **repos;
+ int size;
+ int capacity;
+} config_t;
+
+int config_parse(config_t *config, const char *filename);
+void config_reset(config_t *config);
+
+#endif /* _CONF_H */
+
+/* vim: set et ts=2 sw=2: */
diff --git a/expac.c b/expac.c
index b519d4d..b6f7b0e 100644
--- a/expac.c
+++ b/expac.c
@@ -36,6 +36,10 @@
#include <string.h>
#include <time.h>
+#include "expac.h"
+#include "conf.h"
+#include "util.h"
+
#define DEFAULT_DELIM "\n"
#define DEFAULT_LISTDELIM " "
#define DEFAULT_TIMEFMT "%c"
@@ -50,208 +54,23 @@ static char const digits[] = "0123456789";
static char const printf_flags[] = "'-+ #0I";
alpm_db_t *db_local = NULL;
-alpm_list_t *dblist = NULL;
alpm_list_t *targets = NULL;
bool opt_readone = false;
bool opt_verbose = false;
bool opt_search = false;
-bool opt_local = false;
bool opt_groups = false;
bool opt_localpkg = false;
char opt_humansize = 'B';
+SearchCorpus opt_corpus = SEARCH_LOCAL;
const char *opt_format = NULL;
const char *opt_timefmt = DEFAULT_TIMEFMT;
const char *opt_listdelim = DEFAULT_LISTDELIM;
const char *opt_delim = DEFAULT_DELIM;
+const char *opt_config_file = "/etc/pacman.conf";
int opt_pkgcounter = 0;
typedef const char *(*extractfn)(void*);
-typedef struct config_t {
- char **repos;
- int size;
- int capacity;
-} config_t;
-
-static inline void freep(void *p) { free(*(void **)p); }
-static inline void fclosep(FILE **p) { if (*p) fclose(*p); }
-static inline void globfreep(glob_t *p) { globfree(p); }
-#define _cleanup_(x) __attribute__((cleanup(x)))
-#define _cleanup_free_ _cleanup_(freep)
-
-static size_t strtrim(char *str) {
- char *left = str, *right;
-
- if (!str || *str == '\0') {
- return 0;
- }
-
- while (isspace((unsigned char)*left)) {
- left++;
- }
- if (left != str) {
- memmove(str, left, (strlen(left) + 1));
- left = str;
- }
-
- if (*str == '\0') {
- return 0;
- }
-
- right = strchr(str, '\0') - 1;
- while (isspace((unsigned char)*right)) {
- right--;
- }
- *++right = '\0';
-
- return right - left;
-}
-
-int is_section(const char *s, int n) {
- return s[0] == '[' && s[n-1] == ']';
-}
-
-static int config_add_repo(config_t *config, char *reponame) {
- /* first time setup */
- if (config->repos == NULL) {
- config->repos = calloc(10, sizeof(char*));
- if (config->repos == NULL) {
- return -ENOMEM;
- }
-
- config->size = 0;
- config->capacity = 10;
- }
-
- /* grow when needed */
- if (config->size == config->capacity) {
- void *ptr;
-
- ptr = realloc(config->repos, config->capacity * 2.5 * sizeof(char*));
- if (ptr == NULL) {
- return -ENOMEM;
- }
-
- config->repos = ptr;
- }
-
- config->repos[config->size] = strdup(reponame);
- ++config->size;
-
- return 0;
-}
-
-void config_reset(config_t *config) {
- if (config == NULL)
- return;
-
- for (int i = 0; i < config->size; ++i)
- free(config->repos[i]);
-
- free(config->repos);
-}
-
-static int parse_one_file(config_t *config, const char *filename, char **section);
-
-static int parse_include(config_t *config, const char *include, char **section) {
- _cleanup_(globfreep) glob_t globbuf = {};
-
- if (glob(include, GLOB_NOCHECK, NULL, &globbuf) != 0) {
- fprintf(stderr, "warning: globbing failed on '%s': out of memory\n",
- include);
- return -ENOMEM;
- }
-
- for (size_t i = 0; i < globbuf.gl_pathc; ++i) {
- int r;
- r = parse_one_file(config, globbuf.gl_pathv[i], section);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-static char *split_keyval(char *line, const char *sep) {
- strsep(&line, sep);
- return line;
-}
-
-static int parse_one_file(config_t *config, const char *filename, char **section) {
- _cleanup_(fclosep) FILE *fp = NULL;
- _cleanup_free_ char *line = NULL;
- size_t n = 0;
- int in_options = 0;
-
- if (*section)
- in_options = strcmp(*section, "options") == 0;
-
- fp = fopen(filename, "r");
- if (fp == NULL)
- return -errno;
-
- for (;;) {
- ssize_t len;
-
- errno = 0;
- len = getline(&line, &n, fp);
- if (len < 0) {
- if (errno != 0)
- return -errno;
-
- /* EOF */
- break;
- }
-
- len = strtrim(line);
- if (len == 0 || line[0] == '#')
- continue;
-
- if (is_section(line, len)) {
- free(*section);
- *section = strndup(&line[1], len - 2);
- if (*section == NULL)
- return -ENOMEM;
-
- in_options = strcmp(*section, "options") == 0;
- if (!in_options) {
- int r;
-
- r = config_add_repo(config, *section);
- if (r < 0)
- return r;
-
- }
- continue;
- }
-
- if (in_options && memchr(line, '=', len)) {
- char *val;
-
- val = split_keyval(line, "=");
- strtrim(line);
-
- if (strcmp(line, "Include") == 0) {
- int k;
-
- strtrim(val);
-
- k = parse_include(config, val, section);
- if (k < 0)
- return k;
- }
- }
- }
-
- return 0;
-}
-
-static int config_parse(config_t *config, const char *filename) {
- _cleanup_free_ char *section = NULL;
-
- return parse_one_file(config, filename, &section);
-}
-
static const char *alpm_backup_get_name(alpm_backup_t *bkup) {
return bkup->name;
}
@@ -303,35 +122,6 @@ static char *format_optdep(alpm_depend_t *optdep) {
return out;
}
-static alpm_handle_t *alpm_init(void) {
- alpm_handle_t *alpm = NULL;
- enum _alpm_errno_t alpm_errno = 0;
- config_t config = { NULL, 0, 0 };
- int r;
-
- alpm = alpm_initialize("/", "/var/lib/pacman", &alpm_errno);
- if (!alpm) {
- alpm_strerror(alpm_errno);
- return NULL;
- }
-
- db_local = alpm_get_localdb(alpm);
-
- r = config_parse(&config, "/etc/pacman.conf");
- if (r < 0) {
- fprintf(stderr, "error: failed to parse config: %s\n", strerror(-r));
- return NULL;
- }
-
- for (int i = 0; i < config.size; ++i) {
- alpm_register_syncdb(alpm, config.repos[i], 0);
- }
-
- config_reset(&config);
-
- return alpm;
-}
-
static const char *alpm_dep_get_name(void *dep) {
return ((alpm_depend_t*)dep)->name;
}
@@ -356,8 +146,7 @@ static void usage(void) {
"For more details see expac(1).\n");
}
-static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
- int opt, option_index = 0;
+static int parse_options(int argc, char *argv[]) {
const char *i;
static struct option opts[] = {
@@ -376,22 +165,19 @@ static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
{0, 0, 0, 0}
};
- while (-1 != (opt = getopt_long(argc, argv, "1l:d:gH:hf:pQSst:v", opts, &option_index))) {
+ for (;;) {
+ int opt;
+
+ opt = getopt_long(argc, argv, "1l:d:gH:hf:pQSst:v", opts, NULL);
+ if (opt < 0)
+ break;
+
switch (opt) {
case 'S':
- if (dblist) {
- fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
- return 1;
- }
- dblist = alpm_list_copy(alpm_get_syncdbs(alpm));
+ opt_corpus = SEARCH_SYNC;
break;
case 'Q':
- if (dblist) {
- fprintf(stderr, "error: can only select one repo option (use -h for help)\n");
- return 1;
- }
- dblist = alpm_list_add(dblist, db_local);
- opt_local = true;
+ opt_corpus = SEARCH_LOCAL;
break;
case '1':
opt_readone = true;
@@ -406,13 +192,13 @@ static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
opt_listdelim = optarg;
break;
case 'H':
- for(i = SIZE_TOKENS; *i; i++) {
- if(*i == *optarg) {
+ for (i = SIZE_TOKENS; *i; i++) {
+ if (*i == *optarg) {
opt_humansize = *optarg;
break;
}
}
- if(*i == '\0') {
+ if (*i == '\0') {
fprintf(stderr, "error: invalid SI size formatter: %c\n", *optarg);
return 1;
}
@@ -421,7 +207,7 @@ static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
usage();
return 1;
case 'p':
- opt_localpkg = true;
+ opt_corpus = SEARCH_FILE;
break;
case 's':
opt_search = true;
@@ -440,9 +226,9 @@ static int parse_options(int argc, char *argv[], alpm_handle_t *alpm) {
}
}
- if (optind < argc) {
+ if (optind < argc)
opt_format = argv[optind++];
- } else {
+ else {
fprintf(stderr, "error: missing format string (use -h for help)\n");
return 1;
}
@@ -588,7 +374,7 @@ static bool backup_file_is_modified(const alpm_backup_t *backup_file) {
static alpm_list_t *get_modified_files(alpm_pkg_t *pkg) {
alpm_list_t *i, *modified_files = NULL;
- for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) {
+ for(i = alpm_pkg_get_backup(pkg); i; i = i->next) {
const alpm_backup_t *backup = i->data;
if(backup->hash && backup_file_is_modified(backup)) {
modified_files = alpm_list_add(modified_files, backup->name);
@@ -809,126 +595,165 @@ static alpm_list_t *search_groups(alpm_list_t *dbs, alpm_list_t *groupnames) {
return packages;
}
-static alpm_list_t *resolve_pkg(alpm_list_t *targets) {
+static alpm_list_t *resolve_pkg(alpm_list_t *dblist, alpm_list_t *targets) {
char *pkgname, *reponame;
alpm_list_t *t, *r, *ret = NULL;
- if (targets == NULL) {
+ if (targets == NULL)
return all_packages(dblist);
- } else if (opt_search) {
+ else if (opt_search)
return search_packages(dblist, targets);
- } else if (opt_groups) {
+ else if (opt_groups)
return search_groups(dblist, targets);
- }
/* resolve each target individually from the repo pool */
- for (t = targets; t; t = alpm_list_next(t)) {
+ for (t = targets; t; t = t->next) {
alpm_pkg_t *pkg = NULL;
int found = 0;
pkgname = reponame = t->data;
- if (strchr(pkgname, '/')) {
+ if (strchr(pkgname, '/'))
strsep(&pkgname, "/");
- } else {
+ else
reponame = NULL;
- }
- for (r = dblist; r; r = alpm_list_next(r)) {
+ for (r = dblist; r; r = r->next) {
alpm_db_t *repo = r->data;
- if (reponame && strcmp(reponame, alpm_db_get_name(repo)) != 0) {
+ if (reponame && strcmp(reponame, alpm_db_get_name(repo)) != 0)
continue;
- }
pkg = alpm_db_get_pkg(repo, pkgname);
- if (pkg == NULL) {
+ if (pkg == NULL)
continue;
- }
found = 1;
ret = alpm_list_add(ret, pkg);
- if (opt_readone) {
+ if (opt_readone)
break;
- }
}
- if (!found && opt_verbose) {
+ if (!found && opt_verbose)
fprintf(stderr, "error: package `%s' not found\n", pkgname);
- }
}
return ret;
}
-static alpm_list_t *gather_packages(alpm_handle_t *alpm, alpm_list_t *targets) {
- alpm_list_t *results = NULL;
+void expac_free(Expac *expac) {
+ if (expac == NULL)
+ return;
- if (opt_localpkg) {
- alpm_list_t *i;
+ alpm_release(expac->alpm);
+}
- /* load each target as a package */
- for (i = targets; i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg;
- int err;
+int expac_new(Expac **expac, int argc, char **argv) {
+ Expac *e;
+ enum _alpm_errno_t alpm_errno = 0;
+ config_t config = { NULL, 0, 0 };
+ int r;
- err = alpm_pkg_load(alpm, i->data, 0, 0, &pkg);
- if (err) {
- fprintf(stderr, "error: %s: %s\n", (const char*)i->data,
- alpm_strerror(alpm_errno(alpm)));
- continue;
- }
- results = alpm_list_add(results, pkg);
+ r = parse_options(argc, argv);
+ if (r < 0)
+ return r;
+
+ e = calloc(1, sizeof(*e));
+ if (e == NULL)
+ return -ENOMEM;
+
+ r = config_parse(&config, opt_config_file);
+ if (r < 0)
+ return r;
+
+ e->alpm = alpm_initialize("/", "/var/lib/pacman", &alpm_errno);
+ if (!e->alpm)
+ return -alpm_errno;
+
+ e->db_local = alpm_get_localdb(e->alpm);
+
+ for (int i = 0; i < config.size; ++i)
+ alpm_register_syncdb(e->alpm, config.repos[i], 0);
+
+ config_reset(&config);
+
+ *expac = e;
+
+ return 0;
+}
+
+int expac_search_files(Expac *expac, alpm_list_t *targets, alpm_list_t **results) {
+ alpm_list_t *i;
+
+ /* load each target as a package */
+ for (i = targets; i; i = alpm_list_next(i)) {
+ alpm_pkg_t *pkg;
+ int err;
+
+ err = alpm_pkg_load(expac->alpm, i->data, 0, 0, &pkg);
+ if (err) {
+ fprintf(stderr, "error: %s: %s\n", (const char*)i->data,
+ alpm_strerror(alpm_errno(expac->alpm)));
+ continue;
}
- } else {
- results = resolve_pkg(targets);
+ *results = alpm_list_add(*results, pkg);
}
- return results;
+ return 0;
}
-int main(int argc, char *argv[]) {
- int ret = 1;
- alpm_handle_t *alpm;
- alpm_list_t *results = NULL, *i;
+int expac_search_local(Expac *expac, alpm_list_t *targets, alpm_list_t **results) {
+ alpm_list_t *dblist;
- alpm = alpm_init();
- if (!alpm) {
- return ret;
- }
+ dblist = alpm_list_add(NULL, alpm_get_localdb(expac->alpm));
- ret = parse_options(argc, argv, alpm);
- if (ret != 0) {
- goto finish;
- }
+ *results = resolve_pkg(dblist, targets);
- /* ensure sane defaults */
- if (!dblist && !opt_localpkg) {
- opt_local = true;
- dblist = alpm_list_add(dblist, db_local);
- }
+ alpm_list_free(dblist);
- results = gather_packages(alpm, targets);
- if (results == NULL) {
- ret = 1;
- goto finish;
- }
+ return 0;
+}
- for (i = results; i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = i->data;
- ret += print_pkg(pkg, opt_format);
- }
- ret = !!ret; /* clamp to zero/one */
+int expac_search_sync(Expac *expac, alpm_list_t *targets, alpm_list_t **results) {
+ *results = resolve_pkg(alpm_get_syncdbs(expac->alpm), targets);
+ return 0;
+}
- if(opt_localpkg) {
- alpm_list_free_inner(results, (alpm_list_fn_free)alpm_pkg_free);
+int expac_search(Expac *expac, alpm_list_t *targets, alpm_list_t **results) {
+ switch (opt_corpus) {
+ case SEARCH_LOCAL:
+ return expac_search_local(expac, targets, results);
+ case SEARCH_SYNC:
+ return expac_search_sync(expac, targets, results);
+ case SEARCH_FILE:
+ return expac_search_files(expac, targets, results);
}
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ alpm_list_t *results = NULL;
+ Expac *expac;
+ int r;
+
+ r = expac_new(&expac, argc, argv);
+ if (r < 0)
+ return 1;
+
+ r = expac_search(expac, targets, &results);
+ if (r < 0)
+ return 1;
+
+ if (alpm_list_count(results) == 0)
+ return 1;
+
+ for (alpm_list_t *i = results; i; i = i->next)
+ print_pkg(i->data, opt_format);
+
alpm_list_free(results);
+ expac_free(expac);
-finish:
- alpm_list_free(dblist);
- alpm_list_free(targets);
- alpm_release(alpm);
- return ret;
+ return r;
}
/* vim: set et ts=2 sw=2: */
diff --git a/expac.h b/expac.h
new file mode 100644
index 0000000..29536b2
--- /dev/null
+++ b/expac.h
@@ -0,0 +1,23 @@
+#ifndef _EXPAC_H
+#define _EXPAC_H
+
+#include <alpm.h>
+
+typedef enum SearchCorpus {
+ SEARCH_LOCAL,
+ SEARCH_SYNC,
+ SEARCH_FILE,
+} SearchCorpus;
+
+typedef struct Expac {
+ alpm_handle_t *alpm;
+ alpm_db_t *db_local;
+
+ SearchCorpus search_type;
+} Expac;
+
+int expac_new(Expac **expac, int argc, char **argv);
+
+#endif /* _EXPAC_H */
+
+/* vim: set et ts=2 sw=2: */
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..6d50426
--- /dev/null
+++ b/util.h
@@ -0,0 +1,14 @@
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include <glob.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static inline void freep(void *p) { free(*(void **)p); }
+static inline void fclosep(FILE **p) { if (*p) fclose(*p); }
+static inline void globfreep(glob_t *p) { globfree(p); }
+#define _cleanup_(x) __attribute__((cleanup(x)))
+#define _cleanup_free_ _cleanup_(freep)
+
+#endif /* _UTIL_H */