/* * qpkg.c - Quick package database query * * Written 2010 by Werner Almesberger * Copyright 2010 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include "id.h" #include "prereq.h" #include "gobble.h" #include "qpkg.h" struct tree *packages = NULL; struct tree *versions = NULL; static void list_all_packages(void) { const struct id *id; for (id = first_id(packages); id; id = next_id(id)) { struct pkg *pkg = id->jrb->val; printf("%.*s", (int) id->len, id->s); if (!pkg) printf(" (virtual)"); else { if (pkg->version) printf(" (%.*s)", (int) pkg->version->len, pkg->version->s); if (pkg->more) printf(" +++"); } printf("\n"); } } static void list_one_package(const char *name) { const struct id *id = find_id(packages, name, strlen(name)); const struct pkg *pkg; if (!id) { fprintf(stderr, "no such package \"%s\"\n", name); exit(1); } for (pkg = id->jrb->val; pkg; pkg = pkg->more) printf("%.*s\n", (int) pkg->version->len, pkg->version->s); } static void find_prereq(const char *name, const char *version) { const struct id *id = find_id(packages, name, strlen(name)); struct pkg *pkg; struct pkg **pkgs; if (!id) { fprintf(stderr, "no such package \"%s\"\n", name); exit(1); } pkg = id->jrb->val; if (!pkg) { fprintf(stderr, "package %s is a ghost\n", name); exit(1); } if (version) { id = find_id(versions, version, strlen(version)); if (!id) { fprintf(stderr, "no such version\"%s\"\n", version); exit(1); } while (pkg && pkg->version != id) pkg = pkg->more; if (pkg) { fprintf(stderr, "no %s version\"%s\" found\n", name, version); exit(1); } } pkgs = prereq(pkg); if (!pkgs) { fprintf(stderr, "can't resolve %s%s%s\n", name, version ? " version " : "", version ? version : ""); exit(1); } while (*pkgs) { const char *file = (*pkgs)->filename; const char *end; if (file) { end = strchr(file, '\n'); printf("%.*s\n", (int) (end-file), file); } pkgs++; } } static void usage(const char *name) { fprintf(stderr, "usage: %s [pkg-list ...] list [pkg]\n" " %s [pkg-list ...] prereq pkg [version]\n" , name, name); exit(1); } int main(int argc, char **argv) { int arg; if (argc == 1) usage(*argv); packages = make_tree(comp_id); versions = make_tree(comp_id); for (arg = 1; arg != argc; arg++) { if (*argv[arg] == '-') usage(*argv); if (!strcmp(argv[arg], "list")) { switch (argc-arg) { case 1: list_all_packages(); return 0; case 2: list_one_package(argv[arg+1]); return 0; default: usage(*argv); } } else if (!strcmp(argv[arg], "prereq")) { switch (argc-arg) { case 2: find_prereq(argv[arg+1], NULL); return 0; case 3: find_prereq(argv[arg+1], argv[arg+2]); return 0; default: usage(*argv); } } else { gobble(argv[arg]); } } return 0; }