To: vim_dev@googlegroups.com Subject: Patch 7.4.235 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.235 Problem: It is not easy to get the full path of a command. Solution: Add the exepath() function. Files: src/eval.c, src/misc1.c, src/os_amiga.c, src/os_msdos.c, src/os_unix.c, src/os_vms.c, src/os_win32.c, src/proto/os_amiga.pro, src/proto/os_msdos.pro, src/proto/os_unix.pro, src/proto/os_win32.pro, runtime/doc/eval.txt *** ../vim-7.4.234/src/eval.c 2014-04-01 19:55:46.252787300 +0200 --- src/eval.c 2014-04-01 20:18:39.212768414 +0200 *************** *** 514,519 **** --- 514,520 ---- static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_exepath __ARGS((typval_T *argvars, typval_T *rettv)); static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); #ifdef FEAT_FLOAT static void f_exp __ARGS((typval_T *argvars, typval_T *rettv)); *************** *** 7920,7925 **** --- 7921,7927 ---- {"eval", 1, 1, f_eval}, {"eventhandler", 0, 0, f_eventhandler}, {"executable", 1, 1, f_executable}, + {"exepath", 1, 1, f_exepath}, {"exists", 1, 1, f_exists}, #ifdef FEAT_FLOAT {"exp", 1, 1, f_exp}, *************** *** 10046,10052 **** typval_T *argvars; typval_T *rettv; { ! rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); } /* --- 10048,10069 ---- typval_T *argvars; typval_T *rettv; { ! rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0]), NULL); ! } ! ! /* ! * "exepath()" function ! */ ! static void ! f_exepath(argvars, rettv) ! typval_T *argvars; ! typval_T *rettv; ! { ! char_u *p = NULL; ! ! (void)mch_can_exe(get_tv_string(&argvars[0]), &p); ! rettv->v_type = VAR_STRING; ! rettv->vval.v_string = p; } /* *** ../vim-7.4.234/src/misc1.c 2014-03-12 18:55:52.100906804 +0100 --- src/misc1.c 2014-04-01 20:01:08.752782864 +0200 *************** *** 10728,10734 **** return; /* If the file isn't executable, may not add it. Do accept directories. */ ! if (!isdir && (flags & EW_EXEC) && !mch_can_exe(f)) return; /* Make room for another item in the file list. */ --- 10728,10734 ---- return; /* If the file isn't executable, may not add it. Do accept directories. */ ! if (!isdir && (flags & EW_EXEC) && !mch_can_exe(f, NULL)) return; /* Make room for another item in the file list. */ *** ../vim-7.4.234/src/os_amiga.c 2013-05-06 04:06:04.000000000 +0200 --- src/os_amiga.c 2014-04-01 20:19:50.804767429 +0200 *************** *** 884,891 **** * Return -1 if unknown. */ int ! mch_can_exe(name) char_u *name; { /* TODO */ return -1; --- 884,892 ---- * Return -1 if unknown. */ int ! mch_can_exe(name, path) char_u *name; + char_u **path; { /* TODO */ return -1; *** ../vim-7.4.234/src/os_msdos.c 2014-03-23 15:12:29.931264336 +0100 --- src/os_msdos.c 2014-04-01 20:02:39.996781608 +0200 *************** *** 2945,2958 **** * Return -1 if unknown. */ int ! mch_can_exe(name) char_u *name; { char *p; p = searchpath(name); if (p == NULL || mch_isdir(p)) return FALSE; return TRUE; } --- 2945,2961 ---- * Return -1 if unknown. */ int ! mch_can_exe(name, path) char_u *name; + char_u **path; { char *p; p = searchpath(name); if (p == NULL || mch_isdir(p)) return FALSE; + if (path != NULL) + *path = vim_strsave(p); return TRUE; } *** ../vim-7.4.234/src/os_unix.c 2014-03-12 16:51:35.060792541 +0100 --- src/os_unix.c 2014-04-01 20:46:21.304745550 +0200 *************** *** 2992,2999 **** * Return -1 if unknown. */ int ! mch_can_exe(name) char_u *name; { char_u *buf; char_u *p, *e; --- 2992,3000 ---- * Return -1 if unknown. */ int ! mch_can_exe(name, path) char_u *name; + char_u **path; { char_u *buf; char_u *p, *e; *************** *** 3003,3009 **** if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/')))) { ! return executable_file(name); } p = (char_u *)getenv("PATH"); --- 3004,3021 ---- if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/' || (name[1] == '.' && name[2] == '/')))) { ! if (executable_file(name)) ! { ! if (path != NULL) ! { ! if (name[0] == '.') ! *path = FullName_save(name, TRUE); ! else ! *path = vim_strsave(name); ! } ! return TRUE; ! } ! return FALSE; } p = (char_u *)getenv("PATH"); *************** *** 3032,3038 **** --- 3044,3059 ---- STRCAT(buf, name); retval = executable_file(buf); if (retval == 1) + { + if (path != NULL) + { + if (buf[0] == '.') + *path = FullName_save(buf, TRUE); + else + *path = vim_strsave(buf); + } break; + } if (*e != ':') break; *************** *** 5592,5598 **** continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe(p)) continue; if (--files_free == 0) --- 5613,5619 ---- continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe(p, NULL)) continue; if (--files_free == 0) *************** *** 6090,6096 **** continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe((*file)[i])) continue; p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir)); --- 6111,6117 ---- continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe((*file)[i], NULL)) continue; p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir)); *************** *** 6317,6323 **** /* Reads gpm event and adds special keys to input buf. Returns length of * generated key sequence. ! * This function is made after gui_send_mouse_event */ static int mch_gpm_process() --- 6338,6344 ---- /* Reads gpm event and adds special keys to input buf. Returns length of * generated key sequence. ! * This function is styled after gui_send_mouse_event(). */ static int mch_gpm_process() *** ../vim-7.4.234/src/os_vms.c 2014-03-12 16:51:35.060792541 +0100 --- src/os_vms.c 2014-04-01 20:05:52.960778954 +0200 *************** *** 483,489 **** continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe(vms_fmatch[i])) continue; /* allocate memory for pointers */ --- 483,489 ---- continue; /* Skip files that are not executable if we check for that. */ ! if (!dir && (flags & EW_EXEC) && !mch_can_exe(vms_fmatch[i], NULL)) continue; /* allocate memory for pointers */ *** ../vim-7.4.234/src/os_win32.c 2014-02-11 17:05:57.282217857 +0100 --- src/os_win32.c 2014-04-01 20:26:07.432762248 +0200 *************** *** 1882,1888 **** * TODO: Should somehow check if it's really executable. */ static int ! executable_exists(char *name) { char *dum; char fname[_MAX_PATH]; --- 1882,1888 ---- * TODO: Should somehow check if it's really executable. */ static int ! executable_exists(char *name, char_u **path) { char *dum; char fname[_MAX_PATH]; *************** *** 1905,1910 **** --- 1905,1912 ---- return FALSE; if (GetFileAttributesW(fnamew) & FILE_ATTRIBUTE_DIRECTORY) return FALSE; + if (path != NULL) + *path = utf16_to_enc(fnamew, NULL); return TRUE; } /* Retry with non-wide function (for Windows 98). */ *************** *** 1915,1920 **** --- 1917,1924 ---- return FALSE; if (mch_isdir(fname)) return FALSE; + if (path != NULL) + *path = vim_strsave(fname); return TRUE; } *************** *** 1996,2002 **** vimrun_path = (char *)vim_strsave(vimrun_location); s_dont_use_vimrun = FALSE; } ! else if (executable_exists("vimrun.exe")) s_dont_use_vimrun = FALSE; /* Don't give the warning for a missing vimrun.exe right now, but only --- 2000,2006 ---- vimrun_path = (char *)vim_strsave(vimrun_location); s_dont_use_vimrun = FALSE; } ! else if (executable_exists("vimrun.exe", NULL)) s_dont_use_vimrun = FALSE; /* Don't give the warning for a missing vimrun.exe right now, but only *************** *** 2010,2016 **** * If "finstr.exe" doesn't exist, use "grep -n" for 'grepprg'. * Otherwise the default "findstr /n" is used. */ ! if (!executable_exists("findstr.exe")) set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0); #ifdef FEAT_CLIPBOARD --- 2014,2020 ---- * If "finstr.exe" doesn't exist, use "grep -n" for 'grepprg'. * Otherwise the default "findstr /n" is used. */ ! if (!executable_exists("findstr.exe", NULL)) set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0); #ifdef FEAT_CLIPBOARD *************** *** 3330,3336 **** * Return -1 if unknown. */ int ! mch_can_exe(char_u *name) { char_u buf[_MAX_PATH]; int len = (int)STRLEN(name); --- 3334,3340 ---- * Return -1 if unknown. */ int ! mch_can_exe(char_u *name, char_u **path) { char_u buf[_MAX_PATH]; int len = (int)STRLEN(name); *************** *** 3343,3349 **** * this with a Unix-shell like 'shell'. */ if (vim_strchr(gettail(name), '.') != NULL || strstr((char *)gettail(p_sh), "sh") != NULL) ! if (executable_exists((char *)name)) return TRUE; /* --- 3347,3353 ---- * this with a Unix-shell like 'shell'. */ if (vim_strchr(gettail(name), '.') != NULL || strstr((char *)gettail(p_sh), "sh") != NULL) ! if (executable_exists((char *)name, path)) return TRUE; /* *************** *** 3365,3371 **** } else copy_option_part(&p, buf + len, _MAX_PATH - len, ";"); ! if (executable_exists((char *)buf)) return TRUE; } return FALSE; --- 3369,3375 ---- } else copy_option_part(&p, buf + len, _MAX_PATH - len, ";"); ! if (executable_exists((char *)buf, path)) return TRUE; } return FALSE; *** ../vim-7.4.234/src/proto/os_amiga.pro 2013-08-10 13:37:37.000000000 +0200 --- src/proto/os_amiga.pro 2014-04-01 20:41:23.672749644 +0200 *************** *** 26,32 **** void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); int mch_mkdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name)); int mch_nodetype __ARGS((char_u *name)); void mch_early_init __ARGS((void)); void mch_exit __ARGS((int r)); --- 26,32 ---- void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); int mch_mkdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name, char_u **path)); int mch_nodetype __ARGS((char_u *name)); void mch_early_init __ARGS((void)); void mch_exit __ARGS((int r)); *** ../vim-7.4.234/src/proto/os_msdos.pro 2013-08-10 13:37:37.000000000 +0200 --- src/proto/os_msdos.pro 2014-04-01 20:41:32.432749524 +0200 *************** *** 38,44 **** int mch_setperm __ARGS((char_u *name, long perm)); void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name)); int mch_nodetype __ARGS((char_u *name)); int mch_dirname __ARGS((char_u *buf, int len)); int mch_remove __ARGS((char_u *name)); --- 38,44 ---- int mch_setperm __ARGS((char_u *name, long perm)); void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name, char_u **path)); int mch_nodetype __ARGS((char_u *name)); int mch_dirname __ARGS((char_u *buf, int len)); int mch_remove __ARGS((char_u *name)); *** ../vim-7.4.234/src/proto/os_unix.pro 2013-08-10 13:37:23.000000000 +0200 --- src/proto/os_unix.pro 2014-04-01 20:41:58.712749162 +0200 *************** *** 42,48 **** void mch_free_acl __ARGS((vim_acl_T aclent)); void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name)); int mch_nodetype __ARGS((char_u *name)); void mch_early_init __ARGS((void)); void mch_free_mem __ARGS((void)); --- 42,48 ---- void mch_free_acl __ARGS((vim_acl_T aclent)); void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name, char_u **path)); int mch_nodetype __ARGS((char_u *name)); void mch_early_init __ARGS((void)); void mch_free_mem __ARGS((void)); *** ../vim-7.4.234/src/proto/os_win32.pro 2013-08-10 13:37:38.000000000 +0200 --- src/proto/os_win32.pro 2014-04-01 20:42:16.992748911 +0200 *************** *** 26,32 **** int mch_is_linked __ARGS((char_u *fname)); int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info)); int mch_writable __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name)); int mch_nodetype __ARGS((char_u *name)); vim_acl_T mch_get_acl __ARGS((char_u *fname)); void mch_set_acl __ARGS((char_u *fname, vim_acl_T acl)); --- 26,32 ---- int mch_is_linked __ARGS((char_u *fname)); int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info)); int mch_writable __ARGS((char_u *name)); ! int mch_can_exe __ARGS((char_u *name, char_u **path)); int mch_nodetype __ARGS((char_u *name)); vim_acl_T mch_get_acl __ARGS((char_u *fname)); void mch_set_acl __ARGS((char_u *fname, vim_acl_T acl)); *** ../vim-7.4.234/runtime/doc/eval.txt 2014-04-01 19:55:46.244787300 +0200 --- runtime/doc/eval.txt 2014-04-01 20:54:37.832738720 +0200 *************** *** 1561,1566 **** --- 1562,1571 ---- v:progpath Contains the command with which Vim was invoked, including the path. Useful if you want to message a Vim server using a |--remote-expr|. + To get the full path use: > + echo exepath(v:progpath) + < NOTE: This does not work when the command is a relative path + and the current directory has changed. Read-only. *v:register* *register-variable* *************** *** 1761,1766 **** --- 1766,1772 ---- eval( {string}) any evaluate {string} into its value eventhandler( ) Number TRUE if inside an event handler executable( {expr}) Number 1 if executable {expr} exists + exepath( {expr}) String full path of the command {expr} exists( {expr}) Number TRUE if {expr} exists extend( {expr1}, {expr2} [, {expr3}]) List/Dict insert items of {expr2} into {expr1} *************** *** 2705,2710 **** --- 2711,2725 ---- 0 does not exist -1 not implemented on this system + exepath({expr}) *exepath()* + If {expr} is an executable and is either an absolute path, a + relative path or found in $PATH, return the full path. + Note that the current directory is used when {expr} starts + with "./", which may be a problem for Vim: > + echo exepath(v:progpath) + < If {expr} cannot be found in $PATH or is not executable then + an empty string is returned. + *exists()* exists({expr}) The result is a Number, which is non-zero if {expr} is defined, zero otherwise. The {expr} argument is a string, *** ../vim-7.4.234/src/version.c 2014-04-01 19:55:46.252787300 +0200 --- src/version.c 2014-04-01 20:00:44.108783203 +0200 *************** *** 736,737 **** --- 736,739 ---- { /* Add new patch number below this line */ + /**/ + 235, /**/ -- hundred-and-one symptoms of being an internet addict: 19. All of your friends have an @ in their names. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///