[Dctrl-tools-devel] [SCM] Debian control file query tools branch, master, updated. 2.21.1-8-gb2a4f15
Antti-Juhani Kaijanaho
ajk at debian.org
Sun Apr 22 19:16:08 UTC 2012
The following commit has been merged in the master branch:
commit b2a4f15ad801b30fb8ffdad6856433fcd43c6590
Author: Antti-Juhani Kaijanaho <ajk at debian.org>
Date: Sun Apr 22 22:15:39 2012 +0300
grep-dctrl: Allow distributing atom modifiers over a parenthesed predicate.
Signed-off-by: Antti-Juhani Kaijanaho <ajk at debian.org>
diff --git a/debian/changelog b/debian/changelog
index f430b33..f260bda 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,11 @@
dctrl-tools (2.22) UNRELEASED; urgency=low
* debian/copyright: Upgraded to copyright-format/1.0, and updated.
-
- -- Antti-Juhani Kaijanaho <ajk at debian.org> Sat, 21 Apr 2012 11:32:47 +0300
+ * grep-dctrl: Allow distributing atom modifiers over a parenthesed predicate.
+ Closes: #319760 (allow -F modifiers to apply to an entire expression)
+ Reported by Enrico Zini <enrico at debian.org>
+
+ -- Antti-Juhani Kaijanaho <ajk at debian.org> Sun, 22 Apr 2012 22:09:30 +0300
dctrl-tools (2.21.1) unstable; urgency=low
diff --git a/grep-dctrl/grep-dctrl.c b/grep-dctrl/grep-dctrl.c
index 526ad61..020681c 100644
--- a/grep-dctrl/grep-dctrl.c
+++ b/grep-dctrl/grep-dctrl.c
@@ -501,103 +501,109 @@ static void unexpected(int tok)
}
}
-static struct predicate * parse_conj(struct arguments * args);
+struct predicate_qualifiers {
+ struct strlist *fields;
+ enum matching_mode mm;
+ bool ignore_case;
+ bool whole_pkg;
+};
+static struct predicate * parse_conj(struct arguments * args,
+ struct predicate_qualifiers pq);
-/* prim -> TOK_LP conj TOK_RP
- prim -> prim'
+/* prim -> primtok
+ prim -> primtok prim
+ prim -> TOK_LP conj TOK_RP
+ prim -> TOK_PAT prim'
+ prim -> TOK_STR prim'
- prim' -> primtok
+ prim' ->
prim' -> primtok prim'
- prim' -> TOK_PAT prim''
- prim' -> TOK_STR prim''
-
- prim'' ->
- prim'' -> primtok prim''
primtok -> TOK_FIELD
primtok -> TOK_ERGEX | TOK_REGEX
primtok -> TOK_ICASE | TOK_EXACT | TOK_WHOLE
primtok -> TOK_EQ | TOK_LT | TOK_LE | TOK_GE | TOK_GT
*/
-static struct predicate * parse_prim(struct arguments * args)
+static struct predicate * parse_prim(struct arguments * args,
+ struct predicate_qualifiers pq_)
{
- if (peek_token(args) == TOK_LP) {
- get_token(args);
- struct predicate * rv = parse_conj(args);
- if (get_token(args) != TOK_RP) {
- message(L_FATAL, 0, _("missing ')' in command line"));
- fail();
- }
- return rv;
- }
-
char *pattern = 0;
- struct strlist *fields = strlist_new();
- if (fields == 0) enomem(0);
- enum matching_mode mm = M_SUBSTR;
- bool ignore_case = false;
- bool whole_pkg = false;
- bool nonempty = false;
+ struct predicate *rv = 0;
+ struct predicate_qualifiers pq = pq_;
+ struct strlist_memento mem = strlist_save(pq.fields);
+
+ bool nonempty = false;
while (1) {
- debug("tok = %s, mm = %d", tokdescr(peek_token(args)), mm);
+ debug("tok = %s, mm = %d", tokdescr(peek_token(args)), pq.mm);
switch (peek_token(args)) {
case TOK_FIELD:
- if (!strlist_append(fields, get_string(args))) {
+ if (!strlist_append(pq.fields, get_string(args))) {
enomem(0);
}
break;
case TOK_ERGEX:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_EREGEX;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_EREGEX;
get_token(args);
break;
case TOK_REGEX:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_REGEX;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_REGEX;
get_token(args);
break;
case TOK_ICASE:
- ignore_case = true;
+ pq.ignore_case = true;
get_token(args);
break;
case TOK_EXACT:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_EXACT;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_EXACT;
get_token(args);
break;
case TOK_WHOLE:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_EREGEX;
- whole_pkg = true;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_EREGEX;
+ pq.whole_pkg = true;
get_token(args);
break;
case TOK_EQ:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_VER_EQ;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_VER_EQ;
get_token(args);
break;
case TOK_LT:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_VER_LT;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_VER_LT;
get_token(args);
break;
case TOK_LE:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_VER_LE;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_VER_LE;
get_token(args);
break;
case TOK_GT:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_VER_GT;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_VER_GT;
get_token(args);
break;
case TOK_GE:
- if (mm != M_SUBSTR) goto failmode;
- mm = M_VER_GE;
+ if (pq.mm != M_SUBSTR) goto failmode;
+ pq.mm = M_VER_GE;
get_token(args);
break;
+ case TOK_LP:
+ {
+ get_token(args);
+ rv = parse_conj(args, pq);
+ if (get_token(args) != TOK_RP) {
+ message(L_FATAL, 0,
+ _("missing ')' in command line"));
+ fail();
+ }
+ goto finally;
+ }
case TOK_PAT:
if (pattern != 0) {
message(L_FATAL, 0,
@@ -613,7 +619,7 @@ static struct predicate * parse_prim(struct arguments * args)
default:
goto loop_done;
}
- nonempty = true;
+ nonempty = true;
} loop_done:
if (!nonempty) {
@@ -625,20 +631,19 @@ static struct predicate * parse_prim(struct arguments * args)
fail();
}
- if (strlist_is_empty(fields)) {
- strlist_append(fields, 0);
+ if (strlist_is_empty(pq.fields)) {
+ strlist_append(pq.fields, 0);
}
- struct predicate *rv = 0;
- for (struct strlist_iterator it = strlist_begin(fields);
+ for (struct strlist_iterator it = strlist_begin(pq.fields);
!strlist_iterator_at_end(it); strlist_iterator_next(&it)) {
struct atom * atom = malloc(sizeof *atom);
if (atom == 0) enomem(0);
atom->field_name = strlist_iterator_get(it);
atom->field_inx = -1;
- atom->mode = mm;
- atom->ignore_case = ignore_case;
- atom->whole_pkg = whole_pkg;
+ atom->mode = pq.mm;
+ atom->ignore_case = pq.ignore_case;
+ atom->whole_pkg = pq.whole_pkg;
atom->pat = pattern;
atom->patlen = strlen(pattern);
atom_finish(atom);
@@ -646,26 +651,28 @@ static struct predicate * parse_prim(struct arguments * args)
rv = rv != 0 ? predicate_OR(rv, tmp) : tmp;
}
- strlist_free(fields);
+finally:
+ strlist_restore(mem);
return rv;
failmode:
- strlist_free(fields);
message(L_FATAL, 0, _("inconsistent modifiers of simple filters"));
fail();
- return 0;
+ rv = 0;
+ goto finally;
}
/* neg -> TOK_NOT prim
neg -> prim
*/
-static struct predicate * parse_neg(struct arguments * args)
+static struct predicate * parse_neg(struct arguments * args,
+ struct predicate_qualifiers pq)
{
bool neg = false;
if (peek_token(args) == TOK_NOT) {
neg = true;
get_token(args);
}
- struct predicate * rv = parse_prim(args);
+ struct predicate * rv = parse_prim(args, pq);
if (neg) rv = predicate_NOT(rv);
return rv;
}
@@ -673,12 +680,13 @@ static struct predicate * parse_neg(struct arguments * args)
/* disj -> neg
disj -> disj TOK_OR neg
*/
-static struct predicate * parse_disj(struct arguments * args)
+static struct predicate * parse_disj(struct arguments * args,
+ struct predicate_qualifiers pq)
{
- struct predicate * rv = parse_neg(args);
+ struct predicate * rv = parse_neg(args, pq);
while (peek_token(args) == TOK_OR) {
get_token(args);
- struct predicate * tmp = parse_neg(args);
+ struct predicate * tmp = parse_neg(args, pq);
rv = predicate_OR(rv, tmp);
}
return rv;
@@ -687,12 +695,13 @@ static struct predicate * parse_disj(struct arguments * args)
/* conj -> disj
conj -> conj TOK_AND disj
*/
-static struct predicate * parse_conj(struct arguments * args)
+static struct predicate * parse_conj(struct arguments * args,
+ struct predicate_qualifiers pq)
{
- struct predicate * rv = parse_disj(args);
+ struct predicate * rv = parse_disj(args, pq);
while (peek_token(args) == TOK_AND) {
get_token(args);
- struct predicate * tmp = parse_disj(args);
+ struct predicate * tmp = parse_disj(args, pq);
rv = predicate_AND(rv, tmp);
}
return rv;
@@ -705,7 +714,18 @@ static struct predicate * parse_conj(struct arguments * args)
static void parse_predicate(struct arguments * args)
{
args->toks_pos = 0;
- args->p = parse_conj(args);
+
+ struct predicate_qualifiers pq;
+ pq.fields = strlist_new();
+ if (pq.fields == 0) enomem(0);
+ pq.mm = M_SUBSTR;
+ pq.ignore_case = false;
+ pq.whole_pkg = false;
+
+ args->p = parse_conj(args, pq);
+
+ strlist_free(pq.fields);
+
while (peek_token(args) == TOK_STR) {
if (args->num_fnames >= MAX_FNAMES) {
message(L_FATAL, 0, _("too many file names"));
diff --git a/lib/strlist.c b/lib/strlist.c
index c21a410..2877dc5 100644
--- a/lib/strlist.c
+++ b/lib/strlist.c
@@ -85,3 +85,17 @@ void strlist_iterator_next(struct strlist_iterator * it)
{
it->i++;
}
+
+struct strlist_memento strlist_save(struct strlist *sl)
+{
+ struct strlist_memento rv = {
+ .sl = sl,
+ .n = sl->n
+ };
+ return rv;
+}
+void strlist_restore(struct strlist_memento mem)
+{
+ mem.sl->n = mem.n;
+}
+
diff --git a/lib/strlist.h b/lib/strlist.h
index da64623..d0de21a 100644
--- a/lib/strlist.h
+++ b/lib/strlist.h
@@ -24,12 +24,19 @@ struct strlist_iterator {
struct strlist *sl;
size_t i;
};
+struct strlist_memento {
+ struct strlist *sl;
+ size_t n;
+};
struct strlist *strlist_new(void);
_Bool strlist_append(struct strlist *, const char *);
_Bool strlist_is_empty(struct strlist *);
void strlist_free(struct strlist *);
+struct strlist_memento strlist_save(struct strlist *);
+void strlist_restore(struct strlist_memento);
+
struct strlist_iterator strlist_begin(struct strlist *);
_Bool strlist_iterator_at_end(struct strlist_iterator);
const char *strlist_iterator_get(struct strlist_iterator);
diff --git a/man/grep-dctrl.1.cp b/man/grep-dctrl.1.cp
index 4fe24f0..4729376 100644
--- a/man/grep-dctrl.1.cp
+++ b/man/grep-dctrl.1.cp
@@ -1,6 +1,7 @@
-.TH GREP-DCTRL 1 2011-12-18 "Debian Project" "Debian user's manual"
-\" Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2011
-\" Antti-Juhani Kaijanaho <gaia at iki.fi>
+.TH GREP-DCTRL 1 2012-04-22 "Debian Project" "Debian user's manual"
+\" Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2011,
+\" 2012
+\" Antti-Juhani Kaijanaho <ajk at debian.org>
\" 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
@@ -247,7 +248,9 @@ matches.
Match if both the preceding and the following filter match.
.IP "\fB(\fR ... \fB)"
Parentheses can be used for grouping. Note that they need to be
-escaped for most shells.
+escaped for most shells. Filter modifiers can be given before the
+opening parentheses; they will be treated as if they had been repeated
+for each simple filter inside the parentheses.
.SS Output format modifiers
.IP "\fB\-s \fIfield\fR,\fIfield\fR, ... | \fB\-\-show\-field=\fIfield\fR,\fIfield\fR, ..."
Show only the body of these
diff --git a/tests/0016.out b/tests/bug319760.in
similarity index 50%
copy from tests/0016.out
copy to tests/bug319760.in
index b0bcef9..6d4f0df 100644
--- a/tests/0016.out
+++ b/tests/bug319760.in
@@ -1,4 +1,3 @@
-Source: foo
-
Package: foo
+Whatever: bar
diff --git a/tests/0016.out b/tests/bug319760.out
similarity index 50%
copy from tests/0016.out
copy to tests/bug319760.out
index b0bcef9..6d4f0df 100644
--- a/tests/0016.out
+++ b/tests/bug319760.out
@@ -1,4 +1,3 @@
-Source: foo
-
Package: foo
+Whatever: bar
diff --git a/tests/bug319760.sh b/tests/bug319760.sh
new file mode 100644
index 0000000..eb6cff6
--- /dev/null
+++ b/tests/bug319760.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -e
+
+${GREP_DCTRL:-grep-dctrl} -FPackage \( foo -a ! bar \)
--
Debian control file query tools
More information about the Dctrl-tools-devel
mailing list