aboutsummaryrefslogtreecommitdiffstats
path: root/ref-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'ref-filter.c')
-rw-r--r--ref-filter.c152
1 files changed, 48 insertions, 104 deletions
diff --git a/ref-filter.c b/ref-filter.c
index ee337df232..f0bd32f714 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -67,6 +67,12 @@ struct refname_atom {
int lstrip, rstrip;
};
+static struct ref_trailer_buf {
+ struct string_list filter_list;
+ struct strbuf sepbuf;
+ struct strbuf kvsepbuf;
+} ref_trailer_buf = {STRING_LIST_INIT_NODUP, STRBUF_INIT, STRBUF_INIT};
+
static struct expand_data {
struct object_id oid;
enum object_type type;
@@ -313,28 +319,26 @@ static int subject_atom_parser(const struct ref_format *format, struct used_atom
static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom,
const char *arg, struct strbuf *err)
{
- struct string_list params = STRING_LIST_INIT_DUP;
- int i;
-
atom->u.contents.trailer_opts.no_divider = 1;
if (arg) {
- string_list_split(&params, arg, ',', -1);
- for (i = 0; i < params.nr; i++) {
- const char *s = params.items[i].string;
- if (!strcmp(s, "unfold"))
- atom->u.contents.trailer_opts.unfold = 1;
- else if (!strcmp(s, "only"))
- atom->u.contents.trailer_opts.only_trailers = 1;
- else {
- strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s);
- string_list_clear(&params, 0);
- return -1;
- }
+ const char *argbuf = xstrfmt("%s)", arg);
+ char *invalid_arg = NULL;
+
+ if (format_set_trailers_options(&atom->u.contents.trailer_opts,
+ &ref_trailer_buf.filter_list,
+ &ref_trailer_buf.sepbuf,
+ &ref_trailer_buf.kvsepbuf,
+ &argbuf, &invalid_arg)) {
+ if (!invalid_arg)
+ strbuf_addf(err, _("expected %%(trailers:key=<value>)"));
+ else
+ strbuf_addf(err, _("unknown %%(trailers) argument: %s"), invalid_arg);
+ free((char *)invalid_arg);
+ return -1;
}
}
atom->u.contents.option = C_TRAILERS;
- string_list_clear(&params, 0);
return 0;
}
@@ -768,7 +772,8 @@ static int if_atom_handler(struct atom_value *atomv, struct ref_formatting_state
struct strbuf *unused_err)
{
struct ref_formatting_stack *new_stack;
- struct if_then_else *if_then_else = xcalloc(sizeof(struct if_then_else), 1);
+ struct if_then_else *if_then_else = xcalloc(1,
+ sizeof(struct if_then_else));
if_then_else->str = atomv->atom->u.if_then_else.str;
if_then_else->cmp_status = atomv->atom->u.if_then_else.cmp_status;
@@ -1210,12 +1215,20 @@ static void grab_person(const char *who, struct atom_value *val, int deref, void
}
static void find_subpos(const char *buf,
- const char **sub, unsigned long *sublen,
- const char **body, unsigned long *bodylen,
- unsigned long *nonsiglen,
- const char **sig, unsigned long *siglen)
+ const char **sub, size_t *sublen,
+ const char **body, size_t *bodylen,
+ size_t *nonsiglen,
+ const char **sig, size_t *siglen)
{
+ struct strbuf payload = STRBUF_INIT;
+ struct strbuf signature = STRBUF_INIT;
const char *eol;
+ const char *end = buf + strlen(buf);
+ const char *sigstart;
+
+ /* parse signature first; we might not even have a subject line */
+ parse_signature(buf, end - buf, &payload, &signature);
+
/* skip past header until we hit empty line */
while (*buf && *buf != '\n') {
eol = strchrnul(buf, '\n');
@@ -1226,16 +1239,14 @@ static void find_subpos(const char *buf,
/* skip any empty lines */
while (*buf == '\n')
buf++;
-
- /* parse signature first; we might not even have a subject line */
- *sig = buf + parse_signature(buf, strlen(buf));
- *siglen = strlen(*sig);
+ *sig = strbuf_detach(&signature, siglen);
+ sigstart = buf + parse_signed_buffer(buf, strlen(buf));
/* subject is first non-empty line */
*sub = buf;
/* subject goes to first empty line before signature begins */
if ((eol = strstr(*sub, "\n\n"))) {
- eol = eol < *sig ? eol : *sig;
+ eol = eol < sigstart ? eol : sigstart;
/* check if message uses CRLF */
} else if (! (eol = strstr(*sub, "\r\n\r\n"))) {
/* treat whole message as subject */
@@ -1253,7 +1264,7 @@ static void find_subpos(const char *buf,
buf++;
*body = buf;
*bodylen = strlen(buf);
- *nonsiglen = *sig - buf;
+ *nonsiglen = sigstart - buf;
}
/*
@@ -1285,12 +1296,13 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
{
int i;
const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL;
- unsigned long sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;
+ size_t sublen = 0, bodylen = 0, nonsiglen = 0, siglen = 0;
for (i = 0; i < used_atom_cnt; i++) {
struct used_atom *atom = &used_atom[i];
const char *name = atom->name;
struct atom_value *v = &val[i];
+
if (!!deref != (*name == '*'))
continue;
if (deref)
@@ -1322,7 +1334,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
v->s = xmemdupz(sigpos, siglen);
else if (atom->u.contents.option == C_LINES) {
struct strbuf s = STRBUF_INIT;
- const char *contents_end = bodylen + bodypos - siglen;
+ const char *contents_end = bodypos + nonsiglen;
/* Size is the length of the message after removing the signature */
append_lines(&s, subpos, contents_end - subpos, atom->u.contents.nlines);
@@ -1336,7 +1348,9 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf)
v->s = strbuf_detach(&s, NULL);
} else if (atom->u.contents.option == C_BARE)
v->s = xstrdup(subpos);
+
}
+ free((void *)sigpos);
}
/*
@@ -1663,7 +1677,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err)
int i;
struct object_info empty = OBJECT_INFO_INIT;
- ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
+ CALLOC_ARRAY(ref->value, used_atom_cnt);
if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
@@ -1920,64 +1934,6 @@ static int filter_pattern_match(struct ref_filter *filter, const char *refname)
return match_pattern(filter, refname);
}
-static int qsort_strcmp(const void *va, const void *vb)
-{
- const char *a = *(const char **)va;
- const char *b = *(const char **)vb;
-
- return strcmp(a, b);
-}
-
-static void find_longest_prefixes_1(struct string_list *out,
- struct strbuf *prefix,
- const char **patterns, size_t nr)
-{
- size_t i;
-
- for (i = 0; i < nr; i++) {
- char c = patterns[i][prefix->len];
- if (!c || is_glob_special(c)) {
- string_list_append(out, prefix->buf);
- return;
- }
- }
-
- i = 0;
- while (i < nr) {
- size_t end;
-
- /*
- * Set "end" to the index of the element _after_ the last one
- * in our group.
- */
- for (end = i + 1; end < nr; end++) {
- if (patterns[i][prefix->len] != patterns[end][prefix->len])
- break;
- }
-
- strbuf_addch(prefix, patterns[i][prefix->len]);
- find_longest_prefixes_1(out, prefix, patterns + i, end - i);
- strbuf_setlen(prefix, prefix->len - 1);
-
- i = end;
- }
-}
-
-static void find_longest_prefixes(struct string_list *out,
- const char **patterns)
-{
- struct strvec sorted = STRVEC_INIT;
- struct strbuf prefix = STRBUF_INIT;
-
- strvec_pushv(&sorted, patterns);
- QSORT(sorted.v, sorted.nr, qsort_strcmp);
-
- find_longest_prefixes_1(out, &prefix, sorted.v, sorted.nr);
-
- strvec_clear(&sorted);
- strbuf_release(&prefix);
-}
-
/*
* This is the same as for_each_fullref_in(), but it tries to iterate
* only over the patterns we'll care about. Note that it _doesn't_ do a full
@@ -1988,10 +1944,6 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
void *cb_data,
int broken)
{
- struct string_list prefixes = STRING_LIST_INIT_DUP;
- struct string_list_item *prefix;
- int ret;
-
if (!filter->match_as_path) {
/*
* in this case, the patterns are applied after
@@ -2015,16 +1967,8 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
return for_each_fullref_in("", cb, cb_data, broken);
}
- find_longest_prefixes(&prefixes, filter->name_patterns);
-
- for_each_string_list_item(prefix, &prefixes) {
- ret = for_each_fullref_in(prefix->string, cb, cb_data, broken);
- if (ret)
- break;
- }
-
- string_list_clear(&prefixes, 0);
- return ret;
+ return for_each_fullref_in_prefixes(NULL, filter->name_patterns,
+ cb, cb_data, broken);
}
/*
@@ -2242,7 +2186,7 @@ static void reach_filter(struct ref_array *array,
if (!check_reachable)
return;
- to_clear = xcalloc(sizeof(struct commit *), array->nr);
+ CALLOC_ARRAY(to_clear, array->nr);
repo_init_revisions(the_repository, &revs, NULL);
@@ -2547,7 +2491,7 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg)
{
struct ref_sorting *s;
- s = xcalloc(1, sizeof(*s));
+ CALLOC_ARRAY(s, 1);
s->next = *sorting_tail;
*sorting_tail = s;