Patch 8.2.3320
Problem:    Some local functions are not static.
Solution:   Add "static".  Move snprintf() related code to strings.c.
            (Yegappan Lakshmanan, closes #8734)
Files:      src/alloc.c, src/channel.c, src/dict.c, src/digraph.c, src/edit.c,
            src/ex_docmd.c, src/getchar.c, src/job.c, src/list.c,
            src/message.c, src/profiler.c, src/proto/channel.pro,
            src/proto/dict.pro, src/proto/digraph.pro, src/proto/edit.pro,
            src/proto/ex_docmd.pro, src/proto/getchar.pro, src/proto/job.pro,
            src/proto/list.pro, src/proto/profiler.pro, src/proto/spell.pro,
            src/proto/vim9compile.pro, src/proto/vim9script.pro,
            src/proto/vim9type.pro, src/spell.c, src/strings.c,
            src/vim9compile.c, src/vim9script.c, src/vim9type.c, src/window.c


*** ../vim-8.2.3319/src/alloc.c 2021-08-06 21:51:33.892689095 +0200
--- src/alloc.c 2021-08-09 19:56:02.947236101 +0200
***************
*** 232,250 ****
      mem_pre_alloc_l(&size);
  #endif
  
!     /*
!      * Loop when out of memory: Try to release some memfile blocks and
!      * if some blocks are released call malloc again.
!      */
      for (;;)
      {
!       /*
!        * Handle three kind of systems:
!        * 1. No check for available memory: Just return.
!        * 2. Slow check for available memory: call mch_avail_mem() after
!        *    allocating KEEP_ROOM amount of memory.
!        * 3. Strict check for available memory: call mch_avail_mem()
!        */
        if ((p = malloc(size)) != NULL)
        {
  #ifndef HAVE_AVAIL_MEM
--- 232,246 ----
      mem_pre_alloc_l(&size);
  #endif
  
!     // Loop when out of memory: Try to release some memfile blocks and
!     // if some blocks are released call malloc again.
      for (;;)
      {
!       // Handle three kind of systems:
!       // 1. No check for available memory: Just return.
!       // 2. Slow check for available memory: call mch_avail_mem() after
!       //    allocating KEEP_ROOM amount of memory.
!       // 3. Strict check for available memory: call mch_avail_mem()
        if ((p = malloc(size)) != NULL)
        {
  #ifndef HAVE_AVAIL_MEM
***************
*** 268,277 ****
                goto theend;
  #endif
        }
!       /*
!        * Remember that mf_release_all() is being called to avoid an endless
!        * loop, because mf_release_all() may call alloc() recursively.
!        */
        if (releasing)
            break;
        releasing = TRUE;
--- 264,271 ----
                goto theend;
  #endif
        }
!       // Remember that mf_release_all() is being called to avoid an endless
!       // loop, because mf_release_all() may call alloc() recursively.
        if (releasing)
            break;
        releasing = TRUE;
*** ../vim-8.2.3319/src/channel.c       2021-08-02 18:07:15.186473836 +0200
--- src/channel.c       2021-08-09 19:56:02.947236101 +0200
***************
*** 3025,3031 ****
   * Return a string indicating the status of the channel.
   * If "req_part" is not negative check that part.
   */
!     char *
  channel_status(channel_T *channel, int req_part)
  {
      ch_part_T part;
--- 3025,3031 ----
   * Return a string indicating the status of the channel.
   * If "req_part" is not negative check that part.
   */
!     static char *
  channel_status(channel_T *channel, int req_part)
  {
      ch_part_T part;
*** ../vim-8.2.3319/src/dict.c  2021-07-27 22:00:39.737712414 +0200
--- src/dict.c  2021-08-09 19:56:02.947236101 +0200
***************
*** 805,811 ****
   * Advance over a literal key, including "-".  If the first character is not a
   * literal key character then "key" is returned.
   */
!     char_u *
  skip_literal_key(char_u *key)
  {
      char_u *p;
--- 805,811 ----
   * Advance over a literal key, including "-".  If the first character is not a
   * literal key character then "key" is returned.
   */
!     static char_u *
  skip_literal_key(char_u *key)
  {
      char_u *p;
*** ../vim-8.2.3319/src/digraph.c       2021-07-27 22:00:39.741712405 +0200
--- src/digraph.c       2021-08-09 19:56:02.947236101 +0200
***************
*** 2029,2035 ****
   * If they are valid, returns TRUE; otherwise, give an error message and
   * returns FALSE.
   */
!     int
  check_digraph_chars_valid(int char1, int char2)
  {
      if (char2 == 0)
--- 2029,2035 ----
   * If they are valid, returns TRUE; otherwise, give an error message and
   * returns FALSE.
   */
!     static int
  check_digraph_chars_valid(int char1, int char2)
  {
      if (char2 == 0)
***************
*** 2193,2199 ****
      li2->li_tv.vval.v_string = vim_strsave(buf);
  }
  
!     void
  digraph_getlist_common(int list_all, typval_T *rettv)
  {
      int               i;
--- 2193,2199 ----
      li2->li_tv.vval.v_string = vim_strsave(buf);
  }
  
!     static void
  digraph_getlist_common(int list_all, typval_T *rettv)
  {
      int               i;
*** ../vim-8.2.3319/src/edit.c  2021-07-26 22:19:05.376122583 +0200
--- src/edit.c  2021-08-09 19:56:02.947236101 +0200
***************
*** 1587,1593 ****
   * Note that this doesn't wait for characters, they must be in the typeahead
   * buffer already.
   */
!     int
  decodeModifyOtherKeys(int c)
  {
      char_u  *p = typebuf.tb_buf + typebuf.tb_off;
--- 1587,1593 ----
   * Note that this doesn't wait for characters, they must be in the typeahead
   * buffer already.
   */
!     static int
  decodeModifyOtherKeys(int c)
  {
      char_u  *p = typebuf.tb_buf + typebuf.tb_off;
*** ../vim-8.2.3319/src/ex_docmd.c      2021-08-05 21:17:28.755789462 +0200
--- src/ex_docmd.c      2021-08-09 19:56:02.947236101 +0200
***************
*** 598,604 ****
   * Execute the "+cmd" argument of "edit +cmd fname" and the like.
   * This allows for using a range without ":" in Vim9 script.
   */
!     int
  do_cmd_argument(char_u *cmd)
  {
      return do_cmdline(cmd, NULL, NULL,
--- 598,604 ----
   * Execute the "+cmd" argument of "edit +cmd fname" and the like.
   * This allows for using a range without ":" in Vim9 script.
   */
!     static int
  do_cmd_argument(char_u *cmd)
  {
      return do_cmdline(cmd, NULL, NULL,
*** ../vim-8.2.3319/src/getchar.c       2021-07-27 22:00:39.745712396 +0200
--- src/getchar.c       2021-08-09 19:56:02.951236093 +0200
***************
*** 631,637 ****
      add_buff(&readbuf2, s, -1L);
  }
  
!     void
  stuffReadbuffLen(char_u *s, long len)
  {
      add_buff(&readbuf1, s, len);
--- 631,637 ----
      add_buff(&readbuf2, s, -1L);
  }
  
!     static void
  stuffReadbuffLen(char_u *s, long len)
  {
      add_buff(&readbuf1, s, len);
*** ../vim-8.2.3319/src/job.c   2021-07-27 22:00:39.745712396 +0200
--- src/job.c   2021-08-09 19:56:02.951236093 +0200
***************
*** 1582,1588 ****
  /*
   * Return the effective prompt for the specified buffer.
   */
!     char_u *
  buf_prompt_text(buf_T* buf)
  {
      if (buf->b_prompt_text == NULL)
--- 1582,1588 ----
  /*
   * Return the effective prompt for the specified buffer.
   */
!     static char_u *
  buf_prompt_text(buf_T* buf)
  {
      if (buf->b_prompt_text == NULL)
*** ../vim-8.2.3319/src/list.c  2021-08-04 19:25:50.614808524 +0200
--- src/list.c  2021-08-09 19:56:02.951236093 +0200
***************
*** 620,626 ****
   * As list_append_tv() but move the value instead of copying it.
   * Return FAIL when out of memory.
   */
!     int
  list_append_tv_move(list_T *l, typval_T *tv)
  {
      listitem_T        *li = listitem_alloc();
--- 620,626 ----
   * As list_append_tv() but move the value instead of copying it.
   * Return FAIL when out of memory.
   */
!     static int
  list_append_tv_move(list_T *l, typval_T *tv)
  {
      listitem_T        *li = listitem_alloc();
*** ../vim-8.2.3319/src/message.c       2021-07-11 19:12:00.045760328 +0200
--- src/message.c       2021-08-09 19:56:02.951236093 +0200
***************
*** 12,18 ****
   */
  
  #define MESSAGE_FILE          // don't include prototype for smsg()
- #define USING_FLOAT_STUFF
  
  #include "vim.h"
  
--- 12,17 ----
***************
*** 4108,5219 ****
  }
  
  #endif // FEAT_GUI_DIALOG || FEAT_CON_DIALOG
- 
- #if defined(FEAT_EVAL)
- static char *e_printf = N_("E766: Insufficient arguments for printf()");
- 
- /*
-  * Get number argument from "idxp" entry in "tvs".  First entry is 1.
-  */
-     static varnumber_T
- tv_nr(typval_T *tvs, int *idxp)
- {
-     int               idx = *idxp - 1;
-     varnumber_T       n = 0;
-     int               err = FALSE;
- 
-     if (tvs[idx].v_type == VAR_UNKNOWN)
-       emsg(_(e_printf));
-     else
-     {
-       ++*idxp;
-       n = tv_get_number_chk(&tvs[idx], &err);
-       if (err)
-           n = 0;
-     }
-     return n;
- }
- 
- /*
-  * Get string argument from "idxp" entry in "tvs".  First entry is 1.
-  * If "tofree" is NULL tv_get_string_chk() is used.  Some types (e.g. List)
-  * are not converted to a string.
-  * If "tofree" is not NULL echo_string() is used.  All types are converted to
-  * a string with the same format as ":echo".  The caller must free "*tofree".
-  * Returns NULL for an error.
-  */
-     static char *
- tv_str(typval_T *tvs, int *idxp, char_u **tofree)
- {
-     int                   idx = *idxp - 1;
-     char          *s = NULL;
-     static char_u   numbuf[NUMBUFLEN];
- 
-     if (tvs[idx].v_type == VAR_UNKNOWN)
-       emsg(_(e_printf));
-     else
-     {
-       ++*idxp;
-       if (tofree != NULL)
-           s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID());
-       else
-           s = (char *)tv_get_string_chk(&tvs[idx]);
-     }
-     return s;
- }
- 
- # ifdef FEAT_FLOAT
- /*
-  * Get float argument from "idxp" entry in "tvs".  First entry is 1.
-  */
-     static double
- tv_float(typval_T *tvs, int *idxp)
- {
-     int               idx = *idxp - 1;
-     double    f = 0;
- 
-     if (tvs[idx].v_type == VAR_UNKNOWN)
-       emsg(_(e_printf));
-     else
-     {
-       ++*idxp;
-       if (tvs[idx].v_type == VAR_FLOAT)
-           f = tvs[idx].vval.v_float;
-       else if (tvs[idx].v_type == VAR_NUMBER)
-           f = (double)tvs[idx].vval.v_number;
-       else
-           emsg(_("E807: Expected Float argument for printf()"));
-     }
-     return f;
- }
- # endif
- #endif
- 
- #ifdef FEAT_FLOAT
- /*
-  * Return the representation of infinity for printf() function:
-  * "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF".
-  */
-     static const char *
- infinity_str(int positive,
-            char fmt_spec,
-            int force_sign,
-            int space_for_positive)
- {
-     static const char *table[] =
-     {
-       "-inf", "inf", "+inf", " inf",
-       "-INF", "INF", "+INF", " INF"
-     };
-     int idx = positive * (1 + force_sign + force_sign * space_for_positive);
- 
-     if (ASCII_ISUPPER(fmt_spec))
-       idx += 4;
-     return table[idx];
- }
- #endif
- 
- /*
-  * This code was included to provide a portable vsnprintf() and snprintf().
-  * Some systems may provide their own, but we always use this one for
-  * consistency.
-  *
-  * This code is based on snprintf.c - a portable implementation of snprintf
-  * by Mark Martinec <[email protected]>, Version 2.2, 2000-10-06.
-  * Included with permission.  It was heavily modified to fit in Vim.
-  * The original code, including useful comments, can be found here:
-  *    http://www.ijs.si/software/snprintf/
-  *
-  * This snprintf() only supports the following conversion specifiers:
-  * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)
-  * with flags: '-', '+', ' ', '0' and '#'.
-  * An asterisk is supported for field width as well as precision.
-  *
-  * Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'.
-  *
-  * Length modifiers 'h' (short int) and 'l' (long int) and 'll' (long long 
int)
-  * are supported.  NOTE: for 'll' the argument is varnumber_T or uvarnumber_T.
-  *
-  * The locale is not used, the string is used as a byte string.  This is only
-  * relevant for double-byte encodings where the second byte may be '%'.
-  *
-  * It is permitted for "str_m" to be zero, and it is permitted to specify NULL
-  * pointer for resulting string argument if "str_m" is zero (as per ISO C99).
-  *
-  * The return value is the number of characters which would be generated
-  * for the given input, excluding the trailing NUL. If this value
-  * is greater or equal to "str_m", not all characters from the result
-  * have been stored in str, output bytes beyond the ("str_m"-1) -th character
-  * are discarded. If "str_m" is greater than zero it is guaranteed
-  * the resulting string will be NUL-terminated.
-  */
- 
- /*
-  * When va_list is not supported we only define vim_snprintf().
-  *
-  * vim_vsnprintf_typval() can be invoked with either "va_list" or a list of
-  * "typval_T".  When the latter is not used it must be NULL.
-  */
- 
- // When generating prototypes all of this is skipped, cproto doesn't
- // understand this.
- #ifndef PROTO
- 
- // Like vim_vsnprintf() but append to the string.
-     int
- vim_snprintf_add(char *str, size_t str_m, const char *fmt, ...)
- {
-     va_list   ap;
-     int               str_l;
-     size_t    len = STRLEN(str);
-     size_t    space;
- 
-     if (str_m <= len)
-       space = 0;
-     else
-       space = str_m - len;
-     va_start(ap, fmt);
-     str_l = vim_vsnprintf(str + len, space, fmt, ap);
-     va_end(ap);
-     return str_l;
- }
- 
-     int
- vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
- {
-     va_list   ap;
-     int               str_l;
- 
-     va_start(ap, fmt);
-     str_l = vim_vsnprintf(str, str_m, fmt, ap);
-     va_end(ap);
-     return str_l;
- }
- 
-     int
- vim_vsnprintf(
-     char      *str,
-     size_t    str_m,
-     const char        *fmt,
-     va_list   ap)
- {
-     return vim_vsnprintf_typval(str, str_m, fmt, ap, NULL);
- }
- 
-     int
- vim_vsnprintf_typval(
-     char      *str,
-     size_t    str_m,
-     const char        *fmt,
-     va_list   ap,
-     typval_T  *tvs)
- {
-     size_t    str_l = 0;
-     const char        *p = fmt;
-     int               arg_idx = 1;
- 
-     if (p == NULL)
-       p = "";
-     while (*p != NUL)
-     {
-       if (*p != '%')
-       {
-           char    *q = strchr(p + 1, '%');
-           size_t  n = (q == NULL) ? STRLEN(p) : (size_t)(q - p);
- 
-           // Copy up to the next '%' or NUL without any changes.
-           if (str_l < str_m)
-           {
-               size_t avail = str_m - str_l;
- 
-               mch_memmove(str + str_l, p, n > avail ? avail : n);
-           }
-           p += n;
-           str_l += n;
-       }
-       else
-       {
-           size_t  min_field_width = 0, precision = 0;
-           int     zero_padding = 0, precision_specified = 0, justify_left = 0;
-           int     alternate_form = 0, force_sign = 0;
- 
-           // If both the ' ' and '+' flags appear, the ' ' flag should be
-           // ignored.
-           int     space_for_positive = 1;
- 
-           // allowed values: \0, h, l, L
-           char    length_modifier = '\0';
- 
-           // temporary buffer for simple numeric->string conversion
- # if defined(FEAT_FLOAT)
- #  define TMP_LEN 350 // On my system 1e308 is the biggest number possible.
-                       // That sounds reasonable to use as the maximum
-                       // printable.
- # else
- #  define TMP_LEN 66
- # endif
-           char    tmp[TMP_LEN];
- 
-           // string address in case of string argument
-           const char  *str_arg = NULL;
- 
-           // natural field width of arg without padding and sign
-           size_t  str_arg_l;
- 
-           // unsigned char argument value - only defined for c conversion.
-           // N.B. standard explicitly states the char argument for the c
-           // conversion is unsigned
-           unsigned char uchar_arg;
- 
-           // number of zeros to be inserted for numeric conversions as
-           // required by the precision or minimal field width
-           size_t  number_of_zeros_to_pad = 0;
- 
-           // index into tmp where zero padding is to be inserted
-           size_t  zero_padding_insertion_ind = 0;
- 
-           // current conversion specifier character
-           char    fmt_spec = '\0';
- 
-           // buffer for 's' and 'S' specs
-           char_u  *tofree = NULL;
- 
- 
-           p++;  // skip '%'
- 
-           // parse flags
-           while (*p == '0' || *p == '-' || *p == '+' || *p == ' '
-                                                  || *p == '#' || *p == '\'')
-           {
-               switch (*p)
-               {
-                   case '0': zero_padding = 1; break;
-                   case '-': justify_left = 1; break;
-                   case '+': force_sign = 1; space_for_positive = 0; break;
-                   case ' ': force_sign = 1;
-                             // If both the ' ' and '+' flags appear, the ' '
-                             // flag should be ignored
-                             break;
-                   case '#': alternate_form = 1; break;
-                   case '\'': break;
-               }
-               p++;
-           }
-           // If the '0' and '-' flags both appear, the '0' flag should be
-           // ignored.
- 
-           // parse field width
-           if (*p == '*')
-           {
-               int j;
- 
-               p++;
-               j =
- # if defined(FEAT_EVAL)
-                   tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                       va_arg(ap, int);
-               if (j >= 0)
-                   min_field_width = j;
-               else
-               {
-                   min_field_width = -j;
-                   justify_left = 1;
-               }
-           }
-           else if (VIM_ISDIGIT((int)(*p)))
-           {
-               // size_t could be wider than unsigned int; make sure we treat
-               // argument like common implementations do
-               unsigned int uj = *p++ - '0';
- 
-               while (VIM_ISDIGIT((int)(*p)))
-                   uj = 10 * uj + (unsigned int)(*p++ - '0');
-               min_field_width = uj;
-           }
- 
-           // parse precision
-           if (*p == '.')
-           {
-               p++;
-               precision_specified = 1;
-               if (*p == '*')
-               {
-                   int j;
- 
-                   j =
- # if defined(FEAT_EVAL)
-                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                           va_arg(ap, int);
-                   p++;
-                   if (j >= 0)
-                       precision = j;
-                   else
-                   {
-                       precision_specified = 0;
-                       precision = 0;
-                   }
-               }
-               else if (VIM_ISDIGIT((int)(*p)))
-               {
-                   // size_t could be wider than unsigned int; make sure we
-                   // treat argument like common implementations do
-                   unsigned int uj = *p++ - '0';
- 
-                   while (VIM_ISDIGIT((int)(*p)))
-                       uj = 10 * uj + (unsigned int)(*p++ - '0');
-                   precision = uj;
-               }
-           }
- 
-           // parse 'h', 'l' and 'll' length modifiers
-           if (*p == 'h' || *p == 'l')
-           {
-               length_modifier = *p;
-               p++;
-               if (length_modifier == 'l' && *p == 'l')
-               {
-                   // double l = __int64 / varnumber_T
-                   length_modifier = 'L';
-                   p++;
-               }
-           }
-           fmt_spec = *p;
- 
-           // common synonyms:
-           switch (fmt_spec)
-           {
-               case 'i': fmt_spec = 'd'; break;
-               case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
-               case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
-               case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
-               default: break;
-           }
- 
- # if defined(FEAT_EVAL)
-           switch (fmt_spec)
-           {
-               case 'd': case 'u': case 'o': case 'x': case 'X':
-                   if (tvs != NULL && length_modifier == '\0')
-                       length_modifier = 'L';
-           }
- # endif
- 
-           // get parameter value, do initial processing
-           switch (fmt_spec)
-           {
-               // '%' and 'c' behave similar to 's' regarding flags and field
-               // widths
-           case '%':
-           case 'c':
-           case 's':
-           case 'S':
-               str_arg_l = 1;
-               switch (fmt_spec)
-               {
-               case '%':
-                   str_arg = p;
-                   break;
- 
-               case 'c':
-                   {
-                       int j;
- 
-                       j =
- # if defined(FEAT_EVAL)
-                           tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                               va_arg(ap, int);
-                       // standard demands unsigned char
-                       uchar_arg = (unsigned char)j;
-                       str_arg = (char *)&uchar_arg;
-                       break;
-                   }
- 
-               case 's':
-               case 'S':
-                   str_arg =
- # if defined(FEAT_EVAL)
-                               tvs != NULL ? tv_str(tvs, &arg_idx, &tofree) :
- # endif
-                                   va_arg(ap, char *);
-                   if (str_arg == NULL)
-                   {
-                       str_arg = "[NULL]";
-                       str_arg_l = 6;
-                   }
-                   // make sure not to address string beyond the specified
-                   // precision !!!
-                   else if (!precision_specified)
-                       str_arg_l = strlen(str_arg);
-                   // truncate string if necessary as requested by precision
-                   else if (precision == 0)
-                       str_arg_l = 0;
-                   else
-                   {
-                       // Don't put the #if inside memchr(), it can be a
-                       // macro.
-                       // memchr on HP does not like n > 2^31  !!!
-                       char *q = memchr(str_arg, '\0',
-                                 precision <= (size_t)0x7fffffffL ? precision
-                                                      : (size_t)0x7fffffffL);
-                       str_arg_l = (q == NULL) ? precision
-                                                     : (size_t)(q - str_arg);
-                   }
-                   if (fmt_spec == 'S')
-                   {
-                       if (min_field_width != 0)
-                           min_field_width += STRLEN(str_arg)
-                                    - mb_string2cells((char_u *)str_arg, -1);
-                       if (precision)
-                       {
-                           char_u  *p1;
-                           size_t  i = 0;
- 
-                           for (p1 = (char_u *)str_arg; *p1;
-                                                         p1 += mb_ptr2len(p1))
-                           {
-                               i += (size_t)mb_ptr2cells(p1);
-                               if (i > precision)
-                                   break;
-                           }
-                           str_arg_l = precision = p1 - (char_u *)str_arg;
-                       }
-                   }
-                   break;
- 
-               default:
-                   break;
-               }
-               break;
- 
-           case 'd': case 'u':
-           case 'b': case 'B':
-           case 'o':
-           case 'x': case 'X':
-           case 'p':
-               {
-                   // NOTE: the u, b, o, x, X and p conversion specifiers
-                   // imply the value is unsigned;  d implies a signed
-                   // value
- 
-                   // 0 if numeric argument is zero (or if pointer is
-                   // NULL for 'p'), +1 if greater than zero (or nonzero
-                   // for unsigned arguments), -1 if negative (unsigned
-                   // argument is never negative)
-                   int arg_sign = 0;
- 
-                   // only set for length modifier h, or for no length
-                   // modifiers
-                   int int_arg = 0;
-                   unsigned int uint_arg = 0;
- 
-                   // only set for length modifier l
-                   long int long_arg = 0;
-                   unsigned long int ulong_arg = 0;
- 
-                   // only set for length modifier ll
-                   varnumber_T llong_arg = 0;
-                   uvarnumber_T ullong_arg = 0;
- 
-                   // only set for b conversion
-                   uvarnumber_T bin_arg = 0;
- 
-                   // pointer argument value -only defined for p
-                   // conversion
-                   void *ptr_arg = NULL;
- 
-                   if (fmt_spec == 'p')
-                   {
-                       length_modifier = '\0';
-                       ptr_arg =
- # if defined(FEAT_EVAL)
-                                tvs != NULL ? (void *)tv_str(tvs, &arg_idx,
-                                                                       NULL) :
- # endif
-                                       va_arg(ap, void *);
-                       if (ptr_arg != NULL)
-                           arg_sign = 1;
-                   }
-                   else if (fmt_spec == 'b' || fmt_spec == 'B')
-                   {
-                       bin_arg =
- # if defined(FEAT_EVAL)
-                                   tvs != NULL ?
-                                          (uvarnumber_T)tv_nr(tvs, &arg_idx) :
- # endif
-                                       va_arg(ap, uvarnumber_T);
-                       if (bin_arg != 0)
-                           arg_sign = 1;
-                   }
-                   else if (fmt_spec == 'd')
-                   {
-                       // signed
-                       switch (length_modifier)
-                       {
-                       case '\0':
-                       case 'h':
-                           // char and short arguments are passed as int.
-                           int_arg =
- # if defined(FEAT_EVAL)
-                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                                           va_arg(ap, int);
-                           if (int_arg > 0)
-                               arg_sign =  1;
-                           else if (int_arg < 0)
-                               arg_sign = -1;
-                           break;
-                       case 'l':
-                           long_arg =
- # if defined(FEAT_EVAL)
-                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                                           va_arg(ap, long int);
-                           if (long_arg > 0)
-                               arg_sign =  1;
-                           else if (long_arg < 0)
-                               arg_sign = -1;
-                           break;
-                       case 'L':
-                           llong_arg =
- # if defined(FEAT_EVAL)
-                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
- # endif
-                                           va_arg(ap, varnumber_T);
-                           if (llong_arg > 0)
-                               arg_sign =  1;
-                           else if (llong_arg < 0)
-                               arg_sign = -1;
-                           break;
-                       }
-                   }
-                   else
-                   {
-                       // unsigned
-                       switch (length_modifier)
-                       {
-                           case '\0':
-                           case 'h':
-                               uint_arg =
- # if defined(FEAT_EVAL)
-                                           tvs != NULL ? (unsigned)
-                                                       tv_nr(tvs, &arg_idx) :
- # endif
-                                               va_arg(ap, unsigned int);
-                               if (uint_arg != 0)
-                                   arg_sign = 1;
-                               break;
-                           case 'l':
-                               ulong_arg =
- # if defined(FEAT_EVAL)
-                                           tvs != NULL ? (unsigned long)
-                                                       tv_nr(tvs, &arg_idx) :
- # endif
-                                               va_arg(ap, unsigned long int);
-                               if (ulong_arg != 0)
-                                   arg_sign = 1;
-                               break;
-                           case 'L':
-                               ullong_arg =
- # if defined(FEAT_EVAL)
-                                           tvs != NULL ? (uvarnumber_T)
-                                                       tv_nr(tvs, &arg_idx) :
- # endif
-                                               va_arg(ap, uvarnumber_T);
-                               if (ullong_arg != 0)
-                                   arg_sign = 1;
-                               break;
-                       }
-                   }
- 
-                   str_arg = tmp;
-                   str_arg_l = 0;
- 
-                   // NOTE:
-                   //   For d, i, u, o, x, and X conversions, if precision is
-                   //   specified, the '0' flag should be ignored. This is so
-                   //   with Solaris 2.6, Digital UNIX 4.0, HPUX 10, Linux,
-                   //   FreeBSD, NetBSD; but not with Perl.
-                   if (precision_specified)
-                       zero_padding = 0;
-                   if (fmt_spec == 'd')
-                   {
-                       if (force_sign && arg_sign >= 0)
-                           tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
-                       // leave negative numbers for sprintf to handle, to
-                       // avoid handling tricky cases like (short int)-32768
-                   }
-                   else if (alternate_form)
-                   {
-                       if (arg_sign != 0
-                                    && (fmt_spec == 'b' || fmt_spec == 'B'
-                                     || fmt_spec == 'x' || fmt_spec == 'X') )
-                       {
-                           tmp[str_arg_l++] = '0';
-                           tmp[str_arg_l++] = fmt_spec;
-                       }
-                       // alternate form should have no effect for p
-                       // conversion, but ...
-                   }
- 
-                   zero_padding_insertion_ind = str_arg_l;
-                   if (!precision_specified)
-                       precision = 1;   // default precision is 1
-                   if (precision == 0 && arg_sign == 0)
-                   {
-                       // When zero value is formatted with an explicit
-                       // precision 0, the resulting formatted string is
-                       // empty (d, i, u, b, B, o, x, X, p).
-                   }
-                   else
-                   {
-                       char    f[6];
-                       int     f_l = 0;
- 
-                       // construct a simple format string for sprintf
-                       f[f_l++] = '%';
-                       if (!length_modifier)
-                           ;
-                       else if (length_modifier == 'L')
-                       {
- # ifdef MSWIN
-                           f[f_l++] = 'I';
-                           f[f_l++] = '6';
-                           f[f_l++] = '4';
- # else
-                           f[f_l++] = 'l';
-                           f[f_l++] = 'l';
- # endif
-                       }
-                       else
-                           f[f_l++] = length_modifier;
-                       f[f_l++] = fmt_spec;
-                       f[f_l++] = '\0';
- 
-                       if (fmt_spec == 'p')
-                           str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
-                       else if (fmt_spec == 'b' || fmt_spec == 'B')
-                       {
-                           char            b[8 * sizeof(uvarnumber_T)];
-                           size_t          b_l = 0;
-                           uvarnumber_T    bn = bin_arg;
- 
-                           do
-                           {
-                               b[sizeof(b) - ++b_l] = '0' + (bn & 0x1);
-                               bn >>= 1;
-                           }
-                           while (bn != 0);
- 
-                           memcpy(tmp + str_arg_l, b + sizeof(b) - b_l, b_l);
-                           str_arg_l += b_l;
-                       }
-                       else if (fmt_spec == 'd')
-                       {
-                           // signed
-                           switch (length_modifier)
-                           {
-                           case '\0': str_arg_l += sprintf(
-                                                tmp + str_arg_l, f,
-                                                int_arg);
-                                      break;
-                           case 'h': str_arg_l += sprintf(
-                                                tmp + str_arg_l, f,
-                                                (short)int_arg);
-                                     break;
-                           case 'l': str_arg_l += sprintf(
-                                               tmp + str_arg_l, f, long_arg);
-                                     break;
-                           case 'L': str_arg_l += sprintf(
-                                              tmp + str_arg_l, f, llong_arg);
-                                     break;
-                           }
-                       }
-                       else
-                       {
-                           // unsigned
-                           switch (length_modifier)
-                           {
-                           case '\0': str_arg_l += sprintf(
-                                               tmp + str_arg_l, f,
-                                               uint_arg);
-                                      break;
-                           case 'h': str_arg_l += sprintf(
-                                               tmp + str_arg_l, f,
-                                               (unsigned short)uint_arg);
-                                     break;
-                           case 'l': str_arg_l += sprintf(
-                                              tmp + str_arg_l, f, ulong_arg);
-                                     break;
-                           case 'L': str_arg_l += sprintf(
-                                             tmp + str_arg_l, f, ullong_arg);
-                                     break;
-                           }
-                       }
- 
-                       // include the optional minus sign and possible
-                       // "0x" in the region before the zero padding
-                       // insertion point
-                       if (zero_padding_insertion_ind < str_arg_l
-                               && tmp[zero_padding_insertion_ind] == '-')
-                           zero_padding_insertion_ind++;
-                       if (zero_padding_insertion_ind + 1 < str_arg_l
-                               && tmp[zero_padding_insertion_ind]   == '0'
-                               && (tmp[zero_padding_insertion_ind + 1] == 'x'
-                                || tmp[zero_padding_insertion_ind + 1] == 'X'))
-                           zero_padding_insertion_ind += 2;
-                   }
- 
-                   {
-                       size_t num_of_digits = str_arg_l
-                                                - zero_padding_insertion_ind;
- 
-                       if (alternate_form && fmt_spec == 'o'
-                               // unless zero is already the first
-                               // character
-                               && !(zero_padding_insertion_ind < str_arg_l
-                                   && tmp[zero_padding_insertion_ind] == '0'))
-                       {
-                           // assure leading zero for alternate-form
-                           // octal numbers
-                           if (!precision_specified
-                                            || precision < num_of_digits + 1)
-                           {
-                               // precision is increased to force the
-                               // first character to be zero, except if a
-                               // zero value is formatted with an
-                               // explicit precision of zero
-                               precision = num_of_digits + 1;
-                           }
-                       }
-                       // zero padding to specified precision?
-                       if (num_of_digits < precision)
-                           number_of_zeros_to_pad = precision - num_of_digits;
-                   }
-                   // zero padding to specified minimal field width?
-                   if (!justify_left && zero_padding)
-                   {
-                       int n = (int)(min_field_width - (str_arg_l
-                                                   + number_of_zeros_to_pad));
-                       if (n > 0)
-                           number_of_zeros_to_pad += n;
-                   }
-                   break;
-               }
- 
- # ifdef FEAT_FLOAT
-           case 'f':
-           case 'F':
-           case 'e':
-           case 'E':
-           case 'g':
-           case 'G':
-               {
-                   // Floating point.
-                   double      f;
-                   double      abs_f;
-                   char        format[40];
-                   int         l;
-                   int         remove_trailing_zeroes = FALSE;
- 
-                   f =
- #  if defined(FEAT_EVAL)
-                       tvs != NULL ? tv_float(tvs, &arg_idx) :
- #  endif
-                           va_arg(ap, double);
-                   abs_f = f < 0 ? -f : f;
- 
-                   if (fmt_spec == 'g' || fmt_spec == 'G')
-                   {
-                       // Would be nice to use %g directly, but it prints
-                       // "1.0" as "1", we don't want that.
-                       if ((abs_f >= 0.001 && abs_f < 10000000.0)
-                                                             || abs_f == 0.0)
-                           fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
-                       else
-                           fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
-                       remove_trailing_zeroes = TRUE;
-                   }
- 
-                   if ((fmt_spec == 'f' || fmt_spec == 'F') &&
- #  ifdef VAX
-                           abs_f > 1.0e38
- #  else
-                           abs_f > 1.0e307
- #  endif
-                           )
-                   {
-                       // Avoid a buffer overflow
-                       STRCPY(tmp, infinity_str(f > 0.0, fmt_spec,
-                                             force_sign, space_for_positive));
-                       str_arg_l = STRLEN(tmp);
-                       zero_padding = 0;
-                   }
-                   else
-                   {
-                       if (isnan(f))
-                       {
-                           // Not a number: nan or NAN
-                           STRCPY(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN"
-                                                                     : "nan");
-                           str_arg_l = 3;
-                           zero_padding = 0;
-                       }
-                       else if (isinf(f))
-                       {
-                           STRCPY(tmp, infinity_str(f > 0.0, fmt_spec,
-                                             force_sign, space_for_positive));
-                           str_arg_l = STRLEN(tmp);
-                           zero_padding = 0;
-                       }
-                       else
-                       {
-                           // Regular float number
-                           format[0] = '%';
-                           l = 1;
-                           if (force_sign)
-                               format[l++] = space_for_positive ? ' ' : '+';
-                           if (precision_specified)
-                           {
-                               size_t max_prec = TMP_LEN - 10;
- 
-                               // Make sure we don't get more digits than we
-                               // have room for.
-                               if ((fmt_spec == 'f' || fmt_spec == 'F')
-                                                               && abs_f > 1.0)
-                                   max_prec -= (size_t)log10(abs_f);
-                               if (precision > max_prec)
-                                   precision = max_prec;
-                               l += sprintf(format + l, ".%d", (int)precision);
-                           }
-                           format[l] = fmt_spec == 'F' ? 'f' : fmt_spec;
-                           format[l + 1] = NUL;
- 
-                           str_arg_l = sprintf(tmp, format, f);
-                       }
- 
-                       if (remove_trailing_zeroes)
-                       {
-                           int i;
-                           char *tp;
- 
-                           // Using %g or %G: remove superfluous zeroes.
-                           if (fmt_spec == 'f' || fmt_spec == 'F')
-                               tp = tmp + str_arg_l - 1;
-                           else
-                           {
-                               tp = (char *)vim_strchr((char_u *)tmp,
-                                                fmt_spec == 'e' ? 'e' : 'E');
-                               if (tp != NULL)
-                               {
-                                   // Remove superfluous '+' and leading
-                                   // zeroes from the exponent.
-                                   if (tp[1] == '+')
-                                   {
-                                       // Change "1.0e+07" to "1.0e07"
-                                       STRMOVE(tp + 1, tp + 2);
-                                       --str_arg_l;
-                                   }
-                                   i = (tp[1] == '-') ? 2 : 1;
-                                   while (tp[i] == '0')
-                                   {
-                                       // Change "1.0e07" to "1.0e7"
-                                       STRMOVE(tp + i, tp + i + 1);
-                                       --str_arg_l;
-                                   }
-                                   --tp;
-                               }
-                           }
- 
-                           if (tp != NULL && !precision_specified)
-                               // Remove trailing zeroes, but keep the one
-                               // just after a dot.
-                               while (tp > tmp + 2 && *tp == '0'
-                                                            && tp[-1] != '.')
-                               {
-                                   STRMOVE(tp, tp + 1);
-                                   --tp;
-                                   --str_arg_l;
-                               }
-                       }
-                       else
-                       {
-                           char *tp;
- 
-                           // Be consistent: some printf("%e") use 1.0e+12
-                           // and some 1.0e+012.  Remove one zero in the last
-                           // case.
-                           tp = (char *)vim_strchr((char_u *)tmp,
-                                                fmt_spec == 'e' ? 'e' : 'E');
-                           if (tp != NULL && (tp[1] == '+' || tp[1] == '-')
-                                         && tp[2] == '0'
-                                         && vim_isdigit(tp[3])
-                                         && vim_isdigit(tp[4]))
-                           {
-                               STRMOVE(tp + 2, tp + 3);
-                               --str_arg_l;
-                           }
-                       }
-                   }
-                   if (zero_padding && min_field_width > str_arg_l
-                                             && (tmp[0] == '-' || force_sign))
-                   {
-                       // padding 0's should be inserted after the sign
-                       number_of_zeros_to_pad = min_field_width - str_arg_l;
-                       zero_padding_insertion_ind = 1;
-                   }
-                   str_arg = tmp;
-                   break;
-               }
- # endif
- 
-           default:
-               // unrecognized conversion specifier, keep format string
-               // as-is
-               zero_padding = 0;  // turn zero padding off for non-numeric
-                                  // conversion
-               justify_left = 1;
-               min_field_width = 0;                // reset flags
- 
-               // discard the unrecognized conversion, just keep *
-               // the unrecognized conversion character
-               str_arg = p;
-               str_arg_l = 0;
-               if (*p != NUL)
-                   str_arg_l++;  // include invalid conversion specifier
-                                 // unchanged if not at end-of-string
-               break;
-           }
- 
-           if (*p != NUL)
-               p++;     // step over the just processed conversion specifier
- 
-           // insert padding to the left as requested by min_field_width;
-           // this does not include the zero padding in case of numerical
-           // conversions
-           if (!justify_left)
-           {
-               // left padding with blank or zero
-               int pn = (int)(min_field_width - (str_arg_l + 
number_of_zeros_to_pad));
- 
-               if (pn > 0)
-               {
-                   if (str_l < str_m)
-                   {
-                       size_t avail = str_m - str_l;
- 
-                       vim_memset(str + str_l, zero_padding ? '0' : ' ',
-                                            (size_t)pn > avail ? avail
-                                                               : (size_t)pn);
-                   }
-                   str_l += pn;
-               }
-           }
- 
-           // zero padding as requested by the precision or by the minimal
-           // field width for numeric conversions required?
-           if (number_of_zeros_to_pad == 0)
-           {
-               // will not copy first part of numeric right now, *
-               // force it to be copied later in its entirety
-               zero_padding_insertion_ind = 0;
-           }
-           else
-           {
-               // insert first part of numerics (sign or '0x') before zero
-               // padding
-               int zn = (int)zero_padding_insertion_ind;
- 
-               if (zn > 0)
-               {
-                   if (str_l < str_m)
-                   {
-                       size_t avail = str_m - str_l;
- 
-                       mch_memmove(str + str_l, str_arg,
-                                            (size_t)zn > avail ? avail
-                                                               : (size_t)zn);
-                   }
-                   str_l += zn;
-               }
- 
-               // insert zero padding as requested by the precision or min
-               // field width
-               zn = (int)number_of_zeros_to_pad;
-               if (zn > 0)
-               {
-                   if (str_l < str_m)
-                   {
-                       size_t avail = str_m - str_l;
- 
-                       vim_memset(str + str_l, '0',
-                                            (size_t)zn > avail ? avail
-                                                               : (size_t)zn);
-                   }
-                   str_l += zn;
-               }
-           }
- 
-           // insert formatted string
-           // (or as-is conversion specifier for unknown conversions)
-           {
-               int sn = (int)(str_arg_l - zero_padding_insertion_ind);
- 
-               if (sn > 0)
-               {
-                   if (str_l < str_m)
-                   {
-                       size_t avail = str_m - str_l;
- 
-                       mch_memmove(str + str_l,
-                               str_arg + zero_padding_insertion_ind,
-                               (size_t)sn > avail ? avail : (size_t)sn);
-                   }
-                   str_l += sn;
-               }
-           }
- 
-           // insert right padding
-           if (justify_left)
-           {
-               // right blank padding to the field width
-               int pn = (int)(min_field_width
-                                     - (str_arg_l + number_of_zeros_to_pad));
- 
-               if (pn > 0)
-               {
-                   if (str_l < str_m)
-                   {
-                       size_t avail = str_m - str_l;
- 
-                       vim_memset(str + str_l, ' ',
-                                            (size_t)pn > avail ? avail
-                                                               : (size_t)pn);
-                   }
-                   str_l += pn;
-               }
-           }
-           vim_free(tofree);
-       }
-     }
- 
-     if (str_m > 0)
-     {
-       // make sure the string is nul-terminated even at the expense of
-       // overwriting the last character (shouldn't happen, but just in case)
-       //
-       str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
-     }
- 
-     if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
-       emsg(_("E767: Too many arguments to printf()"));
- 
-     // Return the number of characters formatted (excluding trailing nul
-     // character), that is, the number of characters that would have been
-     // written to the buffer if it were large enough.
-     return (int)str_l;
- }
- 
- #endif // PROTO
--- 4107,4109 ----
*** ../vim-8.2.3319/src/profiler.c      2021-02-19 19:13:13.083904350 +0100
--- src/profiler.c      2021-08-09 19:56:02.951236093 +0200
***************
*** 555,560 ****
--- 555,578 ----
  }
  
  /*
+  * Save time when starting to invoke another script or function.
+  */
+     static void
+ script_prof_save(
+     proftime_T        *tm)        // place to store wait time
+ {
+     scriptitem_T    *si;
+ 
+     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
+     {
+       si = SCRIPT_ITEM(current_sctx.sc_sid);
+       if (si->sn_prof_on && si->sn_pr_nest++ == 0)
+           profile_start(&si->sn_pr_child);
+     }
+     profile_get_wait(tm);
+ }
+ 
+ /*
   * When calling a function: may initialize for profiling.
   */
      void
***************
*** 793,816 ****
  }
  
  /*
-  * Save time when starting to invoke another script or function.
-  */
-     void
- script_prof_save(
-     proftime_T        *tm)        // place to store wait time
- {
-     scriptitem_T    *si;
- 
-     if (SCRIPT_ID_VALID(current_sctx.sc_sid))
-     {
-       si = SCRIPT_ITEM(current_sctx.sc_sid);
-       if (si->sn_prof_on && si->sn_pr_nest++ == 0)
-           profile_start(&si->sn_pr_child);
-     }
-     profile_get_wait(tm);
- }
- 
- /*
   * Count time spent in children after invoking another script or function.
   */
      void
--- 811,816 ----
*** ../vim-8.2.3319/src/proto/channel.pro       2021-06-05 20:51:34.737122348 
+0200
--- src/proto/channel.pro       2021-08-09 19:56:02.951236093 +0200
***************
*** 24,30 ****
  int channel_collapse(channel_T *channel, ch_part_T part, int want_nl);
  int channel_can_write_to(channel_T *channel);
  int channel_is_open(channel_T *channel);
- char *channel_status(channel_T *channel, int req_part);
  void channel_close(channel_T *channel, int invoke_close_cb);
  void channel_clear(channel_T *channel);
  void channel_free_all(void);
--- 24,29 ----
*** ../vim-8.2.3319/src/proto/dict.pro  2021-07-22 14:58:43.469967322 +0200
--- src/proto/dict.pro  2021-08-09 19:56:02.951236093 +0200
***************
*** 34,40 ****
  varnumber_T dict_get_number_check(dict_T *d, char_u *key);
  varnumber_T dict_get_bool(dict_T *d, char_u *key, int def);
  char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
- char_u *skip_literal_key(char_u *key);
  char_u *get_literal_key(char_u **arg);
  int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal);
  void dict_extend(dict_T *d1, dict_T *d2, char_u *action, char *func_name);
--- 34,39 ----
*** ../vim-8.2.3319/src/proto/digraph.pro       2021-07-26 21:54:00.055491571 
+0200
--- src/proto/digraph.pro       2021-08-09 19:56:02.951236093 +0200
***************
*** 3,12 ****
  char_u *get_digraph_for_char(int val_arg);
  int get_digraph(int cmdline);
  int digraph_get(int char1, int char2, int meta_char);
- int check_digraph_chars_valid(int char1, int char2);
  void putdigraph(char_u *str);
  void listdigraphs(int use_headers);
- void digraph_getlist_common(int list_all, typval_T *rettv);
  void f_digraph_get(typval_T *argvars, typval_T *rettv);
  void f_digraph_getlist(typval_T *argvars, typval_T *rettv);
  void f_digraph_set(typval_T *argvars, typval_T *rettv);
--- 3,10 ----
*** ../vim-8.2.3319/src/proto/edit.pro  2020-12-03 19:54:38.177924280 +0100
--- src/proto/edit.pro  2021-08-09 19:56:02.951236093 +0200
***************
*** 2,8 ****
  int edit(int cmdchar, int startln, long count);
  int ins_need_undo_get(void);
  void ins_redraw(int ready);
- int decodeModifyOtherKeys(int c);
  void edit_putchar(int c, int highlight);
  void set_insstart(linenr_T lnum, int col);
  void edit_unputchar(void);
--- 2,7 ----
*** ../vim-8.2.3319/src/proto/ex_docmd.pro      2021-08-05 20:39:59.346053681 
+0200
--- src/proto/ex_docmd.pro      2021-08-09 19:56:02.951236093 +0200
***************
*** 1,7 ****
  /* ex_docmd.c */
  void do_exmode(int improved);
  int do_cmdline_cmd(char_u *cmd);
- int do_cmd_argument(char_u *cmd);
  int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int, 
getline_opt_T), void *cookie, int flags);
  void handle_did_throw(void);
  int getline_equal(char_u *(*fgetline)(int, void *, int, getline_opt_T), void 
*cookie, char_u *(*func)(int, void *, int, getline_opt_T));
--- 1,6 ----
*** ../vim-8.2.3319/src/proto/getchar.pro       2021-06-07 22:04:48.402620082 
+0200
--- src/proto/getchar.pro       2021-08-09 19:56:02.951236093 +0200
***************
*** 15,21 ****
  void AppendNumberToRedobuff(long n);
  void stuffReadbuff(char_u *s);
  void stuffRedoReadbuff(char_u *s);
- void stuffReadbuffLen(char_u *s, long len);
  void stuffReadbuffSpec(char_u *s);
  void stuffcharReadbuff(int c);
  void stuffnumReadbuff(long n);
--- 15,20 ----
*** ../vim-8.2.3319/src/proto/job.pro   2021-06-05 20:51:34.737122348 +0200
--- src/proto/job.pro   2021-08-09 19:56:02.951236093 +0200
***************
*** 20,26 ****
  int job_stop(job_T *job, typval_T *argvars, char *type);
  void invoke_prompt_callback(void);
  int invoke_prompt_interrupt(void);
- char_u *buf_prompt_text(buf_T *buf);
  char_u *prompt_text(void);
  void init_prompt(int cmdchar_todo);
  int prompt_curpos_editable(void);
--- 20,25 ----
*** ../vim-8.2.3319/src/proto/list.pro  2021-02-20 17:03:57.984112613 +0100
--- src/proto/list.pro  2021-08-09 19:56:02.951236093 +0200
***************
*** 24,30 ****
  long list_idx_of_item(list_T *l, listitem_T *item);
  void list_append(list_T *l, listitem_T *item);
  int list_append_tv(list_T *l, typval_T *tv);
- int list_append_tv_move(list_T *l, typval_T *tv);
  int list_append_dict(list_T *list, dict_T *dict);
  int list_append_list(list_T *list1, list_T *list2);
  int list_append_string(list_T *l, char_u *str, int len);
--- 24,29 ----
*** ../vim-8.2.3319/src/proto/profiler.pro      2021-02-19 19:13:13.083904350 
+0100
--- src/proto/profiler.pro      2021-08-09 19:56:02.951236093 +0200
***************
*** 27,33 ****
  void func_line_exec(void *cookie);
  void func_line_end(void *cookie);
  void script_do_profile(scriptitem_T *si);
- void script_prof_save(proftime_T *tm);
  void script_prof_restore(proftime_T *tm);
  void profile_dump(void);
  void script_line_start(void);
--- 27,32 ----
*** ../vim-8.2.3319/src/proto/spell.pro 2021-06-11 19:07:36.734247944 +0200
--- src/proto/spell.pro 2021-08-09 19:56:02.951236093 +0200
***************
*** 5,11 ****
  int match_compoundrule(slang_T *slang, char_u *compflags);
  int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, 
slang_T *slang, int cond_req);
  int spell_valid_case(int wordflags, int treeflags);
- int no_spell_checking(win_T *wp);
  int spell_move_to(win_T *wp, int dir, int allwords, int curline, hlf_T 
*attrp);
  void spell_cat_line(char_u *buf, char_u *line, int maxlen);
  char_u *spell_enc(void);
--- 5,10 ----
*** ../vim-8.2.3319/src/proto/vim9compile.pro   2021-07-19 22:19:25.690972401 
+0200
--- src/proto/vim9compile.pro   2021-08-09 19:56:02.951236093 +0200
***************
*** 1,7 ****
  /* vim9compile.c */
  int check_defined(char_u *p, size_t len, cctx_T *cctx, int is_arg);
  int check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2);
- int use_typecheck(type_T *actual, type_T *expected);
  int need_type(type_T *actual, type_T *expected, int offset, int arg_idx, 
cctx_T *cctx, int silent, int actual_is_const);
  int func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type);
  int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T 
*cctx);
--- 1,6 ----
***************
*** 9,15 ****
  imported_T *find_imported_in_script(char_u *name, size_t len, int sid);
  char_u *peek_next_line_from_context(cctx_T *cctx);
  char_u *next_line_from_context(cctx_T *cctx, int skip_comment);
- char_u *to_name_end(char_u *arg, int use_namespace);
  char_u *to_name_const_end(char_u *arg);
  int get_lambda_tv_and_compile(char_u **arg, typval_T *rettv, int 
types_optional, evalarg_T *evalarg);
  exprtype_T get_compare_type(char_u *p, int *len, int *type_is);
--- 8,13 ----
*** ../vim-8.2.3319/src/proto/vim9script.pro    2021-07-08 21:38:45.339232318 
+0200
--- src/proto/vim9script.pro    2021-08-09 19:56:02.951236093 +0200
***************
*** 11,21 ****
  void mark_imports_for_reload(int sid);
  void ex_import(exarg_T *eap);
  int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, 
cctx_T *cctx, int verbose);
- char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, 
evalarg_T *evalarg, void *cctx);
  char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg);
  void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T 
*tv, type_T **type, int do_member);
  void hide_script_var(scriptitem_T *si, int idx, int func_defined);
- void free_all_script_vars(scriptitem_T *si);
  svar_T *find_typval_in_script(typval_T *dest);
  int check_script_var_type(typval_T *dest, typval_T *value, char_u *name, 
where_T where);
  int check_reserved_name(char_u *name);
--- 11,19 ----
*** ../vim-8.2.3319/src/proto/vim9type.pro      2021-07-29 22:48:50.103129907 
+0200
--- src/proto/vim9type.pro      2021-08-09 19:56:02.951236093 +0200
***************
*** 1,5 ****
  /* vim9type.c */
- type_T *get_type_ptr(garray_T *type_gap);
  void clear_type_list(garray_T *gap);
  type_T *alloc_type(type_T *type);
  void free_type(type_T *type);
--- 1,4 ----
*** ../vim-8.2.3319/src/spell.c 2021-07-20 21:07:32.968058851 +0200
--- src/spell.c 2021-08-09 19:56:02.951236093 +0200
***************
*** 1240,1246 ****
  /*
   * Return TRUE if spell checking is not enabled.
   */
!     int
  no_spell_checking(win_T *wp)
  {
      if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
--- 1240,1246 ----
  /*
   * Return TRUE if spell checking is not enabled.
   */
!     static int
  no_spell_checking(win_T *wp)
  {
      if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
*** ../vim-8.2.3319/src/strings.c       2021-07-27 22:00:39.749712387 +0200
--- src/strings.c       2021-08-09 19:56:02.951236093 +0200
***************
*** 11,16 ****
--- 11,17 ----
   * strings.c: string manipulation functions
   */
  
+ #define USING_FLOAT_STUFF
  #include "vim.h"
  
  /*
***************
*** 77,86 ****
      unsigned  length;
      int               l;
  
!     /*
!      * First count the number of backslashes required.
!      * Then allocate the memory and insert them.
!      */
      length = 1;                               // count the trailing NUL
      for (p = string; *p; p++)
      {
--- 78,85 ----
      unsigned  length;
      int               l;
  
!     // First count the number of backslashes required.
!     // Then allocate the memory and insert them.
      length = 1;                               // count the trailing NUL
      for (p = string; *p; p++)
      {
***************
*** 1265,1274 ****
            len = slen - nbyte;    // default: all bytes that are available.
      }
  
!     /*
!      * Only return the overlap between the specified part and the actual
!      * string.
!      */
      if (nbyte < 0)
      {
        len += nbyte;
--- 1264,1271 ----
            len = slen - nbyte;    // default: all bytes that are available.
      }
  
!     // Only return the overlap between the specified part and the actual
!     // string.
      if (nbyte < 0)
      {
        len += nbyte;
***************
*** 1668,1670 ****
--- 1665,2776 ----
  }
  
  #endif
+ 
+ #if defined(FEAT_EVAL)
+ static char *e_printf = N_("E766: Insufficient arguments for printf()");
+ 
+ /*
+  * Get number argument from "idxp" entry in "tvs".  First entry is 1.
+  */
+     static varnumber_T
+ tv_nr(typval_T *tvs, int *idxp)
+ {
+     int               idx = *idxp - 1;
+     varnumber_T       n = 0;
+     int               err = FALSE;
+ 
+     if (tvs[idx].v_type == VAR_UNKNOWN)
+       emsg(_(e_printf));
+     else
+     {
+       ++*idxp;
+       n = tv_get_number_chk(&tvs[idx], &err);
+       if (err)
+           n = 0;
+     }
+     return n;
+ }
+ 
+ /*
+  * Get string argument from "idxp" entry in "tvs".  First entry is 1.
+  * If "tofree" is NULL tv_get_string_chk() is used.  Some types (e.g. List)
+  * are not converted to a string.
+  * If "tofree" is not NULL echo_string() is used.  All types are converted to
+  * a string with the same format as ":echo".  The caller must free "*tofree".
+  * Returns NULL for an error.
+  */
+     static char *
+ tv_str(typval_T *tvs, int *idxp, char_u **tofree)
+ {
+     int                   idx = *idxp - 1;
+     char          *s = NULL;
+     static char_u   numbuf[NUMBUFLEN];
+ 
+     if (tvs[idx].v_type == VAR_UNKNOWN)
+       emsg(_(e_printf));
+     else
+     {
+       ++*idxp;
+       if (tofree != NULL)
+           s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID());
+       else
+           s = (char *)tv_get_string_chk(&tvs[idx]);
+     }
+     return s;
+ }
+ 
+ # ifdef FEAT_FLOAT
+ /*
+  * Get float argument from "idxp" entry in "tvs".  First entry is 1.
+  */
+     static double
+ tv_float(typval_T *tvs, int *idxp)
+ {
+     int               idx = *idxp - 1;
+     double    f = 0;
+ 
+     if (tvs[idx].v_type == VAR_UNKNOWN)
+       emsg(_(e_printf));
+     else
+     {
+       ++*idxp;
+       if (tvs[idx].v_type == VAR_FLOAT)
+           f = tvs[idx].vval.v_float;
+       else if (tvs[idx].v_type == VAR_NUMBER)
+           f = (double)tvs[idx].vval.v_number;
+       else
+           emsg(_("E807: Expected Float argument for printf()"));
+     }
+     return f;
+ }
+ # endif
+ #endif
+ 
+ #ifdef FEAT_FLOAT
+ /*
+  * Return the representation of infinity for printf() function:
+  * "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF".
+  */
+     static const char *
+ infinity_str(int positive,
+            char fmt_spec,
+            int force_sign,
+            int space_for_positive)
+ {
+     static const char *table[] =
+     {
+       "-inf", "inf", "+inf", " inf",
+       "-INF", "INF", "+INF", " INF"
+     };
+     int idx = positive * (1 + force_sign + force_sign * space_for_positive);
+ 
+     if (ASCII_ISUPPER(fmt_spec))
+       idx += 4;
+     return table[idx];
+ }
+ #endif
+ 
+ /*
+  * This code was included to provide a portable vsnprintf() and snprintf().
+  * Some systems may provide their own, but we always use this one for
+  * consistency.
+  *
+  * This code is based on snprintf.c - a portable implementation of snprintf
+  * by Mark Martinec <[email protected]>, Version 2.2, 2000-10-06.
+  * Included with permission.  It was heavily modified to fit in Vim.
+  * The original code, including useful comments, can be found here:
+  *    http://www.ijs.si/software/snprintf/
+  *
+  * This snprintf() only supports the following conversion specifiers:
+  * s, c, d, u, o, x, X, p  (and synonyms: i, D, U, O - see below)
+  * with flags: '-', '+', ' ', '0' and '#'.
+  * An asterisk is supported for field width as well as precision.
+  *
+  * Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'.
+  *
+  * Length modifiers 'h' (short int) and 'l' (long int) and 'll' (long long 
int)
+  * are supported.  NOTE: for 'll' the argument is varnumber_T or uvarnumber_T.
+  *
+  * The locale is not used, the string is used as a byte string.  This is only
+  * relevant for double-byte encodings where the second byte may be '%'.
+  *
+  * It is permitted for "str_m" to be zero, and it is permitted to specify NULL
+  * pointer for resulting string argument if "str_m" is zero (as per ISO C99).
+  *
+  * The return value is the number of characters which would be generated
+  * for the given input, excluding the trailing NUL. If this value
+  * is greater or equal to "str_m", not all characters from the result
+  * have been stored in str, output bytes beyond the ("str_m"-1) -th character
+  * are discarded. If "str_m" is greater than zero it is guaranteed
+  * the resulting string will be NUL-terminated.
+  */
+ 
+ /*
+  * When va_list is not supported we only define vim_snprintf().
+  *
+  * vim_vsnprintf_typval() can be invoked with either "va_list" or a list of
+  * "typval_T".  When the latter is not used it must be NULL.
+  */
+ 
+ // When generating prototypes all of this is skipped, cproto doesn't
+ // understand this.
+ #ifndef PROTO
+ 
+ // Like vim_vsnprintf() but append to the string.
+     int
+ vim_snprintf_add(char *str, size_t str_m, const char *fmt, ...)
+ {
+     va_list   ap;
+     int               str_l;
+     size_t    len = STRLEN(str);
+     size_t    space;
+ 
+     if (str_m <= len)
+       space = 0;
+     else
+       space = str_m - len;
+     va_start(ap, fmt);
+     str_l = vim_vsnprintf(str + len, space, fmt, ap);
+     va_end(ap);
+     return str_l;
+ }
+ 
+     int
+ vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
+ {
+     va_list   ap;
+     int               str_l;
+ 
+     va_start(ap, fmt);
+     str_l = vim_vsnprintf(str, str_m, fmt, ap);
+     va_end(ap);
+     return str_l;
+ }
+ 
+     int
+ vim_vsnprintf(
+     char      *str,
+     size_t    str_m,
+     const char        *fmt,
+     va_list   ap)
+ {
+     return vim_vsnprintf_typval(str, str_m, fmt, ap, NULL);
+ }
+ 
+     int
+ vim_vsnprintf_typval(
+     char      *str,
+     size_t    str_m,
+     const char        *fmt,
+     va_list   ap,
+     typval_T  *tvs)
+ {
+     size_t    str_l = 0;
+     const char        *p = fmt;
+     int               arg_idx = 1;
+ 
+     if (p == NULL)
+       p = "";
+     while (*p != NUL)
+     {
+       if (*p != '%')
+       {
+           char    *q = strchr(p + 1, '%');
+           size_t  n = (q == NULL) ? STRLEN(p) : (size_t)(q - p);
+ 
+           // Copy up to the next '%' or NUL without any changes.
+           if (str_l < str_m)
+           {
+               size_t avail = str_m - str_l;
+ 
+               mch_memmove(str + str_l, p, n > avail ? avail : n);
+           }
+           p += n;
+           str_l += n;
+       }
+       else
+       {
+           size_t  min_field_width = 0, precision = 0;
+           int     zero_padding = 0, precision_specified = 0, justify_left = 0;
+           int     alternate_form = 0, force_sign = 0;
+ 
+           // If both the ' ' and '+' flags appear, the ' ' flag should be
+           // ignored.
+           int     space_for_positive = 1;
+ 
+           // allowed values: \0, h, l, L
+           char    length_modifier = '\0';
+ 
+           // temporary buffer for simple numeric->string conversion
+ # if defined(FEAT_FLOAT)
+ #  define TMP_LEN 350 // On my system 1e308 is the biggest number possible.
+                       // That sounds reasonable to use as the maximum
+                       // printable.
+ # else
+ #  define TMP_LEN 66
+ # endif
+           char    tmp[TMP_LEN];
+ 
+           // string address in case of string argument
+           const char  *str_arg = NULL;
+ 
+           // natural field width of arg without padding and sign
+           size_t  str_arg_l;
+ 
+           // unsigned char argument value - only defined for c conversion.
+           // N.B. standard explicitly states the char argument for the c
+           // conversion is unsigned
+           unsigned char uchar_arg;
+ 
+           // number of zeros to be inserted for numeric conversions as
+           // required by the precision or minimal field width
+           size_t  number_of_zeros_to_pad = 0;
+ 
+           // index into tmp where zero padding is to be inserted
+           size_t  zero_padding_insertion_ind = 0;
+ 
+           // current conversion specifier character
+           char    fmt_spec = '\0';
+ 
+           // buffer for 's' and 'S' specs
+           char_u  *tofree = NULL;
+ 
+ 
+           p++;  // skip '%'
+ 
+           // parse flags
+           while (*p == '0' || *p == '-' || *p == '+' || *p == ' '
+                                                  || *p == '#' || *p == '\'')
+           {
+               switch (*p)
+               {
+                   case '0': zero_padding = 1; break;
+                   case '-': justify_left = 1; break;
+                   case '+': force_sign = 1; space_for_positive = 0; break;
+                   case ' ': force_sign = 1;
+                             // If both the ' ' and '+' flags appear, the ' '
+                             // flag should be ignored
+                             break;
+                   case '#': alternate_form = 1; break;
+                   case '\'': break;
+               }
+               p++;
+           }
+           // If the '0' and '-' flags both appear, the '0' flag should be
+           // ignored.
+ 
+           // parse field width
+           if (*p == '*')
+           {
+               int j;
+ 
+               p++;
+               j =
+ # if defined(FEAT_EVAL)
+                   tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                       va_arg(ap, int);
+               if (j >= 0)
+                   min_field_width = j;
+               else
+               {
+                   min_field_width = -j;
+                   justify_left = 1;
+               }
+           }
+           else if (VIM_ISDIGIT((int)(*p)))
+           {
+               // size_t could be wider than unsigned int; make sure we treat
+               // argument like common implementations do
+               unsigned int uj = *p++ - '0';
+ 
+               while (VIM_ISDIGIT((int)(*p)))
+                   uj = 10 * uj + (unsigned int)(*p++ - '0');
+               min_field_width = uj;
+           }
+ 
+           // parse precision
+           if (*p == '.')
+           {
+               p++;
+               precision_specified = 1;
+               if (*p == '*')
+               {
+                   int j;
+ 
+                   j =
+ # if defined(FEAT_EVAL)
+                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                           va_arg(ap, int);
+                   p++;
+                   if (j >= 0)
+                       precision = j;
+                   else
+                   {
+                       precision_specified = 0;
+                       precision = 0;
+                   }
+               }
+               else if (VIM_ISDIGIT((int)(*p)))
+               {
+                   // size_t could be wider than unsigned int; make sure we
+                   // treat argument like common implementations do
+                   unsigned int uj = *p++ - '0';
+ 
+                   while (VIM_ISDIGIT((int)(*p)))
+                       uj = 10 * uj + (unsigned int)(*p++ - '0');
+                   precision = uj;
+               }
+           }
+ 
+           // parse 'h', 'l' and 'll' length modifiers
+           if (*p == 'h' || *p == 'l')
+           {
+               length_modifier = *p;
+               p++;
+               if (length_modifier == 'l' && *p == 'l')
+               {
+                   // double l = __int64 / varnumber_T
+                   length_modifier = 'L';
+                   p++;
+               }
+           }
+           fmt_spec = *p;
+ 
+           // common synonyms:
+           switch (fmt_spec)
+           {
+               case 'i': fmt_spec = 'd'; break;
+               case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+               case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+               case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+               default: break;
+           }
+ 
+ # if defined(FEAT_EVAL)
+           switch (fmt_spec)
+           {
+               case 'd': case 'u': case 'o': case 'x': case 'X':
+                   if (tvs != NULL && length_modifier == '\0')
+                       length_modifier = 'L';
+           }
+ # endif
+ 
+           // get parameter value, do initial processing
+           switch (fmt_spec)
+           {
+               // '%' and 'c' behave similar to 's' regarding flags and field
+               // widths
+           case '%':
+           case 'c':
+           case 's':
+           case 'S':
+               str_arg_l = 1;
+               switch (fmt_spec)
+               {
+               case '%':
+                   str_arg = p;
+                   break;
+ 
+               case 'c':
+                   {
+                       int j;
+ 
+                       j =
+ # if defined(FEAT_EVAL)
+                           tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                               va_arg(ap, int);
+                       // standard demands unsigned char
+                       uchar_arg = (unsigned char)j;
+                       str_arg = (char *)&uchar_arg;
+                       break;
+                   }
+ 
+               case 's':
+               case 'S':
+                   str_arg =
+ # if defined(FEAT_EVAL)
+                               tvs != NULL ? tv_str(tvs, &arg_idx, &tofree) :
+ # endif
+                                   va_arg(ap, char *);
+                   if (str_arg == NULL)
+                   {
+                       str_arg = "[NULL]";
+                       str_arg_l = 6;
+                   }
+                   // make sure not to address string beyond the specified
+                   // precision !!!
+                   else if (!precision_specified)
+                       str_arg_l = strlen(str_arg);
+                   // truncate string if necessary as requested by precision
+                   else if (precision == 0)
+                       str_arg_l = 0;
+                   else
+                   {
+                       // Don't put the #if inside memchr(), it can be a
+                       // macro.
+                       // memchr on HP does not like n > 2^31  !!!
+                       char *q = memchr(str_arg, '\0',
+                                 precision <= (size_t)0x7fffffffL ? precision
+                                                      : (size_t)0x7fffffffL);
+                       str_arg_l = (q == NULL) ? precision
+                                                     : (size_t)(q - str_arg);
+                   }
+                   if (fmt_spec == 'S')
+                   {
+                       if (min_field_width != 0)
+                           min_field_width += STRLEN(str_arg)
+                                    - mb_string2cells((char_u *)str_arg, -1);
+                       if (precision)
+                       {
+                           char_u  *p1;
+                           size_t  i = 0;
+ 
+                           for (p1 = (char_u *)str_arg; *p1;
+                                                         p1 += mb_ptr2len(p1))
+                           {
+                               i += (size_t)mb_ptr2cells(p1);
+                               if (i > precision)
+                                   break;
+                           }
+                           str_arg_l = precision = p1 - (char_u *)str_arg;
+                       }
+                   }
+                   break;
+ 
+               default:
+                   break;
+               }
+               break;
+ 
+           case 'd': case 'u':
+           case 'b': case 'B':
+           case 'o':
+           case 'x': case 'X':
+           case 'p':
+               {
+                   // NOTE: the u, b, o, x, X and p conversion specifiers
+                   // imply the value is unsigned;  d implies a signed
+                   // value
+ 
+                   // 0 if numeric argument is zero (or if pointer is
+                   // NULL for 'p'), +1 if greater than zero (or nonzero
+                   // for unsigned arguments), -1 if negative (unsigned
+                   // argument is never negative)
+                   int arg_sign = 0;
+ 
+                   // only set for length modifier h, or for no length
+                   // modifiers
+                   int int_arg = 0;
+                   unsigned int uint_arg = 0;
+ 
+                   // only set for length modifier l
+                   long int long_arg = 0;
+                   unsigned long int ulong_arg = 0;
+ 
+                   // only set for length modifier ll
+                   varnumber_T llong_arg = 0;
+                   uvarnumber_T ullong_arg = 0;
+ 
+                   // only set for b conversion
+                   uvarnumber_T bin_arg = 0;
+ 
+                   // pointer argument value -only defined for p
+                   // conversion
+                   void *ptr_arg = NULL;
+ 
+                   if (fmt_spec == 'p')
+                   {
+                       length_modifier = '\0';
+                       ptr_arg =
+ # if defined(FEAT_EVAL)
+                                tvs != NULL ? (void *)tv_str(tvs, &arg_idx,
+                                                                       NULL) :
+ # endif
+                                       va_arg(ap, void *);
+                       if (ptr_arg != NULL)
+                           arg_sign = 1;
+                   }
+                   else if (fmt_spec == 'b' || fmt_spec == 'B')
+                   {
+                       bin_arg =
+ # if defined(FEAT_EVAL)
+                                   tvs != NULL ?
+                                          (uvarnumber_T)tv_nr(tvs, &arg_idx) :
+ # endif
+                                       va_arg(ap, uvarnumber_T);
+                       if (bin_arg != 0)
+                           arg_sign = 1;
+                   }
+                   else if (fmt_spec == 'd')
+                   {
+                       // signed
+                       switch (length_modifier)
+                       {
+                       case '\0':
+                       case 'h':
+                           // char and short arguments are passed as int.
+                           int_arg =
+ # if defined(FEAT_EVAL)
+                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                                           va_arg(ap, int);
+                           if (int_arg > 0)
+                               arg_sign =  1;
+                           else if (int_arg < 0)
+                               arg_sign = -1;
+                           break;
+                       case 'l':
+                           long_arg =
+ # if defined(FEAT_EVAL)
+                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                                           va_arg(ap, long int);
+                           if (long_arg > 0)
+                               arg_sign =  1;
+                           else if (long_arg < 0)
+                               arg_sign = -1;
+                           break;
+                       case 'L':
+                           llong_arg =
+ # if defined(FEAT_EVAL)
+                                       tvs != NULL ? tv_nr(tvs, &arg_idx) :
+ # endif
+                                           va_arg(ap, varnumber_T);
+                           if (llong_arg > 0)
+                               arg_sign =  1;
+                           else if (llong_arg < 0)
+                               arg_sign = -1;
+                           break;
+                       }
+                   }
+                   else
+                   {
+                       // unsigned
+                       switch (length_modifier)
+                       {
+                           case '\0':
+                           case 'h':
+                               uint_arg =
+ # if defined(FEAT_EVAL)
+                                           tvs != NULL ? (unsigned)
+                                                       tv_nr(tvs, &arg_idx) :
+ # endif
+                                               va_arg(ap, unsigned int);
+                               if (uint_arg != 0)
+                                   arg_sign = 1;
+                               break;
+                           case 'l':
+                               ulong_arg =
+ # if defined(FEAT_EVAL)
+                                           tvs != NULL ? (unsigned long)
+                                                       tv_nr(tvs, &arg_idx) :
+ # endif
+                                               va_arg(ap, unsigned long int);
+                               if (ulong_arg != 0)
+                                   arg_sign = 1;
+                               break;
+                           case 'L':
+                               ullong_arg =
+ # if defined(FEAT_EVAL)
+                                           tvs != NULL ? (uvarnumber_T)
+                                                       tv_nr(tvs, &arg_idx) :
+ # endif
+                                               va_arg(ap, uvarnumber_T);
+                               if (ullong_arg != 0)
+                                   arg_sign = 1;
+                               break;
+                       }
+                   }
+ 
+                   str_arg = tmp;
+                   str_arg_l = 0;
+ 
+                   // NOTE:
+                   //   For d, i, u, o, x, and X conversions, if precision is
+                   //   specified, the '0' flag should be ignored. This is so
+                   //   with Solaris 2.6, Digital UNIX 4.0, HPUX 10, Linux,
+                   //   FreeBSD, NetBSD; but not with Perl.
+                   if (precision_specified)
+                       zero_padding = 0;
+                   if (fmt_spec == 'd')
+                   {
+                       if (force_sign && arg_sign >= 0)
+                           tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+                       // leave negative numbers for sprintf to handle, to
+                       // avoid handling tricky cases like (short int)-32768
+                   }
+                   else if (alternate_form)
+                   {
+                       if (arg_sign != 0
+                                    && (fmt_spec == 'b' || fmt_spec == 'B'
+                                     || fmt_spec == 'x' || fmt_spec == 'X') )
+                       {
+                           tmp[str_arg_l++] = '0';
+                           tmp[str_arg_l++] = fmt_spec;
+                       }
+                       // alternate form should have no effect for p
+                       // conversion, but ...
+                   }
+ 
+                   zero_padding_insertion_ind = str_arg_l;
+                   if (!precision_specified)
+                       precision = 1;   // default precision is 1
+                   if (precision == 0 && arg_sign == 0)
+                   {
+                       // When zero value is formatted with an explicit
+                       // precision 0, the resulting formatted string is
+                       // empty (d, i, u, b, B, o, x, X, p).
+                   }
+                   else
+                   {
+                       char    f[6];
+                       int     f_l = 0;
+ 
+                       // construct a simple format string for sprintf
+                       f[f_l++] = '%';
+                       if (!length_modifier)
+                           ;
+                       else if (length_modifier == 'L')
+                       {
+ # ifdef MSWIN
+                           f[f_l++] = 'I';
+                           f[f_l++] = '6';
+                           f[f_l++] = '4';
+ # else
+                           f[f_l++] = 'l';
+                           f[f_l++] = 'l';
+ # endif
+                       }
+                       else
+                           f[f_l++] = length_modifier;
+                       f[f_l++] = fmt_spec;
+                       f[f_l++] = '\0';
+ 
+                       if (fmt_spec == 'p')
+                           str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
+                       else if (fmt_spec == 'b' || fmt_spec == 'B')
+                       {
+                           char            b[8 * sizeof(uvarnumber_T)];
+                           size_t          b_l = 0;
+                           uvarnumber_T    bn = bin_arg;
+ 
+                           do
+                           {
+                               b[sizeof(b) - ++b_l] = '0' + (bn & 0x1);
+                               bn >>= 1;
+                           }
+                           while (bn != 0);
+ 
+                           memcpy(tmp + str_arg_l, b + sizeof(b) - b_l, b_l);
+                           str_arg_l += b_l;
+                       }
+                       else if (fmt_spec == 'd')
+                       {
+                           // signed
+                           switch (length_modifier)
+                           {
+                           case '\0': str_arg_l += sprintf(
+                                                tmp + str_arg_l, f,
+                                                int_arg);
+                                      break;
+                           case 'h': str_arg_l += sprintf(
+                                                tmp + str_arg_l, f,
+                                                (short)int_arg);
+                                     break;
+                           case 'l': str_arg_l += sprintf(
+                                               tmp + str_arg_l, f, long_arg);
+                                     break;
+                           case 'L': str_arg_l += sprintf(
+                                              tmp + str_arg_l, f, llong_arg);
+                                     break;
+                           }
+                       }
+                       else
+                       {
+                           // unsigned
+                           switch (length_modifier)
+                           {
+                           case '\0': str_arg_l += sprintf(
+                                               tmp + str_arg_l, f,
+                                               uint_arg);
+                                      break;
+                           case 'h': str_arg_l += sprintf(
+                                               tmp + str_arg_l, f,
+                                               (unsigned short)uint_arg);
+                                     break;
+                           case 'l': str_arg_l += sprintf(
+                                              tmp + str_arg_l, f, ulong_arg);
+                                     break;
+                           case 'L': str_arg_l += sprintf(
+                                             tmp + str_arg_l, f, ullong_arg);
+                                     break;
+                           }
+                       }
+ 
+                       // include the optional minus sign and possible
+                       // "0x" in the region before the zero padding
+                       // insertion point
+                       if (zero_padding_insertion_ind < str_arg_l
+                               && tmp[zero_padding_insertion_ind] == '-')
+                           zero_padding_insertion_ind++;
+                       if (zero_padding_insertion_ind + 1 < str_arg_l
+                               && tmp[zero_padding_insertion_ind]   == '0'
+                               && (tmp[zero_padding_insertion_ind + 1] == 'x'
+                                || tmp[zero_padding_insertion_ind + 1] == 'X'))
+                           zero_padding_insertion_ind += 2;
+                   }
+ 
+                   {
+                       size_t num_of_digits = str_arg_l
+                                                - zero_padding_insertion_ind;
+ 
+                       if (alternate_form && fmt_spec == 'o'
+                               // unless zero is already the first
+                               // character
+                               && !(zero_padding_insertion_ind < str_arg_l
+                                   && tmp[zero_padding_insertion_ind] == '0'))
+                       {
+                           // assure leading zero for alternate-form
+                           // octal numbers
+                           if (!precision_specified
+                                            || precision < num_of_digits + 1)
+                           {
+                               // precision is increased to force the
+                               // first character to be zero, except if a
+                               // zero value is formatted with an
+                               // explicit precision of zero
+                               precision = num_of_digits + 1;
+                           }
+                       }
+                       // zero padding to specified precision?
+                       if (num_of_digits < precision)
+                           number_of_zeros_to_pad = precision - num_of_digits;
+                   }
+                   // zero padding to specified minimal field width?
+                   if (!justify_left && zero_padding)
+                   {
+                       int n = (int)(min_field_width - (str_arg_l
+                                                   + number_of_zeros_to_pad));
+                       if (n > 0)
+                           number_of_zeros_to_pad += n;
+                   }
+                   break;
+               }
+ 
+ # ifdef FEAT_FLOAT
+           case 'f':
+           case 'F':
+           case 'e':
+           case 'E':
+           case 'g':
+           case 'G':
+               {
+                   // Floating point.
+                   double      f;
+                   double      abs_f;
+                   char        format[40];
+                   int         l;
+                   int         remove_trailing_zeroes = FALSE;
+ 
+                   f =
+ #  if defined(FEAT_EVAL)
+                       tvs != NULL ? tv_float(tvs, &arg_idx) :
+ #  endif
+                           va_arg(ap, double);
+                   abs_f = f < 0 ? -f : f;
+ 
+                   if (fmt_spec == 'g' || fmt_spec == 'G')
+                   {
+                       // Would be nice to use %g directly, but it prints
+                       // "1.0" as "1", we don't want that.
+                       if ((abs_f >= 0.001 && abs_f < 10000000.0)
+                                                             || abs_f == 0.0)
+                           fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
+                       else
+                           fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
+                       remove_trailing_zeroes = TRUE;
+                   }
+ 
+                   if ((fmt_spec == 'f' || fmt_spec == 'F') &&
+ #  ifdef VAX
+                           abs_f > 1.0e38
+ #  else
+                           abs_f > 1.0e307
+ #  endif
+                           )
+                   {
+                       // Avoid a buffer overflow
+                       STRCPY(tmp, infinity_str(f > 0.0, fmt_spec,
+                                             force_sign, space_for_positive));
+                       str_arg_l = STRLEN(tmp);
+                       zero_padding = 0;
+                   }
+                   else
+                   {
+                       if (isnan(f))
+                       {
+                           // Not a number: nan or NAN
+                           STRCPY(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN"
+                                                                     : "nan");
+                           str_arg_l = 3;
+                           zero_padding = 0;
+                       }
+                       else if (isinf(f))
+                       {
+                           STRCPY(tmp, infinity_str(f > 0.0, fmt_spec,
+                                             force_sign, space_for_positive));
+                           str_arg_l = STRLEN(tmp);
+                           zero_padding = 0;
+                       }
+                       else
+                       {
+                           // Regular float number
+                           format[0] = '%';
+                           l = 1;
+                           if (force_sign)
+                               format[l++] = space_for_positive ? ' ' : '+';
+                           if (precision_specified)
+                           {
+                               size_t max_prec = TMP_LEN - 10;
+ 
+                               // Make sure we don't get more digits than we
+                               // have room for.
+                               if ((fmt_spec == 'f' || fmt_spec == 'F')
+                                                               && abs_f > 1.0)
+                                   max_prec -= (size_t)log10(abs_f);
+                               if (precision > max_prec)
+                                   precision = max_prec;
+                               l += sprintf(format + l, ".%d", (int)precision);
+                           }
+                           format[l] = fmt_spec == 'F' ? 'f' : fmt_spec;
+                           format[l + 1] = NUL;
+ 
+                           str_arg_l = sprintf(tmp, format, f);
+                       }
+ 
+                       if (remove_trailing_zeroes)
+                       {
+                           int i;
+                           char *tp;
+ 
+                           // Using %g or %G: remove superfluous zeroes.
+                           if (fmt_spec == 'f' || fmt_spec == 'F')
+                               tp = tmp + str_arg_l - 1;
+                           else
+                           {
+                               tp = (char *)vim_strchr((char_u *)tmp,
+                                                fmt_spec == 'e' ? 'e' : 'E');
+                               if (tp != NULL)
+                               {
+                                   // Remove superfluous '+' and leading
+                                   // zeroes from the exponent.
+                                   if (tp[1] == '+')
+                                   {
+                                       // Change "1.0e+07" to "1.0e07"
+                                       STRMOVE(tp + 1, tp + 2);
+                                       --str_arg_l;
+                                   }
+                                   i = (tp[1] == '-') ? 2 : 1;
+                                   while (tp[i] == '0')
+                                   {
+                                       // Change "1.0e07" to "1.0e7"
+                                       STRMOVE(tp + i, tp + i + 1);
+                                       --str_arg_l;
+                                   }
+                                   --tp;
+                               }
+                           }
+ 
+                           if (tp != NULL && !precision_specified)
+                               // Remove trailing zeroes, but keep the one
+                               // just after a dot.
+                               while (tp > tmp + 2 && *tp == '0'
+                                                            && tp[-1] != '.')
+                               {
+                                   STRMOVE(tp, tp + 1);
+                                   --tp;
+                                   --str_arg_l;
+                               }
+                       }
+                       else
+                       {
+                           char *tp;
+ 
+                           // Be consistent: some printf("%e") use 1.0e+12
+                           // and some 1.0e+012.  Remove one zero in the last
+                           // case.
+                           tp = (char *)vim_strchr((char_u *)tmp,
+                                                fmt_spec == 'e' ? 'e' : 'E');
+                           if (tp != NULL && (tp[1] == '+' || tp[1] == '-')
+                                         && tp[2] == '0'
+                                         && vim_isdigit(tp[3])
+                                         && vim_isdigit(tp[4]))
+                           {
+                               STRMOVE(tp + 2, tp + 3);
+                               --str_arg_l;
+                           }
+                       }
+                   }
+                   if (zero_padding && min_field_width > str_arg_l
+                                             && (tmp[0] == '-' || force_sign))
+                   {
+                       // padding 0's should be inserted after the sign
+                       number_of_zeros_to_pad = min_field_width - str_arg_l;
+                       zero_padding_insertion_ind = 1;
+                   }
+                   str_arg = tmp;
+                   break;
+               }
+ # endif
+ 
+           default:
+               // unrecognized conversion specifier, keep format string
+               // as-is
+               zero_padding = 0;  // turn zero padding off for non-numeric
+                                  // conversion
+               justify_left = 1;
+               min_field_width = 0;                // reset flags
+ 
+               // discard the unrecognized conversion, just keep *
+               // the unrecognized conversion character
+               str_arg = p;
+               str_arg_l = 0;
+               if (*p != NUL)
+                   str_arg_l++;  // include invalid conversion specifier
+                                 // unchanged if not at end-of-string
+               break;
+           }
+ 
+           if (*p != NUL)
+               p++;     // step over the just processed conversion specifier
+ 
+           // insert padding to the left as requested by min_field_width;
+           // this does not include the zero padding in case of numerical
+           // conversions
+           if (!justify_left)
+           {
+               // left padding with blank or zero
+               int pn = (int)(min_field_width - (str_arg_l + 
number_of_zeros_to_pad));
+ 
+               if (pn > 0)
+               {
+                   if (str_l < str_m)
+                   {
+                       size_t avail = str_m - str_l;
+ 
+                       vim_memset(str + str_l, zero_padding ? '0' : ' ',
+                                            (size_t)pn > avail ? avail
+                                                               : (size_t)pn);
+                   }
+                   str_l += pn;
+               }
+           }
+ 
+           // zero padding as requested by the precision or by the minimal
+           // field width for numeric conversions required?
+           if (number_of_zeros_to_pad == 0)
+           {
+               // will not copy first part of numeric right now, *
+               // force it to be copied later in its entirety
+               zero_padding_insertion_ind = 0;
+           }
+           else
+           {
+               // insert first part of numerics (sign or '0x') before zero
+               // padding
+               int zn = (int)zero_padding_insertion_ind;
+ 
+               if (zn > 0)
+               {
+                   if (str_l < str_m)
+                   {
+                       size_t avail = str_m - str_l;
+ 
+                       mch_memmove(str + str_l, str_arg,
+                                            (size_t)zn > avail ? avail
+                                                               : (size_t)zn);
+                   }
+                   str_l += zn;
+               }
+ 
+               // insert zero padding as requested by the precision or min
+               // field width
+               zn = (int)number_of_zeros_to_pad;
+               if (zn > 0)
+               {
+                   if (str_l < str_m)
+                   {
+                       size_t avail = str_m - str_l;
+ 
+                       vim_memset(str + str_l, '0',
+                                            (size_t)zn > avail ? avail
+                                                               : (size_t)zn);
+                   }
+                   str_l += zn;
+               }
+           }
+ 
+           // insert formatted string
+           // (or as-is conversion specifier for unknown conversions)
+           {
+               int sn = (int)(str_arg_l - zero_padding_insertion_ind);
+ 
+               if (sn > 0)
+               {
+                   if (str_l < str_m)
+                   {
+                       size_t avail = str_m - str_l;
+ 
+                       mch_memmove(str + str_l,
+                               str_arg + zero_padding_insertion_ind,
+                               (size_t)sn > avail ? avail : (size_t)sn);
+                   }
+                   str_l += sn;
+               }
+           }
+ 
+           // insert right padding
+           if (justify_left)
+           {
+               // right blank padding to the field width
+               int pn = (int)(min_field_width
+                                     - (str_arg_l + number_of_zeros_to_pad));
+ 
+               if (pn > 0)
+               {
+                   if (str_l < str_m)
+                   {
+                       size_t avail = str_m - str_l;
+ 
+                       vim_memset(str + str_l, ' ',
+                                            (size_t)pn > avail ? avail
+                                                               : (size_t)pn);
+                   }
+                   str_l += pn;
+               }
+           }
+           vim_free(tofree);
+       }
+     }
+ 
+     if (str_m > 0)
+     {
+       // make sure the string is nul-terminated even at the expense of
+       // overwriting the last character (shouldn't happen, but just in case)
+       //
+       str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
+     }
+ 
+     if (tvs != NULL && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
+       emsg(_("E767: Too many arguments to printf()"));
+ 
+     // Return the number of characters formatted (excluding trailing nul
+     // character), that is, the number of characters that would have been
+     // written to the buffer if it were large enough.
+     return (int)str_l;
+ }
+ 
+ #endif // PROTO
*** ../vim-8.2.3319/src/vim9compile.c   2021-08-08 14:41:48.723930691 +0200
--- src/vim9compile.c   2021-08-09 19:56:02.955236082 +0200
***************
*** 1012,1018 ****
   * Return TRUE if "actual" could be "expected" and a runtime typecheck is to 
be
   * used.  Return FALSE if the types will never match.
   */
!     int
  use_typecheck(type_T *actual, type_T *expected)
  {
      if (actual->tt_type == VAR_ANY
--- 1012,1018 ----
   * Return TRUE if "actual" could be "expected" and a runtime typecheck is to 
be
   * used.  Return FALSE if the types will never match.
   */
!     static int
  use_typecheck(type_T *actual, type_T *expected)
  {
      if (actual->tt_type == VAR_ANY
***************
*** 3579,3585 ****
   * Return a pointer to just after the name.  Equal to "arg" if there is no
   * valid name.
   */
!     char_u *
  to_name_end(char_u *arg, int use_namespace)
  {
      char_u    *p;
--- 3579,3585 ----
   * Return a pointer to just after the name.  Equal to "arg" if there is no
   * valid name.
   */
!     static char_u *
  to_name_end(char_u *arg, int use_namespace)
  {
      char_u    *p;
*** ../vim-8.2.3319/src/vim9script.c    2021-08-05 20:39:59.354053658 +0200
--- src/vim9script.c    2021-08-09 19:56:02.955236082 +0200
***************
*** 246,251 ****
--- 246,293 ----
  }
  
  /*
+  * Free the script variables from "sn_all_vars".
+  */
+     static void
+ free_all_script_vars(scriptitem_T *si)
+ {
+     int               todo;
+     hashtab_T *ht = &si->sn_all_vars.dv_hashtab;
+     hashitem_T        *hi;
+     sallvar_T *sav;
+     sallvar_T *sav_next;
+ 
+     hash_lock(ht);
+     todo = (int)ht->ht_used;
+     for (hi = ht->ht_array; todo > 0; ++hi)
+     {
+       if (!HASHITEM_EMPTY(hi))
+       {
+           --todo;
+ 
+           // Free the variable.  Don't remove it from the hashtab, ht_array
+           // might change then.  hash_clear() takes care of it later.
+           sav = HI2SAV(hi);
+           while (sav != NULL)
+           {
+               sav_next = sav->sav_next;
+               if (sav->sav_di == NULL)
+                   clear_tv(&sav->sav_tv);
+               vim_free(sav);
+               sav = sav_next;
+           }
+       }
+     }
+     hash_clear(ht);
+     hash_init(ht);
+ 
+     ga_clear(&si->sn_var_vals);
+ 
+     // existing commands using script variable indexes are no longer valid
+     si->sn_script_seq = current_sctx.sc_seq;
+ }
+ 
+ /*
   * Free all imported items in script "sid".
   */
      void
***************
*** 286,400 ****
  }
  
  /*
-  * ":import Item from 'filename'"
-  * ":import Item as Alias from 'filename'"
-  * ":import {Item} from 'filename'".
-  * ":import {Item as Alias} from 'filename'"
-  * ":import {Item, Item} from 'filename'"
-  * ":import {Item, Item as Alias} from 'filename'"
-  *
-  * ":import * as Name from 'filename'"
-  */
-     void
- ex_import(exarg_T *eap)
- {
-     char_u    *cmd_end;
-     evalarg_T evalarg;
- 
-     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
-     {
-       emsg(_(e_import_can_only_be_used_in_script));
-       return;
-     }
-     fill_evalarg_from_eap(&evalarg, eap, eap->skip);
- 
-     cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid,
-                                                              &evalarg, NULL);
-     if (cmd_end != NULL)
-       set_nextcmd(eap, cmd_end);
-     clear_evalarg(&evalarg, eap);
- }
- 
- /*
-  * Find an exported item in "sid" matching the name at "*argp".
-  * When it is a variable return the index.
-  * When it is a user function return "*ufunc".
-  * When not found returns -1 and "*ufunc" is NULL.
-  */
-     int
- find_exported(
-       int         sid,
-       char_u      *name,
-       ufunc_T     **ufunc,
-       type_T      **type,
-       cctx_T      *cctx,
-       int         verbose)
- {
-     int               idx = -1;
-     svar_T    *sv;
-     scriptitem_T *script = SCRIPT_ITEM(sid);
- 
-     // Find name in "script".
-     idx = get_script_item_idx(sid, name, 0, cctx);
-     if (idx >= 0)
-     {
-       sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
-       if (!sv->sv_export)
-       {
-           if (verbose)
-               semsg(_(e_item_not_exported_in_script_str), name);
-           return -1;
-       }
-       *type = sv->sv_type;
-       *ufunc = NULL;
-     }
-     else
-     {
-       char_u  buffer[200];
-       char_u  *funcname;
- 
-       // it could be a user function.
-       if (STRLEN(name) < sizeof(buffer) - 15)
-           funcname = buffer;
-       else
-       {
-           funcname = alloc(STRLEN(name) + 15);
-           if (funcname == NULL)
-               return -1;
-       }
-       funcname[0] = K_SPECIAL;
-       funcname[1] = KS_EXTRA;
-       funcname[2] = (int)KE_SNR;
-       sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
-       *ufunc = find_func(funcname, FALSE, NULL);
-       if (funcname != buffer)
-           vim_free(funcname);
- 
-       if (*ufunc == NULL)
-       {
-           if (verbose)
-               semsg(_(e_item_not_found_in_script_str), name);
-           return -1;
-       }
-       else if (((*ufunc)->uf_flags & FC_EXPORT) == 0)
-       {
-           if (verbose)
-               semsg(_(e_item_not_exported_in_script_str), name);
-           *ufunc = NULL;
-           return -1;
-       }
-     }
- 
-     return idx;
- }
- 
- /*
   * Handle an ":import" command and add the resulting imported_T to "gap", when
   * not NULL, or script "import_sid" sn_imports.
   * "cctx" is NULL at the script level.
   * Returns a pointer to after the command or NULL in case of failure
   */
!     char_u *
  handle_import(
        char_u      *arg_start,
        garray_T    *gap,
--- 328,339 ----
  }
  
  /*
   * Handle an ":import" command and add the resulting imported_T to "gap", when
   * not NULL, or script "import_sid" sn_imports.
   * "cctx" is NULL at the script level.
   * Returns a pointer to after the command or NULL in case of failure
   */
!     static char_u *
  handle_import(
        char_u      *arg_start,
        garray_T    *gap,
***************
*** 676,681 ****
--- 615,723 ----
  }
  
  /*
+  * ":import Item from 'filename'"
+  * ":import Item as Alias from 'filename'"
+  * ":import {Item} from 'filename'".
+  * ":import {Item as Alias} from 'filename'"
+  * ":import {Item, Item} from 'filename'"
+  * ":import {Item, Item as Alias} from 'filename'"
+  *
+  * ":import * as Name from 'filename'"
+  */
+     void
+ ex_import(exarg_T *eap)
+ {
+     char_u    *cmd_end;
+     evalarg_T evalarg;
+ 
+     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
+     {
+       emsg(_(e_import_can_only_be_used_in_script));
+       return;
+     }
+     fill_evalarg_from_eap(&evalarg, eap, eap->skip);
+ 
+     cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid,
+                                                              &evalarg, NULL);
+     if (cmd_end != NULL)
+       set_nextcmd(eap, cmd_end);
+     clear_evalarg(&evalarg, eap);
+ }
+ 
+ /*
+  * Find an exported item in "sid" matching the name at "*argp".
+  * When it is a variable return the index.
+  * When it is a user function return "*ufunc".
+  * When not found returns -1 and "*ufunc" is NULL.
+  */
+     int
+ find_exported(
+       int         sid,
+       char_u      *name,
+       ufunc_T     **ufunc,
+       type_T      **type,
+       cctx_T      *cctx,
+       int         verbose)
+ {
+     int               idx = -1;
+     svar_T    *sv;
+     scriptitem_T *script = SCRIPT_ITEM(sid);
+ 
+     // Find name in "script".
+     idx = get_script_item_idx(sid, name, 0, cctx);
+     if (idx >= 0)
+     {
+       sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
+       if (!sv->sv_export)
+       {
+           if (verbose)
+               semsg(_(e_item_not_exported_in_script_str), name);
+           return -1;
+       }
+       *type = sv->sv_type;
+       *ufunc = NULL;
+     }
+     else
+     {
+       char_u  buffer[200];
+       char_u  *funcname;
+ 
+       // it could be a user function.
+       if (STRLEN(name) < sizeof(buffer) - 15)
+           funcname = buffer;
+       else
+       {
+           funcname = alloc(STRLEN(name) + 15);
+           if (funcname == NULL)
+               return -1;
+       }
+       funcname[0] = K_SPECIAL;
+       funcname[1] = KS_EXTRA;
+       funcname[2] = (int)KE_SNR;
+       sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
+       *ufunc = find_func(funcname, FALSE, NULL);
+       if (funcname != buffer)
+           vim_free(funcname);
+ 
+       if (*ufunc == NULL)
+       {
+           if (verbose)
+               semsg(_(e_item_not_found_in_script_str), name);
+           return -1;
+       }
+       else if (((*ufunc)->uf_flags & FC_EXPORT) == 0)
+       {
+           if (verbose)
+               semsg(_(e_item_not_exported_in_script_str), name);
+           *ufunc = NULL;
+           return -1;
+       }
+     }
+ 
+     return idx;
+ }
+ 
+ /*
   * Declare a script-local variable without init: "let var: type".
   * "const" is an error since the value is missing.
   * Returns a pointer to after the type.
***************
*** 904,951 ****
  }
  
  /*
-  * Free the script variables from "sn_all_vars".
-  */
-     void
- free_all_script_vars(scriptitem_T *si)
- {
-     int               todo;
-     hashtab_T *ht = &si->sn_all_vars.dv_hashtab;
-     hashitem_T        *hi;
-     sallvar_T *sav;
-     sallvar_T *sav_next;
- 
-     hash_lock(ht);
-     todo = (int)ht->ht_used;
-     for (hi = ht->ht_array; todo > 0; ++hi)
-     {
-       if (!HASHITEM_EMPTY(hi))
-       {
-           --todo;
- 
-           // Free the variable.  Don't remove it from the hashtab, ht_array
-           // might change then.  hash_clear() takes care of it later.
-           sav = HI2SAV(hi);
-           while (sav != NULL)
-           {
-               sav_next = sav->sav_next;
-               if (sav->sav_di == NULL)
-                   clear_tv(&sav->sav_tv);
-               vim_free(sav);
-               sav = sav_next;
-           }
-       }
-     }
-     hash_clear(ht);
-     hash_init(ht);
- 
-     ga_clear(&si->sn_var_vals);
- 
-     // existing commands using script variable indexes are no longer valid
-     si->sn_script_seq = current_sctx.sc_seq;
- }
- 
- /*
   * Find the script-local variable that links to "dest".
   * Returns NULL if not found and give an internal error.
   */
--- 946,951 ----
*** ../vim-8.2.3319/src/vim9type.c      2021-08-01 15:40:24.648232770 +0200
--- src/vim9type.c      2021-08-09 19:56:02.955236082 +0200
***************
*** 24,30 ****
   * Allocate memory for a type_T and add the pointer to type_gap, so that it 
can
   * be easily freed later.
   */
!     type_T *
  get_type_ptr(garray_T *type_gap)
  {
      type_T *type;
--- 24,30 ----
   * Allocate memory for a type_T and add the pointer to type_gap, so that it 
can
   * be easily freed later.
   */
!     static type_T *
  get_type_ptr(garray_T *type_gap)
  {
      type_T *type;
*** ../vim-8.2.3319/src/window.c        2021-08-07 22:35:49.034237954 +0200
--- src/window.c        2021-08-09 19:56:02.955236082 +0200
***************
*** 4475,4481 ****
  #endif
  }
  
! #if defined(FEAT_PERL) || defined(FEAT_LUA) || defined(PROTO)
  /*
   * Find window number "winnr" (counting top to bottom).
   */
--- 4475,4481 ----
  #endif
  }
  
! #if defined(FEAT_PERL) || defined(PROTO)
  /*
   * Find window number "winnr" (counting top to bottom).
   */
*** ../vim-8.2.3319/src/version.c       2021-08-09 13:20:30.198002335 +0200
--- src/version.c       2021-08-09 19:58:29.930887032 +0200
***************
*** 757,758 ****
--- 757,760 ----
  {   /* Add new patch number below this line */
+ /**/
+     3320,
  /**/

-- 
BLACK KNIGHT:  I move for no man.
ARTHUR:        So be it!
    [hah] [parry thrust]
    [ARTHUR chops the BLACK KNIGHT's left arm off]
ARTHUR:        Now stand aside, worthy adversary.
BLACK KNIGHT:  'Tis but a scratch.
                                  The Quest for the Holy Grail (Monty Python)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/202108091759.179Hxd5s2444237%40masaka.moolenaar.net.

Raspunde prin e-mail lui