packages: poldek/poldek-ls-queryfmt.patch (NEW) - support for query format ...
megabajt
megabajt at pld-linux.org
Sun Dec 13 21:49:15 CET 2009
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 <marcin.banasiak at gmail.com>
+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 <megabajt at pld-linux.org>
++
++ 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>>
More information about the pld-cvs-commit
mailing list