ref-filter: make "%(symref)" atom work with the ':short' modifier
[gitweb.git] / ref-filter.c
index 4a05150578d71fc68d0335a41719fe738df2fca9..26116b805eab45b39b6b6f46d720bc61ffea94c1 100644 (file)
@@ -48,8 +48,10 @@ static struct used_atom {
        union {
                char color[COLOR_MAXLEN];
                struct align align;
-               enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT }
-                       remote_ref;
+               struct {
+                       enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT } option;
+                       unsigned int nobracket : 1;
+               } remote_ref;
                struct {
                        enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
                        unsigned int nlines;
@@ -77,16 +79,33 @@ static void color_atom_parser(struct used_atom *atom, const char *color_value)
 
 static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
 {
-       if (!arg)
-               atom->u.remote_ref = RR_NORMAL;
-       else if (!strcmp(arg, "short"))
-               atom->u.remote_ref = RR_SHORTEN;
-       else if (!strcmp(arg, "track"))
-               atom->u.remote_ref = RR_TRACK;
-       else if (!strcmp(arg, "trackshort"))
-               atom->u.remote_ref = RR_TRACKSHORT;
-       else
-               die(_("unrecognized format: %%(%s)"), atom->name);
+       struct string_list params = STRING_LIST_INIT_DUP;
+       int i;
+
+       if (!arg) {
+               atom->u.remote_ref.option = RR_NORMAL;
+               return;
+       }
+
+       atom->u.remote_ref.nobracket = 0;
+       string_list_split(&params, arg, ',', -1);
+
+       for (i = 0; i < params.nr; i++) {
+               const char *s = params.items[i].string;
+
+               if (!strcmp(s, "short"))
+                       atom->u.remote_ref.option = RR_SHORTEN;
+               else if (!strcmp(s, "track"))
+                       atom->u.remote_ref.option = RR_TRACK;
+               else if (!strcmp(s, "trackshort"))
+                       atom->u.remote_ref.option = RR_TRACKSHORT;
+               else if (!strcmp(s, "nobracket"))
+                       atom->u.remote_ref.nobracket = 1;
+               else
+                       die(_("unrecognized format: %%(%s)"), atom->name);
+       }
+
+       string_list_clear(&params, 0);
 }
 
 static void body_atom_parser(struct used_atom *atom, const char *arg)
@@ -333,7 +352,7 @@ int parse_ref_filter_atom(const char *atom, const char *ep)
                valid_atom[i].parser(&used_atom[at], arg);
        if (*atom == '*')
                need_tagged = 1;
-       if (!strcmp(used_atom[at].name, "symref"))
+       if (!strcmp(valid_atom[i].name, "symref"))
                need_symref = 1;
        return at;
 }
@@ -1069,25 +1088,27 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
                                    struct branch *branch, const char **s)
 {
        int num_ours, num_theirs;
-       if (atom->u.remote_ref == RR_SHORTEN)
+       if (atom->u.remote_ref.option == RR_SHORTEN)
                *s = shorten_unambiguous_ref(refname, warn_ambiguous_refs);
-       else if (atom->u.remote_ref == RR_TRACK) {
+       else if (atom->u.remote_ref.option == RR_TRACK) {
                if (stat_tracking_info(branch, &num_ours,
                                       &num_theirs, NULL)) {
-                       *s = "[gone]";
-                       return;
-               }
-
-               if (!num_ours && !num_theirs)
+                       *s = xstrdup("gone");
+               } else if (!num_ours && !num_theirs)
                        *s = "";
                else if (!num_ours)
-                       *s = xstrfmt("[behind %d]", num_theirs);
+                       *s = xstrfmt("behind %d", num_theirs);
                else if (!num_theirs)
-                       *s = xstrfmt("[ahead %d]", num_ours);
+                       *s = xstrfmt("ahead %d", num_ours);
                else
-                       *s = xstrfmt("[ahead %d, behind %d]",
+                       *s = xstrfmt("ahead %d, behind %d",
                                     num_ours, num_theirs);
-       } else if (atom->u.remote_ref == RR_TRACKSHORT) {
+               if (!atom->u.remote_ref.nobracket && *s[0]) {
+                       const char *to_free = *s;
+                       *s = xstrfmt("[%s]", *s);
+                       free((void *)to_free);
+               }
+       } else if (atom->u.remote_ref.option == RR_TRACKSHORT) {
                if (stat_tracking_info(branch, &num_ours,
                                       &num_theirs, NULL))
                        return;