Patch 8.1.1981
Problem:    The evalfunc.c file is too big.
Solution:   Move undo functions to undo.c.  Move cmdline functions to
            ex_getln.c.  Move some container functions to list.c.
Files:      src/evalfunc.c, src/undo.c, src/proto/undo.pro, src/ex_getln.c,
            src/proto/ex_getln.pro, src/list.c, src/proto/list.pro


*** ../vim-8.1.1980/src/evalfunc.c      2019-09-04 15:54:23.912359700 +0200
--- src/evalfunc.c      2019-09-04 17:47:07.849024639 +0200
***************
*** 24,36 ****
  # include <time.h>    // for time_t
  #endif
  
- static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
- 
  #ifdef FEAT_FLOAT
  static void f_abs(typval_T *argvars, typval_T *rettv);
  static void f_acos(typval_T *argvars, typval_T *rettv);
  #endif
- static void f_add(typval_T *argvars, typval_T *rettv);
  static void f_and(typval_T *argvars, typval_T *rettv);
  static void f_append(typval_T *argvars, typval_T *rettv);
  static void f_appendbufline(typval_T *argvars, typval_T *rettv);
--- 24,33 ----
***************
*** 73,79 ****
  static void f_cos(typval_T *argvars, typval_T *rettv);
  static void f_cosh(typval_T *argvars, typval_T *rettv);
  #endif
- static void f_count(typval_T *argvars, typval_T *rettv);
  static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
  static void f_cursor(typval_T *argsvars, typval_T *rettv);
  #ifdef MSWIN
--- 70,75 ----
***************
*** 96,102 ****
  #endif
  static void f_expand(typval_T *argvars, typval_T *rettv);
  static void f_expandcmd(typval_T *argvars, typval_T *rettv);
- static void f_extend(typval_T *argvars, typval_T *rettv);
  static void f_feedkeys(typval_T *argvars, typval_T *rettv);
  #ifdef FEAT_FLOAT
  static void f_float2nr(typval_T *argvars, typval_T *rettv);
--- 92,97 ----
***************
*** 115,123 ****
  static void f_getchar(typval_T *argvars, typval_T *rettv);
  static void f_getcharmod(typval_T *argvars, typval_T *rettv);
  static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
- static void f_getcmdline(typval_T *argvars, typval_T *rettv);
- static void f_getcmdpos(typval_T *argvars, typval_T *rettv);
- static void f_getcmdtype(typval_T *argvars, typval_T *rettv);
  static void f_getcmdwintype(typval_T *argvars, typval_T *rettv);
  static void f_getenv(typval_T *argvars, typval_T *rettv);
  static void f_getfontname(typval_T *argvars, typval_T *rettv);
--- 110,115 ----
***************
*** 149,155 ****
  static void f_inputrestore(typval_T *argvars, typval_T *rettv);
  static void f_inputsave(typval_T *argvars, typval_T *rettv);
  static void f_inputsecret(typval_T *argvars, typval_T *rettv);
- static void f_insert(typval_T *argvars, typval_T *rettv);
  static void f_invert(typval_T *argvars, typval_T *rettv);
  static void f_islocked(typval_T *argvars, typval_T *rettv);
  #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
--- 141,146 ----
***************
*** 221,230 ****
  static void f_remote_read(typval_T *argvars, typval_T *rettv);
  static void f_remote_send(typval_T *argvars, typval_T *rettv);
  static void f_remote_startserver(typval_T *argvars, typval_T *rettv);
- static void f_remove(typval_T *argvars, typval_T *rettv);
  static void f_rename(typval_T *argvars, typval_T *rettv);
  static void f_repeat(typval_T *argvars, typval_T *rettv);
- static void f_reverse(typval_T *argvars, typval_T *rettv);
  #ifdef FEAT_FLOAT
  static void f_round(typval_T *argvars, typval_T *rettv);
  #endif
--- 212,219 ----
***************
*** 246,252 ****
  static void f_serverlist(typval_T *argvars, typval_T *rettv);
  static void f_setbufline(typval_T *argvars, typval_T *rettv);
  static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
- static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
  static void f_setenv(typval_T *argvars, typval_T *rettv);
  static void f_setfperm(typval_T *argvars, typval_T *rettv);
  static void f_setline(typval_T *argvars, typval_T *rettv);
--- 235,240 ----
***************
*** 320,327 ****
  static void f_trunc(typval_T *argvars, typval_T *rettv);
  #endif
  static void f_type(typval_T *argvars, typval_T *rettv);
- static void f_undofile(typval_T *argvars, typval_T *rettv);
- static void f_undotree(typval_T *argvars, typval_T *rettv);
  static void f_virtcol(typval_T *argvars, typval_T *rettv);
  static void f_visualmode(typval_T *argvars, typval_T *rettv);
  static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
