From f5895fd399855e782ed0f86f1ac0531517efa0d9 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 10 Aug 2015 05:32:22 -0400 Subject: cache.h: complete set of git_path_submodule helpers The git_path function has "git_pathdup" and "strbuf_git_path" variants, but git_submodule_path only comes in the dangerous, static-buffer variant. That makes refactoring callers to use the safer functions hard (since they don't exist). Since we're already using a strbuf behind the scenes, it's easy to expose all three of these interfaces with thin wrappers. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- path.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'path.c') diff --git a/path.c b/path.c index 10f4cbf6b7..9aad9a1878 100644 --- a/path.c +++ b/path.c @@ -224,11 +224,10 @@ const char *mkpath(const char *fmt, ...) return cleanup_path(pathname->buf); } -const char *git_path_submodule(const char *path, const char *fmt, ...) +static void do_submodule_path(struct strbuf *buf, const char *path, + const char *fmt, va_list args) { - struct strbuf *buf = get_pathname(); const char *git_dir; - va_list args; strbuf_addstr(buf, path); if (buf->len && buf->buf[buf->len - 1] != '/') @@ -242,13 +241,39 @@ const char *git_path_submodule(const char *path, const char *fmt, ...) } strbuf_addch(buf, '/'); - va_start(args, fmt); strbuf_vaddf(buf, fmt, args); - va_end(args); strbuf_cleanup_path(buf); +} + +const char *git_path_submodule(const char *path, const char *fmt, ...) +{ + va_list args; + struct strbuf *buf = get_pathname(); + va_start(args, fmt); + do_submodule_path(buf, path, fmt, args); + va_end(args); return buf->buf; } +char *git_pathdup_submodule(const char *path, const char *fmt, ...) +{ + va_list args; + struct strbuf buf = STRBUF_INIT; + va_start(args, fmt); + do_submodule_path(&buf, path, fmt, args); + va_end(args); + return strbuf_detach(&buf, NULL); +} + +void strbuf_git_path_submodule(struct strbuf *buf, const char *path, + const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_submodule_path(buf, path, fmt, args); + va_end(args); +} + int validate_headref(const char *path) { struct stat st; -- cgit v1.2.1 From 07e3070d2aa69b0c8f1da5f103a87125ff4baaea Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 10 Aug 2015 05:36:27 -0400 Subject: path.c: drop git_path_submodule There are no callers of the slightly-dangerous static-buffer git_path_submodule left. Let's drop it. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- path.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'path.c') diff --git a/path.c b/path.c index 9aad9a1878..94d7ec24e8 100644 --- a/path.c +++ b/path.c @@ -245,16 +245,6 @@ static void do_submodule_path(struct strbuf *buf, const char *path, strbuf_cleanup_path(buf); } -const char *git_path_submodule(const char *path, const char *fmt, ...) -{ - va_list args; - struct strbuf *buf = get_pathname(); - va_start(args, fmt); - do_submodule_path(buf, path, fmt, args); - va_end(args); - return buf->buf; -} - char *git_pathdup_submodule(const char *path, const char *fmt, ...) { va_list args; -- cgit v1.2.1 From f932729cc7707390f4d6739be1573e93ceb9df22 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 10 Aug 2015 05:38:57 -0400 Subject: memoize common git-path "constant" files One of the most common uses of git_path() is to pass a constant, like git_path("MERGE_MSG"). This has two drawbacks: 1. The return value is a static buffer, and the lifetime is dependent on other calls to git_path, etc. 2. There's no compile-time checking of the pathname. This is OK for a one-off (after all, we have to spell it correctly at least once), but many of these constant strings appear throughout the code. This patch introduces a series of functions to "memoize" these strings, which are essentially globals for the lifetime of the program. We compute the value once, take ownership of the buffer, and return the cached value for subsequent calls. cache.h provides a helper macro for defining these functions as one-liners, and defines a few common ones for global use. Using a macro is a little bit gross, but it does nicely document the purpose of the functions. If we need to touch them all later (e.g., because we learned how to change the git_dir variable at runtime, and need to invalidate all of the stored values), it will be much easier to have the complete list. Note that the shared-global functions have separate, manual declarations. We could do something clever with the macros (e.g., expand it to a declaration in some places, and a declaration _and_ a definition in path.c). But there aren't that many, and it's probably better to stay away from too-magical macros. Likewise, if we abandon the C preprocessor in favor of generating these with a script, we could get much fancier. E.g., normalizing "FOO/BAR-BAZ" into "git_path_foo_bar_baz". But the small amount of saved typing is probably not worth the resulting confusion to readers who want to grep for the function's definition. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- path.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'path.c') diff --git a/path.c b/path.c index 94d7ec24e8..95acbafa68 100644 --- a/path.c +++ b/path.c @@ -933,3 +933,13 @@ char *xdg_config_home(const char *filename) return mkpathdup("%s/.config/git/%s", home, filename); return NULL; } + +GIT_PATH_FUNC(git_path_cherry_pick_head, "CHERRY_PICK_HEAD") +GIT_PATH_FUNC(git_path_revert_head, "REVERT_HEAD") +GIT_PATH_FUNC(git_path_squash_msg, "SQUASH_MSG") +GIT_PATH_FUNC(git_path_merge_msg, "MERGE_MSG") +GIT_PATH_FUNC(git_path_merge_rr, "MERGE_RR") +GIT_PATH_FUNC(git_path_merge_mode, "MERGE_MODE") +GIT_PATH_FUNC(git_path_merge_head, "MERGE_HEAD") +GIT_PATH_FUNC(git_path_fetch_head, "FETCH_HEAD") +GIT_PATH_FUNC(git_path_shallow, "shallow") -- cgit v1.2.1