package

simple and robust package manager
Log | Files | Refs | README

commit cc0a1a31b4b895fd0a859fd48347d0cecef4b605
parent d0c9c5e3e8733dd27ae3bbf8fec89cb1085c69bc
Author: Josuah Demangeon <mail@josuah.net>
Date:   Sun, 20 Jan 2019 00:50:33 +0100

handle build-time, run-time, libraries dependencies

Diffstat:
Mhier.c | 50+++++++++++++++++++++++++-------------------------
Mmem.c | 11++---------
Mmem.h | 3+--
Mpackage-add.c | 125++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mpackage-build.c | 122++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mpackage-dep.c | 8++++----
Mpackage-get.c | 9++++-----
Mpackage-install.c | 2+-
Mpackage-tree.c | 38+++++++++++++++++++-------------------
Mpackage.c | 133+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mpackage.h | 7+++++--
11 files changed, 280 insertions(+), 228 deletions(-)

diff --git a/hier.c b/hier.c @@ -68,9 +68,9 @@ hier_remove(char const *dir) stralloc path = STRALLOC_ZERO; int ret = 0; - if (!stralloc_cats(&path, dir)) goto err; + if (!stralloc_cats(&path, dir)) goto error; ret = hier_remove_recurse(&path); -err: +error: stralloc_free(&path); return ret; } @@ -84,15 +84,15 @@ copy(char const *from, char const *to, unsigned int mode) int r = -1; int w = 1; /* for empty files */ - fd_from = open_read(from); if (fd_from == -1) goto err; - fd_to = open_trunc(to); if (fd_to == -1) goto err; + fd_from = open_read(from); if (fd_from == -1) goto error; + fd_to = open_trunc(to); if (fd_to == -1) goto error; while (1) { r = read(fd_from, buf, sizeof buf); if (r <= 0) break; w = write(fd_to, buf, r); if (w < r) break; } - if (chmod(to, mode) == -1) goto err; + if (chmod(to, mode) == -1) goto error; -err: close(fd_from); +error: close(fd_from); close(fd_to); return r == 0 && w > 0; } @@ -121,37 +121,37 @@ hier_copy_recurse(stralloc *from, stralloc *to, int action) if (str_equal(de->d_name, "..")) continue; from->n = from_n; - if (!stralloc_cats(from, de->d_name)) goto err; - if (!stralloc_cat0(from)) goto err; + if (!stralloc_cats(from, de->d_name)) goto error; + if (!stralloc_cat0(from)) goto error; from->n--; to->n = to_n; - if (!stralloc_cats(to, de->d_name)) goto err; - if (!stralloc_cat0(to)) goto err; + if (!stralloc_cats(to, de->d_name)) goto error; + if (!stralloc_cat0(to)) goto error; to->n--; - if (lstat(from->x, &st) == -1) goto err; + if (lstat(from->x, &st) == -1) goto error; if (S_ISDIR(st.st_mode)) { - if (mkdir(to->x, st.st_mode) == -1 && errno != EEXIST) goto err; - if (!hier_copy_recurse(from, to, action)) goto err; + if (mkdir(to->x, st.st_mode) == -1 && errno != EEXIST) goto error; + if (!hier_copy_recurse(from, to, action)) goto error; } else if (S_ISREG(st.st_mode)) { switch (action) { case 0: - if (!copy(from->x, to->x, st.st_mode)) goto err; + if (!copy(from->x, to->x, st.st_mode)) goto error; break; case 1: unlink(to->x); - if (symlink(from->x, to->x) == -1) goto err; + if (symlink(from->x, to->x) == -1) goto error; break; } } else if (S_ISLNK(st.st_mode)) { unlink(to->x); - if (readlink(from->x, ln, sizeof ln) == -1) goto err; - if (symlink(ln, to->x) == -1) goto err; - } else goto err; + if (readlink(from->x, ln, sizeof ln) == -1) goto error; + if (symlink(ln, to->x) == -1) goto error; + } else goto error; } ret = 1; -err: +error: closedir(dp); return ret; } @@ -163,10 +163,10 @@ hier_copy(char const *from, char const *to) stralloc sa_to = STRALLOC_ZERO; int ret = 0; - if (!stralloc_cats(&sa_from, from)) goto err; - if (!stralloc_cats(&sa_to, to)) goto err; + if (!stralloc_cats(&sa_from, from)) goto error; + if (!stralloc_cats(&sa_to, to)) goto error; ret = hier_copy_recurse(&sa_from, &sa_to, 0); -err: +error: stralloc_free(&sa_from); stralloc_free(&sa_to); return ret; @@ -179,10 +179,10 @@ hier_symlink(char const *from, char const *to) stralloc sa_to = STRALLOC_ZERO; int ret = 0; - if (!stralloc_cats(&sa_from, from)) goto err; - if (!stralloc_cats(&sa_to, to)) goto err; + if (!stralloc_cats(&sa_from, from)) goto error; + if (!stralloc_cats(&sa_to, to)) goto error; ret = hier_copy_recurse(&sa_from, &sa_to, 1); -err: +error: stralloc_free(&sa_from); stralloc_free(&sa_to); return ret; diff --git a/mem.c b/mem.c @@ -1,15 +1,8 @@ #include "mem.h" -int +size_t mem_chr(char const *buf, size_t n, char c) { char *p = memchr(buf, c, n); - return p ? p - buf : c; -} - -int -mem_rchr(const char *buf, size_t n, char c) -{ - char *p = memchr(buf, c, n); - return p ? p - buf : c; + return p ? p - buf : n; } diff --git a/mem.h b/mem.h @@ -11,7 +11,6 @@ #define mem_set(buf, n, c) memset(buf, c, n) #define mem_zero(buf, n) memset(buf, 0, n) -int mem_chr(char const *, size_t, char); -int mem_rchr(const char *, size_t, char); +size_t mem_chr(char const *, size_t, char); #endif diff --git a/package-add.c b/package-add.c @@ -18,6 +18,60 @@ die_nomem(void) } int +get(package const *p, char const *def, char const *pkg) +{ + stralloc sa; + char fmt[PACKAGE_FMT + 80]; + char const *argv[] = { "package-get", "-d", def, "-p", pkg, fmt, NULL }; + + fmt[package_fmt(p, fmt)] = '\0'; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, pkg)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, fmt)) die_nomem(); + if (!stralloc_cats(&sa, "/source.tar")) die_nomem(); + if (!stralloc_cat0(&sa)) die_nomem(); + if (stat_isfile(sa.x)) return 0; + + log_info_2("package-get ", fmt); + return forkexec_wait(argv); +} + +int +build(package const *p, char const *def, char const *pkg) +{ + stralloc sa; + char fmt[PACKAGE_FMT + 80]; + char const *argv[] = { "package-build", "-d", def, "-p", pkg, fmt, NULL }; + + fmt[package_fmt(p, fmt)] = '\0'; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, pkg)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, fmt)) die_nomem(); + if (!stralloc_cats(&sa, "/current")) die_nomem(); + if (!stralloc_cat0(&sa)) die_nomem(); + if (stat_islink(sa.x)) return 0; + + log_info_2("package-build ", fmt); + return forkexec_wait(argv); +} + +int +install(package const *p, char const *def, char const *pkg, char const *root) +{ + char fmt[PACKAGE_FMT + 80]; + char const *argv[] = { "package-install", "-d", def, "-p", pkg, "-r", root, fmt, NULL }; + + fmt[package_fmt(p, fmt)] = '\0'; + + log_info_2("package-install ", fmt); + return forkexec_wait(argv); +} + +int main(int argc, char **argv) { genalloc ga; @@ -27,8 +81,7 @@ main(int argc, char **argv) char *def = PACKAGE_DEF; char *root = PACKAGE_ROOT; char **av = argv; - char fmt[PACKAGE_FMT + 80]; - int flag_i = 0; + int flag_n = 0; int x; (void)argc; @@ -37,7 +90,7 @@ main(int argc, char **argv) if (str_equal(*av, "-d")) { if (!(def = *++av)) break; continue; } if (str_equal(*av, "-p")) { if (!(pkg = *++av)) break; continue; } if (str_equal(*av, "-r")) { if (!(root = *++av)) break; continue; } - if (str_equal(*av, "-i")) { flag_i = 1; continue; } + if (str_equal(*av, "-n")) { flag_n = 1; continue; } break; } @@ -46,9 +99,10 @@ main(int argc, char **argv) if (!stat_isdir(def)) log_fatal_sys_1(101, def); if (!stat_isdir(pkg)) log_fatal_sys_1(101, pkg); - n = package_scan(&p, *av); + n = package_scan(&p, *av, strlen(*av)); if (n == 0 || (*av)[n] != '\0') log_fatal_2(1, "invalid package name: ", *av); + p.dep_run = 1; if (!package_version(&p, def)) log_fatal_sys_3(101, "not read ", *av,"'s version"); @@ -58,62 +112,41 @@ main(int argc, char **argv) log_fatal_sys_1(103, "could not resolve package dependencies"); if (!genalloc_append(&ga, p)) die_nomem(); + // download everything for (size_t i = 0; i < genalloc_len(&ga, package); ++i) { - stralloc sa = STRALLOC_ZERO; package *p = genalloc_get(&ga, package, i); - char const *argv[] = { "package-get", "-d", def, "-p", pkg, fmt, NULL }; - fmt[package_fmt(p, fmt)] = '\0'; + if ((x = get(p, def, pkg)) != 0) return x; + } - stralloc_zero(&sa); - if (!stralloc_cats(&sa, pkg)) die_nomem(); - if (!stralloc_cats(&sa, "/")) die_nomem(); - if (!stralloc_cats(&sa, fmt)) die_nomem(); - if (!stralloc_cats(&sa, "/source.tar")) die_nomem(); - if (!stralloc_cat0(&sa)) die_nomem(); - if (stat_isfile(sa.x)) continue; + // build everything and install build-time dependencies + for (size_t i = 0; i < genalloc_len(&ga, package); ++i) + { + package *p = genalloc_get(&ga, package, i); - log_info_2("package-get ", fmt); - if ((x = forkexec_wait(argv)) != 0) goto error; + if ((x = build(p, def, pkg)) != 0) return x; + if (p->dep_build) + if ((x = install(p, def, pkg, root)) != 0) goto error; } + if (flag_n) return 0; + + // install run-time dependencies and main argument for (size_t i = 0; i < genalloc_len(&ga, package); ++i) { - stralloc sa = STRALLOC_ZERO; package *p = genalloc_get(&ga, package, i); - char const *argv[] = { NULL, "-d", def, "-p", pkg, NULL, NULL, NULL, NULL }; - - fmt[package_fmt(p, fmt)] = '\0'; - - stralloc_zero(&sa); - if (!stralloc_cats(&sa, pkg)) die_nomem(); - if (!stralloc_cats(&sa, "/")) die_nomem(); - if (!stralloc_cats(&sa, fmt)) die_nomem(); - if (!stralloc_cats(&sa, "/current")) die_nomem(); - if (!stralloc_cat0(&sa)) die_nomem(); - if (stat_islink(sa.x)) goto install; - - argv[0] = "package-build"; - argv[5] = fmt; - argv[6] = NULL; - log_info_2("package-build ", fmt); - if ((x = forkexec_wait(argv)) != 0) goto error; -install: - if (!flag_i) continue; - - argv[0] = "package-install"; - argv[5] = "-r"; - argv[6] = root; - argv[7] = fmt; - argv[8] = NULL; - log_info_2("package-install ", fmt); - if ((x = forkexec_wait(argv)) != 0) goto error; + + if (p->dep_run) + if ((x = install(p, def, pkg, root)) != 0) goto error; } return 0; error: - fmt[fmt_long(fmt, x)] = '\0'; - log_error_2("exited with status ", fmt); + { + char fmt[50]; + fmt[fmt_long(fmt, x)] = '\0'; + log_error_2("exited with status ", fmt); + } return x; } diff --git a/package-build.c b/package-build.c @@ -39,10 +39,10 @@ patch(package const *p, char *def) int ret = 0; stralloc_init(&sa); - if (!stralloc_cats(&sa, def)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; n = sa.n; d[0] = "default"; @@ -52,14 +52,14 @@ patch(package const *p, char *def) size_t m; sa.n = n; - if (!stralloc_cats(&sa, d[i])) goto err; - if (!stralloc_cats(&sa, "/patch/")) goto err; + if (!stralloc_cats(&sa, d[i])) goto error; + if (!stralloc_cats(&sa, "/patch/")) goto error; m = sa.n; - if (!stralloc_cat0(&sa)) goto err; + if (!stralloc_cat0(&sa)) goto error; dp = opendir(sa.x); if (dp == NULL) { if (errno == ENOTDIR || errno == ENOENT) continue; - goto err; + goto error; } while ((de = readdir(dp)) != NULL) { char const *argv[] = { "patch", "-N", NULL }; @@ -68,19 +68,19 @@ patch(package const *p, char *def) if (str_equal(de->d_name, "..")) continue; sa.n = m; - if (!stralloc_cats(&sa, de->d_name)) goto err; - if (!stralloc_cat0(&sa)) goto err; - if ((fd = open_read(sa.x)) == -1) goto err; + if (!stralloc_cats(&sa, de->d_name)) goto error; + if (!stralloc_cat0(&sa)) goto error; + if ((fd = open_read(sa.x)) == -1) goto error; buffer_puts(buffer_1, argv[0]); buffer_puts(buffer_1, " "); buffer_puts(buffer_1, argv[1]); buffer_puts(buffer_1, " "); buffer_puts(buffer_1, sa.x); buffer_puts(buffer_1, "\n"); buffer_flush(buffer_1); - if ((ret = forkexec_redir(argv, 0, fd)) != 0) goto err; + if ((ret = forkexec_redir(argv, 0, fd)) != 0) goto error; close(fd); } closedir(dp); } -err: +error: if (fd >= 0) close(fd); stralloc_free(&sa); if (ret != 0) closedir(dp); @@ -95,24 +95,24 @@ copy(package const *p, char const *def) int ret = 0; stralloc_init(&sa); - if (!stralloc_cats(&sa, def)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; n = sa.n; - if (!stralloc_cats(&sa, "default/data")) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto err; + if (!stralloc_cats(&sa, "default/data")) goto error; + if (!stralloc_cat0(&sa)) goto error; + if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto error; sa.n = n; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/data")) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto err; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/data")) goto error; + if (!stralloc_cat0(&sa)) goto error; + if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto error; ret = 1; -err: +error: stralloc_free(&sa); return ret; } @@ -126,24 +126,24 @@ build(package const *p, char const *def) int ret = -1; stralloc_init(&sa); - if (!stralloc_cats(&sa, def)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; n = sa.n; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/build")) goto err; - if (!stralloc_cat0(&sa)) goto err; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; argv[0] = sa.x; - if (stat_isfile(sa.x)) { ret = forkexec_redir(argv, 2, 1); goto err; } + if (stat_isfile(sa.x)) { ret = forkexec_redir(argv, 2, 1); goto error; } sa.n = n; - if (!stralloc_cats(&sa, "default/build")) goto err; - if (!stralloc_cat0(&sa)) goto err; + if (!stralloc_cats(&sa, "default/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; argv[0] = sa.x; - if (stat_isfile(sa.x)) { ret = forkexec_redir(argv, 2, 1); goto err; } -err: + if (stat_isfile(sa.x)) { ret = forkexec_redir(argv, 2, 1); goto error; } +error: stralloc_free(&sa); return ret; } @@ -173,20 +173,20 @@ env(package *p, char const *def, char const *pkg, char const *id) int ret = 0; stralloc_init(&sa); - if (!stralloc_cats(&sa, pkg)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, id)) goto err; - if (!stralloc_cats(&sa, "/build")) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (!env_sane_name("PREFIX", sa.x)) goto err; + if (!stralloc_cats(&sa, pkg)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, id)) goto error; + if (!stralloc_cats(&sa, "/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; + if (!env_sane_name("PREFIX", sa.x)) goto error; errno = 0; fd = package_opendepfile(p, def); - if (fd == -1) { ret = (errno == ENOTDIR || errno == ENOENT); goto err; } + if (fd == -1) { ret = (errno == ENOTDIR || errno == ENOENT); goto error; } stralloc_init(&line); buffer_init(&b, &read, fd, buf, sizeof buf); @@ -195,22 +195,22 @@ env(package *p, char const *def, char const *pkg, char const *id) package new; line.n -= (line.x[line.n - 1] == '\n'); - if (!stralloc_cat0(&line)) goto err; - n = package_scan(&new, line.x); if (n == 0 || line.x[n] != '\0') goto err; - if (!package_version(&new, def)) goto err; + if (!stralloc_cat0(&line)) goto error; + n = package_dep_scan(&new, line.x, line.n); if (n == 0 || line.x[n] != '\0') goto error; + if (!package_version(&new, def)) goto error; stralloc_zero(&sa); - if (!stralloc_cats(&sa, pkg)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, new.name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, new.ver)) goto err; - if (!stralloc_cats(&sa, "/current/build")) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (!env_sane_name(new.name, sa.x)) goto err; + if (!stralloc_cats(&sa, pkg)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, new.name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, new.ver)) goto error; + if (!stralloc_cats(&sa, "/current/build")) goto error; + if (!stralloc_cat0(&sa)) goto error; + if (!env_sane_name(new.name, sa.x)) goto error; } ret = (r == 0); -err: +error: stralloc_free(&sa); stralloc_free(&line); if (fd >= 0) close(fd); @@ -243,7 +243,7 @@ main(int argc, char **argv) if (chdir(pkg) == -1) log_fatal_sys_2(101, "chdir ", pkg); - if ((*av)[package_scan(&p, *av)] != '\0') + if ((*av)[package_scan(&p, *av, strlen(*av))] != '\0') log_fatal_sys_2(1, "invalid package format: ", *av); if (mkdir(p.name, 075) == -1 && errno != EEXIST) log_fatal_sys_4(101, "mkdir ", pkg, "/", p.name); diff --git a/package-dep.c b/package-dep.c @@ -31,12 +31,12 @@ main(int argc, char **argv) if (!stat_isdir(def)) log_fatal_sys_1(101, def); - n = package_scan(&p, *argv); - if (n == 0 || (*argv)[n] != '\0') - log_fatal_2(1, "invalid package name: ", *argv); + n = package_scan(&p, *av, str_len(*av)); + if (n == 0 || (*av)[n] != '\0') + log_fatal_2(1, "invalid package name: ", *av); if (!package_version(&p, def)) - log_fatal_sys_3(103, "could not get ", *argv," version"); + log_fatal_sys_3(103, "could not get ", *av," version"); genalloc_init(&ga); if (!package_dep(&p, &ga, def)) diff --git a/package-get.c b/package-get.c @@ -47,7 +47,7 @@ main(int argc, char **argv) if (!*av) log_usage(*argv, "package[/version]"); if (!stat_isdir(def)) log_fatal_sys_1(101, def); - n = package_scan(&p, *av); + n = package_scan(&p, *av, strlen(*av)); if ((*av)[n] != '\0') log_fatal_2(1, "invalid package format: ", *argv); if (!package_version(&p, def)) @@ -114,14 +114,13 @@ main(int argc, char **argv) argv[2] = sa.x; argv[3] = NULL; if ((forkexec_redir(argv, 2, fd_log)) != 0) - log_error_4("downloading package ", p.name, "/", p.ver); + log_error_1(sa.x); else if (rename("source.tmp", "source.tar") == -1) - log_fatal_sys_1(100, "rename source.tmp source.tar"); + log_fatal_sys_1(101, "rename source.tmp source.tar"); else return 0; } if (r < 0) log_error_sys_1("buffering"); - log_fatal_4(1, "could not download ", p.name, "/", p.ver); - return 2; + return 100; } diff --git a/package-install.c b/package-install.c @@ -37,7 +37,7 @@ main(int argc, char **argv) if (!stat_isdir(def)) log_fatal_sys_1(101, def); if (!stat_isdir(root)) log_fatal_sys_1(101, root); - if (*av[0] == '\0' || (*av)[package_scan(&p, *av)] != '\0') + if (*av[0] == '\0' || (*av)[package_scan(&p, *av, strlen(*av))] != '\0') log_fatal_sys_2(1, "invalid package format: ", *av); if (!package_version(&p, def)) log_fatal_sys_2(101, "version ", p.name); diff --git a/package-tree.c b/package-tree.c @@ -21,20 +21,20 @@ tree(package *p, stralloc *prefix, char const *def) size_t n; int ret = 0; - if (!package_version(p, def)) goto err; - if (!stralloc_cats(prefix, p->name)) goto err; - if (!stralloc_cats(prefix, " - ")) goto err; - if (!stralloc_cats(prefix, p->ver)) goto err; - if (!stralloc_cats(prefix, "/")) goto err; + if (!package_version(p, def)) goto error; + if (!stralloc_cats(prefix, p->name)) goto error; + if (!stralloc_cats(prefix, " - ")) goto error; + if (!stralloc_cats(prefix, p->ver)) goto error; + if (!stralloc_cats(prefix, "/")) goto error; buffer_puts(buffer_1, "\t"); buffer_put(buffer_1, prefix->x, prefix->n - 1); buffer_puts(buffer_1, "\n"); stralloc_init(&sa); - if (!stralloc_cats(&sa, def)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; n = sa.n; ver[0] = p->ver; ver[1] = "default"; @@ -42,28 +42,28 @@ tree(package *p, stralloc *prefix, char const *def) for (size_t i = 0; i < 2 && fd == -1; ++i) { sa.n = n; - if (!stralloc_cats(&sa, ver[i])) goto err; - if (!stralloc_cats(&sa, "/dependencies")) goto err; - if (!stralloc_cat0(&sa)) goto err; + if (!stralloc_cats(&sa, ver[i])) goto error; + if (!stralloc_cats(&sa, "/dependencies")) goto error; + if (!stralloc_cat0(&sa)) goto error; fd = open_read(sa.x); } - if (fd == -1) { ret = (errno == ENOENT); goto err; } + if (fd == -1) { ret = (errno == ENOENT); goto error; } buffer_init(&b, &read, fd, buf, sizeof buf); while (stralloc_zero(&sa), (r = buffer_getline(&b, &sa))) { if (sa.x[sa.n - 1] == '\n') --sa.n; - if (!stralloc_cat0(&sa)) goto err; - if (sa.x[package_scan(p, sa.x)] != '\0') goto err; + if (!stralloc_cat0(&sa)) goto error; + if (sa.x[package_dep_scan(p, sa.x, sa.n)] != '\0') goto error; n = prefix->n; - if (!tree(p, prefix, def)) goto err; + if (!tree(p, prefix, def)) goto error; prefix->n = n; } - if (r != 0) goto err; + if (r != 0) goto error; ret = 1; -err: +error: stralloc_free(&sa); if (fd >= 0) close (fd); return ret; @@ -81,7 +81,7 @@ main(int argc, char **argv) if (argc != 2) log_usage(*argv, "package[/version]"); ++argv; - if (!package_scan(&p, *argv)) + if (!package_scan(&p, *argv, strlen(*argv))) log_fatal_2(1, "invalid package format: ", *argv); stralloc_init(&sa); diff --git a/package.c b/package.c @@ -14,6 +14,8 @@ #include "stralloc.h" #include "tai.h" +#include <stdio.h> + size_t package_fmt(package const *p, char *buf) { @@ -29,36 +31,77 @@ package_fmt(package const *p, char *buf) } size_t -package_scan(package *p, char const *s) +package_scan(package *p, char const *s, size_t n) { size_t i; - size_t n = 0; - size_t v = 0; + size_t x = 0; + size_t y = 0; if (s[0] == '/') return 0; - for (n = 0, i = 0 ;; ++n, ++i) + for (i = 0; i < n; ++i, ++x) { if (!isprint(s[i]) || s[i] == ' ') goto end; - if (s[i] == '/') break; + if (s[i] == '/') { ++i; break; } if (i >= sizeof p->name) return 0; - p->name[n] = s[i]; + p->name[x] = s[i]; } - for (v = 0, ++i ;; ++i, ++v) + for (; i < n; ++i, ++y) { if (!isprint(s[i]) || s[i] == ' ') goto end; if (s[i] == '/') break; if (i > sizeof p->ver) return 0; - p->ver[v] = s[i]; + p->ver[y] = s[i]; } - end: - p->name[n] = '\0'; - p->ver[v] = '\0'; + p->dep_build = 0; + p->dep_run = 0; + p->dep_lib = 0; + p->name[x] = '\0'; + p->ver[y] = '\0'; return i; } +size_t +package_dep_scan(package *p, char const *s, size_t n) +{ + size_t x; + size_t y; + + mem_zero((char *)p, sizeof *p); + if ((x = mem_chr(s, n, ':')) == n) return 0; + + y = package_scan(p, s + x + 1, n - x - 1); + if (x + 1 + y == n) return 0; + + for (size_t i = 0; i < x; ++i) + { + switch (s[i]) + { + case 'b': p->dep_build = 1; break; + case 'l': p->dep_lib = 1; break; + case 'r': p->dep_run = 1; break; + default: return 0; + } + } + + return x + 1 + y; +} + +static int +package_hasdep(package const *p, genalloc *packages) +{ + for (size_t i = 0; i < genalloc_len(packages, package); ++i) + { + package *x = genalloc_get(packages, package, i); + if (str_equal(x->name, p->name)) + if (str_equal(x->ver, p->ver)) + return 1; + } + return 0; +} + int package_version(package *p, char const *def) { @@ -71,26 +114,26 @@ package_version(package *p, char const *def) if (*p->ver) return 1; stralloc_init(&sa); - if (!stralloc_cats(&sa, def)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/default/version")) goto err; - if (!stralloc_cat0(&sa)) goto err; + if (!stralloc_cats(&sa, def)) goto error; + if (!stralloc_cats(&sa, "/")) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_cats(&sa, "/default/version")) goto error; + if (!stralloc_cat0(&sa)) goto error; - fd = open_read(sa.x); if (fd == -1) goto err; + fd = open_read(sa.x); if (fd == -1) goto error; stralloc_zero(&sa); buffer_init(&b, &read, fd, buf, sizeof buf); - if (buffer_getline(&b, &sa) <= 0) goto err; + if (buffer_getline(&b, &sa) <= 0) goto error; if (sa.x[sa.n - 1] == '\n') --sa.n; - if (sa.n >= sizeof p->ver) goto err; + if (sa.n >= sizeof p->ver) goto error; mem_copy(p->ver, sa.x, sa.n); p->ver[sa.n] = '\0'; ret = 1; -err: +error: stralloc_free(&sa); if (fd >= 0) close(fd); return ret; @@ -104,47 +147,31 @@ package_opendepfile(package const *p, char const *def) int fd = -1; stralloc_init(&sa); - if (!stralloc_copys(&sa, def)) goto err; - if (!stralloc_append(&sa, '/')) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_append(&sa, '/')) goto err; + if (!stralloc_copys(&sa, def)) goto error; + if (!stralloc_append(&sa, '/')) goto error; + if (!stralloc_cats(&sa, p->name)) goto error; + if (!stralloc_append(&sa, '/')) goto error; n = sa.n; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/dependencies")) goto err; - if (!stralloc_append(&sa, '\0')) goto err; + if (!stralloc_cats(&sa, p->ver)) goto error; + if (!stralloc_cats(&sa, "/dependencies")) goto error; + if (!stralloc_append(&sa, '\0')) goto error; errno = 0; fd = open_read(sa.x); if (errno == ENOTDIR || errno == ENOENT) { sa.n = n; - if (!stralloc_cats(&sa, "default/dependencies")) goto err; - if (!stralloc_append(&sa, '\0')) goto err; + if (!stralloc_cats(&sa, "default/dependencies")) goto error; + if (!stralloc_append(&sa, '\0')) goto error; errno = 0; fd = open_read(sa.x); } -err: +error: stralloc_free(&sa); return fd; } -static int -package_hasdep(package const *p, genalloc *packages) -{ - size_t i; - - for (i = 0; i < genalloc_len(packages, package); ++i) - { - package *x = genalloc_get(packages, package, i); - if (str_equal(x->name, p->name)) - if (str_equal(x->ver, p->ver)) - return 1; - } - - return 0; -} - int package_dep(package const *p, genalloc *packages, char const *def) { @@ -166,19 +193,17 @@ package_dep(package const *p, genalloc *packages, char const *def) package new; size_t n; - stralloc_cat0(&sa); - n = package_scan(&new, sa.x); if (n == 0) goto err; - if (sa.x[n] != '\n' && sa.x[n] != '\0') goto err; - if (!package_version(&new, def)) goto err; - + n = package_dep_scan(&new, sa.x, sa.n); + if (sa.x[n] != '\n' && sa.n != n) goto error; + if (!package_version(&new, def)) goto error; if (package_hasdep(&new, packages)) continue; - if (!package_dep(&new, packages, def)) goto err; - if (!genalloc_append(packages, new)) goto err; + if (!package_dep(&new, packages, def)) goto error; + if (!genalloc_append(packages, new)) goto error; } ret = (r == 0); -err: +error: stralloc_free(&sa); close(fd); return ret; diff --git a/package.h b/package.h @@ -12,13 +12,16 @@ typedef struct { char name[NAME_MAX]; char ver[NAME_MAX]; + char dep_build; + char dep_run; + char dep_lib; } package; int package_dep(package const *, genalloc *, char const *); -int package_lock(package *, char const *); int package_opendepfile(package const *, char const *); int package_version(package *, char const *); +size_t package_dep_scan(package *, char const *, size_t); size_t package_fmt(package const *, char *); -size_t package_scan(package *, char const *); +size_t package_scan(package *, char const *, size_t); #endif