--- 308,313 ----
***************
*** 1218,1261 ****
  #endif
  
  /*
-  * "add(list, item)" function
-  */
-     static void
- f_add(typval_T *argvars, typval_T *rettv)
- {
-     list_T    *l;
-     blob_T    *b;
- 
-     rettv->vval.v_number = 1; /* Default: Failed */
-     if (argvars[0].v_type == VAR_LIST)
-     {
-       if ((l = argvars[0].vval.v_list) != NULL
-               && !var_check_lock(l->lv_lock,
-                                        (char_u *)N_("add() argument"), TRUE)
-               && list_append_tv(l, &argvars[1]) == OK)
-           copy_tv(&argvars[0], rettv);
-     }
-     else if (argvars[0].v_type == VAR_BLOB)
-     {
-       if ((b = argvars[0].vval.v_blob) != NULL
-               && !var_check_lock(b->bv_lock,
-                                        (char_u *)N_("add() argument"), TRUE))
-       {
-           int         error = FALSE;
-           varnumber_T n = tv_get_number_chk(&argvars[1], &error);
- 
-           if (!error)
-           {
-               ga_append(&b->bv_ga, (int)n);
-               copy_tv(&argvars[0], rettv);
-           }
-       }
-     }
-     else
-       emsg(_(e_listblobreq));
- }
- 
- /*
   * "and(expr, expr)" function
   */
      static void
--- 1204,1209 ----
***************
*** 2149,2261 ****
  #endif
  
  /*
-  * "count()" function
-  */
-     static void
- f_count(typval_T *argvars, typval_T *rettv)
- {
-     long      n = 0;
-     int               ic = FALSE;
-     int               error = FALSE;
- 
-     if (argvars[2].v_type != VAR_UNKNOWN)
-       ic = (int)tv_get_number_chk(&argvars[2], &error);
- 
-     if (argvars[0].v_type == VAR_STRING)
-     {
-       char_u *expr = tv_get_string_chk(&argvars[1]);
-       char_u *p = argvars[0].vval.v_string;
-       char_u *next;
- 
-       if (!error && expr != NULL && *expr != NUL && p != NULL)
-       {
-           if (ic)
-           {
-               size_t len = STRLEN(expr);
- 
-               while (*p != NUL)
-               {
-                   if (MB_STRNICMP(p, expr, len) == 0)
-                   {
-                       ++n;
-                       p += len;
-                   }
-                   else
-                       MB_PTR_ADV(p);
-               }
-           }
-           else
-               while ((next = (char_u *)strstr((char *)p, (char *)expr))
-                                                                      != NULL)
-               {
-                   ++n;
-                   p = next + STRLEN(expr);
-               }
-       }
- 
-     }
-     else if (argvars[0].v_type == VAR_LIST)
-     {
-       listitem_T      *li;
-       list_T          *l;
-       long            idx;
- 
-       if ((l = argvars[0].vval.v_list) != NULL)
-       {
-           li = l->lv_first;
-           if (argvars[2].v_type != VAR_UNKNOWN)
-           {
-               if (argvars[3].v_type != VAR_UNKNOWN)
-               {
-                   idx = (long)tv_get_number_chk(&argvars[3], &error);
-                   if (!error)
-                   {
-                       li = list_find(l, idx);
-                       if (li == NULL)
-                           semsg(_(e_listidx), idx);
-                   }
-               }
-               if (error)
-                   li = NULL;
-           }
- 
-           for ( ; li != NULL; li = li->li_next)
-               if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
-                   ++n;
-       }
-     }
-     else if (argvars[0].v_type == VAR_DICT)
-     {
-       int             todo;
-       dict_T          *d;
-       hashitem_T      *hi;
- 
-       if ((d = argvars[0].vval.v_dict) != NULL)
-       {
-           if (argvars[2].v_type != VAR_UNKNOWN)
-           {
-               if (argvars[3].v_type != VAR_UNKNOWN)
-                   emsg(_(e_invarg));
-           }
- 
-           todo = error ? 0 : (int)d->dv_hashtab.ht_used;
-           for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
-           {
-               if (!HASHITEM_EMPTY(hi))
-               {
-                   --todo;
-                   if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
-                       ++n;
-               }
-           }
-       }
-     }
-     else
-       semsg(_(e_listdictarg), "count()");
-     rettv->vval.v_number = n;
- }
- 
- /*
   * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
   *
   * Checks the existence of a cscope connection.
--- 2097,2102 ----
***************
*** 3044,3135 ****
  }
  
  /*
-  * "extend(list, list [, idx])" function
-  * "extend(dict, dict [, action])" function
-  */
-     static void
- f_extend(typval_T *argvars, typval_T *rettv)
- {
-     char_u      *arg_errmsg = (char_u *)N_("extend() argument");
- 
-     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
-     {
-       list_T          *l1, *l2;
-       listitem_T      *item;
-       long            before;
-       int             error = FALSE;
- 
-       l1 = argvars[0].vval.v_list;
-       l2 = argvars[1].vval.v_list;
-       if (l1 != NULL && !var_check_lock(l1->lv_lock, arg_errmsg, TRUE)
-               && l2 != NULL)
-       {
-           if (argvars[2].v_type != VAR_UNKNOWN)
-           {
-               before = (long)tv_get_number_chk(&argvars[2], &error);
-               if (error)
-                   return;             /* type error; errmsg already given */
- 
-               if (before == l1->lv_len)
-                   item = NULL;
-               else
-               {
-                   item = list_find(l1, before);
-                   if (item == NULL)
-                   {
-                       semsg(_(e_listidx), before);
-                       return;
-                   }
-               }
-           }
-           else
-               item = NULL;
-           list_extend(l1, l2, item);
- 
-           copy_tv(&argvars[0], rettv);
-       }
-     }
-     else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
-     {
-       dict_T  *d1, *d2;
-       char_u  *action;
-       int     i;
- 
-       d1 = argvars[0].vval.v_dict;
-       d2 = argvars[1].vval.v_dict;
-       if (d1 != NULL && !var_check_lock(d1->dv_lock, arg_errmsg, TRUE)
-               && d2 != NULL)
-       {
-           /* Check the third argument. */
-           if (argvars[2].v_type != VAR_UNKNOWN)
-           {
-               static char *(av[]) = {"keep", "force", "error"};
- 
-               action = tv_get_string_chk(&argvars[2]);
-               if (action == NULL)
-                   return;             /* type error; errmsg already given */
-               for (i = 0; i < 3; ++i)
-                   if (STRCMP(action, av[i]) == 0)
-                       break;
-               if (i == 3)
-               {
-                   semsg(_(e_invarg2), action);
-                   return;
-               }
-           }
-           else
-               action = (char_u *)"force";
- 
-           dict_extend(d1, d2, action);
- 
-           copy_tv(&argvars[0], rettv);
-       }
-     }
-     else
-       semsg(_(e_listdictarg), "extend()");
- }
- 
- /*
   * "feedkeys()" function
   */
      static void
