* [PATCH 0/2] RUNTIME_PREFIX enhancements
@ 2009-02-18 15:10 Johannes Schindelin
2009-02-18 15:11 ` [PATCH 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
` (2 more replies)
0 siblings, 3 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 15:10 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
When I ran "make" in msysGit's /git/, I was greeted by a pretty unfriendly
message about a RUNTIME_PREFIX that could not be determined.
Not understanding the code in exec_cmd.c, I went back to a comment I made
to one of the iterations of the RUNTIME_PREFIX patch series (back when I
spent a considerable amount of time to understand the code), and turned it
into a patch myself.
I hope you will agree that the code introduced in 1/2 is more
understandable than what is removed in 2/2 in favor of the former.
The real meat comes in patch 2/2:
The problem is that Windows will look in the current directory before
looking in the PATH when it tries to execute a program. So it will find
the executable C:\msysgit\git\git.exe and be unable to strip the suffices
"libexec/git-core" or "bin".
I just added "git" (which should not hurt other users, but instead help
them if they did not install Git but run it in-place).
Johannes Schindelin (2):
Introduce the function strip_path_suffix()
system_path(): simplify using strip_path_suffix(), and add suffix
"git"
cache.h | 2 ++
exec_cmd.c | 32 +++-----------------------------
path.c | 33 +++++++++++++++++++++++++++++++++
3 files changed, 38 insertions(+), 29 deletions(-)
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/2] Introduce the function strip_path_suffix()
2009-02-18 15:10 [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
@ 2009-02-18 15:11 ` Johannes Schindelin
2009-02-18 19:39 ` Johannes Sixt
2009-02-18 15:11 ` [PATCH " Johannes Schindelin
2009-02-18 19:38 ` [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Sixt
2 siblings, 1 reply; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 15:11 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
The function strip_path_suffix() will try to split the given path into
prefix/suffix. The suffix has to be passed to the function, and if the
path matches, the prefix is set.
Arbitrary runs of directory separators ("slashes") are assumed identical.
Example:
strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
"libexec///git-core", &prefix)
will set prefix to "C:\\msysgit" and return 0.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
cache.h | 2 ++
path.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index 4e28c24..2186143 100644
--- a/cache.h
+++ b/cache.h
@@ -629,6 +629,8 @@ const char *make_nonrelative_path(const char *path);
const char *make_relative_path(const char *abs, const char *base);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, const char *prefix_list);
+int strip_path_suffix(const char *path, const char *suffix,
+ const char **prefix);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index 4b9107f..947e5b7 100644
--- a/path.c
+++ b/path.c
@@ -499,3 +499,36 @@ int longest_ancestor_length(const char *path, const char *prefix_list)
return max_len;
}
+
+/* strip arbitrary amount of directory separators at end of path */
+static inline int chomp_trailing_dir_sep(const char *path, int len)
+{
+ while (len && is_dir_sep(path[len - 1]))
+ len--;
+ return len;
+}
+
+/* sets prefix if the suffix matches */
+int strip_path_suffix(const char *path, const char *suffix, const char **prefix)
+{
+ int path_len = strlen(path), suffix_len = strlen(suffix);
+
+ while (suffix_len) {
+ if (!path_len)
+ return 1;
+
+ if (is_dir_sep(path[path_len - 1])) {
+ if (!is_dir_sep(suffix[suffix_len - 1]))
+ return 1;
+ path_len = chomp_trailing_dir_sep(path, path_len);
+ suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
+ }
+ else if (path[--path_len] != suffix[--suffix_len])
+ return 1;
+ }
+
+ if (path_len && !is_dir_sep(path[path_len - 1]))
+ return 1;
+ *prefix = xstrndup(path, chomp_trailing_dir_sep(path, path_len));
+ return 0;
+}
--
1.6.1.1.825.g72a9f
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git"
2009-02-18 15:10 [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
2009-02-18 15:11 ` [PATCH 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
@ 2009-02-18 15:11 ` Johannes Schindelin
2009-02-18 19:38 ` [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Sixt
2 siblings, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 15:11 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
At least for the author of this patch, the logic in system_path() was
too hard to understand. Using the function strip_path_suffix() documents
the idea of the code better.
The real change is to add the suffix "git", so that a runtime prefix will
be computed correctly even when the executable was called in /git/ as is
the case in msysGit (Windows insists to search the current directory
before the PATH when looking for an executable).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
exec_cmd.c | 32 +++-----------------------------
1 files changed, 3 insertions(+), 29 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index f234066..f89268b 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -23,35 +23,9 @@ const char *system_path(const char *path)
assert(argv0_path);
assert(is_absolute_path(argv0_path));
- if (!prefix) {
- const char *strip[] = {
- GIT_EXEC_PATH,
- BINDIR,
- 0
- };
- const char **s;
-
- for (s = strip; *s; s++) {
- const char *sargv = argv0_path + strlen(argv0_path);
- const char *ss = *s + strlen(*s);
- while (argv0_path < sargv && *s < ss
- && (*sargv == *ss ||
- (is_dir_sep(*sargv) && is_dir_sep(*ss)))) {
- sargv--;
- ss--;
- }
- if (*s == ss) {
- struct strbuf d = STRBUF_INIT;
- /* We also skip the trailing directory separator. */
- assert(sargv - argv0_path - 1 >= 0);
- strbuf_add(&d, argv0_path, sargv - argv0_path - 1);
- prefix = strbuf_detach(&d, NULL);
- break;
- }
- }
- }
-
- if (!prefix) {
+ if (!prefix && strip_path_suffix(argv0_path, GIT_EXEC_PATH, &prefix) &&
+ strip_path_suffix(argv0_path, BINDIR, &prefix) &&
+ strip_path_suffix(argv0_path, "git", &prefix)) {
prefix = PREFIX;
fprintf(stderr, "RUNTIME_PREFIX requested, "
"but prefix computation failed. "
--
1.6.1.1.825.g72a9f
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 0/2] RUNTIME_PREFIX enhancements
2009-02-18 15:10 [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
2009-02-18 15:11 ` [PATCH 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
2009-02-18 15:11 ` [PATCH " Johannes Schindelin
@ 2009-02-18 19:38 ` Johannes Sixt
2009-02-18 21:11 ` Johannes Schindelin
2 siblings, 1 reply; 20+ messages in thread
From: Johannes Sixt @ 2009-02-18 19:38 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> When I ran "make" in msysGit's /git/, I was greeted by a pretty unfriendly
> message about a RUNTIME_PREFIX that could not be determined.
;)
I have a patch in my private tree that removes the warning.
Actually I wouldn't mind the warning because it is only visible for
developers. Unfortunately, it is poison for gitk (you know, Tcl/Tk
treats any output on stderr as program failure...)
> The real meat comes in patch 2/2:
>
> The problem is that Windows will look in the current directory before
> looking in the PATH when it tries to execute a program. So it will find
> the executable C:\msysgit\git\git.exe and be unable to strip the suffices
> "libexec/git-core" or "bin".
>
> I just added "git" (which should not hurt other users, but instead help
> them if they did not install Git but run it in-place).
This only silences the warning, but there is no guarantee that the
resulting git suite works because your msysgit developer may not have
installed stuff in C:\msysgit\libexec\git-core, yet. What the patch does
is exactly the same as if the compiled-in prefix that the warning
mentions were used, which in the msysgit case on your machine happens to
be C:\msysgit. Or am I missing something?
I think that the better solution is to remove the warning instead of
introducing this special case suffix "git".
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] Introduce the function strip_path_suffix()
2009-02-18 15:11 ` [PATCH 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
@ 2009-02-18 19:39 ` Johannes Sixt
2009-02-18 21:13 ` Johannes Schindelin
` (3 more replies)
0 siblings, 4 replies; 20+ messages in thread
From: Johannes Sixt @ 2009-02-18 19:39 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> The function strip_path_suffix() will try to split the given path into
> prefix/suffix. The suffix has to be passed to the function, and if the
> path matches, the prefix is set.
>
> Arbitrary runs of directory separators ("slashes") are assumed identical.
>
> Example:
>
> strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
> "libexec///git-core", &prefix)
>
> will set prefix to "C:\\msysgit" and return 0.
But you implemented it so that prefix is actually "C:\\msysgit/\\"
(unless, of course, I'm reading the code wrong).
> +/* sets prefix if the suffix matches */
> +int strip_path_suffix(const char *path, const char *suffix, const char **prefix)
For a general purpose function, the API is very unnatural (and geared
towards its only user in patch 2/2). I'd expect that the return value is
the result or NULL on failure.
I would not raise this concern if this were a static function near its
only call site.
> +{
> + int path_len = strlen(path), suffix_len = strlen(suffix);
> +
> + while (suffix_len) {
> + if (!path_len)
> + return 1;
> +
> + if (is_dir_sep(path[path_len - 1])) {
> + if (!is_dir_sep(suffix[suffix_len - 1]))
> + return 1;
> + path_len = chomp_trailing_dir_sep(path, path_len);
> + suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
> + }
> + else if (path[--path_len] != suffix[--suffix_len])
> + return 1;
> + }
> +
> + if (path_len && !is_dir_sep(path[path_len - 1]))
> + return 1;
Should strip_path_suffix("foo/bar", "foo/bar", &prefix) succeed and
prefix be the empty string? This implementation says it should be so.
That's just a question...
> + *prefix = xstrndup(path, chomp_trailing_dir_sep(path, path_len));
> + return 0;
> +}
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/2] RUNTIME_PREFIX enhancements
2009-02-18 19:38 ` [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Sixt
@ 2009-02-18 21:11 ` Johannes Schindelin
2009-02-18 22:52 ` Johannes Sixt
0 siblings, 1 reply; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 21:11 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Wed, 18 Feb 2009, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > When I ran "make" in msysGit's /git/, I was greeted by a pretty unfriendly
> > message about a RUNTIME_PREFIX that could not be determined.
>
> ;)
>
> I have a patch in my private tree that removes the warning.
I briefly considered this. But my patch actually does something different
than hiding an error condition. It copes with the very peculiar situation
we have on Windows.
I still would like to see the warning if something goes wrong -- _outside_
/git/.
> This only silences the warning, but there is no guarantee that the
> resulting git suite works because your msysgit developer may not have
> installed stuff in C:\msysgit\libexec\git-core, yet.
The good thing: it still works. Why? Because Git actually does _not_
search the Git binaries in libexec/git-core. It adds that directory to
PATH and lets the PATH lookup handle the searching. So it kind of works,
but in a different manner than you think it works.
But that cannot be helped.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] Introduce the function strip_path_suffix()
2009-02-18 19:39 ` Johannes Sixt
@ 2009-02-18 21:13 ` Johannes Schindelin
2009-02-18 22:27 ` Johannes Sixt
2009-02-19 19:10 ` [PATCH v2 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
` (2 subsequent siblings)
3 siblings, 1 reply; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 21:13 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Wed, 18 Feb 2009, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > The function strip_path_suffix() will try to split the given path into
> > prefix/suffix. The suffix has to be passed to the function, and if
> > the path matches, the prefix is set.
> >
> > Arbitrary runs of directory separators ("slashes") are assumed
> > identical.
> >
> > Example:
> >
> > strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
> > "libexec///git-core", &prefix)
> >
> > will set prefix to "C:\\msysgit" and return 0.
>
> But you implemented it so that prefix is actually "C:\\msysgit/\\"
> (unless, of course, I'm reading the code wrong).
This is supposed to handle that case:
*prefix = xstrndup(path, chomp_trailing_dir_sep(path, path_len));
> > +/* sets prefix if the suffix matches */
> > +int strip_path_suffix(const char *path, const char *suffix, const char
> > **prefix)
>
> For a general purpose function, the API is very unnatural (and geared
> towards its only user in patch 2/2). I'd expect that the return value is
> the result or NULL on failure.
Good point. Will change.
> > +{
> > + int path_len = strlen(path), suffix_len = strlen(suffix);
> > +
> > + while (suffix_len) {
> > + if (!path_len)
> > + return 1;
> > +
> > + if (is_dir_sep(path[path_len - 1])) {
> > + if (!is_dir_sep(suffix[suffix_len - 1]))
> > + return 1;
> > + path_len = chomp_trailing_dir_sep(path, path_len);
> > + suffix_len = chomp_trailing_dir_sep(suffix,
> > suffix_len);
> > + }
> > + else if (path[--path_len] != suffix[--suffix_len])
> > + return 1;
> > + }
> > +
> > + if (path_len && !is_dir_sep(path[path_len - 1]))
> > + return 1;
>
> Should strip_path_suffix("foo/bar", "foo/bar", &prefix) succeed and
> prefix be the empty string? This implementation says it should be so.
> That's just a question...
Yes, I assumed that that makes sense.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] Introduce the function strip_path_suffix()
2009-02-18 21:13 ` Johannes Schindelin
@ 2009-02-18 22:27 ` Johannes Sixt
2009-02-18 23:18 ` Johannes Schindelin
0 siblings, 1 reply; 20+ messages in thread
From: Johannes Sixt @ 2009-02-18 22:27 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> On Wed, 18 Feb 2009, Johannes Sixt wrote:
>> Johannes Schindelin schrieb:
>>> strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
>>> "libexec///git-core", &prefix)
>>>
>>> will set prefix to "C:\\msysgit" and return 0.
>> But you implemented it so that prefix is actually "C:\\msysgit/\\"
>> (unless, of course, I'm reading the code wrong).
>
> This is supposed to handle that case:
>
> *prefix = xstrndup(path, chomp_trailing_dir_sep(path, path_len));
Ah, I missed that final call of chomp_trailing_dir_sep.
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/2] RUNTIME_PREFIX enhancements
2009-02-18 21:11 ` Johannes Schindelin
@ 2009-02-18 22:52 ` Johannes Sixt
2009-02-18 23:19 ` Johannes Schindelin
0 siblings, 1 reply; 20+ messages in thread
From: Johannes Sixt @ 2009-02-18 22:52 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> On Wed, 18 Feb 2009, Johannes Sixt wrote:
>> This only silences the warning, but there is no guarantee that the
>> resulting git suite works because your msysgit developer may not have
>> installed stuff in C:\msysgit\libexec\git-core, yet.
>
> The good thing: it still works. Why? Because Git actually does _not_
> search the Git binaries in libexec/git-core. It adds that directory to
> PATH and lets the PATH lookup handle the searching. So it kind of works,
> but in a different manner than you think it works.
I see why it works: Because we add argv0_path to PATH. I had forgotten
about this fact. It comes after git_exec_path(), and so we pick up the
binaries and shell scripts from the build directory if there is nothing
in $prefix/libexec/git-core.
It's sad that your patch requires the source to live in a directory
named 'git'. But I don't know how to do it better. :-(
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/2] Introduce the function strip_path_suffix()
2009-02-18 22:27 ` Johannes Sixt
@ 2009-02-18 23:18 ` Johannes Schindelin
0 siblings, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 23:18 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Wed, 18 Feb 2009, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > On Wed, 18 Feb 2009, Johannes Sixt wrote:
> > > Johannes Schindelin schrieb:
> > > > strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
> > > > "libexec///git-core", &prefix)
> > > >
> > > > will set prefix to "C:\\msysgit" and return 0.
> > > But you implemented it so that prefix is actually "C:\\msysgit/\\"
> > > (unless, of course, I'm reading the code wrong).
> >
> > This is supposed to handle that case:
> >
> > *prefix = xstrndup(path, chomp_trailing_dir_sep(path, path_len));
>
> Ah, I missed that final call of chomp_trailing_dir_sep.
I have to admit that I was aware of the fact that it is easy to miss, but
could not find a better way to present it.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 0/2] RUNTIME_PREFIX enhancements
2009-02-18 22:52 ` Johannes Sixt
@ 2009-02-18 23:19 ` Johannes Schindelin
0 siblings, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-18 23:19 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Wed, 18 Feb 2009, Johannes Sixt wrote:
> It's sad that your patch requires the source to live in a directory
> named 'git'. But I don't know how to do it better. :-(
Let's move it to /bin/
Ducks,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 0/2] RUNTIME_PREFIX enhancements
2009-02-18 19:39 ` Johannes Sixt
2009-02-18 21:13 ` Johannes Schindelin
@ 2009-02-19 19:10 ` Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git" Johannes Schindelin
3 siblings, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 19:10 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
The idea is to simplify the RUNTIME_PREFIX code, and to make Git handle
the case where the binary was found in $ROOT/git/, too.
Changes since v1:
- changed the signature of strip_path_suffix() as suggested by Hannes:
char *strip_path_suffix(const char *path, const char *suffix)
- added a test to test-path-utils
Johannes Schindelin (2):
Introduce the function strip_path_suffix()
system_path(): simplify using strip_path_suffix(), and add suffix
"git"
cache.h | 1 +
exec_cmd.c | 33 ++++-----------------------------
path.c | 32 ++++++++++++++++++++++++++++++++
t/t0060-path-utils.sh | 4 ++++
test-path-utils.c | 6 ++++++
5 files changed, 47 insertions(+), 29 deletions(-)
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 1/2] Introduce the function strip_path_suffix()
2009-02-18 19:39 ` Johannes Sixt
2009-02-18 21:13 ` Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
@ 2009-02-19 19:10 ` Johannes Schindelin
2009-02-19 20:12 ` Johannes Schindelin
2009-02-19 20:26 ` Johannes Sixt
2009-02-19 19:10 ` [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git" Johannes Schindelin
3 siblings, 2 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 19:10 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
The function strip_path_suffix() will try to strip a given suffix from
a given path. The suffix must start at a directory boundary (i.e. "core"
is not a path suffix of "libexec/git-core", but "git-core" is).
Arbitrary runs of directory separators ("slashes") are assumed identical.
Example:
strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
"libexec///git-core", &prefix)
will set prefix to "C:\\msysgit" and return 0.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
cache.h | 1 +
path.c | 32 ++++++++++++++++++++++++++++++++
t/t0060-path-utils.sh | 4 ++++
test-path-utils.c | 6 ++++++
4 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index c926bc7..1fa184d 100644
--- a/cache.h
+++ b/cache.h
@@ -630,6 +630,7 @@ const char *make_nonrelative_path(const char *path);
const char *make_relative_path(const char *abs, const char *base);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, const char *prefix_list);
+char *strip_path_suffix(const char *path, const char *suffix);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, unsigned long *);
diff --git a/path.c b/path.c
index 4b9107f..2030bf1 100644
--- a/path.c
+++ b/path.c
@@ -499,3 +499,35 @@ int longest_ancestor_length(const char *path, const char *prefix_list)
return max_len;
}
+
+/* strip arbitrary amount of directory separators at end of path */
+static inline int chomp_trailing_dir_sep(const char *path, int len)
+{
+ while (len && is_dir_sep(path[len - 1]))
+ len--;
+ return len;
+}
+
+/* sets prefix if the suffix matches */
+char *strip_path_suffix(const char *path, const char *suffix)
+{
+ int path_len = strlen(path), suffix_len = strlen(suffix);
+
+ while (suffix_len) {
+ if (!path_len)
+ return NULL;
+
+ if (is_dir_sep(path[path_len - 1])) {
+ if (!is_dir_sep(suffix[suffix_len - 1]))
+ return NULL;
+ path_len = chomp_trailing_dir_sep(path, path_len);
+ suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
+ }
+ else if (path[--path_len] != suffix[--suffix_len])
+ return NULL;
+ }
+
+ if (path_len && !is_dir_sep(path[path_len - 1]))
+ return NULL;
+ return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
+}
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 4ed1f0b..8336114 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -85,4 +85,8 @@ ancestor /foo/bar :://foo/.:: 4
ancestor /foo/bar //foo/./::/bar 4
ancestor /foo/bar ::/bar -1
+test_expect_success 'strip_path_suffix' '
+ test c:/msysgit = $(test-path-utils strip_path_suffix \
+ c:/msysgit/libexec//git-core libexec/git-core)
+'
test_done
diff --git a/test-path-utils.c b/test-path-utils.c
index 5168a8e..d261398 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -26,6 +26,12 @@ int main(int argc, char **argv)
return 0;
}
+ if (argc == 4 && !strcmp(argv[1], "strip_path_suffix")) {
+ char *prefix = strip_path_suffix(argv[2], argv[3]);
+ printf("%s\n", prefix ? prefix : "(null)");
+ return 0;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;
--
1.6.2.rc1.380.g0299c
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git"
2009-02-18 19:39 ` Johannes Sixt
` (2 preceding siblings ...)
2009-02-19 19:10 ` [PATCH v2 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
@ 2009-02-19 19:10 ` Johannes Schindelin
2009-02-19 20:39 ` Johannes Sixt
3 siblings, 1 reply; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 19:10 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
At least for the author of this patch, the logic in system_path() was
too hard to understand. Using the function strip_path_suffix() documents
the idea of the code better.
The real change is to add the suffix "git", so that a runtime prefix will
be computed correctly even when the executable was called in /git/ as is
the case in msysGit (Windows insists to search the current directory
before the PATH when looking for an executable).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
exec_cmd.c | 33 ++++-----------------------------
1 files changed, 4 insertions(+), 29 deletions(-)
diff --git a/exec_cmd.c b/exec_cmd.c
index f234066..217c125 100644
--- a/exec_cmd.c
+++ b/exec_cmd.c
@@ -23,35 +23,10 @@ const char *system_path(const char *path)
assert(argv0_path);
assert(is_absolute_path(argv0_path));
- if (!prefix) {
- const char *strip[] = {
- GIT_EXEC_PATH,
- BINDIR,
- 0
- };
- const char **s;
-
- for (s = strip; *s; s++) {
- const char *sargv = argv0_path + strlen(argv0_path);
- const char *ss = *s + strlen(*s);
- while (argv0_path < sargv && *s < ss
- && (*sargv == *ss ||
- (is_dir_sep(*sargv) && is_dir_sep(*ss)))) {
- sargv--;
- ss--;
- }
- if (*s == ss) {
- struct strbuf d = STRBUF_INIT;
- /* We also skip the trailing directory separator. */
- assert(sargv - argv0_path - 1 >= 0);
- strbuf_add(&d, argv0_path, sargv - argv0_path - 1);
- prefix = strbuf_detach(&d, NULL);
- break;
- }
- }
- }
-
- if (!prefix) {
+ if (!prefix &&
+ !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
+ !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
+ !(prefix = strip_path_suffix(argv0_path, "git"))) {
prefix = PREFIX;
fprintf(stderr, "RUNTIME_PREFIX requested, "
"but prefix computation failed. "
--
1.6.2.rc1.380.g0299c
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 1/2] Introduce the function strip_path_suffix()
2009-02-19 19:10 ` [PATCH v2 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
@ 2009-02-19 20:12 ` Johannes Schindelin
2009-02-19 20:26 ` Johannes Sixt
1 sibling, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 20:12 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Steffen Prohaska
Hi,
On Thu, 19 Feb 2009, Johannes Schindelin wrote:
> The function strip_path_suffix() will try to strip a given suffix from
> a given path. The suffix must start at a directory boundary (i.e. "core"
> is not a path suffix of "libexec/git-core", but "git-core" is).
>
> Arbitrary runs of directory separators ("slashes") are assumed identical.
>
> Example:
>
> strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
> "libexec///git-core", &prefix)
>
> will set prefix to "C:\\msysgit" and return 0.
Aargh, of course I managed to forget to adjust the example. Here it goes:
prefix = strip_path_suffix("C:\\msysgit/\\libexec\\git-core",
"libexec///git-core");
will set prefix to "C:\\msysgit".
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 1/2] Introduce the function strip_path_suffix()
2009-02-19 19:10 ` [PATCH v2 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
2009-02-19 20:12 ` Johannes Schindelin
@ 2009-02-19 20:26 ` Johannes Sixt
2009-02-19 20:44 ` Johannes Schindelin
1 sibling, 1 reply; 20+ messages in thread
From: Johannes Sixt @ 2009-02-19 20:26 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> +/* sets prefix if the suffix matches */
/*
* If path ends with suffix (complete path components), returns the
* part before suffix (sans trailing directory separators).
* Otherwise returns NULL.
*/
> +char *strip_path_suffix(const char *path, const char *suffix)
Looks good otherwise.
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git"
2009-02-19 19:10 ` [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git" Johannes Schindelin
@ 2009-02-19 20:39 ` Johannes Sixt
2009-02-19 20:48 ` Johannes Schindelin
2009-02-20 8:35 ` Junio C Hamano
0 siblings, 2 replies; 20+ messages in thread
From: Johannes Sixt @ 2009-02-19 20:39 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster, Steffen Prohaska
Johannes Schindelin schrieb:
> The real change is to add the suffix "git", so that a runtime prefix will
> be computed correctly even when the executable was called in /git/ as is
> the case in msysGit (Windows insists to search the current directory
> before the PATH when looking for an executable).
msysgit is important enough to be supported by upstream git, in
particular since it is *the* user of RUNTIME_PREFIX, so that this
special-casing is warranted. Therefore:
Acked-by: Johannes Sixt <j6t@kdbg.org>
-- Hannes
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 1/2] Introduce the function strip_path_suffix()
2009-02-19 20:26 ` Johannes Sixt
@ 2009-02-19 20:44 ` Johannes Schindelin
0 siblings, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 20:44 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Thu, 19 Feb 2009, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > +/* sets prefix if the suffix matches */
>
> /*
> * If path ends with suffix (complete path components), returns the
> * part before suffix (sans trailing directory separators).
> * Otherwise returns NULL.
> */
Thanks. It shows that I did not really have time to polish this properly
today, does it not?
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git"
2009-02-19 20:39 ` Johannes Sixt
@ 2009-02-19 20:48 ` Johannes Schindelin
2009-02-20 8:35 ` Junio C Hamano
1 sibling, 0 replies; 20+ messages in thread
From: Johannes Schindelin @ 2009-02-19 20:48 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Steffen Prohaska
Hi,
On Thu, 19 Feb 2009, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
> > The real change is to add the suffix "git", so that a runtime prefix will
> > be computed correctly even when the executable was called in /git/ as is
> > the case in msysGit (Windows insists to search the current directory
> > before the PATH when looking for an executable).
>
> msysgit is important enough to be supported by upstream git, in particular
> since it is *the* user of RUNTIME_PREFIX, so that this special-casing is
> warranted. Therefore:
>
> Acked-by: Johannes Sixt <j6t@kdbg.org>
Thanks.
Note, however, that IMHO RUNTIME_PREFIX would be good for non-Windows,
too, as it would make Git relocatable.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git"
2009-02-19 20:39 ` Johannes Sixt
2009-02-19 20:48 ` Johannes Schindelin
@ 2009-02-20 8:35 ` Junio C Hamano
1 sibling, 0 replies; 20+ messages in thread
From: Junio C Hamano @ 2009-02-20 8:35 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Johannes Schindelin, git, gitster, Steffen Prohaska
Thanks; both patches applied.
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2009-02-20 8:38 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-18 15:10 [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
2009-02-18 15:11 ` [PATCH 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
2009-02-18 19:39 ` Johannes Sixt
2009-02-18 21:13 ` Johannes Schindelin
2009-02-18 22:27 ` Johannes Sixt
2009-02-18 23:18 ` Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 0/2] RUNTIME_PREFIX enhancements Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 1/2] Introduce the function strip_path_suffix() Johannes Schindelin
2009-02-19 20:12 ` Johannes Schindelin
2009-02-19 20:26 ` Johannes Sixt
2009-02-19 20:44 ` Johannes Schindelin
2009-02-19 19:10 ` [PATCH v2 2/2] system_path(): simplify using strip_path_suffix(), and add suffix "git" Johannes Schindelin
2009-02-19 20:39 ` Johannes Sixt
2009-02-19 20:48 ` Johannes Schindelin
2009-02-20 8:35 ` Junio C Hamano
2009-02-18 15:11 ` [PATCH " Johannes Schindelin
2009-02-18 19:38 ` [PATCH 0/2] RUNTIME_PREFIX enhancements Johannes Sixt
2009-02-18 21:11 ` Johannes Schindelin
2009-02-18 22:52 ` Johannes Sixt
2009-02-18 23:19 ` Johannes Schindelin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).