git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/8] trailer: add interface for iterating over commit trailers

From
Jeff King <peff@peff.net>
Date
Sep 25, 2020, 07:02 UTC
Message-ID
<20200925070249.GC62741@coredump.intra.peff.net>
In-Reply-To
<20200925070120.GA3669667@coredump.intra.peff.net>

The trailer code knows how to parse out the trailers and re-format them, but there's no easy way to iterate over the trailers (you can use trailer_info, but you have to then do a bunch of extra parsing).

Let's add an iteration interface that makes this easy to do.
Signed-off-by: Jeff King <peff@peff.net>
---
 trailer.c | 36 ++++++++++++++++++++++++++++++++++++
 trailer.h | 44 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/trailer.c b/trailer.c
index 68dabc2556..3f7391d793 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1183,3 +1183,39 @@ void format_trailers_from_commit(struct strbuf *out, const char *msg,
 	format_trailer_info(out, &info, opts);
 	trailer_info_release(&info);
 }
+
+void trailer_iterator_init(struct trailer_iterator *iter, const char *msg)
+{
+	struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
+	strbuf_init(&iter->key, 0);
+	strbuf_init(&iter->val, 0);
+	opts.no_divider = 1;
+	trailer_info_get(&iter->info, msg, &opts);
+	iter->cur = 0;
+}
+
+int trailer_iterator_advance(struct trailer_iterator *iter)
+{
+	while (iter->cur < iter->info.trailer_nr) {
+		char *trailer = iter->info.trailers[iter->cur++];
+		int separator_pos = find_separator(trailer, separators);
+
+		if (separator_pos < 1)
+			continue; /* not a real trailer */
+
+		strbuf_reset(&iter->key);
+		strbuf_reset(&iter->val);
+		parse_trailer(&iter->key, &iter->val, NULL,
+			      trailer, separator_pos);
+		unfold_value(&iter->val);
+		return 1;
+	}
+	return 0;
+}
+
+void trailer_iterator_release(struct trailer_iterator *iter)
+{
+	trailer_info_release(&iter->info);
+	strbuf_release(&iter->val);
+	strbuf_release(&iter->key);
+}
diff --git a/trailer.h b/trailer.h
index 203acf4ee1..af9949363a 100644
--- a/trailer.h
+++ b/trailer.h
@@ -2,8 +2,7 @@
 #define TRAILER_H
 
 #include "list.h"
-
-struct strbuf;
+#include "strbuf.h"
 
 enum trailer_where {
 	WHERE_DEFAULT,
@@ -103,4 +102,45 @@ void trailer_info_release(struct trailer_info *info);
 void format_trailers_from_commit(struct strbuf *out, const char *msg,
 				 const struct process_trailer_options *opts);
 
+/*
+ * An interface for iterating over the trailers found in a particular commit
+ * message. Use like:
+ *
+ *   struct trailer_iterator iter;
+ *   trailer_iterator_init(&iter, msg);
+ *   while (trailer_iterator_advance(&iter))
+ *      ... do something with iter.key and iter.val ...
+ *   trailer_iterator_release(&iter);
+ */
+struct trailer_iterator {
+	struct strbuf key;
+	struct strbuf val;
+
+	/* private */
+	struct trailer_info info;
+	size_t cur;
+};
+
+/*
+ * Initialize "iter" in preparation for walking over the trailers in the commit
+ * message "msg". The "msg" pointer must remain valid until the iterator is
+ * released.
+ *
+ * After initializing, we are not yet pointing
+ */
+void trailer_iterator_init(struct trailer_iterator *iter, const char *msg);
+
+/*
+ * Advance to the next trailer of the iterator. Returns 0 if there is no such
+ * trailer, and 1 otherwise. The key and value of the trailer can be
+ * fetched from the iter->key and iter->value fields (which are valid
+ * only until the next advance).
+ */
+int trailer_iterator_advance(struct trailer_iterator *iter);
+
+/*
+ * Release all resources associated with the trailer iteration.
+ */
+void trailer_iterator_release(struct trailer_iterator *iter);
+
 #endif /* TRAILER_H */
-- 
2.28.0.1085.g44a0350633
Previous: Jeff KingNext: Martin Ågren
Message 10 of 44 in “parsing trailers with shortlog”
  1. 0/8 parsing trailers with shortlogJeff King, Sep 25, 2020
  2. 1/8 shortlog: change "author" variables to "ident"Jeff King, Sep 25, 2020
  3. 2/8 shortlog: refactor committer/author groupingJeff King, Sep 25, 2020
  4. Eric SunshineSep 25, 2020
  5. Jeff KingSep 27, 2020
  6. Jeff KingSep 27, 2020
  7. Eric SunshineSep 27, 2020
  8. Martin ÅgrenSep 26, 2020
  9. Jeff KingSep 27, 2020
  10. 3/8 trailer: add interface for iterating over commit trailersJeff King, Sep 25, 2020
  11. Martin ÅgrenSep 26, 2020
  12. Jeff KingSep 27, 2020
  13. 4/8 shortlog: match commit trailers with --groupJeff King, Sep 25, 2020
  14. 5/8 shortlog: de-duplicate trailer valuesJeff King, Sep 25, 2020
  15. 6/8 shortlog: rename parse_stdin_ident()Jeff King, Sep 25, 2020
  16. 7/8 shortlog: parse trailer identsJeff King, Sep 25, 2020
  17. 8/8 shortlog: allow multiple groups to be specifiedJeff King, Sep 25, 2020
  18. Eric SunshineSep 25, 2020
  19. Jeff KingSep 27, 2020
  20. Martin ÅgrenSep 26, 2020
  21. Jeff KingSep 27, 2020
  22. Derrick StoleeSep 25, 2020
  23. Junio C HamanoSep 25, 2020
  24. 0/8 parsing trailers with shortlogJeff King, Sep 27, 2020
  25. 1/8 shortlog: change "author" variables to "ident"Jeff King, Sep 27, 2020
  26. Junio C HamanoSep 27, 2020
  27. 2/8 shortlog: add grouping optionJeff King, Sep 27, 2020
  28. 3/8 trailer: add interface for iterating over commit trailersJeff King, Sep 27, 2020
  29. 4/8 shortlog: match commit trailers with --groupJeff King, Sep 27, 2020
  30. Junio C HamanoSep 27, 2020
  31. Jeff KingSep 28, 2020
  32. Junio C HamanoSep 28, 2020
  33. 5/8 shortlog: de-duplicate trailer valuesJeff King, Sep 27, 2020
  34. Junio C HamanoSep 27, 2020
  35. Jeff KingSep 28, 2020
  36. 6/8 shortlog: rename parse_stdin_ident()Jeff King, Sep 27, 2020
  37. 7/8 shortlog: parse trailer identsJeff King, Sep 27, 2020
  38. Junio C HamanoSep 27, 2020
  39. 8/8 shortlog: allow multiple groups to be specifiedJeff King, Sep 27, 2020
  40. Junio C HamanoSep 27, 2020
  41. Jeff KingSep 28, 2020
  42. Junio C HamanoDec 28, 2020
  43. Junio C HamanoFeb 4, 2021
  44. Martin ÅgrenSep 27, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.