--- 2885,2890 ----
***************
*** 4059,4098 ****
  }
  
  /*
-  * "getcmdline()" function
-  */
-     static void
- f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = get_cmdline_str();
- }
- 
- /*
-  * "getcmdpos()" function
-  */
-     static void
- f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     rettv->vval.v_number = get_cmdline_pos() + 1;
- }
- 
- /*
-  * "getcmdtype()" function
-  */
-     static void
- f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     rettv->v_type = VAR_STRING;
-     rettv->vval.v_string = alloc(2);
-     if (rettv->vval.v_string != NULL)
-     {
-       rettv->vval.v_string[0] = get_cmdline_type();
-       rettv->vval.v_string[1] = NUL;
-     }
- }
- 
- /*
   * "getcmdwintype()" function
   */
      static void
--- 3814,3819 ----
***************
*** 5735,5816 ****
  }
  
  /*
-  * "insert()" function
-  */
-     static void
- f_insert(typval_T *argvars, typval_T *rettv)
- {
-     long      before = 0;
-     listitem_T        *item;
-     list_T    *l;
-     int               error = FALSE;
- 
-     if (argvars[0].v_type == VAR_BLOB)
-     {
-       int         val, len;
-       char_u      *p;
- 
-       len = blob_len(argvars[0].vval.v_blob);
-       if (argvars[2].v_type != VAR_UNKNOWN)
-       {
-           before = (long)tv_get_number_chk(&argvars[2], &error);
-           if (error)
-               return;         // type error; errmsg already given
-           if (before < 0 || before > len)
-           {
-               semsg(_(e_invarg2), tv_get_string(&argvars[2]));
-               return;
-           }
-       }
-       val = tv_get_number_chk(&argvars[1], &error);
-       if (error)
-           return;
-       if (val < 0 || val > 255)
-       {
-           semsg(_(e_invarg2), tv_get_string(&argvars[1]));
-           return;
-       }
- 
-       if (ga_grow(&argvars[0].vval.v_blob->bv_ga, 1) == FAIL)
-           return;
-       p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
-       mch_memmove(p + before + 1, p + before, (size_t)len - before);
-       *(p + before) = val;
-       ++argvars[0].vval.v_blob->bv_ga.ga_len;
- 
-       copy_tv(&argvars[0], rettv);
-     }
-     else if (argvars[0].v_type != VAR_LIST)
-       semsg(_(e_listblobarg), "insert()");
-     else if ((l = argvars[0].vval.v_list) != NULL
-           && !var_check_lock(l->lv_lock,
-                                    (char_u *)N_("insert() argument"), TRUE))
-     {
-       if (argvars[2].v_type != VAR_UNKNOWN)
-           before = (long)tv_get_number_chk(&argvars[2], &error);
-       if (error)
-           return;             /* type error; errmsg already given */
- 
-       if (before == l->lv_len)
-           item = NULL;
-       else
-       {
-           item = list_find(l, before);
-           if (item == NULL)
-           {
-               semsg(_(e_listidx), before);
-               l = NULL;
-           }
-       }
-       if (l != NULL)
-       {
-           list_insert_tv(l, &argvars[1], item);
-           copy_tv(&argvars[0], rettv);
-       }
-     }
- }
- 
- /*
   * "invert(expr)" function
   */
      static void
