Skip to content

Commit e8c352c

Browse files
jonathantanmygitster
authored andcommitted
trailer: have function to describe trailer layout
Create a function that, taking a string, describes the position of its trailer block (if available) and the contents thereof, and make trailer use it. This makes it easier for other Git components, in the future, to interpret trailer blocks in the same way as trailer. In a subsequent patch, another component will be made to use this. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 022349c commit e8c352c

File tree

2 files changed

+107
-36
lines changed

2 files changed

+107
-36
lines changed

trailer.c

Lines changed: 82 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static LIST_HEAD(conf_head);
4646

4747
static char *separators = ":";
4848

49+
static int configured;
50+
4951
#define TRAILER_ARG_STRING "$ARG"
5052

5153
static const char *git_generated_prefixes[] = {
@@ -546,6 +548,17 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
546548
return 0;
547549
}
548550

551+
static void ensure_configured(void)
552+
{
553+
if (configured)
554+
return;
555+
556+
/* Default config must be setup first */
557+
git_config(git_trailer_default_config, NULL);
558+
git_config(git_trailer_config, NULL);
559+
configured = 1;
560+
}
561+
549562
static const char *token_from_item(struct arg_item *item, char *tok)
550563
{
551564
if (item->conf.key)
@@ -875,59 +888,43 @@ static int process_input_file(FILE *outfile,
875888
const char *str,
876889
struct list_head *head)
877890
{
878-
int patch_start, trailer_start, trailer_end;
891+
struct trailer_info info;
879892
struct strbuf tok = STRBUF_INIT;
880893
struct strbuf val = STRBUF_INIT;
881-
struct trailer_item *last = NULL;
882-
struct strbuf *trailer, **trailer_lines, **ptr;
894+
int i;
883895

884-
patch_start = find_patch_start(str);
885-
trailer_end = find_trailer_end(str, patch_start);
886-
trailer_start = find_trailer_start(str, trailer_end);
896+
trailer_info_get(&info, str);
887897

888898
/* Print lines before the trailers as is */
889-
fwrite(str, 1, trailer_start, outfile);
899+
fwrite(str, 1, info.trailer_start - str, outfile);
890900

891-
if (!ends_with_blank_line(str, trailer_start))
901+
if (!info.blank_line_before_trailer)
892902
fprintf(outfile, "\n");
893903

894-
/* Parse trailer lines */
895-
trailer_lines = strbuf_split_buf(str + trailer_start,
896-
trailer_end - trailer_start,
897-
'\n',
898-
0);
899-
for (ptr = trailer_lines; *ptr; ptr++) {
904+
for (i = 0; i < info.trailer_nr; i++) {
900905
int separator_pos;
901-
trailer = *ptr;
902-
if (trailer->buf[0] == comment_line_char)
903-
continue;
904-
if (last && isspace(trailer->buf[0])) {
905-
struct strbuf sb = STRBUF_INIT;
906-
strbuf_addf(&sb, "%s\n%s", last->value, trailer->buf);
907-
strbuf_strip_suffix(&sb, "\n");
908-
free(last->value);
909-
last->value = strbuf_detach(&sb, NULL);
906+
char *trailer = info.trailers[i];
907+
if (trailer[0] == comment_line_char)
910908
continue;
911-
}
912-
separator_pos = find_separator(trailer->buf, separators);
909+
separator_pos = find_separator(trailer, separators);
913910
if (separator_pos >= 1) {
914-
parse_trailer(&tok, &val, NULL, trailer->buf,
911+
parse_trailer(&tok, &val, NULL, trailer,
915912
separator_pos);
916-
last = add_trailer_item(head,
917-
strbuf_detach(&tok, NULL),
918-
strbuf_detach(&val, NULL));
913+
add_trailer_item(head,
914+
strbuf_detach(&tok, NULL),
915+
strbuf_detach(&val, NULL));
919916
} else {
920-
strbuf_addbuf(&val, trailer);
917+
strbuf_addstr(&val, trailer);
921918
strbuf_strip_suffix(&val, "\n");
922919
add_trailer_item(head,
923920
NULL,
924921
strbuf_detach(&val, NULL));
925-
last = NULL;
926922
}
927923
}
928-
strbuf_list_free(trailer_lines);
929924

930-
return trailer_end;
925+
trailer_info_release(&info);
926+
927+
return info.trailer_end - str;
931928
}
932929

933930
static void free_all(struct list_head *head)
@@ -978,9 +975,7 @@ void process_trailers(const char *file, int in_place, int trim_empty, struct str
978975
int trailer_end;
979976
FILE *outfile = stdout;
980977

981-
/* Default config must be setup first */
982-
git_config(git_trailer_default_config, NULL);
983-
git_config(git_trailer_config, NULL);
978+
ensure_configured();
984979

985980
read_input_file(&sb, file);
986981

@@ -1007,3 +1002,54 @@ void process_trailers(const char *file, int in_place, int trim_empty, struct str
10071002

10081003
strbuf_release(&sb);
10091004
}
1005+
1006+
void trailer_info_get(struct trailer_info *info, const char *str)
1007+
{
1008+
int patch_start, trailer_end, trailer_start;
1009+
struct strbuf **trailer_lines, **ptr;
1010+
char **trailer_strings = NULL;
1011+
size_t nr = 0, alloc = 0;
1012+
char **last = NULL;
1013+
1014+
ensure_configured();
1015+
1016+
patch_start = find_patch_start(str);
1017+
trailer_end = find_trailer_end(str, patch_start);
1018+
trailer_start = find_trailer_start(str, trailer_end);
1019+
1020+
trailer_lines = strbuf_split_buf(str + trailer_start,
1021+
trailer_end - trailer_start,
1022+
'\n',
1023+
0);
1024+
for (ptr = trailer_lines; *ptr; ptr++) {
1025+
if (last && isspace((*ptr)->buf[0])) {
1026+
struct strbuf sb = STRBUF_INIT;
1027+
strbuf_attach(&sb, *last, strlen(*last), strlen(*last));
1028+
strbuf_addbuf(&sb, *ptr);
1029+
*last = strbuf_detach(&sb, NULL);
1030+
continue;
1031+
}
1032+
ALLOC_GROW(trailer_strings, nr + 1, alloc);
1033+
trailer_strings[nr] = strbuf_detach(*ptr, NULL);
1034+
last = find_separator(trailer_strings[nr], separators) >= 1
1035+
? &trailer_strings[nr]
1036+
: NULL;
1037+
nr++;
1038+
}
1039+
strbuf_list_free(trailer_lines);
1040+
1041+
info->blank_line_before_trailer = ends_with_blank_line(str,
1042+
trailer_start);
1043+
info->trailer_start = str + trailer_start;
1044+
info->trailer_end = str + trailer_end;
1045+
info->trailers = trailer_strings;
1046+
info->trailer_nr = nr;
1047+
}
1048+
1049+
void trailer_info_release(struct trailer_info *info)
1050+
{
1051+
int i;
1052+
for (i = 0; i < info->trailer_nr; i++)
1053+
free(info->trailers[i]);
1054+
free(info->trailers);
1055+
}

trailer.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
#ifndef TRAILER_H
22
#define TRAILER_H
33

4+
struct trailer_info {
5+
/*
6+
* True if there is a blank line before the location pointed to by
7+
* trailer_start.
8+
*/
9+
int blank_line_before_trailer;
10+
11+
/*
12+
* Pointers to the start and end of the trailer block found. If there
13+
* is no trailer block found, these 2 pointers point to the end of the
14+
* input string.
15+
*/
16+
const char *trailer_start, *trailer_end;
17+
18+
/*
19+
* Array of trailers found.
20+
*/
21+
char **trailers;
22+
size_t trailer_nr;
23+
};
24+
425
void process_trailers(const char *file, int in_place, int trim_empty,
526
struct string_list *trailers);
627

28+
void trailer_info_get(struct trailer_info *info, const char *str);
29+
30+
void trailer_info_release(struct trailer_info *info);
31+
732
#endif /* TRAILER_H */

0 commit comments

Comments
 (0)