mirror of
https://github.com/neovim/neovim.git
synced 2025-10-16 14:56:08 +00:00
win: executable(): also check extension
This commit is contained in:
@@ -258,8 +258,9 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
|
|||||||
if (!pathext) {
|
if (!pathext) {
|
||||||
pathext = ".com;.exe;.bat;.cmd";
|
pathext = ".com;.exe;.bat;.cmd";
|
||||||
}
|
}
|
||||||
bool ok = is_executable((char *)name) || is_executable_ext((char *)name,
|
bool ok = (is_extension_executable((char *)name)
|
||||||
pathext);
|
&& is_executable((char *)name))
|
||||||
|
|| is_executable_ext((char *)name, pathext);
|
||||||
#else
|
#else
|
||||||
// Must have path separator, cannot execute files in the current directory.
|
// Must have path separator, cannot execute files in the current directory.
|
||||||
const bool ok = ((const char_u *)gettail_dir((const char *)name) != name
|
const bool ok = ((const char_u *)gettail_dir((const char *)name) != name
|
||||||
@@ -277,6 +278,68 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
|
|||||||
return is_executable_in_path(name, abspath);
|
return is_executable_in_path(name, abspath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/// Returns true if extension of `name` is executalbe file exteinsion.
|
||||||
|
static bool is_extension_executable(const char *name)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
// Don't check extensions, when a Unix-shell like 'shell'.
|
||||||
|
const char_u *shell_end = p_sh + STRLEN(p_sh);
|
||||||
|
while (true) {
|
||||||
|
if (*shell_end == '.') {
|
||||||
|
break;
|
||||||
|
} else if (shell_end == p_sh
|
||||||
|
|| (*shell_end == '/' || *shell_end == '\\')) {
|
||||||
|
shell_end = p_sh + STRLEN(p_sh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shell_end--;
|
||||||
|
}
|
||||||
|
if (mb_strnicmp(shell_end - 2, (const char_u *)"sh", 2) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pathext = os_getenv("PATHEXT");
|
||||||
|
if (!pathext) {
|
||||||
|
pathext = ".com;.exe;.bat;.cmd";
|
||||||
|
}
|
||||||
|
const char *ext_pos = name + STRLEN(name) - 1;
|
||||||
|
while (name != ext_pos) {
|
||||||
|
if (*ext_pos == '\\' || *ext_pos == '/') {
|
||||||
|
ext_pos = name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*ext_pos == '.') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ext_pos--;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cur_pos = pathext;
|
||||||
|
while (true) {
|
||||||
|
// Don't check extension, if $PATHEXT contain dot itself.
|
||||||
|
if (*cur_pos == '.'
|
||||||
|
&& (*(cur_pos + 1) == ENV_SEPCHAR || *(cur_pos + 1) == NUL)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char *ext_end = strchr(cur_pos, ENV_SEPCHAR);
|
||||||
|
size_t ext_len = ext_end ?
|
||||||
|
(size_t)(ext_end - cur_pos) :
|
||||||
|
(STRLEN(pathext) - (size_t)(cur_pos - pathext));
|
||||||
|
if (ext_pos != name && mb_strnicmp((const char_u *)ext_pos,
|
||||||
|
(const char_u *)cur_pos, ext_len) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ext_end == NULL) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
cur_pos = ++ext_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Returns true if `name` is an executable file.
|
/// Returns true if `name` is an executable file.
|
||||||
static bool is_executable(const char *name)
|
static bool is_executable(const char *name)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
@@ -378,7 +441,8 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
|
|||||||
append_path(buf, (char *)name, buf_len);
|
append_path(buf, (char *)name, buf_len);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
bool ok = is_executable(buf) || is_executable_ext(buf, pathext);
|
bool ok = (is_extension_executable(buf) && is_executable(buf))
|
||||||
|
|| is_executable_ext(buf, pathext);
|
||||||
#else
|
#else
|
||||||
bool ok = is_executable(buf);
|
bool ok = is_executable(buf);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user