From fc72c51a467305eb7b8f1154465ae63c22477f5c Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Sat, 15 Sep 2018 08:36:18 +0000 Subject: [PATCH] add library findpkg and quote --- Makefile | 20 +++--- lib/findpkg.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 lib/findpkg.c diff --git a/Makefile b/Makefile index dce8134..2e29167 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,10 @@ lib/jsw/jsw_hlib.c \ lib/jsw/jsw_rbtree.c JSWOBJ=$(JSWSRC:%.c=%.o) +LIBZPMSRC=sha256.c db.c compress.c uncompress.c zpm.c zpm_hash.c \ + foreach_path.c vercmp.o findpkg.c quote.c + +LIBZPMOBJ=$(addprefix lib/, $(LIBZPMSRC:%.c=%.o)) curdir=$(shell pwd) @@ -35,6 +39,11 @@ d: printf '%s\n' $(LZMAOBJ) printf '%s\n' $(PATH) +libzpm.a: $(LIBZPMOBJ) sqlite/sqlite3.o \ + $(LZMAOBJ) \ + $(JSWOBJ) + ar rcuv $@ $? + package: zpm-$(ZPMVER)-1.zpm lzmaupdate: @@ -120,6 +129,9 @@ zpm-foreach-path: zpm-foreach-path.o libzpm.a sqlite/sqlite3.h zpm-findpkg: zpm-findpkg.o libzpm.a $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lzpm -lelf +zpm-quote: zpm-quote.o libzpm.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lzpm -lelf + newdb.c: db.sql echo "char createdb[] = {" > $@ xxd -i < $< >> $@ @@ -139,14 +151,6 @@ zpm-vercmp: zpm-vercmp.o lib/vercmp.o zpm-shell: sqlite/sqlite3.o sqlite/shell.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ -libzpm.a: lib/sha256.o lib/db.o lib/compress.o lib/uncompress.o lib/zpm.o \ - sqlite/sqlite3.o lib/zpm_hash.o \ - lib/foreach_path.o \ - lib/vercmp.o \ - lib/sha256.o \ - $(LZMAOBJ) \ - $(JSWOBJ) - ar rcuv $@ $? libelf.a: elf/libelf.o ar rcuv $@ $? diff --git a/lib/findpkg.c b/lib/findpkg.c new file mode 100644 index 0000000..a8d8ff4 --- /dev/null +++ b/lib/findpkg.c @@ -0,0 +1,164 @@ +#include +#include +#include +#include + +#include "zpm.h" + +#include "sqlite3.h" + +int zpm_parse_package(char *pstr, char *name, char *ver, int *rel) { + if (name) *name = 0; + if (ver) *ver = 0; + if (rel) *rel = 0; + int havename = 0; + int havever = 0; + int haverel = 0; + + /* string - ver - rel */ + /* rel is all digits */ + /* possible forms: + * ^(.+)-([0-9][^-]*)-([\d+])$ + * ^(.+)-([0-9][^-]*)$ + * ^(.+)$ + * The main problem in parsing is that the package name itself + * can contain a '-', so you can't just split on '-' + * Also, the version can be just digits. + */ + + /* everything up to the first '-' is in the name */ + while (*pstr) { + if (*pstr == '-' && isdigit(*(pstr+1))) { + break; + } + if (name) { + *name++ = *pstr; + } + pstr++; + havename = 1; + } + if (name) *name = 0; + if (*pstr == '-') { + pstr++; + } + while (*pstr && *pstr != '-') { + if (ver) { + *ver++ = *pstr; + } + pstr++; + havever = 1; + } + if (ver) *ver = 0; + if (*pstr == '-') { + pstr++; + } + /* TODO use strtol */ + if (rel && *pstr) { + haverel = 1; + *rel = atoi(pstr); + } + + return havename + havever + haverel; +} + +/* + * flags 0 = find installed + * flags 1 = skip installed + * flags 2 = skip not installed + */ + +struct zpm_package *zpm_package_alloc(struct zpm *zpm) { + struct zpm_package *pkg; + + pkg = malloc(sizeof *pkg); + if (pkg) { + pkg->zpm = zpm; + pkg->release = 0; + } + return pkg; +} + +void zpm_sqlite_error(struct zpm *zpm) { + zpm->error = 1; + if (zpm->errmsg) free(zpm->errmsg); + zpm->errmsg = zpm_strdup((char *)sqlite3_errmsg(zpm->db)); +} + +char *zpm_findpkg(struct zpm *zpm, char *pkgstr) { + char *select = "select pkgid, package, version, release from packages_pkgid"; + char *group = "group by package having max( version||'-'||release collate vercmp) order by length(package), package, version||'-'||release collate vercmp limit 1"; +#if 0 + char *sstr[] = { + "status = 'installed'", + "", + "status != 'installed'" + }; +#endif + +// char *order = "order by package, version collate vercmp, cast(release as integer)"; + sqlite3_str *sql; + sqlite3_stmt *stmt; + char *query; + char package[32]; + char version[32]; + int release; + + /* null pkgstr find "best" package + * best is shortest complete package if any are complete + * shortest incomplete if any are incomplete + * where more than one version is in those sets, best is + * latest as determined by vercmp + */ + + /* given a package name, get the packages */ + /* no package name, get all */ + + // char where[1024] = ""; + + zpm_parse_package(pkgstr, package, version, &release); + + /* install a collation function */ + zpm_addvercmp(zpm); + + /* TODO allow more args to nail down version and release */ + + sql = sqlite3_str_new(zpm->db); + sqlite3_str_appendall(sql, select); + sqlite3_str_appendf(sql, " where package = %q", package); + if (*version) { + sqlite3_str_appendf(sql, " and version = %q", version); + } + if (release) { + sqlite3_str_appendf(sql, " and release = %d", release); + } + sqlite3_str_appendf(sql, " %s", group); + sqlite3_str_appendf(sql, " limit 1"); + + if (sqlite3_str_errcode(sql)) { + zpm->error = 1; + sqlite3_free(sqlite3_str_finish(sql)); + return 0; + } + + query = sqlite3_str_finish(sql); + sqlite3_prepare_v2(zpm->db, query, strlen(query), &stmt, NULL); + sqlite3_free(query); + + free(zpm->pkgid); + zpm->pkgid = 0; + + switch (sqlite3_step(stmt)) { + case SQLITE_ROW: + zpm->pkgid = zpm_strdup((char *)sqlite3_column_text(stmt, 0)); + break; + case SQLITE_DONE: + /* not found */ + break; + default: + zpm_sqlite_error(zpm); + break; + } + sqlite3_finalize(stmt); + + return zpm->pkgid; +} -- 2.40.0