Skip to content

Commit d43974f

Browse files
committed
Change trailer API to return a simple array
1 parent 5734768 commit d43974f

File tree

3 files changed

+46
-32
lines changed

3 files changed

+46
-32
lines changed

include/git2/message.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,18 @@ GIT_BEGIN_DECL
3838
*/
3939
GIT_EXTERN(int) git_message_prettify(git_buf *out, const char *message, int strip_comments, char comment_char);
4040

41-
typedef int(*git_message_trailer_cb)(const char *key, const char *value, void *payload);
41+
typedef struct {
42+
const char *key;
43+
const char *value;
44+
} git_message_trailer;
45+
46+
typedef struct {
47+
git_message_trailer *trailers;
48+
size_t count;
49+
50+
/* private */
51+
char *_trailer_block;
52+
} git_message_trailer_array;
4253

4354
/**
4455
* Parse trailers out of a message, calling a callback once for each trailer.
@@ -48,15 +59,14 @@ typedef int(*git_message_trailer_cb)(const char *key, const char *value, void *p
4859
* Trailers are key/value pairs in the last paragraph of a message, not
4960
* including any patches or conflicts that may be present.
5061
*
62+
* @param arr A pre-allocated git_message_trailer_array struct to be filled in
63+
* with any trailers found during parsing.
5164
* @param message The message to be parsed
52-
* @param cb The callback to call for each trailer found in the message. The
53-
* key and value arguments are pointers to NUL-terminated C strings. These
54-
* pointers are only guaranteed to be valid until the callback returns.
55-
* User code must make a copy of this data should it need to be retained
56-
* @param payload Pointer to callback data (optional)
5765
* @return 0 on success, or non-zero callback return value.
5866
*/
59-
GIT_EXTERN(int) git_message_trailers(const char *message, git_message_trailer_cb cb, void *payload);
67+
GIT_EXTERN(int) git_message_trailers(git_message_trailer_array *arr, const char *message);
68+
69+
GIT_EXTERN(void) git_message_trailer_array_free(git_message_trailer_array *arr);
6070

6171
/** @} */
6272
GIT_END_DECL

src/trailer.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* This file is part of libgit2, distributed under the GNU GPL v2 with
55
* a Linking Exception. For full terms see the included COPYING file.
66
*/
7+
#include "array.h"
78
#include "common.h"
89
#include "git2/message.h"
910

@@ -279,13 +280,16 @@ enum trailer_state {
279280
#define NEXT(st) { state = (st); ptr++; continue; }
280281
#define GOTO(st) { state = (st); continue; }
281282

282-
int git_message_trailers(const char *message, git_message_trailer_cb cb, void *payload)
283+
typedef git_array_t(git_message_trailer) git_array_trailer_t;
284+
285+
int git_message_trailers(git_message_trailer_array *trailer_arr, const char *message)
283286
{
284287
enum trailer_state state = S_START;
285288
int rc = 0;
286289
char *ptr;
287290
char *key = NULL;
288291
char *value = NULL;
292+
git_array_trailer_t arr = GIT_ARRAY_INIT;
289293

290294
size_t trailer_len;
291295
char *trailer = find_trailer(message, &trailer_len);
@@ -373,9 +377,10 @@ int git_message_trailers(const char *message, git_message_trailer_cb cb, void *p
373377
GOTO(S_VALUE_END);
374378
}
375379
case S_VALUE_END: {
376-
if ((rc = cb(key, value, payload))) {
377-
goto ret;
378-
}
380+
git_message_trailer *t = git_array_alloc(arr);
381+
382+
t->key = key;
383+
t->value = value;
379384

380385
key = NULL;
381386
value = NULL;
@@ -397,6 +402,15 @@ int git_message_trailers(const char *message, git_message_trailer_cb cb, void *p
397402
}
398403

399404
ret:
400-
git__free(trailer);
405+
trailer_arr->_trailer_block = trailer;
406+
trailer_arr->trailers = arr.ptr;
407+
trailer_arr->count = arr.size;
408+
401409
return rc;
402410
}
411+
412+
void git_message_trailer_array_free(git_message_trailer_array *arr)
413+
{
414+
git__free(arr->_trailer_block);
415+
git__free(arr->trailers);
416+
}

tests/message/trailer.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,22 @@ struct trailer {
66
const char *value;
77
};
88

9-
struct cb_state {
10-
struct trailer *trailer;
11-
};
12-
13-
static int trailer_cb(const char *key, const char *value, void *st_)
14-
{
15-
struct cb_state *st = st_;
16-
17-
cl_assert_equal_s(st->trailer->key, key);
18-
cl_assert_equal_s(st->trailer->value, value);
19-
20-
st->trailer++;
21-
22-
return 0;
23-
}
24-
259
static void assert_trailers(const char *message, struct trailer *trailers)
2610
{
27-
struct cb_state st = { trailers };
11+
git_message_trailer_array arr;
2812

29-
int rc = git_message_trailers(message, trailer_cb, &st);
13+
int rc = git_message_trailers(&arr, message);
3014

31-
cl_assert_equal_s(NULL, st.trailer->key);
32-
cl_assert_equal_s(NULL, st.trailer->value);
15+
cl_assert_equal_i(0, rc);
16+
17+
for(size_t i=0; i<arr.count; i++) {
18+
cl_assert_equal_s(arr.trailers[i].key, trailers[i].key);
19+
cl_assert_equal_s(arr.trailers[i].value, trailers[i].value);
20+
}
3321

3422
cl_assert_equal_i(0, rc);
23+
24+
git_message_trailer_array_free(&arr);
3525
}
3626

3727
void test_message_trailer__simple(void)

0 commit comments

Comments
 (0)