aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRui Abreu Ferreira <raf-ep@gmx.com>2015-05-12 19:52:06 +0100
committerSeth Jackson <sethjackson@gmail.com>2016-01-30 15:09:18 -0500
commitda4bf813daf1d54c3cdfbeb480b7ce15a7372834 (patch)
tree882028f6ac260e4bf779eb54dfbd30b659b8fa30 /src
parent8f22031708b351ec5bb73952e6afc39b07a72ae2 (diff)
downloadrneovim-da4bf813daf1d54c3cdfbeb480b7ce15a7372834.tar.gz
rneovim-da4bf813daf1d54c3cdfbeb480b7ce15a7372834.tar.bz2
rneovim-da4bf813daf1d54c3cdfbeb480b7ce15a7372834.zip
Windows: use $PATHEXT to find executables in path.
is_executable_in_path() searches for executables in $PATH, but on Windows executable files have extensions available in the environment var $PATHEXT. This commit changes is_executable_in_path() to append those extensions to the filename. This patch diverges from standard Vim, in that Vim only checked for the given filename if it already has an extensions. This one always checks for the given filename.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/os/fs.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 21f0fc6f41..2e671653ed 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -146,6 +146,16 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
}
size_t buf_len = STRLEN(name) + STRLEN(path) + 2;
+
+#ifdef WIN32
+ const char *pathext = os_getenv("PATHEXT");
+ if (!pathext) {
+ pathext = ".com;.exe;.bat;.cmd";
+ }
+
+ buf_len += STRLEN(pathext);
+#endif
+
char_u *buf = xmalloc(buf_len);
// Walk through all entries in $PATH to check if "name" exists there and
@@ -169,6 +179,38 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
return true;
}
+#ifdef WIN32
+ // Try appending file extensions from $PATHEXT to the name.
+ char *buf_end = xstrchrnul((char *)buf, '\0');
+ for (const char *ext = pathext; *ext; ext++) {
+ // Skip the extension if there is no suffix after a '.'.
+ if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ';')) {
+ *ext++;
+
+ continue;
+ }
+
+ const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
+ STRLCPY(buf_end, ext, ext_end - ext + 1);
+
+ if (is_executable(buf)) {
+ // Check if the caller asked for a copy of the path.
+ if (abspath != NULL) {
+ *abspath = save_absolute_path(buf);
+ }
+
+ xfree(buf);
+
+ return true;
+ }
+
+ if (*ext_end != ENV_SEPCHAR) {
+ break;
+ }
+ ext = ext_end;
+ }
+#endif
+
if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
xfree(buf);