Skip to content

Commit f46094a

Browse files
five-shgitster
authored andcommitted
ref-filter: add multiple-option parsing functions
The functions match_placeholder_arg_value() match_placeholder_bool_arg() were added in pretty 4f732e0 (pretty: allow %(trailers) options with explicit value, 2019-01-29) to parse multiple options in an argument to --pretty. For example, git log --pretty="%(trailers:key=Signed-Off-By,separator=%x2C )" will output all the trailers matching the key and seperates them by a comma followed by a space per commit. Add similar functions, match_atom_arg_value() match_atom_bool_arg() in ref-filter. There is no atom yet that can use these functions in ref-filter, but we are going to add a new %(describe) atom in a subsequent commit where we parse options like tags=<bool-value> or match=<pattern> given to it. Helped-by: Junio C Hamano <[email protected]> Mentored-by: Christian Couder <[email protected]> Mentored-by: Hariom Verma <[email protected]> Signed-off-by: Kousik Sanagavarapu <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cba07a3 commit f46094a

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

ref-filter.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "git-compat-util.h"
22
#include "environment.h"
33
#include "gettext.h"
4+
#include "config.h"
45
#include "gpg-interface.h"
56
#include "hex.h"
67
#include "parse-options.h"
@@ -255,6 +256,110 @@ static int err_bad_arg(struct strbuf *sb, const char *name, const char *arg)
255256
return -1;
256257
}
257258

259+
/*
260+
* Parse option of name "candidate" in the option string "to_parse" of
261+
* the form
262+
*
263+
* "candidate1[=val1],candidate2[=val2],candidate3[=val3],..."
264+
*
265+
* The remaining part of "to_parse" is stored in "end" (if we are
266+
* parsing the last candidate, then this is NULL) and the value of
267+
* the candidate is stored in "valuestart" and its length in "valuelen",
268+
* that is the portion after "=". Since it is possible for a "candidate"
269+
* to not have a value, in such cases, "valuestart" is set to point to
270+
* NULL and "valuelen" to 0.
271+
*
272+
* The function returns 1 on success. It returns 0 if we don't find
273+
* "candidate" in "to_parse" or we find "candidate" but it is followed
274+
* by more chars (for example, "candidatefoo"), that is, we don't find
275+
* an exact match.
276+
*
277+
* This function only does the above for one "candidate" at a time. So
278+
* it has to be called each time trying to parse a "candidate" in the
279+
* option string "to_parse".
280+
*/
281+
static int match_atom_arg_value(const char *to_parse, const char *candidate,
282+
const char **end, const char **valuestart,
283+
size_t *valuelen)
284+
{
285+
const char *atom;
286+
287+
if (!skip_prefix(to_parse, candidate, &atom))
288+
return 0; /* definitely not "candidate" */
289+
290+
if (*atom == '=') {
291+
/* we just saw "candidate=" */
292+
*valuestart = atom + 1;
293+
atom = strchrnul(*valuestart, ',');
294+
*valuelen = atom - *valuestart;
295+
} else if (*atom != ',' && *atom != '\0') {
296+
/* key begins with "candidate" but has more chars */
297+
return 0;
298+
} else {
299+
/* just "candidate" without "=val" */
300+
*valuestart = NULL;
301+
*valuelen = 0;
302+
}
303+
304+
/* atom points at either the ',' or NUL after this key[=val] */
305+
if (*atom == ',')
306+
atom++;
307+
else if (*atom)
308+
BUG("Why is *atom not NULL yet?");
309+
310+
*end = atom;
311+
return 1;
312+
}
313+
314+
/*
315+
* Parse boolean option of name "candidate" in the option list "to_parse"
316+
* of the form
317+
*
318+
* "candidate1[=bool1],candidate2[=bool2],candidate3[=bool3],..."
319+
*
320+
* The remaining part of "to_parse" is stored in "end" (if we are parsing
321+
* the last candidate, then this is NULL) and the value (if given) is
322+
* parsed and stored in "val", so "val" always points to either 0 or 1.
323+
* If the value is not given, then "val" is set to point to 1.
324+
*
325+
* The boolean value is parsed using "git_parse_maybe_bool()", so the
326+
* accepted values are
327+
*
328+
* to set true - "1", "yes", "true"
329+
* to set false - "0", "no", "false"
330+
*
331+
* This function returns 1 on success. It returns 0 when we don't find
332+
* an exact match for "candidate" or when the boolean value given is
333+
* not valid.
334+
*/
335+
static int match_atom_bool_arg(const char *to_parse, const char *candidate,
336+
const char **end, int *val)
337+
{
338+
const char *argval;
339+
char *strval;
340+
size_t arglen;
341+
int v;
342+
343+
if (!match_atom_arg_value(to_parse, candidate, end, &argval, &arglen))
344+
return 0;
345+
346+
if (!argval) {
347+
*val = 1;
348+
return 1;
349+
}
350+
351+
strval = xstrndup(argval, arglen);
352+
v = git_parse_maybe_bool(strval);
353+
free(strval);
354+
355+
if (v == -1)
356+
return 0;
357+
358+
*val = v;
359+
360+
return 1;
361+
}
362+
258363
static int color_atom_parser(struct ref_format *format, struct used_atom *atom,
259364
const char *color_value, struct strbuf *err)
260365
{

0 commit comments

Comments
 (0)