summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2021-08-09 19:59:06 +0200
committerBram Moolenaar <Bram@vim.org>2021-08-09 19:59:06 +0200
commit8ee52affe7fd4daa03e002bc06611f0a8c3bcd5b (patch)
treebf218a0a9a9a0c8c182aca16491f5063f79acce5 /src
parenteed9616120f60ad17d5e133f505bba5c559aee89 (diff)
downloadvim-git-8ee52affe7fd4daa03e002bc06611f0a8c3bcd5b.tar.gz
patch 8.2.3320: some local functions are not staticv8.2.3320
Problem: Some local functions are not static. Solution: Add "static". Move snprintf() related code to strings.c. (Yegappan Lakshmanan, closes #8734)
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c24
-rw-r--r--src/channel.c2
-rw-r--r--src/dict.c2
-rw-r--r--src/digraph.c4
-rw-r--r--src/edit.c2
-rw-r--r--src/ex_docmd.c2
-rw-r--r--src/getchar.c2
-rw-r--r--src/job.c2
-rw-r--r--src/list.c2
-rw-r--r--src/message.c1110
-rw-r--r--src/profiler.c36
-rw-r--r--src/proto/channel.pro1
-rw-r--r--src/proto/dict.pro1
-rw-r--r--src/proto/digraph.pro2
-rw-r--r--src/proto/edit.pro1
-rw-r--r--src/proto/ex_docmd.pro1
-rw-r--r--src/proto/getchar.pro1
-rw-r--r--src/proto/job.pro1
-rw-r--r--src/proto/list.pro1
-rw-r--r--src/proto/profiler.pro1
-rw-r--r--src/proto/spell.pro1
-rw-r--r--src/proto/vim9compile.pro2
-rw-r--r--src/proto/vim9script.pro2
-rw-r--r--src/proto/vim9type.pro1
-rw-r--r--src/spell.c2
-rw-r--r--src/strings.c1122
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c4
-rw-r--r--src/vim9script.c292
-rw-r--r--src/vim9type.c2
-rw-r--r--src/window.c2
31 files changed, 1303 insertions, 1327 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 817e322fd..a2dc08067 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -232,19 +232,15 @@ lalloc(size_t size, int message)
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.
- */
+ // 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()
- */
+ // 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,10 +264,8 @@ lalloc(size_t size, int message)
goto theend;
#endif
}
- /*
- * Remember that mf_release_all() is being called to avoid an endless
- * loop, because mf_release_all() may call alloc() recursively.
- */
+ // 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;
diff --git a/src/channel.c b/src/channel.c
index 47c742d83..9c23bf47b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -3025,7 +3025,7 @@ channel_has_readahead(channel_T *channel, ch_part_T part)
* Return a string indicating the status of the channel.
* If "req_part" is not negative check that part.
*/
- char *
+ static char *
channel_status(channel_T *channel, int req_part)
{
ch_part_T part;
diff --git a/src/dict.c b/src/dict.c
index 82397d512..9ce6dda3d 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -805,7 +805,7 @@ dict2string(typval_T *tv, int copyID, int restore_copyID)
* Advance over a literal key, including "-". If the first character is not a
* literal key character then "key" is returned.
*/
- char_u *
+ static char_u *
skip_literal_key(char_u *key)
{
char_u *p;
diff --git a/src/digraph.c b/src/digraph.c
index 4a185399d..2bc02ebed 100644
--- a/src/digraph.c
+++ b/src/digraph.c
@@ -2029,7 +2029,7 @@ registerdigraph(int char1, int char2, int n)
* If they are valid, returns TRUE; otherwise, give an error message and
* returns FALSE.
*/
- int
+ static int
check_digraph_chars_valid(int char1, int char2)
{
if (char2 == 0)
@@ -2193,7 +2193,7 @@ digraph_getlist_appendpair(digr_T *dp, list_T *l)
li2->li_tv.vval.v_string = vim_strsave(buf);
}
- void
+ static void
digraph_getlist_common(int list_all, typval_T *rettv)
{
int i;
diff --git a/src/edit.c b/src/edit.c
index 6bdeded00..93b1342db 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1587,7 +1587,7 @@ ins_ctrl_v(void)
* Note that this doesn't wait for characters, they must be in the typeahead
* buffer already.
*/
- int
+ static int
decodeModifyOtherKeys(int c)
{
char_u *p = typebuf.tb_buf + typebuf.tb_off;
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index c071a7a13..0f0e627d1 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -598,7 +598,7 @@ do_cmdline_cmd(char_u *cmd)
* Execute the "+cmd" argument of "edit +cmd fname" and the like.
* This allows for using a range without ":" in Vim9 script.
*/
- int
+ static int
do_cmd_argument(char_u *cmd)
{
return do_cmdline(cmd, NULL, NULL,
diff --git a/src/getchar.c b/src/getchar.c
index 196a3aeeb..52c77210a 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -631,7 +631,7 @@ stuffRedoReadbuff(char_u *s)
add_buff(&readbuf2, s, -1L);
}
- void
+ static void
stuffReadbuffLen(char_u *s, long len)
{
add_buff(&readbuf1, s, len);
diff --git a/src/job.c b/src/job.c
index 892d237a3..884bf64b8 100644
--- a/src/job.c
+++ b/src/job.c
@@ -1582,7 +1582,7 @@ invoke_prompt_interrupt(void)
/*
* Return the effective prompt for the specified buffer.
*/
- char_u *
+ static char_u *
buf_prompt_text(buf_T* buf)
{
if (buf->b_prompt_text == NULL)
diff --git a/src/list.c b/src/list.c
index bf24cee22..afbc7d395 100644
--- a/src/list.c
+++ b/src/list.c
@@ -620,7 +620,7 @@ list_append_tv(list_T *l, typval_T *tv)
* As list_append_tv() but move the value instead of copying it.
* Return FAIL when out of memory.
*/
- int
+ static int
list_append_tv_move(list_T *l, typval_T *tv)
{
listitem_T *li = listitem_alloc();
diff --git a/src/message.c b/src/message.c
index 7fb7264bd..23b84fa83 100644
--- a/src/message.c
+++ b/src/message.c
@@ -12,7 +12,6 @@
*/
#define MESSAGE_FILE // don't include prototype for smsg()
-#define USING_FLOAT_STUFF
#include "vim.h"
@@ -4108,1112 +4107,3 @@ vim_dialog_yesnoallcancel(
}
#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 <mark.martinec@ijs.si>, 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
diff --git a/src/profiler.c b/src/profiler.c
index 6f2f2d0a8..3638a0b5c 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -555,6 +555,24 @@ func_do_profile(ufunc_T *fp)
}
/*
+ * 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,24 +811,6 @@ script_do_profile(scriptitem_T *si)
}
/*
- * 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
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 32e68d894..17ce77711 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -24,7 +24,6 @@ void channel_consume(channel_T *channel, ch_part_T part, int len);
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);
diff --git a/src/proto/dict.pro b/src/proto/dict.pro
index 5d7638538..3089c1fff 100644
--- a/src/proto/dict.pro
+++ b/src/proto/dict.pro
@@ -34,7 +34,6 @@ varnumber_T dict_get_number_def(dict_T *d, char_u *key, int def);
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);
diff --git a/src/proto/digraph.pro b/src/proto/digraph.pro
index 8a6566c2d..09089352d 100644
--- a/src/proto/digraph.pro
+++ b/src/proto/digraph.pro
@@ -3,10 +3,8 @@ int do_digraph(int c);
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);
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
index d1b34c36d..a233e401a 100644
--- a/src/proto/edit.pro
+++ b/src/proto/edit.pro
@@ -2,7 +2,6 @@
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);
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index ae378d9ed..f96f8cf78 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -1,7 +1,6 @@
/* 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));
diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro
index 5f07ad6c2..0b357a28e 100644
--- a/src/proto/getchar.pro
+++ b/src/proto/getchar.pro
@@ -15,7 +15,6 @@ void AppendCharToRedobuff(int c);
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);
diff --git a/src/proto/job.pro b/src/proto/job.pro
index 3927e7f48..f740bd23d 100644
--- a/src/proto/job.pro
+++ b/src/proto/job.pro
@@ -20,7 +20,6 @@ char *job_status(job_T *job);
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);
diff --git a/src/proto/list.pro b/src/proto/list.pro
index 192981d86..c3c3227f5 100644
--- a/src/proto/list.pro
+++ b/src/proto/list.pro
@@ -24,7 +24,6 @@ listitem_T *list_find_index(list_T *l, long *idx);
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);
diff --git a/src/proto/profiler.pro b/src/proto/profiler.pro
index 1882fbf10..a7d065edb 100644
--- a/src/proto/profiler.pro
+++ b/src/proto/profiler.pro
@@ -27,7 +27,6 @@ void func_line_start(void *cookie, long lnum);
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);
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index 3f97008a3..4a3e85b14 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -5,7 +5,6 @@ int can_compound(slang_T *slang, char_u *word, char_u *flags);
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);
diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro
index bdefb4ec9..81da2a5df 100644
--- a/src/proto/vim9compile.pro
+++ b/src/proto/vim9compile.pro
@@ -1,7 +1,6 @@
/* 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);
@@ -9,7 +8,6 @@ imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
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);
diff --git a/src/proto/vim9script.pro b/src/proto/vim9script.pro
index 41bf1287a..1b73e87bb 100644
--- a/src/proto/vim9script.pro
+++ b/src/proto/vim9script.pro
@@ -11,11 +11,9 @@ void free_imports_and_script_vars(int sid);
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);
diff --git a/src/proto/vim9type.pro b/src/proto/vim9type.pro
index 6e8f486bc..b14e46665 100644
--- a/src/proto/vim9type.pro
+++ b/src/proto/vim9type.pro
@@ -1,5 +1,4 @@
/* 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);
diff --git a/src/spell.c b/src/spell.c
index 46912ffdf..f472f9932 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -1240,7 +1240,7 @@ spell_valid_case(
/*
* Return TRUE if spell checking is not enabled.
*/
- int
+ static int
no_spell_checking(win_T *wp)
{
if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
diff --git a/src/strings.c b/src/strings.c
index f4b83d908..ef0282a69 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -11,6 +11,7 @@
* strings.c: string manipulation functions
*/
+#define USING_FLOAT_STUFF
#include "vim.h"
/*
@@ -77,10 +78,8 @@ vim_strsave_escaped_ext(
unsigned length;
int l;
- /*
- * First count the number of backslashes required.
- * Then allocate the memory and insert them.
- */
+ // 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,10 +1264,8 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
len = slen - nbyte; // default: all bytes that are available.
}
- /*
- * Only return the overlap between the specified part and the actual
- * string.
- */
+ // Only return the overlap between the specified part and the actual
+ // string.
if (nbyte < 0)
{
len += nbyte;
@@ -1668,3 +1665,1112 @@ f_trim(typval_T *argvars, typval_T *rettv)
}
#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 <mark.martinec@ijs.si>, 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
diff --git a/src/version.c b/src/version.c
index 61d7b10f4..43ff1568a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3320,
+/**/
3319,
/**/
3318,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index c08aad634..6bb109069 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1012,7 +1012,7 @@ generate_SETTYPE(
* Return TRUE if "actual" could be "expected" and a runtime typecheck is to be
* used. Return FALSE if the types will never match.
*/
- int
+ static int
use_typecheck(type_T *actual, type_T *expected)
{
if (actual->tt_type == VAR_ANY
@@ -3579,7 +3579,7 @@ theend:
* Return a pointer to just after the name. Equal to "arg" if there is no
* valid name.
*/
- char_u *
+ static char_u *
to_name_end(char_u *arg, int use_namespace)
{
char_u *p;
diff --git a/src/vim9script.c b/src/vim9script.c
index 68919e8cc..66305a304 100644
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -246,6 +246,48 @@ new_imported(garray_T *gap)
}
/*
+ * 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,115 +328,12 @@ mark_imports_for_reload(int sid)
}
/*
- * ":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 *
+ static char_u *
handle_import(
char_u *arg_start,
garray_T *gap,
@@ -676,6 +615,109 @@ erret:
}
/*
+ * ":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,48 +946,6 @@ hide_script_var(scriptitem_T *si, int idx, int func_defined)
}
/*
- * 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.
*/
diff --git a/src/vim9type.c b/src/vim9type.c
index cb366f99e..d3562e788 100644
--- a/src/vim9type.c
+++ b/src/vim9type.c
@@ -24,7 +24,7 @@
* Allocate memory for a type_T and add the pointer to type_gap, so that it can
* be easily freed later.
*/
- type_T *
+ static type_T *
get_type_ptr(garray_T *type_gap)
{
type_T *type;
diff --git a/src/window.c b/src/window.c
index 1cc85497d..b0bdd5946 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4475,7 +4475,7 @@ win_goto(win_T *wp)
#endif
}
-#if defined(FEAT_PERL) || defined(FEAT_LUA) || defined(PROTO)
+#if defined(FEAT_PERL) || defined(PROTO)
/*
* Find window number "winnr" (counting top to bottom).
*/