Skip to content

Commit c12b7d0

Browse files
committed
common: Add a flag for left anchored substring match to recsel.
* common/recsel.c (struct recsel_expr_s): Add field lefta. (recsel_parse_expr): Parse it. (recsel_select): Implement selection. -- This flags makes it for example easy to select keys last updated from an ldap server: gpg --list-filter 'select=origin=ks && -^ url =~ ldap' \ -k --with-key-origin
1 parent e5555a4 commit c12b7d0

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

common/recsel.c

+15-3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct recsel_expr_s
6464
unsigned int not:1; /* Negate operators. */
6565
unsigned int disjun:1;/* Start of a disjunction. */
6666
unsigned int xcase:1; /* String match is case sensitive. */
67+
unsigned int lefta:1; /* String match is left anchored. */
6768
const char *value; /* (Points into NAME.) */
6869
long numvalue; /* strtol of VALUE. */
6970
char name[1]; /* Name of the property. */
@@ -140,6 +141,7 @@ find_next_lc (char *string)
140141
* Values for <flag> must be space separated and any of:
141142
*
142143
* -- VALUE spans to the end of the expression.
144+
* -^ The substring match is left anchored.
143145
* -c The string match in this part is done case-sensitive.
144146
* -t Do not trim leading and trailing spaces from VALUE.
145147
* Note that a space after <op> is here required.
@@ -176,6 +178,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
176178
int toend = 0;
177179
int xcase = 0;
178180
int notrim = 0;
181+
int lefta = 0;
179182
int disjun = 0;
180183
char *next_lc = NULL;
181184

@@ -206,6 +209,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
206209
case '-': toend = 1; break;
207210
case 'c': xcase = 1; break;
208211
case 't': notrim = 1; break;
212+
case '^': lefta = 1; break;
209213
default:
210214
log_error ("invalid flag '-%c' in expression\n", *expr);
211215
recsel_release (se_head);
@@ -235,6 +239,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
235239
se->not = 0;
236240
se->disjun = disjun;
237241
se->xcase = xcase;
242+
se->lefta = lefta;
238243

239244
if (!se_head)
240245
se_head = se;
@@ -463,9 +468,10 @@ recsel_dump (recsel_expr_t selector)
463468
log_debug ("--- Begin selectors ---\n");
464469
for (se = selector; se; se = se->next)
465470
{
466-
log_debug ("%s %s %s %s '%s'\n",
471+
log_debug ("%s %s %s %s %s '%s'\n",
467472
se==selector? " ": (se->disjun? "||":"&&"),
468473
se->xcase? "-c":" ",
474+
se->lefta? "-^":" ",
469475
se->name,
470476
se->op == SELECT_SAME? (se->not? "<>":"= "):
471477
se->op == SELECT_SUB? (se->not? "!~":"=~"):
@@ -529,9 +535,15 @@ recsel_select (recsel_expr_t selector,
529535
break;
530536
case SELECT_SUB:
531537
if (se->xcase)
532-
result = !!gnupg_memstr (value, valuelen, se->value);
538+
result = (gnupg_memstr (value, valuelen, se->value)
539+
&& (!se->lefta
540+
|| (selen <= valuelen
541+
&& !memcmp (value, se->value, selen))));
533542
else
534-
result = !!memistr (value, valuelen, se->value);
543+
result = (memistr (value, valuelen, se->value)
544+
&& (!se->lefta
545+
|| (selen <= valuelen
546+
&& !memicmp (value, se->value, selen))));
535547
break;
536548
case SELECT_NONEMPTY:
537549
result = !!valuelen;

common/t-recsel.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,27 @@ run_test_2 (void)
225225
if (!recsel_select (se, test_2_getval, NULL))
226226
fail (0, 0);
227227
FREEEXPR();
228-
ADDEXPR ("uid =~ @");
228+
ADDEXPR ("uid !~ @");
229+
if (recsel_select (se, test_2_getval, NULL))
230+
fail (0, 0);
231+
232+
FREEEXPR();
233+
ADDEXPR ("uid =~ foo@");
234+
if (!recsel_select (se, test_2_getval, NULL))
235+
fail (0, 0);
236+
FREEEXPR();
237+
ADDEXPR ("uid =~ oo@");
238+
if (!recsel_select (se, test_2_getval, NULL))
239+
fail (0, 0);
240+
FREEEXPR();
241+
/* Again but with left anchored substring. */
242+
ADDEXPR ("-^ uid =~ foo@");
229243
if (!recsel_select (se, test_2_getval, NULL))
230244
fail (0, 0);
245+
FREEEXPR();
246+
ADDEXPR ("-^ uid =~ oo@");
247+
if (recsel_select (se, test_2_getval, NULL))
248+
fail (0, 0);
231249

232250
FREEEXPR();
233251
ADDEXPR ("keyid == 0x12345678");

doc/gpg.texi

+4-2
Original file line numberDiff line numberDiff line change
@@ -2561,8 +2561,8 @@ gpg can track the origin of a key. Certain origins are implicitly
25612561
known (e.g., keyserver, web key directory) and set. For a standard
25622562
import the origin of the keys imported can be set with this option.
25632563
To list the possible values use "help" for @var{string}. Some origins
2564-
can store an optional @var{url} argument. That URL can appended to
2565-
@var{string} after a comma.
2564+
can store an optional @var{url} argument; such an URL can be appended to
2565+
@var{string} delimited by a comma.
25662566

25672567
@item --import-options @var{parameters}
25682568
@opindex import-options
@@ -4389,6 +4389,8 @@ are:
43894389
@table @asis
43904390
@item --
43914391
@var{VALUE} spans to the end of the expression.
4392+
@item -^
4393+
The substring match is left anchored.
43924394
@item -c
43934395
The string match in this part is done case-sensitive.
43944396
@item -t

0 commit comments

Comments
 (0)