--- 5456,5461 ----
***************
*** 7362,7385 ****
  }
  
  /*
-  * "remove()" function
-  */
-     static void
- f_remove(typval_T *argvars, typval_T *rettv)
- {
-     char_u    *arg_errmsg = (char_u *)N_("remove() argument");
- 
-     if (argvars[0].v_type == VAR_DICT)
-       dict_remove(argvars, rettv, arg_errmsg);
-     else if (argvars[0].v_type == VAR_BLOB)
-       blob_remove(argvars, rettv);
-     else if (argvars[0].v_type == VAR_LIST)
-       list_remove(argvars, rettv, arg_errmsg);
-     else
-       semsg(_(e_listdictblobarg), "remove()");
- }
- 
- /*
   * "rename({from}, {to})" function
   */
      static void
--- 7007,7012 ----
***************
*** 7439,7489 ****
      }
  }
  
- /*
-  * "reverse({list})" function
-  */
-     static void
- f_reverse(typval_T *argvars, typval_T *rettv)
- {
-     list_T    *l;
-     listitem_T        *li, *ni;
- 
-     if (argvars[0].v_type == VAR_BLOB)
-     {
-       blob_T  *b = argvars[0].vval.v_blob;
-       int     i, len = blob_len(b);
- 
-       for (i = 0; i < len / 2; i++)
-       {
-           int tmp = blob_get(b, i);
- 
-           blob_set(b, i, blob_get(b, len - i - 1));
-           blob_set(b, len - i - 1, tmp);
-       }
-       rettv_blob_set(rettv, b);
-       return;
-     }
- 
-     if (argvars[0].v_type != VAR_LIST)
-       semsg(_(e_listblobarg), "reverse()");
-     else if ((l = argvars[0].vval.v_list) != NULL
-           && !var_check_lock(l->lv_lock,
-                                   (char_u *)N_("reverse() argument"), TRUE))
-     {
-       li = l->lv_last;
-       l->lv_first = l->lv_last = NULL;
-       l->lv_len = 0;
-       while (li != NULL)
-       {
-           ni = li->li_prev;
-           list_append(l, li);
-           li = ni;
-       }
-       rettv_list_set(rettv, l);
-       l->lv_idx = l->lv_len - l->lv_idx - 1;
-     }
- }
- 
  #define SP_NOMOVE     0x01        /* don't move cursor */
  #define SP_REPEAT     0x02        /* repeat to find outer pair */
  #define SP_RETCOUNT   0x04        /* return matchcount */
--- 7066,7071 ----
***************
*** 8287,8304 ****
  }
  
  /*
-  * "setcmdpos()" function
-  */
-     static void
- f_setcmdpos(typval_T *argvars, typval_T *rettv)
- {
-     int               pos = (int)tv_get_number(&argvars[0]) - 1;
- 
-     if (pos >= 0)
-       rettv->vval.v_number = set_cmdline_pos(pos);
- }
- 
- /*
   * "setenv()" function
   */
      static void
--- 7869,7874 ----
***************
*** 10573,10635 ****
  }
  
  /*
-  * "undofile(name)" function
-  */
-     static void
- f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     rettv->v_type = VAR_STRING;
- #ifdef FEAT_PERSISTENT_UNDO
-     {
-       char_u *fname = tv_get_string(&argvars[0]);
- 
-       if (*fname == NUL)
-       {
-           /* If there is no file name there will be no undo file. */
-           rettv->vval.v_string = NULL;
-       }
-       else
-       {
-           char_u *ffname = FullName_save(fname, TRUE);
- 
-           if (ffname != NULL)
-               rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);
-           vim_free(ffname);
-       }
-     }
- #else
-     rettv->vval.v_string = NULL;
- #endif
- }
- 
- /*
-  * "undotree()" function
-  */
-     static void
- f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
- {
-     if (rettv_dict_alloc(rettv) == OK)
-     {
-       dict_T *dict = rettv->vval.v_dict;
-       list_T *list;
- 
-       dict_add_number(dict, "synced", (long)curbuf->b_u_synced);
-       dict_add_number(dict, "seq_last", curbuf->b_u_seq_last);
-       dict_add_number(dict, "save_last", (long)curbuf->b_u_save_nr_last);
-       dict_add_number(dict, "seq_cur", curbuf->b_u_seq_cur);
-       dict_add_number(dict, "time_cur", (long)curbuf->b_u_time_cur);
-       dict_add_number(dict, "save_cur", (long)curbuf->b_u_save_nr_cur);
- 
-       list = list_alloc();
-       if (list != NULL)
-       {
-           u_eval_tree(curbuf->b_u_oldhead, list);
-           dict_add_list(dict, "entries", list);
-       }
-     }
- }
- 
- /*
   * "virtcol(string)" function
   */
      static void
--- 10143,10148 ----
*** ../vim-8.1.1980/src/undo.c  2019-08-20 20:13:40.334821916 +0200
--- src/undo.c  2019-09-04 17:19:07.185654779 +0200
***************
*** 3572,3577 ****
--- 3572,3578 ----
  }
  
  #if defined(FEAT_EVAL) || defined(PROTO)
