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