Loading ...
Sorry, an error occurred while loading the content.
 

E685: Internal error: hash_add() happen when assigning autoload variable

Expand Messages
  • Yukihiro Nakadaira
    Steps to reproduce: $ cat ~/.vim/autoload/Foo.vim let Foo#x = 0 $ vim -u NONE -N ... E685: Internal error: hash_add() eval.c:set_var() - var_check_func_name()
    Message 1 of 8 , Dec 31, 2013
      Steps to reproduce:
        $ cat ~/.vim/autoload/Foo.vim
        let Foo#x = 0
        $ vim -u NONE -N
        :let Foo#x = function('tr')
        E685: Internal error: hash_add()

      eval.c:set_var()
        -> var_check_func_name()    Foo.vim is loaded and Foo#x is created.
        -> hash_add()               error, because Foo#x is already exists.

      Please check the following patch.

      diff -r 2f856c7c1d43 src/eval.c
      --- a/src/eval.c    Sun Dec 15 10:02:33 2013 +0100
      +++ b/src/eval.c    Wed Jan 01 13:44:46 2014 +0900
      @@ -20718,6 +20718,8 @@
           char_u *name;    /* points to start of variable name */
           int    new_var;  /* TRUE when creating the variable */
       {
      +    int err;
      +
           if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
               && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
                                    ? name[2] : name[0]))
      @@ -20729,7 +20731,10 @@
           /* Don't allow hiding a function.  When "v" is not NULL we might be
            * assigning another function to the same var, the type is checked
            * below. */
      -    if (new_var && function_exists(name))
      +    no_autoload = TRUE;
      +    err = new_var && function_exists(name);
      +    no_autoload = FALSE;
      +    if (err)
           {
           EMSG2(_("E705: Variable name conflicts with existing function: %s"),
                                           name);


      --
      Yukihiro Nakadaira - yukihiro.nakadaira@...

      --
      --
      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 vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Bram Moolenaar
      Yukihiro - ... Thanks, I ll check it out. -- hundred-and-one symptoms of being an internet addict: 96. On Super Bowl Sunday, you followed the score by going to
      Message 2 of 8 , Jan 5, 2014
        Yukihiro -

        > Steps to reproduce:
        > $ cat ~/.vim/autoload/Foo.vim
        > let Foo#x = 0
        > $ vim -u NONE -N
        > :let Foo#x = function('tr')
        > E685: Internal error: hash_add()
        >
        > eval.c:set_var()
        > -> var_check_func_name() Foo.vim is loaded and Foo#x is created.
        > -> hash_add() error, because Foo#x is already exists.
        >
        > Please check the following patch.

        Thanks, I'll check it out.

        --
        hundred-and-one symptoms of being an internet addict:
        96. On Super Bowl Sunday, you followed the score by going to the
        Yahoo main page instead of turning on the TV.

        /// Bram Moolenaar -- Bram@... -- 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 vim_dev+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
      • Nikolay Pavlov
        On Jan 1, 2014 9:47 AM, Yukihiro Nakadaira ... Are you sure that no_autoload variable may never be TRUE when callin this
        Message 3 of 8 , Jan 5, 2014


          On Jan 1, 2014 9:47 AM, "Yukihiro Nakadaira" <yukihiro.nakadaira@...> wrote:
          >
          > Steps to reproduce:
          >   $ cat ~/.vim/autoload/Foo.vim
          >   let Foo#x = 0
          >   $ vim -u NONE -N
          >   :let Foo#x = function('tr')
          >   E685: Internal error: hash_add()
          >
          > eval.c:set_var()
          >   -> var_check_func_name()    Foo.vim is loaded and Foo#x is created.
          >   -> hash_add()               error, because Foo#x is already exists.
          >
          > Please check the following patch.
          >
          > diff -r 2f856c7c1d43 src/eval.c
          > --- a/src/eval.c    Sun Dec 15 10:02:33 2013 +0100
          > +++ b/src/eval.c    Wed Jan 01 13:44:46 2014 +0900
          > @@ -20718,6 +20718,8 @@
          >      char_u *name;    /* points to start of variable name */
          >      int    new_var;  /* TRUE when creating the variable */
          >  {
          > +    int err;
          > +
          >      if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
          >          && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
          >                               ? name[2] : name[0]))
          > @@ -20729,7 +20731,10 @@
          >      /* Don't allow hiding a function.  When "v" is not NULL we might be
          >       * assigning another function to the same var, the type is checked
          >       * below. */
          > -    if (new_var && function_exists(name))
          > +    no_autoload = TRUE;
          > +    err = new_var && function_exists(name);
          > +    no_autoload = FALSE;

          Are you sure that no_autoload variable may never be TRUE when callin this function?

          > +    if (err)
          >      {
          >      EMSG2(_("E705: Variable name conflicts with existing function: %s"),
          >                                      name);
          >
          >
          > --
          > Yukihiro Nakadaira - yukihiro.nakadaira@...
          >
          > --
          > --
          > 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 vim_dev+unsubscribe@....
          > For more options, visit https://groups.google.com/groups/opt_out.

          --
          --
          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 vim_dev+unsubscribe@....
          For more options, visit https://groups.google.com/groups/opt_out.
        • Yukihiro Nakadaira
          ... Yes, I am. -- Yukihiro Nakadaira - yukihiro.nakadaira@gmail.com -- -- You received this message from the vim_dev maillist. Do not top-post! Type your
          Message 4 of 8 , Jan 6, 2014
            On Sun, Jan 5, 2014 at 11:44 PM, Nikolay Pavlov <zyx.vim@...> wrote:


            On Jan 1, 2014 9:47 AM, "Yukihiro Nakadaira" <yukihiro.nakadaira@...> wrote:
            >
            > Steps to reproduce:
            >   $ cat ~/.vim/autoload/Foo.vim
            >   let Foo#x = 0
            >   $ vim -u NONE -N
            >   :let Foo#x = function('tr')
            >   E685: Internal error: hash_add()
            >
            > eval.c:set_var()
            >   -> var_check_func_name()    Foo.vim is loaded and Foo#x is created.
            >   -> hash_add()               error, because Foo#x is already exists.
            >
            > Please check the following patch.
            >
            > diff -r 2f856c7c1d43 src/eval.c
            > --- a/src/eval.c    Sun Dec 15 10:02:33 2013 +0100
            > +++ b/src/eval.c    Wed Jan 01 13:44:46 2014 +0900
            > @@ -20718,6 +20718,8 @@
            >      char_u *name;    /* points to start of variable name */
            >      int    new_var;  /* TRUE when creating the variable */
            >  {
            > +    int err;
            > +
            >      if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
            >          && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
            >                               ? name[2] : name[0]))
            > @@ -20729,7 +20731,10 @@
            >      /* Don't allow hiding a function.  When "v" is not NULL we might be
            >       * assigning another function to the same var, the type is checked
            >       * below. */
            > -    if (new_var && function_exists(name))
            > +    no_autoload = TRUE;
            > +    err = new_var && function_exists(name);
            > +    no_autoload = FALSE;

            Are you sure that no_autoload variable may never be TRUE when callin this function?


            Yes, I am.
             
            --
            Yukihiro Nakadaira - yukihiro.nakadaira@...

            --
            --
            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 vim_dev+unsubscribe@....
            For more options, visit https://groups.google.com/groups/opt_out.
          • ZyX
            ... You should not be. let d={} echo exists( *d[extend(g:, { Foo#x : function( tr )})] ) . f_exists() sets no_autoload to TRUE, dict_extend() runs
            Message 5 of 8 , Jan 6, 2014
              > Yes, I am.

              You should not be.

              let d={}
              echo exists('*d[extend(g:, {"Foo#x": function("tr")})]')

              . f_exists() sets no_autoload to TRUE, dict_extend() runs var_check_func_name() which you have modified setting it back to FALSE before f_exists ends. f_exists should by the way save no_autoload variable for the same reason: it may be called recursively.

              --
              --
              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 vim_dev+unsubscribe@....
              For more options, visit https://groups.google.com/groups/opt_out.
            • Yukihiro Nakadaira
              ... Thank you for finding it out. I didn t notice it. Perhaps there is another problem that exists( x[y#z()] ) doesn t trigger autoload. -- Yukihiro Nakadaira
              Message 6 of 8 , Jan 6, 2014
                On Tue, Jan 7, 2014 at 5:33 AM, ZyX <zyx.vim@...> wrote:
                > Yes, I am.

                You should not be.

                    let d={}
                    echo exists('*d[extend(g:, {"Foo#x": function("tr")})]')

                . f_exists() sets no_autoload to TRUE, dict_extend() runs var_check_func_name() which you have modified setting it back to FALSE before f_exists ends. f_exists should by the way save no_autoload variable for the same reason: it may be called recursively.

                Thank you for finding it out.  I didn't notice it.
                Perhaps there is another problem that exists('x[y#z()]') doesn't trigger autoload.

                --
                Yukihiro Nakadaira - yukihiro.nakadaira@...

                --
                --
                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 vim_dev+unsubscribe@....
                For more options, visit https://groups.google.com/groups/opt_out.
              • ZyX
                ... There is. The very good probability of such bugs is one of the reasons why I did not even consider adding similar global in extended funcref patch when I
                Message 7 of 8 , Jan 6, 2014
                  > Thank you for finding it out.  I didn't notice it.
                  >
                  > Perhaps there is another problem that exists('x[y#z()]') doesn't trigger autoload.

                  There is. The very good probability of such bugs is one of the reasons why I did not even consider adding similar global in extended funcref patch when I encountered similar problems (and removed no_autoload from there once it got my attention).

                  --
                  --
                  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 vim_dev+unsubscribe@....
                  For more options, visit https://groups.google.com/groups/opt_out.
                • ZyX
                  ... This patch replaces global with arguments in flags passed to some functions. Changed behavior: lockvar and islocked() no longer trigger script autoloading
                  Message 8 of 8 , Jan 6, 2014
                    > There is. The very good probability of such bugs is one of the reasons why I did not even consider adding similar global in extended funcref patch when I encountered similar problems (and removed no_autoload from there once it got my attention).

                    This patch replaces global with arguments in flags passed to some functions.

                    Changed behavior: lockvar and islocked() no longer trigger script autoloading (except for evaluating nested expressions like islocked('not#autoloaded#dict[autoloaded#function()]')). Do not think anybody actually relied on this.

                    # HG changeset patch
                    # User ZyX <kp-pav@...>
                    # Date 1389066029 -14400
                    # Tue Jan 07 07:40:29 2014 +0400
                    # Branch remove-no_autoload-global
                    # Node ID 7b182c0bfaf563de5b977e8773c409fef2457297
                    # Parent bc19475ed196b91bf1ecda2224d88a47b5b497bb
                    Replace no_autoload global with arguments and flags

                    diff -r bc19475ed196 -r 7b182c0bfaf5 src/eval.c
                    --- a/src/eval.c Mon Jan 06 15:51:55 2014 +0100
                    +++ b/src/eval.c Tue Jan 07 07:40:29 2014 +0400
                    @@ -125,9 +125,6 @@
                    */
                    static hashtab_T compat_hashtab;

                    -/* When using exists() don't auto-load a script. */
                    -static int no_autoload = FALSE;
                    -
                    /*
                    * When recursively copying lists and dicts we need to remember which ones we
                    * have done to avoid endless recursiveness. This unique ID is used for that.
                    @@ -156,6 +153,14 @@
                    /* Values for trans_function_name() argument: */
                    #define TFN_INT 1 /* internal function name OK */
                    #define TFN_QUIET 2 /* no error messages */
                    +#define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */
                    +
                    +/* #define TFN_TO_GLVAL(flags) (flags&(TFN_QUIET|TFN_NO_AUTOLOAD)) */
                    +#define TFN_TO_GLV(flags) (flags)
                    +
                    +/* Values for get_lval() flags argument: */
                    +#define GLV_QUIET TFN_QUIET /* no error messages */
                    +#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */

                    /*
                    * Structure to hold info for a user function.
                    @@ -390,7 +395,7 @@
                    static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
                    static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
                    static int check_changedtick __ARGS((char_u *arg));
                    -static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
                    +static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags));
                    static void clear_lval __ARGS((lval_T *lp));
                    static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op));
                    static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op));
                    @@ -770,7 +775,7 @@
                    static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end));
                    static int eval_isnamec __ARGS((int c));
                    static int eval_isnamec1 __ARGS((int c));
                    -static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose));
                    +static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose, int no_autoload));
                    static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose));
                    static typval_T *alloc_tv __ARGS((void));
                    static typval_T *alloc_string_tv __ARGS((char_u *string));
                    @@ -781,8 +786,8 @@
                    static char_u *get_tv_string __ARGS((typval_T *varp));
                    static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
                    static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
                    -static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
                    -static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int writing));
                    +static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int no_autoload));
                    +static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int no_autoload));
                    static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
                    static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
                    static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
                    @@ -1059,7 +1064,7 @@
                    ga_init2(&redir_ga, (int)sizeof(char), 500);

                    /* Parse the variable name (can be a dict or list entry). */
                    - redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE,
                    + redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
                    FNE_CHECK_START);
                    if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
                    {
                    @@ -1150,7 +1155,7 @@
                    /* Call get_lval() again, if it's inside a Dict or List it may
                    * have changed. */
                    redir_endp = get_lval(redir_varname, NULL, redir_lval,
                    - FALSE, FALSE, FALSE, FNE_CHECK_START);
                    + FALSE, FALSE, 0, FNE_CHECK_START);
                    if (redir_endp != NULL && redir_lval->ll_name != NULL)
                    set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
                    clear_lval(redir_lval);
                    @@ -2239,7 +2244,7 @@
                    {
                    if (tofree != NULL)
                    name = tofree;
                    - if (get_var_tv(name, len, &tv, TRUE) == FAIL)
                    + if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL)
                    error = TRUE;
                    else
                    {
                    @@ -2474,7 +2479,7 @@
                    {
                    lval_T lv;

                    - p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START);
                    + p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
                    if (p != NULL && lv.ll_name != NULL)
                    {
                    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
                    @@ -2519,18 +2524,22 @@
                    * "unlet" is TRUE for ":unlet": slightly different behavior when something is
                    * wrong; must end in space or cmd separator.
                    *
                    + * flags:
                    + * GLV_QUIET: do not give error messages
                    + * GLV_NO_AUTOLOAD: do not use script autoloading
                    + *
                    * Returns a pointer to just after the name, including indexes.
                    * When an evaluation error occurs "lp->ll_name" is NULL;
                    * Returns NULL for a parsing error. Still need to free items in "lp"!
                    */
                    static char_u *
                    -get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags)
                    +get_lval(name, rettv, lp, unlet, skip, flags, fne_flags)
                    char_u *name;
                    typval_T *rettv;
                    lval_T *lp;
                    int unlet;
                    int skip;
                    - int quiet; /* don't give error messages */
                    + int flags; /* don't give error messages */
                    int fne_flags; /* flags for find_name_end() */
                    {
                    char_u *p;
                    @@ -2573,7 +2582,7 @@
                    /* Report an invalid expression in braces, unless the
                    * expression evaluation has been cancelled due to an
                    * aborting error, an interrupt, or an exception. */
                    - if (!aborting() && !quiet)
                    + if (!aborting() && !(flags & GLV_QUIET))
                    {
                    emsg_severe = TRUE;
                    EMSG2(_(e_invarg2), name);
                    @@ -2591,8 +2600,8 @@

                    cc = *p;
                    *p = NUL;
                    - v = find_var(lp->ll_name, &ht);
                    - if (v == NULL && !quiet)
                    + v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
                    + if (v == NULL && !(flags & GLV_QUIET))
                    EMSG2(_(e_undefvar), lp->ll_name);
                    *p = cc;
                    if (v == NULL)
                    @@ -2608,13 +2617,13 @@
                    && !(lp->ll_tv->v_type == VAR_DICT
                    && lp->ll_tv->vval.v_dict != NULL))
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_("E689: Can only index a List or Dictionary"));
                    return NULL;
                    }
                    if (lp->ll_range)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_("E708: [:] must come last"));
                    return NULL;
                    }
                    @@ -2627,7 +2636,7 @@
                    ;
                    if (len == 0)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_(e_emptykey));
                    return NULL;
                    }
                    @@ -2657,7 +2666,7 @@
                    {
                    if (lp->ll_tv->v_type == VAR_DICT)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_(e_dictrange));
                    if (!empty1)
                    clear_tv(&var1);
                    @@ -2666,7 +2675,7 @@
                    if (rettv != NULL && (rettv->v_type != VAR_LIST
                    || rettv->vval.v_list == NULL))
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_("E709: [:] requires a List value"));
                    if (!empty1)
                    clear_tv(&var1);
                    @@ -2700,7 +2709,7 @@

                    if (*p != ']')
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_(e_missbrac));
                    if (!empty1)
                    clear_tv(&var1);
                    @@ -2721,7 +2730,7 @@
                    key = get_tv_string(&var1); /* is number or string */
                    if (*key == NUL)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG(_(e_emptykey));
                    clear_tv(&var1);
                    return NULL;
                    @@ -2768,7 +2777,7 @@
                    /* Key does not exist in dict: may need to add it. */
                    if (*p == '[' || *p == '.' || unlet)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSG2(_(e_dictkey), key);
                    if (len == -1)
                    clear_tv(&var1);
                    @@ -2819,7 +2828,7 @@
                    {
                    if (lp->ll_range && !lp->ll_empty2)
                    clear_tv(&var2);
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSGN(_(e_listidx), lp->ll_n1);
                    return NULL;
                    }
                    @@ -2839,7 +2848,7 @@
                    ni = list_find(lp->ll_list, lp->ll_n2);
                    if (ni == NULL)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSGN(_(e_listidx), lp->ll_n2);
                    return NULL;
                    }
                    @@ -2851,7 +2860,7 @@
                    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
                    if (lp->ll_n2 < lp->ll_n1)
                    {
                    - if (!quiet)
                    + if (!(flags & GLV_QUIET))
                    EMSGN(_(e_listidx), lp->ll_n2);
                    return NULL;
                    }
                    @@ -2904,7 +2913,7 @@

                    /* handle +=, -= and .= */
                    if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
                    - &tv, TRUE) == OK)
                    + &tv, TRUE, FALSE) == OK)
                    {
                    if (tv_op(&tv, rettv, op) == OK)
                    set_var(lp->ll_name, &tv, FALSE);
                    @@ -3556,7 +3565,7 @@
                    do
                    {
                    /* Parse the name and find the end. */
                    - name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE,
                    + name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
                    FNE_CHECK_START);
                    if (lv.ll_name == NULL)
                    error = TRUE; /* error but continue parsing */
                    @@ -3709,7 +3718,7 @@
                    ret = FAIL;
                    else
                    {
                    - di = find_var(lp->ll_name, NULL);
                    + di = find_var(lp->ll_name, NULL, TRUE);
                    if (di == NULL)
                    ret = FAIL;
                    else
                    @@ -5179,7 +5188,7 @@
                    }
                    }
                    else if (evaluate)
                    - ret = get_var_tv(s, len, rettv, TRUE);
                    + ret = get_var_tv(s, len, rettv, TRUE, FALSE);
                    else
                    ret = OK;
                    }
                    @@ -8284,7 +8293,7 @@

                    cc = name[*lenp];
                    name[*lenp] = NUL;
                    - v = find_var(name, NULL);
                    + v = find_var(name, NULL, FALSE);
                    name[*lenp] = cc;
                    if (v != NULL && v->di_tv.v_type == VAR_FUNC)
                    {
                    @@ -10039,8 +10048,6 @@
                    int n = FALSE;
                    int len = 0;

                    - no_autoload = TRUE;
                    -
                    p = get_tv_string(&argvars[0]);
                    if (*p == '$') /* environment variable */
                    {
                    @@ -10091,7 +10098,7 @@
                    {
                    if (tofree != NULL)
                    name = tofree;
                    - n = (get_var_tv(name, len, &tv, FALSE) == OK);
                    + n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK);
                    if (n)
                    {
                    /* handle d.key, l[idx], f(expr) */
                    @@ -10107,8 +10114,6 @@
                    }

                    rettv->vval.v_number = n;
                    -
                    - no_autoload = FALSE;
                    }

                    #ifdef FEAT_FLOAT
                    @@ -13344,8 +13349,8 @@
                    dictitem_T *di;

                    rettv->vval.v_number = -1;
                    - end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE,
                    - FNE_CHECK_START);
                    + end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
                    + GLV_NO_AUTOLOAD, FNE_CHECK_START);
                    if (end != NULL && lv.ll_name != NULL)
                    {
                    if (*end != NUL)
                    @@ -13358,7 +13363,7 @@
                    rettv->vval.v_number = 1; /* always locked */
                    else
                    {
                    - di = find_var(lv.ll_name, NULL);
                    + di = find_var(lv.ll_name, NULL, TRUE);
                    if (di != NULL)
                    {
                    /* Consider a variable locked when:
                    @@ -19774,11 +19779,12 @@
                    * Return OK or FAIL.
                    */
                    static int
                    -get_var_tv(name, len, rettv, verbose)
                    +get_var_tv(name, len, rettv, verbose, no_autoload)
                    char_u *name;
                    int len; /* length of "name" */
                    typval_T *rettv; /* NULL when only checking existence */
                    int verbose; /* may give error message */
                    + int no_autoload; /* do not use script autoloading */
                    {
                    int ret = OK;
                    typval_T *tv = NULL;
                    @@ -19805,7 +19811,7 @@
                    */
                    else
                    {
                    - v = find_var(name, NULL);
                    + v = find_var(name, NULL, no_autoload);
                    if (v != NULL)
                    tv = &v->di_tv;
                    }
                    @@ -20207,9 +20213,10 @@
                    * hashtab_T used.
                    */
                    static dictitem_T *
                    -find_var(name, htp)
                    +find_var(name, htp, no_autoload)
                    char_u *name;
                    hashtab_T **htp;
                    + int no_autoload;
                    {
                    char_u *varname;
                    hashtab_T *ht;
                    @@ -20219,7 +20226,7 @@
                    *htp = ht;
                    if (ht == NULL)
                    return NULL;
                    - return find_var_in_ht(ht, *name, varname, htp != NULL);
                    + return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
                    }

                    /*
                    @@ -20227,11 +20234,11 @@
                    * Returns NULL if not found.
                    */
                    static dictitem_T *
                    -find_var_in_ht(ht, htname, varname, writing)
                    +find_var_in_ht(ht, htname, varname, no_autoload)
                    hashtab_T *ht;
                    int htname;
                    char_u *varname;
                    - int writing;
                    + int no_autoload;
                    {
                    hashitem_T *hi;

                    @@ -20263,7 +20270,7 @@
                    * worked find the variable again. Don't auto-load a script if it was
                    * loaded already, otherwise it would be loaded every time when
                    * checking if a function name is a Funcref variable. */
                    - if (ht == &globvarht && !writing)
                    + if (ht == &globvarht && !no_autoload)
                    {
                    /* Note: script_autoload() may make "hi" invalid. It must either
                    * be obtained again or not used. */
                    @@ -20343,7 +20350,7 @@
                    {
                    dictitem_T *v;

                    - v = find_var(name, NULL);
                    + v = find_var(name, NULL, FALSE);
                    if (v == NULL)
                    return NULL;
                    return get_tv_string(&v->di_tv);
                    @@ -21672,7 +21679,7 @@
                    */
                    if (fudi.fd_dict == NULL)
                    {
                    - v = find_var(name, &ht);
                    + v = find_var(name, &ht, FALSE);
                    if (v != NULL && v->di_tv.v_type == VAR_FUNC)
                    {
                    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
                    @@ -21830,8 +21837,9 @@
                    * Also handles a Funcref in a List or Dictionary.
                    * Returns the function name in allocated memory, or NULL for failure.
                    * flags:
                    - * TFN_INT: internal function name OK
                    - * TFN_QUIET: be quiet
                    + * TFN_INT: internal function name OK
                    + * TFN_QUIET: be quiet
                    + * TFN_NO_AUTOLOAD: do not use script autoloading
                    * Advances "pp" to just after the function name (if no error).
                    */
                    static char_u *
                    @@ -21869,7 +21877,7 @@
                    if (lead > 2)
                    start += lead;

                    - end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET,
                    + end = get_lval(start, NULL, &lv, FALSE, skip, TFN_TO_GLV(flags),
                    lead > 2 ? 0 : FNE_CHECK_START);
                    if (end == start)
                    {
                    @@ -22146,7 +22154,8 @@
                    char_u *p;
                    int n = FALSE;

                    - p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
                    + p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
                    + NULL);
                    nm = skipwhite(nm);

                    /* Only accept "funcname", "funcname ", "funcname (..." and
                    @@ -22393,10 +22402,6 @@
                    int ret = FALSE;
                    int i;

                    - /* Return quickly when autoload disabled. */
                    - if (no_autoload)
                    - return FALSE;
                    -
                    /* If there is no '#' after name[0] there is no package name. */
                    p = vim_strchr(name, AUTOLOAD_CHAR);
                    if (p == NULL || p == name)
                    diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test55.in
                    --- a/src/testdir/test55.in Mon Jan 06 15:51:55 2014 +0100
                    +++ b/src/testdir/test55.in Tue Jan 07 07:40:29 2014 +0400
                    @@ -282,6 +282,13 @@
                    : $put =ps
                    : endfor
                    :endfor
                    +:" :lockvar/islocked() triggering script autoloading
                    +:set rtp+=./sautest
                    +:lockvar g:foo#x
                    +:unlockvar g:foo#x
                    +:$put ='locked g:foo#x:'.islocked('g:foo#x')
                    +:$put ='exists g:foo#x:'.exists('g:foo#x')
                    +:$put ='g:foo#x: '.g:foo#x
                    :"
                    :" a:000 function argument
                    :" first the tests that should fail
                    diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test55.ok
                    --- a/src/testdir/test55.ok Mon Jan 06 15:51:55 2014 +0100
                    +++ b/src/testdir/test55.ok Tue Jan 07 07:40:29 2014 +0400
                    @@ -86,6 +86,9 @@
                    FFpFFpp
                    0000-000
                    ppppppp
                    +locked g:foo#x:-1
                    +exists g:foo#x:0
                    +g:foo#x: 1
                    caught a:000
                    caught a:000[0]
                    caught a:000[2]
                    diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test60.in
                    --- a/src/testdir/test60.in Mon Jan 06 15:51:55 2014 +0100
                    +++ b/src/testdir/test60.in Tue Jan 07 07:40:29 2014 +0400
                    @@ -1,4 +1,4 @@
                    -Tests for the exists() function. vim: set ft=vim :
                    +Tests for the exists() function. vim: set ft=vim ts=8 :

                    STARTTEST
                    :so small.vim
                    @@ -11,8 +11,10 @@
                    endfunction
                    :function! TestExists()
                    augroup myagroup
                    - autocmd! BufEnter *.my echo 'myfile edited'
                    + autocmd! BufEnter *.my echo "myfile edited"
                    + autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu"
                    augroup END
                    + set rtp+=./sautest

                    let test_cases = []

                    @@ -95,10 +97,15 @@
                    " Non-existing user defined function
                    let test_cases += [['*MyxyzFunc', 0]]

                    + " Function that may be created by FuncUndefined event
                    + let test_cases += [['*UndefFun', 0]]
                    + " Function that may be created by script autoloading
                    + let test_cases += [['*foo#F', 0]]
                    +
                    redir! > test.out

                    for [test_case, result] in test_cases
                    - echo test_case . ": " . result
                    + echo test_case . ": " . result
                    call RunTest(test_case, result)
                    endfor

                    @@ -207,6 +214,14 @@
                    echo "FAILED"
                    endif

                    + " Non-existing autoload variable that may be autoloaded
                    + echo 'foo#x: 0'
                    + if !exists('foo#x')
                    + echo "OK"
                    + else
                    + echo "FAILED"
                    + endif
                    +
                    " Valid local list
                    let local_list = ["blue", "orange"]
                    echo 'local_list: 1'
                    @@ -566,6 +581,10 @@

                    call TestFuncArg("arg1", "arg2")

                    + echo ' g:foo#x =' g:foo#x
                    + echo ' foo#F()' foo#F()
                    + echo 'UndefFun()' UndefFun()
                    +
                    redir END
                    endfunction
                    :call TestExists()
                    @@ -576,5 +595,6 @@
                    :set ff=unix
                    :w
                    :qa!
                    +:while getchar(1) | call getchar() | endwhile
                    ENDTEST

                    diff -r bc19475ed196 -r 7b182c0bfaf5 src/testdir/test60.ok
                    --- a/src/testdir/test60.ok Mon Jan 06 15:51:55 2014 +0100
                    +++ b/src/testdir/test60.ok Tue Jan 07 07:40:29 2014 +0400
                    @@ -71,6 +71,10 @@
                    OK
                    *MyxyzFunc: 0
                    OK
                    +*UndefFun: 0
                    +OK
                    +*foo#F: 0
                    +OK
                    :edit: 2
                    OK
                    :edit/a: 0
                    @@ -95,6 +99,8 @@
                    OK
                    local_var: 0
                    OK
                    +foo#x: 0
                    +OK
                    local_list: 1
                    OK
                    local_list[1]: 1
                    @@ -195,3 +201,6 @@
                    OK
                    a:2: 0
                    OK
                    + g:foo#x = 1
                    + foo#F() 0
                    +UndefFun() 0

                    --
                    --
                    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 vim_dev+unsubscribe@....
                    For more options, visit https://groups.google.com/groups/opt_out.
                  Your message has been successfully submitted and would be delivered to recipients shortly.