+ 
  /*
   * For undotree(): Append the list of undo blocks at "first_uhp" to "list".
   * Recursive.
***************
*** 3612,3615 ****
--- 3613,3674 ----
        uhp = uhp->uh_prev.ptr;
      }
  }
+ 
+ /*
+  * "undofile(name)" function
+  */
+     void
+ f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+     rettv->v_type = VAR_STRING;
+ #ifdef FEAT_PERSISTENT_UNDO
+     {
+       char_u *fname = tv_get_string(&argvars[0]);
+ 
+       if (*fname == NUL)
+       {
+           /* If there is no file name there will be no undo file. */
+           rettv->vval.v_string = NULL;
+       }
+       else
+       {
+           char_u *ffname = FullName_save(fname, TRUE);
+ 
+           if (ffname != NULL)
+               rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);
+           vim_free(ffname);
+       }
+     }
+ #else
+     rettv->vval.v_string = NULL;
+ #endif
+ }
+ 
+ /*
+  * "undotree()" function
+  */
+     void
+ f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+     if (rettv_dict_alloc(rettv) == OK)
+     {
+       dict_T *dict = rettv->vval.v_dict;
+       list_T *list;
+ 
+       dict_add_number(dict, "synced", (long)curbuf->b_u_synced);
+       dict_add_number(dict, "seq_last", curbuf->b_u_seq_last);
+       dict_add_number(dict, "save_last", (long)curbuf->b_u_save_nr_last);
+       dict_add_number(dict, "seq_cur", curbuf->b_u_seq_cur);
+       dict_add_number(dict, "time_cur", (long)curbuf->b_u_time_cur);
+       dict_add_number(dict, "save_cur", (long)curbuf->b_u_save_nr_cur);
+ 
+       list = list_alloc();
+       if (list != NULL)
+       {
+           u_eval_tree(curbuf->b_u_oldhead, list);
+           dict_add_list(dict, "entries", list);
+       }
+     }
+ }
+ 
  #endif
*** ../vim-8.1.1980/src/proto/undo.pro  2019-08-20 20:13:40.334821916 +0200
--- src/proto/undo.pro  2019-09-04 17:19:10.013639800 +0200
***************
*** 28,31 ****
--- 28,33 ----
  int bufIsChangedNotTerm(buf_T *buf);
  int curbufIsChanged(void);
  void u_eval_tree(u_header_T *first_uhp, list_T *list);
+ void f_undofile(typval_T *argvars, typval_T *rettv);
+ void f_undotree(typval_T *argvars, typval_T *rettv);
  /* vim: set ft=c : */
*** ../vim-8.1.1980/src/ex_getln.c      2019-09-01 16:01:25.584754569 +0200
--- src/ex_getln.c      2019-09-04 17:28:16.446847959 +0200
***************
*** 3868,3874 ****
   * Only works when the command line is being edited.
   * Returns NULL when something is wrong.
   */
