Patch 8.2.1968
Problem:    Vim9: has() assumes a feature does not change dynamically.
Solution:   Check whether a feature may change dynamically. (closes #7265)
Files:      src/vim9compile.c, src/evalfunc.c, src/proto/evalfunc.pro,
            src/testdir/test_vim9_disassemble.vim


*** ../vim-8.2.1967/src/vim9compile.c   2020-11-05 18:45:42.966909992 +0100
--- src/vim9compile.c   2020-11-07 22:24:29.979071185 +0100
***************
*** 2620,2626 ****
        else if (*s == '\'')
            (void)eval_lit_string(&s, &argvars[0], TRUE);
        s = skipwhite(s);
!       if (*s == ')' && argvars[0].v_type == VAR_STRING)
        {
            typval_T    *tv = &ppconst->pp_tv[ppconst->pp_used];
  
--- 2620,2627 ----
        else if (*s == '\'')
            (void)eval_lit_string(&s, &argvars[0], TRUE);
        s = skipwhite(s);
!       if (*s == ')' && argvars[0].v_type == VAR_STRING
!               && !dynamic_feature(argvars[0].vval.v_string))
        {
            typval_T    *tv = &ppconst->pp_tv[ppconst->pp_used];
  
*** ../vim-8.2.1967/src/evalfunc.c      2020-11-05 20:46:28.716616921 +0100
--- src/evalfunc.c      2020-11-07 22:35:50.537374152 +0100
***************
*** 5484,5489 ****
--- 5484,5556 ----
  }
  
  /*
+  * Return TRUE if "feature" can change later.
+  * Also when checking for the feature has side effects, such as loading a DLL.
+  */
+     int
+ dynamic_feature(char_u *feature)
+ {
+     return (feature == NULL
+ #if defined(FEAT_BEVAL) && defined(FEAT_GUI_MSWIN)
+           || STRICMP(feature, "balloon_multiline") == 0
+ #endif
+ #if defined(FEAT_GUI) && defined(FEAT_BROWSE)
+           || (STRICMP(feature, "browse") == 0 && !gui.in_use)
+ #endif
+ #ifdef VIMDLL
+           || STRICMP(feature, "filterpipe") == 0
+ #endif
+ #if defined(FEAT_GUI) && !defined(ALWAYS_USE_GUI)
+           // this can only change on Unix where the ":gui" command could be
+           // used.
+           || (STRICMP(feature, "gui_running") == 0 && !gui.in_use)
+ #endif
+ #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
+           || STRICMP(feature, "iconv") == 0
+ #endif
+ #ifdef DYNAMIC_LUA
+           || STRICMP(feature, "lua") == 0
+ #endif
+ #ifdef FEAT_MOUSE_GPM
+           || (STRICMP(feature, "mouse_gpm_enabled") == 0 && !gpm_enabled())
+ #endif
+ #ifdef DYNAMIC_MZSCHEME
+           || STRICMP(feature, "mzscheme") == 0
+ #endif
+ #ifdef FEAT_NETBEANS_INTG
+           || STRICMP(feature, "netbeans_enabled") == 0
+ #endif
+ #ifdef DYNAMIC_PERL
+           || STRICMP(feature, "perl") == 0
+ #endif
+ #ifdef DYNAMIC_PYTHON
+           || STRICMP(feature, "python") == 0
+ #endif
+ #ifdef DYNAMIC_PYTHON3
+           || STRICMP(feature, "python3") == 0
+ #endif
+ #if defined(DYNAMIC_PYTHON) || defined(DYNAMIC_PYTHON3)
+           || STRICMP(feature, "pythonx") == 0
+ #endif
+ #ifdef DYNAMIC_RUBY
+           || STRICMP(feature, "ruby") == 0
+ #endif
+ #ifdef FEAT_SYN_HL
+           || STRICMP(feature, "syntax_items") == 0
+ #endif
+ #ifdef DYNAMIC_TCL
+           || STRICMP(feature, "tcl") == 0
+ #endif
+           // once "starting" is zero it will stay that way
+           || (STRICMP(feature, "vim_starting") == 0 && starting != 0)
+           || STRICMP(feature, "multi_byte_encoding") == 0
+ #if defined(FEAT_TERMINAL) && defined(MSWIN)
+           || STRICMP(feature, "conpty") == 0
+ #endif
+           );
+ }
+ 
+ /*
   * "haslocaldir()" function
   */
      static void
*** ../vim-8.2.1967/src/proto/evalfunc.pro      2020-10-21 16:42:18.513821908 
+0200
--- src/proto/evalfunc.pro      2020-11-07 19:59:19.697307232 +0100
***************
*** 16,21 ****
--- 16,22 ----
  void execute_redir_str(char_u *value, int value_len);
  void execute_common(typval_T *argvars, typval_T *rettv, int arg_off);
  void f_has(typval_T *argvars, typval_T *rettv);
+ int dynamic_feature(char_u *feature);
  void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
  void range_list_materialize(list_T *list);
  float_T vim_round(float_T f);
*** ../vim-8.2.1967/src/testdir/test_vim9_disassemble.vim       2020-11-05 
18:45:42.970909982 +0100
--- src/testdir/test_vim9_disassemble.vim       2020-11-07 22:57:02.182229509 
+0100
***************
*** 629,634 ****
--- 629,642 ----
    endif
  enddef
  
+ def HasGuiRunning()
+   if has("gui_running")
+     echo "yes"
+   else
+     echo "no"
+   endif
+ enddef
+ 
  def Test_disassemble_const_expr()
    assert_equal("\nyes", execute('HasEval()'))
    var instr = execute('disassemble HasEval')
***************
*** 676,681 ****
--- 684,750 ----
    assert_notmatch('PUSHS "something"', instr)
    assert_notmatch('PUSHS "less"', instr)
    assert_notmatch('JUMP', instr)
+ 
+   var result: string
+   var instr_expected: string
+   if has('gui')
+     if has('gui_running')
+       # GUI already running, always returns "yes"
+       result = "\nyes"
+       instr_expected = 'HasGuiRunning.*' ..
+           'if has("gui_running")\_s*' ..
+           '  echo "yes"\_s*' ..
+           '\d PUSHS "yes"\_s*' ..
+           '\d ECHO 1\_s*' ..
+           'else\_s*' ..
+           '  echo "no"\_s*' ..
+           'endif'
+     else
+       result = "\nno"
+       if has('unix')
+         # GUI not running but can start later, call has()
+         instr_expected = 'HasGuiRunning.*' ..
+             'if has("gui_running")\_s*' ..
+             '\d PUSHS "gui_running"\_s*' ..
+             '\d BCALL has(argc 1)\_s*' ..
+             '\d JUMP_IF_FALSE -> \d\_s*' ..
+             '  echo "yes"\_s*' ..
+             '\d PUSHS "yes"\_s*' ..
+             '\d ECHO 1\_s*' ..
+             'else\_s*' ..
+             '\d JUMP -> \d\_s*' ..
+             '  echo "no"\_s*' ..
+             '\d PUSHS "no"\_s*' ..
+             '\d ECHO 1\_s*' ..
+             'endif'
+       else
+         # GUI not running, always return "no"
+         instr_expected = 'HasGuiRunning.*' ..
+             'if has("gui_running")\_s*' ..
+             '  echo "yes"\_s*' ..
+             'else\_s*' ..
+             '  echo "no"\_s*' ..
+             '\d PUSHS "no"\_s*' ..
+             '\d ECHO 1\_s*' ..
+             'endif'
+       endif
+     endif
+   else
+     # GUI not supported, always return "no"
+     result = "\nno"
+     instr_expected = 'HasGuiRunning.*' ..
+         'if has("gui_running")\_s*' ..
+         '  echo "yes"\_s*' ..
+         'else\_s*' ..
+         '  echo "no"\_s*' ..
+         '\d PUSHS "no"\_s*' ..
+         '\d ECHO 1\_s*' ..
+         'endif'
+   endif
+ 
+   assert_equal(result, execute('HasGuiRunning()'))
+   instr = execute('disassemble HasGuiRunning')
+   assert_match(instr_expected, instr)
  enddef
  
  def ReturnInIf(): string
*** ../vim-8.2.1967/src/version.c       2020-11-07 18:40:47.136725212 +0100
--- src/version.c       2020-11-07 22:36:26.877283699 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     1968,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
217. Your sex life has drastically improved...so what if it's only cyber-sex!

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202011081214.0A8CEYLn937016%40masaka.moolenaar.net.

Raspunde prin e-mail lui