]> git.ipfire.org Git - thirdparty/git.git/blobdiff - ref-filter.c
ref-filter: add multiple-option parsing functions
[thirdparty/git.git] / ref-filter.c
index 60919f375fe574e34bbf93343b7678a3e8876bd0..66b8bc586d1c3de2ad020aa7fda1739a5f40001a 100644 (file)
@@ -1,6 +1,7 @@
 #include "git-compat-util.h"
 #include "environment.h"
 #include "gettext.h"
+#include "config.h"
 #include "gpg-interface.h"
 #include "hex.h"
 #include "parse-options.h"
@@ -255,6 +256,110 @@ static int err_bad_arg(struct strbuf *sb, const char *name, const char *arg)
        return -1;
 }
 
+/*
+ * Parse option of name "candidate" in the option string "to_parse" of
+ * the form
+ *
+ *     "candidate1[=val1],candidate2[=val2],candidate3[=val3],..."
+ *
+ * The remaining part of "to_parse" is stored in "end" (if we are
+ * parsing the last candidate, then this is NULL) and the value of
+ * the candidate is stored in "valuestart" and its length in "valuelen",
+ * that is the portion after "=". Since it is possible for a "candidate"
+ * to not have a value, in such cases, "valuestart" is set to point to
+ * NULL and "valuelen" to 0.
+ *
+ * The function returns 1 on success. It returns 0 if we don't find
+ * "candidate" in "to_parse" or we find "candidate" but it is followed
+ * by more chars (for example, "candidatefoo"), that is, we don't find
+ * an exact match.
+ *
+ * This function only does the above for one "candidate" at a time. So
+ * it has to be called each time trying to parse a "candidate" in the
+ * option string "to_parse".
+ */
+static int match_atom_arg_value(const char *to_parse, const char *candidate,
+                               const char **end, const char **valuestart,
+                               size_t *valuelen)
+{
+       const char *atom;
+
+       if (!skip_prefix(to_parse, candidate, &atom))
+               return 0; /* definitely not "candidate" */
+
+       if (*atom == '=') {
+               /* we just saw "candidate=" */
+               *valuestart = atom + 1;
+               atom = strchrnul(*valuestart, ',');
+               *valuelen = atom - *valuestart;
+       } else if (*atom != ',' && *atom != '\0') {
+               /* key begins with "candidate" but has more chars */
+               return 0;
+       } else {
+               /* just "candidate" without "=val" */
+               *valuestart = NULL;
+               *valuelen = 0;
+       }
+
+       /* atom points at either the ',' or NUL after this key[=val] */
+       if (*atom == ',')
+               atom++;
+       else if (*atom)
+               BUG("Why is *atom not NULL yet?");
+
+       *end = atom;
+       return 1;
+}
+
+/*
+ * Parse boolean option of name "candidate" in the option list "to_parse"
+ * of the form
+ *
+ *     "candidate1[=bool1],candidate2[=bool2],candidate3[=bool3],..."
+ *
+ * The remaining part of "to_parse" is stored in "end" (if we are parsing
+ * the last candidate, then this is NULL) and the value (if given) is
+ * parsed and stored in "val", so "val" always points to either 0 or 1.
+ * If the value is not given, then "val" is set to point to 1.
+ *
+ * The boolean value is parsed using "git_parse_maybe_bool()", so the
+ * accepted values are
+ *
+ *     to set true  - "1", "yes", "true"
+ *     to set false - "0", "no", "false"
+ *
+ * This function returns 1 on success. It returns 0 when we don't find
+ * an exact match for "candidate" or when the boolean value given is
+ * not valid.
+ */
+static int match_atom_bool_arg(const char *to_parse, const char *candidate,
+                               const char **end, int *val)
+{
+       const char *argval;
+       char *strval;
+       size_t arglen;
+       int v;
+
+       if (!match_atom_arg_value(to_parse, candidate, end, &argval, &arglen))
+               return 0;
+
+       if (!argval) {
+               *val = 1;
+               return 1;
+       }
+
+       strval = xstrndup(argval, arglen);
+       v = git_parse_maybe_bool(strval);
+       free(strval);
+
+       if (v == -1)
+               return 0;
+
+       *val = v;
+
+       return 1;
+}
+
 static int color_atom_parser(struct ref_format *format, struct used_atom *atom,
                             const char *color_value, struct strbuf *err)
 {