Author: megabajt Date: Sun Dec 13 20:49:15 2009 GMT Module: packages Tag: HEAD ---- Log message: - support for query format (ls --qf=QUERYFMT)
---- Files affected: packages/poldek: poldek-ls-queryfmt.patch (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: packages/poldek/poldek-ls-queryfmt.patch diff -u /dev/null packages/poldek/poldek-ls-queryfmt.patch:1.1 --- /dev/null Sun Dec 13 21:49:15 2009 +++ packages/poldek/poldek-ls-queryfmt.patch Sun Dec 13 21:49:10 2009 @@ -0,0 +1,1266 @@ +commit 4b027294335c0672311f021f2dc76edaab049b11 +Author: Marcin Banasiak <[email protected]> +Date: Sun Dec 13 20:50:11 2009 +0100 + + Support for query format in ls command. + + Syntax of the queryfmt is almost the same as in rpm except query + expressions which are not (yet) supported. + + To see supported tags type: + ls --querytags + +diff --git a/cli/Makefile.am b/cli/Makefile.am +index 53fcdfd..4a32e01 100644 +--- a/cli/Makefile.am ++++ b/cli/Makefile.am +@@ -28,6 +28,7 @@ libpoclidek_la_SOURCES = \ + op_split.c \ + op_verify.c \ + ls.c \ ++ ls_queryfmt.c ls_queryfmt.h \ + install.c \ + uninstall.c \ + desc.c \ +diff --git a/cli/ls_queryfmt.c b/cli/ls_queryfmt.c +new file mode 100644 +index 0000000..1a0c02f +--- /dev/null ++++ b/cli/ls_queryfmt.c +@@ -0,0 +1,1096 @@ ++/* ++ Copyright (C) 2009 Marcin Banasiak <[email protected]> ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License, version 2 as ++ published by the Free Software Foundation (see file COPYING for details). ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++/* for asprintf() from stdio.h */ ++#define _GNU_SOURCE ++ ++/* FIXME: nbuf.h should include stdint.h */ ++#include <stdint.h> ++ ++#include <sys/stat.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <time.h> ++ ++#include <trurl/trurl.h> ++ ++#include "capreq.h" ++#include "i18n.h" ++#include "log.h" ++#include "ls_queryfmt.h" ++#include "pkgu.h" ++#include "pkgfl.h" ++ ++#define n_strcase_eq(s, p) (strcasecmp(s, p) == 0) ++ ++static const char *invalid_format = N_("invalid format:"); ++ ++enum LsqfParseMode { ++ LSQF_PARSE_NORMAL = 0, ++ LSQF_PARSE_ARRAY ++}; ++ ++/* Tags have to be in alphabetical order. */ ++enum { ++ LSQF_TAG_UNKNOWN = -1, ++ ++ LSQF_TAG_ARCH = 0, ++ LSQF_TAG_BASENAMES, ++ LSQF_TAG_BUILDHOST, ++ LSQF_TAG_BUILDTIME, ++ LSQF_TAG_CONFLICTFLAGS, ++ LSQF_TAG_CONFLICTS, ++ LSQF_TAG_CONFLICTVERSION, ++ LSQF_TAG_DESCRIPTION, ++ LSQF_TAG_DIRNAMES, ++ LSQF_TAG_EPOCH, ++ LSQF_TAG_FILELINKTOS, ++ LSQF_TAG_FILEMODES, ++ LSQF_TAG_FILENAMES, ++ LSQF_TAG_FILESIZES, ++ LSQF_TAG_GROUP, ++ LSQF_TAG_LICENSE, ++ LSQF_TAG_NAME, ++ LSQF_TAG_NVRA, ++ LSQF_TAG_OBSOLETEFLAGS, ++ LSQF_TAG_OBSOLETES, ++ LSQF_TAG_OBSOLETEVERSION, ++ LSQF_TAG_PACKAGECOLOR, ++ LSQF_TAG_PROVIDEFLAGS, ++ LSQF_TAG_PROVIDES, ++ LSQF_TAG_PROVIDEVERSION, ++ LSQF_TAG_RELEASE, ++ LSQF_TAG_REQUIREFLAGS, ++ LSQF_TAG_REQUIRES, ++ LSQF_TAG_REQUIREVERSION, ++ LSQF_TAG_SIZE, ++ LSQF_TAG_SOURCERPM, ++ LSQF_TAG_SUGGESTSFLAGS, ++ LSQF_TAG_SUGGESTS, ++ LSQF_TAG_SUGGESTSVERSION, ++ LSQF_TAG_SUMMARY, ++ LSQF_TAG_URL, ++ LSQF_TAG_VENDOR, ++ LSQF_TAG_VERSION, ++ ++ LSQF_N_TAGS ++}; ++ ++enum { ++ LSQF_TAG_OUTFMTFN_NONE = 0, ++ ++ LSQF_TAG_OUTFMTFN_DATE, ++ LSQF_TAG_OUTFMTFN_DAY, ++ LSQF_TAG_OUTFMTFN_DEPFLAGS ++}; ++ ++struct lsqf_tags { ++ int tagid; ++ int is_array : 1; ++ int need_uinf : 1; ++ int need_flist : 1; ++ const char *tagname[4]; ++}; ++ ++/* ++ * LSQF_TAG_* have to be added in the same sequence as in enumeration ++ * (LSQF_TAG_ value is an index in lsqf_tags[] array). ++ */ ++static const struct lsqf_tags lsqf_tags[] = { ++ { LSQF_TAG_ARCH, 0, 0, 0, { "ARCH", NULL } }, ++ { LSQF_TAG_BASENAMES, 1, 0, 1, { "BASENAMES", NULL } }, ++ { LSQF_TAG_BUILDHOST, 0, 1, 0, { "BUILDHOST", NULL } }, ++ { LSQF_TAG_BUILDTIME, 0, 0, 0, { "BUILDTIME", NULL } }, ++ { LSQF_TAG_CONFLICTFLAGS, 1, 0, 0, { "CONFLICTFLAGS", NULL } }, ++ { LSQF_TAG_CONFLICTS, 1, 0, 0, { "C", "CONFLICTNAME", "CONFLICTS", NULL } }, ++ { LSQF_TAG_CONFLICTVERSION, 1, 0, 0, { "CONFLICTVERSION", NULL } }, ++ { LSQF_TAG_DESCRIPTION, 0, 1, 0, { "DESCRIPTION", NULL } }, ++ { LSQF_TAG_DIRNAMES, 1, 0, 1, { "DIRNAMES", NULL } }, ++ { LSQF_TAG_EPOCH, 0, 0, 0, { "E", "EPOCH", NULL } }, ++ { LSQF_TAG_FILELINKTOS, 1, 0, 1, { "FILELINKTOS", NULL } }, ++ { LSQF_TAG_FILEMODES, 1, 0, 1, { "FILEMODES", NULL } }, ++ { LSQF_TAG_FILENAMES, 1, 0, 1, { "FILENAMES", NULL } }, ++ { LSQF_TAG_FILESIZES, 1, 0, 1, { "FILESIZES", NULL } }, ++ { LSQF_TAG_GROUP, 0, 0, 0, { "GROUP", NULL } }, ++ { LSQF_TAG_LICENSE, 0, 1, 0, { "LICENSE", NULL } }, ++ { LSQF_TAG_NAME, 0, 0, 0, { "N", "NAME", NULL } }, ++ { LSQF_TAG_NVRA, 0, 0, 0, { "NVRA", NULL } }, ++ { LSQF_TAG_OBSOLETEFLAGS, 1, 0, 0, { "OBSOLETEFLAGS", NULL } }, ++ { LSQF_TAG_OBSOLETES, 1, 0, 0, { "O", "OBSOLETENAME", "OBSOLETES", NULL } }, ++ { LSQF_TAG_OBSOLETEVERSION, 1, 0, 0, { "OBSOLETEVERSION", NULL } }, ++ { LSQF_TAG_PACKAGECOLOR, 0, 0, 0, { "PACKAGECOLOR", NULL } }, ++ { LSQF_TAG_PROVIDEFLAGS, 1, 0, 0, { "PROVIDEFLAGS", NULL } }, ++ { LSQF_TAG_PROVIDES, 1, 0, 0, { "P", "PROVIDENAME", "PROVIDES", NULL } }, ++ { LSQF_TAG_PROVIDEVERSION, 1, 0, 0, { "PROVIDEVERSION", NULL } }, ++ { LSQF_TAG_RELEASE, 0, 0, 0, { "R", "RELEASE", NULL } }, ++ { LSQF_TAG_REQUIREFLAGS, 1, 0, 0, { "REQUIREFLAGS", NULL } }, ++ { LSQF_TAG_REQUIRES, 1, 0, 0, { "REQUIRENAME", "REQUIRES", NULL } }, ++ { LSQF_TAG_REQUIREVERSION, 1, 0, 0, { "REQUIREVERSION", NULL } }, ++ { LSQF_TAG_SIZE, 0, 0, 0, { "SIZE", NULL } }, ++ { LSQF_TAG_SOURCERPM, 0, 0, 0, { "SOURCERPM", NULL } }, ++ { LSQF_TAG_SUGGESTSFLAGS, 1, 0, 0, { "SUGGESTSFLAGS", NULL } }, ++ { LSQF_TAG_SUGGESTS, 1, 0, 0, { "SUGGESTS", "SUGGESTSNAME", NULL } }, ++ { LSQF_TAG_SUGGESTSVERSION, 1, 0, 0, { "SUGGESTSVERSION", NULL } }, ++ { LSQF_TAG_SUMMARY, 0, 1, 0, { "SUMMARY", NULL } }, ++ { LSQF_TAG_URL, 0, 1, 0, { "URL", NULL } }, ++ { LSQF_TAG_VENDOR, 0, 1, 0, { "VENDOR", NULL } }, ++ { LSQF_TAG_VERSION, 0, 0, 0, { "V", "VERSION", NULL } }, ++ { LSQF_N_TAGS, 0, 0, 0, { NULL } } ++}; ++ ++struct lsqf_pkgdata { ++ const struct pkg *pkg; ++ struct pkgflist *flist; ++ struct pkguinf *uinf; ++}; ++ ++static struct lsqf_pkgdata *lsqf_pkgdata_new(const struct pkg *pkg) ++{ ++ struct lsqf_pkgdata *pkgdata = NULL; ++ ++ pkgdata = n_malloc(sizeof(struct lsqf_pkgdata)); ++ ++ if (pkgdata) { ++ pkgdata->pkg = pkg; ++ pkgdata->flist = NULL; ++ pkgdata->uinf = NULL; ++ } ++ ++ return pkgdata; ++} ++ ++static struct pkgflist *lsqf_pkgdata_flist(struct lsqf_pkgdata *pkgdata) ++{ ++ if (pkgdata->flist == NULL) ++ pkgdata->flist = pkg_get_flist(pkgdata->pkg); ++ ++ return pkgdata->flist; ++} ++ ++static struct pkguinf *lsqf_pkgdata_uinf(struct lsqf_pkgdata *pkgdata) ++{ ++ if (pkgdata->uinf == NULL) ++ pkgdata->uinf = pkg_uinf(pkgdata->pkg); ++ ++ return pkgdata->uinf; ++} ++ ++static void lsqf_pkgdata_free(struct lsqf_pkgdata *pkgdata) ++{ ++ if (pkgdata) { ++ if (pkgdata->flist) ++ pkgflist_free(pkgdata->flist); ++ ++ if (pkgdata->uinf) ++ pkguinf_free(pkgdata->uinf); ++ ++ n_free(pkgdata); ++ } ++} ++ ++static int get_tagid_by_name(char *tag) ++{ ++ if (tag) { ++ unsigned int i, j; ++ ++ for (i = 0; i < LSQF_N_TAGS; i++) { ++ for (j = 0; lsqf_tags[i].tagname[j]; j++) { ++ if (n_strcase_eq(tag, lsqf_tags[i].tagname[j])) { ++ return lsqf_tags[i].tagid; ++ } ++ } ++ } ++ } ++ ++ return LSQF_TAG_UNKNOWN; ++} ++ ++static int get_outfmtfnid_by_name(char *outfmtfn) ++{ ++ if (outfmtfn && *outfmtfn) { ++ if (n_str_eq(outfmtfn, "date")) ++ return LSQF_TAG_OUTFMTFN_DATE; ++ if (n_str_eq(outfmtfn, "day")) ++ return LSQF_TAG_OUTFMTFN_DAY; ++ if (n_str_eq(outfmtfn, "depflags")) ++ return LSQF_TAG_OUTFMTFN_DEPFLAGS; ++ } ++ ++ return LSQF_TAG_OUTFMTFN_NONE; ++} ++ ++/* TODO: move to capreq.c */ ++static int capreq_snprintf_evr(char *str, size_t size, const struct capreq *cr) ++{ ++ int n = 0; ++ ++ n_assert(size > 0); ++ ++ if (capreq_has_epoch(cr)) ++ n += n_snprintf(&str[n], size - n, "%d:", capreq_epoch(cr)); ++ ++ if (capreq_has_ver(cr)) ++ n += n_snprintf(&str[n], size - n, "%s", capreq_ver(cr)); ++ ++ if (capreq_has_rel(cr)) { ++ n_assert(capreq_has_ver(cr)); ++ ++ n += n_snprintf(&str[n], size - n, "-%s", capreq_rel(cr)); ++ } ++ ++ return n; ++} ++ ++static char *format_date(int outfmtfnid, uint32_t time) ++{ ++ char *buf = NULL, datestr[32];; ++ ++ if (outfmtfnid == LSQF_TAG_OUTFMTFN_DATE) { ++ strftime(datestr, sizeof(datestr), "%c", gmtime((time_t *)&time)); ++ asprintf(&buf, "%s", datestr); ++ } else if (outfmtfnid == LSQF_TAG_OUTFMTFN_DAY) { ++ strftime(datestr, sizeof(datestr), "%a %b %d %Y", gmtime((time_t *)&time)); ++ asprintf(&buf, "%s", datestr); ++ } else { ++ asprintf(&buf, "%u", time); ++ } ++ ++ return buf; ++} ++ ++static char *format_flags(int outfmtfnid, struct capreq *cr) ++{ ++ char *buf = NULL; ++ ++ if (outfmtfnid == LSQF_TAG_OUTFMTFN_DEPFLAGS) { ++ char relstr[3], *p; ++ ++ p = relstr; ++ *p = '\0'; ++ ++ if (cr->cr_relflags & REL_LT) ++ *p++ = '<'; ++ else if (cr->cr_relflags & REL_GT) ++ *p++ = '>'; ++ ++ if (cr->cr_relflags & REL_EQ) ++ *p++ = '='; ++ ++ *p = '\0'; ++ ++ asprintf(&buf, " %s ", relstr); ++ } else { ++ asprintf(&buf, "%u", cr->cr_relflags); ++ } ++ ++ return buf; ++} ++ ++static char *get_str_by_tagid(const struct lsqf_ent *ent, struct lsqf_pkgdata *pkgdata, unsigned int num) ++{ ++ const struct pkg *pkg = pkgdata->pkg; ++ struct capreq *c = NULL; ++ char *buf = NULL, evr[32]; ++ unsigned int i; ++ ++ if (lsqf_tags[ent->tag.id].need_uinf) { ++ struct pkguinf *pkgu = lsqf_pkgdata_uinf(pkgdata); ++ const char *str = NULL; ++ ++ switch (ent->tag.id) { ++ case LSQF_TAG_BUILDHOST: ++ str = pkguinf_get(pkgu, PKGUINF_BUILDHOST); ++ break; ++ ++ case LSQF_TAG_DESCRIPTION: ++ str = pkguinf_get(pkgu, PKGUINF_DESCRIPTION); ++ break; ++ ++ case LSQF_TAG_LICENSE: ++ str = pkguinf_get(pkgu, PKGUINF_LICENSE); ++ break; ++ ++ case LSQF_TAG_SUMMARY: ++ str = pkguinf_get(pkgu, PKGUINF_SUMMARY); ++ break; ++ ++ case LSQF_TAG_URL: ++ str = pkguinf_get(pkgu, PKGUINF_URL); ++ break; ++ ++ case LSQF_TAG_VENDOR: ++ str = pkguinf_get(pkgu, PKGUINF_VENDOR); ++ break; ++ ++ default: ++ n_assert(0); ++ } ++ ++ if (str) ++ buf = n_strdup(str); ++ else ++ buf = n_strdup("(none)"); ++ ++ } else if (lsqf_tags[ent->tag.id].need_flist) { ++ struct pkgflist *flist = lsqf_pkgdata_flist(pkgdata); ++ struct pkgfl_ent *flent; ++ ++ if (flist) { ++ switch (ent->tag.id) { ++ case LSQF_TAG_BASENAMES: ++ case LSQF_TAG_FILELINKTOS: ++ case LSQF_TAG_FILEMODES: ++ case LSQF_TAG_FILENAMES: ++ case LSQF_TAG_FILESIZES: ++ for (i = 0; i < n_tuple_size(flist->fl); i++) { ++ flent = n_tuple_nth(flist->fl, i); ++ ++ if (flent->items <= num) ++ num -= flent->items; ++ else ++ break; ++ } ++ ++ if (ent->tag.id == LSQF_TAG_BASENAMES) ++ buf = n_strdup(flent->files[num]->basename); ++ else if (ent->tag.id == LSQF_TAG_FILEMODES) ++ asprintf(&buf, "%u", flent->files[num]->mode); ++ else if (ent->tag.id == LSQF_TAG_FILENAMES) { ++ if (*flent->dirname == '/') ++ asprintf(&buf, "%s%s", flent->dirname, flent->files[num]->basename); ++ else ++ asprintf(&buf, "/%s%s%s", flent->dirname, ++ *flent->files[num]->basename ? "/" : "", ++ flent->files[num]->basename); ++ } else if (ent->tag.id == LSQF_TAG_FILESIZES) ++ asprintf(&buf, "%u", flent->files[num]->size); ++ else ++ if (S_ISLNK(flent->files[num]->mode)) ++ buf = n_strdup(flent->files[num]->basename + strlen(flent->files[num]->basename) + 1); ++ ++ break; ++ ++ case LSQF_TAG_DIRNAMES: ++ flent = n_tuple_nth(flist->fl, num); ++ ++ asprintf(&buf, "%s%s", *flent->dirname == '/' ? "" : "/", ++ flent->dirname); ++ break; ++ ++ default: ++ n_assert(0); ++ } ++ } ++ } else { ++ switch (ent->tag.id) { ++ case LSQF_TAG_ARCH: ++ buf = n_strdup(pkg_arch(pkg)); ++ break; ++ ++ case LSQF_TAG_BUILDTIME: ++ buf = format_date(ent->tag.outfmtfnid, pkg->btime); ++ break; ++ ++ case LSQF_TAG_CONFLICTFLAGS: ++ case LSQF_TAG_CONFLICTS: ++ case LSQF_TAG_CONFLICTVERSION: ++ case LSQF_TAG_OBSOLETEFLAGS: ++ case LSQF_TAG_OBSOLETES: ++ case LSQF_TAG_OBSOLETEVERSION: ++ { ++ unsigned int n = 0; ++ ++ for (i = 0; i < n_array_size(pkg->cnfls); i++) { ++ struct capreq *cr = n_array_nth(pkg->cnfls, i); ++ ++ if (ent->tag.id == LSQF_TAG_CONFLICTS || ent->tag.id == LSQF_TAG_CONFLICTFLAGS) { ++ if (!capreq_is_obsl(cr)) { ++ if (n == num) { ++ c = cr; ++ break; ++ } ++ ++ n++; ++ } ++ } else { ++ if (capreq_is_obsl(cr)) { ++ if (n == num) { ++ c = cr; ++ break; ++ } ++ ++ n++; ++ } ++ } ++ } ++ ++ if (c) { ++ if (ent->tag.id == LSQF_TAG_CONFLICTS || ent->tag.id == LSQF_TAG_OBSOLETES) ++ buf = n_strdup(capreq_name(c)); ++ else if (ent->tag.id == LSQF_TAG_CONFLICTFLAGS || ent->tag.id == LSQF_TAG_OBSOLETEFLAGS) ++ buf = format_flags(ent->tag.outfmtfnid, c); ++ else if (ent->tag.id == LSQF_TAG_CONFLICTVERSION || ent->tag.id == LSQF_TAG_OBSOLETEVERSION) ++ if (capreq_snprintf_evr(evr, sizeof(evr), c) > 0) ++ buf = n_strdup(evr); ++ ++ } ++ break; ++ } ++ ++ case LSQF_TAG_EPOCH: ++ asprintf(&buf, "%d", pkg->epoch); ++ break; ++ ++ case LSQF_TAG_GROUP: ++ buf = n_strdup(pkg_group(pkg)); ++ break; ++ ++ case LSQF_TAG_NAME: ++ buf = n_strdup(pkg->name); ++ break; ++ ++ case LSQF_TAG_NVRA: ++ buf = n_strdup(pkg_id(pkg)); ++ break; ++ ++ case LSQF_TAG_PACKAGECOLOR: ++ asprintf(&buf, "%d", pkg->color); ++ break; ++ ++ case LSQF_TAG_PROVIDEFLAGS: ++ buf = format_flags(ent->tag.outfmtfnid, n_array_nth(pkg->caps, num)); ++ break; ++ ++ case LSQF_TAG_PROVIDES: ++ c = n_array_nth(pkg->caps, num); ++ buf = n_strdup(capreq_name(c)); ++ break; ++ ++ case LSQF_TAG_PROVIDEVERSION: ++ c = n_array_nth(pkg->caps, num); ++ ++ if (capreq_snprintf_evr(evr, sizeof(evr), c) > 0) ++ buf = n_strdup(evr); ++ ++ break; ++ ++ case LSQF_TAG_RELEASE: ++ buf = n_strdup(pkg->rel); ++ break; ++ ++ case LSQF_TAG_REQUIREFLAGS: ++ buf = format_flags(ent->tag.outfmtfnid, n_array_nth(pkg->reqs, num)); ++ break; ++ ++ case LSQF_TAG_REQUIRES: ++ c = n_array_nth(pkg->reqs, num); ++ ++ if (capreq_is_rpmlib(c)) ++ asprintf(&buf, "rpmlib(%s)", capreq_name(c)); ++ else ++ buf = n_strdup(capreq_name(c)); ++ ++ break; ++ ++ case LSQF_TAG_REQUIREVERSION: ++ c = n_array_nth(pkg->reqs, num); ++ ++ if (capreq_snprintf_evr(evr, sizeof(evr), c) > 0) ++ buf = n_strdup(evr); ++ ++ break; ++ ++ case LSQF_TAG_VERSION: ++ buf = n_strdup(pkg->ver); ++ break; ++ ++ case LSQF_TAG_SIZE: ++ asprintf(&buf, "%u", pkg->size); ++ break; ++ ++ case LSQF_TAG_SOURCERPM: ++ buf = n_strdup(pkg_srcfilename_s(pkg)); ++ break; ++ ++ case LSQF_TAG_SUGGESTSFLAGS: ++ buf = format_flags(ent->tag.outfmtfnid, n_array_nth(pkg->sugs, num)); ++ break; ++ ++ case LSQF_TAG_SUGGESTS: ++ c = n_array_nth(pkg->sugs, num); ++ buf = n_strdup(capreq_name(c)); ++ break; ++ ++ case LSQF_TAG_SUGGESTSVERSION: ++ c = n_array_nth(pkg->sugs, num); ++ ++ if (capreq_snprintf_evr(evr, sizeof(evr), c) > 0) ++ buf = n_strdup(evr); ++ ++ break; ++ ++ default: ++ n_assert(0); ++ } ++ } ++ ++ return buf; ++} ++ ++static char get_escaped_char(char zn) ++{ ++ switch (zn) { ++ case 'a': return '\a'; ++ case 'b': return '\b'; ++ case 'f': return '\f'; ++ case 'n': return '\n'; ++ case 'r': return '\r'; <<Diff was trimmed, longer than 597 lines>> _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