!     char_u *
  get_cmdline_str(void)
  {
      cmdline_info_T *p;
--- 3868,3874 ----
   * Only works when the command line is being edited.
   * Returns NULL when something is wrong.
   */
!     static char_u *
  get_cmdline_str(void)
  {
      cmdline_info_T *p;
***************
*** 3882,3900 ****
  }
  
  /*
!  * Get the current command line position, counted in bytes.
!  * Zero is the first position.
!  * Only works when the command line is being edited.
!  * Returns -1 when something is wrong.
   */
!     int
! get_cmdline_pos(void)
  {
      cmdline_info_T *p = get_ccline_ptr();
  
!     if (p == NULL)
!       return -1;
!     return p->cmdpos;
  }
  
  /*
--- 3882,3907 ----
  }
  
  /*
!  * "getcmdline()" function
!  */
!     void
! f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
! {
!     rettv->v_type = VAR_STRING;
!     rettv->vval.v_string = get_cmdline_str();
! }
! 
! /*
!  * "getcmdpos()" function
   */
!     void
! f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
  {
      cmdline_info_T *p = get_ccline_ptr();
  
!     rettv->vval.v_number = 0;
!     if (p != NULL)
!     rettv->vval.v_number = p->cmdpos + 1;
  }
  
  /*
***************
*** 3902,3908 ****
   * Only works when the command line is being edited.
   * Returns 1 when failed, 0 when OK.
   */
!     int
  set_cmdline_pos(
      int               pos)
  {
--- 3909,3915 ----
   * Only works when the command line is being edited.
   * Returns 1 when failed, 0 when OK.
   */
!     static int
  set_cmdline_pos(
      int               pos)
  {
***************
*** 3919,3924 ****
--- 3926,3959 ----
        new_cmdpos = pos;
      return 0;
  }
+ 
+ /*
+  * "setcmdpos()" function
+  */
+     void
+ f_setcmdpos(typval_T *argvars, typval_T *rettv)
+ {
+     int               pos = (int)tv_get_number(&argvars[0]) - 1;
+ 
+     if (pos >= 0)
+       rettv->vval.v_number = set_cmdline_pos(pos);
+ }
+ 
+ /*
+  * "getcmdtype()" function
+  */
+     void
+ f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
+ {
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = alloc(2);
+     if (rettv->vval.v_string != NULL)
+     {
+       rettv->vval.v_string[0] = get_cmdline_type();
+       rettv->vval.v_string[1] = NUL;
+     }
+ }
+ 
  #endif
  
  #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
*** ../vim-8.1.1980/src/proto/ex_getln.pro      2019-09-01 16:01:25.584754569 
+0200
--- src/proto/ex_getln.pro      2019-09-04 17:28:35.062755344 +0200
***************
*** 28,36 ****
  void escape_fname(char_u **pp);
  void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
  cmdline_info_T *get_cmdline_info(void);
! char_u *get_cmdline_str(void);
! int get_cmdline_pos(void);
! int set_cmdline_pos(int pos);
  int get_cmdline_type(void);
  int get_cmdline_firstc(void);
  int get_list_range(char_u **str, int *num1, int *num2);
--- 28,37 ----
  void escape_fname(char_u **pp);
  void tilde_replace(char_u *orig_pat, int num_files, char_u **files);
  cmdline_info_T *get_cmdline_info(void);
! void f_getcmdline(typval_T *argvars, typval_T *rettv);
! void f_getcmdpos(typval_T *argvars, typval_T *rettv);
! void f_setcmdpos(typval_T *argvars, typval_T *rettv);
! void f_getcmdtype(typval_T *argvars, typval_T *rettv);
  int get_cmdline_type(void);
  int get_cmdline_firstc(void);
  int get_list_range(char_u **str, int *num1, int *num2);
*** ../vim-8.1.1980/src/list.c  2019-09-04 14:41:11.838454277 +0200
--- src/list.c  2019-09-04 17:47:27.624980132 +0200
***************
*** 8,20 ****
   */
  
  /*
!  * list.c: List support
   */
  
  #include "vim.h"
  
  #if defined(FEAT_EVAL) || defined(PROTO)
  
  /* List heads for garbage collection. */
  static list_T         *first_list = NULL;     /* list of all lists */
  
--- 8,22 ----
   */
  
  /*
!  * list.c: List support and container (List, Dict, Blob) functions.
   */
  
  #include "vim.h"
  
  #if defined(FEAT_EVAL) || defined(PROTO)
  
+ static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
+ 
  /* List heads for garbage collection. */
  static list_T         *first_list = NULL;     /* list of all lists */
  
***************
*** 1763,1766 ****
--- 1765,2138 ----
      filter_map(argvars, rettv, TRUE);
  }
  
+ /*
+  * "add(list, item)" function
+  */
+     void
+ f_add(typval_T *argvars, typval_T *rettv)
+ {
+     list_T    *l;
+     blob_T    *b;
+ 
+     rettv->vval.v_number = 1; /* Default: Failed */
+     if (argvars[0].v_type == VAR_LIST)
+     {
+       if ((l = argvars[0].vval.v_list) != NULL
+               && !var_check_lock(l->lv_lock,
+                                        (char_u *)N_("add() argument"), TRUE)
+               && list_append_tv(l, &argvars[1]) == OK)
+           copy_tv(&argvars[0], rettv);
+     }
+     else if (argvars[0].v_type == VAR_BLOB)
+     {
+       if ((b = argvars[0].vval.v_blob) != NULL
+               && !var_check_lock(b->bv_lock,
+                                        (char_u *)N_("add() argument"), TRUE))
+       {
+           int         error = FALSE;
+           varnumber_T n = tv_get_number_chk(&argvars[1], &error);
+ 
+           if (!error)
+           {
+               ga_append(&b->bv_ga, (int)n);
+               copy_tv(&argvars[0], rettv);
+           }
+       }
+     }
+     else
+       emsg(_(e_listblobreq));
+ }
+ 
+ /*
+  * "count()" function
+  */
+     void
+ f_count(typval_T *argvars, typval_T *rettv)
+ {
+     long      n = 0;
+     int               ic = FALSE;
+     int               error = FALSE;
+ 
+     if (argvars[2].v_type != VAR_UNKNOWN)
+       ic = (int)tv_get_number_chk(&argvars[2], &error);
+ 
+     if (argvars[0].v_type == VAR_STRING)
+     {
+       char_u *expr = tv_get_string_chk(&argvars[1]);
+       char_u *p = argvars[0].vval.v_string;
+       char_u *next;
+ 
+       if (!error && expr != NULL && *expr != NUL && p != NULL)
+       {
+           if (ic)
+           {
+               size_t len = STRLEN(expr);
+ 
+               while (*p != NUL)
+               {
+                   if (MB_STRNICMP(p, expr, len) == 0)
+                   {
+                       ++n;
+                       p += len;
+                   }
+                   else
+                       MB_PTR_ADV(p);
+               }
+           }
+           else
+               while ((next = (char_u *)strstr((char *)p, (char *)expr))
+                                                                      != NULL)
+               {
+                   ++n;
+                   p = next + STRLEN(expr);
+               }
+       }
+ 
+     }
+     else if (argvars[0].v_type == VAR_LIST)
+     {
+       listitem_T      *li;
+       list_T          *l;
+       long            idx;
+ 
+       if ((l = argvars[0].vval.v_list) != NULL)
+       {
+           li = l->lv_first;
+           if (argvars[2].v_type != VAR_UNKNOWN)
+           {
+               if (argvars[3].v_type != VAR_UNKNOWN)
+               {
+                   idx = (long)tv_get_number_chk(&argvars[3], &error);
+                   if (!error)
+                   {
+                       li = list_find(l, idx);
+                       if (li == NULL)
+                           semsg(_(e_listidx), idx);
+                   }
+               }
+               if (error)
+                   li = NULL;
+           }
+ 
+           for ( ; li != NULL; li = li->li_next)
+               if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
+                   ++n;
+       }
+     }
+     else if (argvars[0].v_type == VAR_DICT)
+     {
+       int             todo;
+       dict_T          *d;
+       hashitem_T      *hi;
+ 
+       if ((d = argvars[0].vval.v_dict) != NULL)
+       {
+           if (argvars[2].v_type != VAR_UNKNOWN)
+           {
+               if (argvars[3].v_type != VAR_UNKNOWN)
+                   emsg(_(e_invarg));
+           }
+ 
+           todo = error ? 0 : (int)d->dv_hashtab.ht_used;
+           for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
+           {
+               if (!HASHITEM_EMPTY(hi))
+               {
+                   --todo;
+                   if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
+                       ++n;
+               }
+           }
+       }
+     }
+     else
+       semsg(_(e_listdictarg), "count()");
+     rettv->vval.v_number = n;
+ }
+ 
+ /*
+  * "extend(list, list [, idx])" function
+  * "extend(dict, dict [, action])" function
+  */
+     void
+ f_extend(typval_T *argvars, typval_T *rettv)
+ {
+     char_u      *arg_errmsg = (char_u *)N_("extend() argument");
+ 
+     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
+     {
+       list_T          *l1, *l2;
+       listitem_T      *item;
+       long            before;
+       int             error = FALSE;
+ 
+       l1 = argvars[0].vval.v_list;
+       l2 = argvars[1].vval.v_list;
+       if (l1 != NULL && !var_check_lock(l1->lv_lock, arg_errmsg, TRUE)
+               && l2 != NULL)
+       {
+           if (argvars[2].v_type != VAR_UNKNOWN)
+           {
+               before = (long)tv_get_number_chk(&argvars[2], &error);
+               if (error)
+                   return;             /* type error; errmsg already given */
+ 
+               if (before == l1->lv_len)
+                   item = NULL;
+               else
+               {
+                   item = list_find(l1, before);
+                   if (item == NULL)
+                   {
+                       semsg(_(e_listidx), before);
+                       return;
+                   }
+               }
+           }
+           else
+               item = NULL;
+           list_extend(l1, l2, item);
+ 
+           copy_tv(&argvars[0], rettv);
+       }
+     }
+     else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
+     {
+       dict_T  *d1, *d2;
+       char_u  *action;
+       int     i;
+ 
+       d1 = argvars[0].vval.v_dict;
+       d2 = argvars[1].vval.v_dict;
+       if (d1 != NULL && !var_check_lock(d1->dv_lock, arg_errmsg, TRUE)
+               && d2 != NULL)
+       {
+           /* Check the third argument. */
+           if (argvars[2].v_type != VAR_UNKNOWN)
+           {
+               static char *(av[]) = {"keep", "force", "error"};
+ 
+               action = tv_get_string_chk(&argvars[2]);
+               if (action == NULL)
+                   return;             /* type error; errmsg already given */
+               for (i = 0; i < 3; ++i)
+                   if (STRCMP(action, av[i]) == 0)
+                       break;
+               if (i == 3)
+               {
+                   semsg(_(e_invarg2), action);
+                   return;
+               }
+           }
+           else
+               action = (char_u *)"force";
+ 
+           dict_extend(d1, d2, action);
+ 
+           copy_tv(&argvars[0], rettv);
+       }
+     }
+     else
+       semsg(_(e_listdictarg), "extend()");
+ }
+ 
+ /*
+  * "insert()" function
+  */
+     void
+ f_insert(typval_T *argvars, typval_T *rettv)
+ {
+     long      before = 0;
+     listitem_T        *item;
+     list_T    *l;
+     int               error = FALSE;
+ 
+     if (argvars[0].v_type == VAR_BLOB)
+     {
+       int         val, len;
+       char_u      *p;
+ 
+       len = blob_len(argvars[0].vval.v_blob);
+       if (argvars[2].v_type != VAR_UNKNOWN)
+       {
+           before = (long)tv_get_number_chk(&argvars[2], &error);
+           if (error)
+               return;         // type error; errmsg already given
+           if (before < 0 || before > len)
+           {
+               semsg(_(e_invarg2), tv_get_string(&argvars[2]));
+               return;
+           }
+       }
+       val = tv_get_number_chk(&argvars[1], &error);
+       if (error)
+           return;
+       if (val < 0 || val > 255)
+       {
+           semsg(_(e_invarg2), tv_get_string(&argvars[1]));
+           return;
+       }
+ 
+       if (ga_grow(&argvars[0].vval.v_blob->bv_ga, 1) == FAIL)
+           return;
+       p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
+       mch_memmove(p + before + 1, p + before, (size_t)len - before);
+       *(p + before) = val;
+       ++argvars[0].vval.v_blob->bv_ga.ga_len;
+ 
+       copy_tv(&argvars[0], rettv);
+     }
+     else if (argvars[0].v_type != VAR_LIST)
+       semsg(_(e_listblobarg), "insert()");
+     else if ((l = argvars[0].vval.v_list) != NULL
+           && !var_check_lock(l->lv_lock,
+                                    (char_u *)N_("insert() argument"), TRUE))
+     {
+       if (argvars[2].v_type != VAR_UNKNOWN)
+           before = (long)tv_get_number_chk(&argvars[2], &error);
+       if (error)
+           return;             /* type error; errmsg already given */
+ 
+       if (before == l->lv_len)
+           item = NULL;
+       else
+       {
+           item = list_find(l, before);
+           if (item == NULL)
+           {
+               semsg(_(e_listidx), before);
+               l = NULL;
+           }
+       }
+       if (l != NULL)
+       {
+           list_insert_tv(l, &argvars[1], item);
+           copy_tv(&argvars[0], rettv);
+       }
+     }
+ }
+ 
+ /*
+  * "remove()" function
+  */
+     void
+ f_remove(typval_T *argvars, typval_T *rettv)
+ {
+     char_u    *arg_errmsg = (char_u *)N_("remove() argument");
+ 
+     if (argvars[0].v_type == VAR_DICT)
+       dict_remove(argvars, rettv, arg_errmsg);
+     else if (argvars[0].v_type == VAR_BLOB)
+       blob_remove(argvars, rettv);
+     else if (argvars[0].v_type == VAR_LIST)
+       list_remove(argvars, rettv, arg_errmsg);
+     else
+       semsg(_(e_listdictblobarg), "remove()");
+ }
+ 
+ /*
+  * "reverse({list})" function
+  */
+     void
+ f_reverse(typval_T *argvars, typval_T *rettv)
+ {
+     list_T    *l;
+     listitem_T        *li, *ni;
+ 
+     if (argvars[0].v_type == VAR_BLOB)
+     {
+       blob_T  *b = argvars[0].vval.v_blob;
+       int     i, len = blob_len(b);
+ 
+       for (i = 0; i < len / 2; i++)
+       {
+           int tmp = blob_get(b, i);
+ 
+           blob_set(b, i, blob_get(b, len - i - 1));
+           blob_set(b, len - i - 1, tmp);
+       }
+       rettv_blob_set(rettv, b);
+       return;
+     }
+ 
+     if (argvars[0].v_type != VAR_LIST)
+       semsg(_(e_listblobarg), "reverse()");
+     else if ((l = argvars[0].vval.v_list) != NULL
+           && !var_check_lock(l->lv_lock,
+                                   (char_u *)N_("reverse() argument"), TRUE))
+     {
+       li = l->lv_last;
+       l->lv_first = l->lv_last = NULL;
+       l->lv_len = 0;
+       while (li != NULL)
+       {
+           ni = li->li_prev;
+           list_append(l, li);
+           li = ni;
+       }
+       rettv_list_set(rettv, l);
+       l->lv_idx = l->lv_len - l->lv_idx - 1;
+     }
+ }
+ 
  #endif // defined(FEAT_EVAL)
*** ../vim-8.1.1980/src/proto/list.pro  2019-09-04 14:41:11.838454277 +0200
--- src/proto/list.pro  2019-09-04 17:46:07.533153800 +0200
***************
*** 43,46 ****
--- 43,52 ----
  void f_uniq(typval_T *argvars, typval_T *rettv);
  void f_filter(typval_T *argvars, typval_T *rettv);
  void f_map(typval_T *argvars, typval_T *rettv);
+ void f_add(typval_T *argvars, typval_T *rettv);
+ void f_count(typval_T *argvars, typval_T *rettv);
+ void f_extend(typval_T *argvars, typval_T *rettv);
+ void f_insert(typval_T *argvars, typval_T *rettv);
+ void f_remove(typval_T *argvars, typval_T *rettv);
+ void f_reverse(typval_T *argvars, typval_T *rettv);
  /* vim: set ft=c : */
*** ../vim-8.1.1980/src/version.c       2019-09-04 16:32:19.748321815 +0200
--- src/version.c       2019-09-04 17:18:57.933703831 +0200
***************
*** 759,760 ****
--- 759,762 ----
  {   /* Add new patch number below this line */
+ /**/
+     1981,
  /**/

-- 
Wizards had always known that the act of observation changed the thing that
was observed, and sometimes forgot that it also changed the observer too.
                        Terry Pratchett  -  Interesting times

 /// 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/201909041548.x84FmedW018482%40masaka.moolenaar.net.

Raspunde prin e-mail lui