wt-status: move strbuf into read_and_strip_branch()
The strbufs are placed outside read_and_strip_branch as a premature optimization: when it reads "refs/heads/foo" to strbuf and wants to return just "foo", it could do so without memory movement. In return the caller must not use the returned pointer after releasing strbufs, which own the buffers that contain the returned strings. It's a clumsy design. By moving strbufs into read_and_strip_branch(), the returned pointer always points to a malloc'd buffer or NULL. The pointer can be passed around and freed after use. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Mar 16, 2013 at 09:12 UTC
8b87cfd000c7c98f58279cff698f6e8c7892c059
2 files changed
+32
-37
wt-status.c
+30
-35
@@ -967,41 +967,41 @@ static void show_bisect_in_progress(struct wt_status *s,
967
/*
968
* Extract branch information from rebase/bisect
969
*/
970
-static void read_and_strip_branch(struct strbuf *sb,
971
- const char **branch,
972
- const char *path)
970
+static char *read_and_strip_branch(const char *path)
971
{
972
+ struct strbuf sb = STRBUF_INIT;
973
unsigned char sha1[20];
974
976
- strbuf_reset(sb);
977
- if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0)
978
- return;
975
+ if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
976
+ goto got_nothing;
977
980
- while (sb->len && sb->buf[sb->len - 1] == '\n')
981
- strbuf_setlen(sb, sb->len - 1);
982
- if (!sb->len)
983
- return;
984
- if (!prefixcmp(sb->buf, "refs/heads/"))
985
- *branch = sb->buf + strlen("refs/heads/");
986
- else if (!prefixcmp(sb->buf, "refs/"))
987
- *branch = sb->buf;
988
- else if (!get_sha1_hex(sb->buf, sha1)) {
978
+ while (&sb.len && sb.buf[sb.len - 1] == '\n')
979
+ strbuf_setlen(&sb, sb.len - 1);
980
+ if (!sb.len)
981
+ goto got_nothing;
982
+ if (!prefixcmp(sb.buf, "refs/heads/"))
983
+ strbuf_remove(&sb,0, strlen("refs/heads/"));
984
+ else if (!prefixcmp(sb.buf, "refs/"))
985
+ ;
986
+ else if (!get_sha1_hex(sb.buf, sha1)) {
987
const char *abbrev;
988
abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
991
- strbuf_reset(sb);
992
- strbuf_addstr(sb, abbrev);
993
- *branch = sb->buf;
994
- } else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */
995
- ;
989
+ strbuf_reset(&sb);
990
+ strbuf_addstr(&sb, abbrev);
991
+ } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
992
+ goto got_nothing;
993
else /* bisect */
997
- *branch = sb->buf;
994
+ ;
995
+ return strbuf_detach(&sb, NULL);
996
+
997
+got_nothing:
998
+ strbuf_release(&sb);
999
+ return NULL;
1000
}
1001
1002
static void wt_status_print_state(struct wt_status *s)
1003
{
1004
const char *state_color = color(WT_STATUS_HEADER, s);
1003
- struct strbuf branch = STRBUF_INIT;
1004
- struct strbuf onto = STRBUF_INIT;
1005
struct wt_status_state state;
1006
struct stat st;
1007
@@ -1016,27 +1016,22 @@ static void wt_status_print_state(struct wt_status *s)
1016
state.am_empty_patch = 1;
1017
} else {
1018
state.rebase_in_progress = 1;
1019
- read_and_strip_branch(&branch, &state.branch,
1020
- "rebase-apply/head-name");
1021
- read_and_strip_branch(&onto, &state.onto,
1022
- "rebase-apply/onto");
1019
+ state.branch = read_and_strip_branch("rebase-apply/head-name");
1020
+ state.onto = read_and_strip_branch("rebase-apply/onto");
1021
}
1022
} else if (!stat(git_path("rebase-merge"), &st)) {
1023
if (!stat(git_path("rebase-merge/interactive"), &st))
1024
state.rebase_interactive_in_progress = 1;
1025
else
1026
state.rebase_in_progress = 1;
1029
- read_and_strip_branch(&branch, &state.branch,
1030
- "rebase-merge/head-name");
1031
- read_and_strip_branch(&onto, &state.onto,
1032
- "rebase-merge/onto");
1027
+ state.branch = read_and_strip_branch("rebase-merge/head-name");
1028
+ state.onto = read_and_strip_branch("rebase-merge/onto");
1029
} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) {
1030
state.cherry_pick_in_progress = 1;
1031
}
1032
if (!stat(git_path("BISECT_LOG"), &st)) {
1033
state.bisect_in_progress = 1;
1038
- read_and_strip_branch(&branch, &state.branch,
1039
- "BISECT_START");
1034
+ state.branch = read_and_strip_branch("BISECT_START");
1035
}
1036
1037
if (state.merge_in_progress)
@@ -1049,8 +1044,8 @@ static void wt_status_print_state(struct wt_status *s)
1044
show_cherry_pick_in_progress(s, &state, state_color);
1045
if (state.bisect_in_progress)
1046
show_bisect_in_progress(s, &state, state_color);
1052
- strbuf_release(&branch);
1053
- strbuf_release(&onto);
1047
+ free(state.branch);
1048
+ free(state.onto);
1049
}
1050
1051
void wt_status_print(struct wt_status *s)
wt-status.h
+2
-2
@@ -79,8 +79,8 @@ struct wt_status_state {
79
int rebase_interactive_in_progress;
80
int cherry_pick_in_progress;
81
int bisect_in_progress;
82
- const char *branch;
83
- const char *onto;
82
+ char *branch;
83
+ char *onto;
84
};
85
86
void wt_status_prepare(struct wt_status *s);