Compare commits

...

7 Commits

Author SHA1 Message Date
Bram Moolenaar
226400830b patch 8.0.1736: check for C99 features is incomplete
Problem:    Check for C99 features is incomplete.
Solution:   Use AC_PROG_CC_C99 and when C99 isn't fully supported check the
            features we need. (James McCoy, closes #2820)
2018-04-19 20:39:41 +02:00
Bram Moolenaar
285e335869 patch 8.0.1735: flexible array member feature not supported by HP-UX
Problem:    Flexible array member feature not supported by HP-UX. (John
            Marriott)
Solution:   Do not use the flexible array member feature of C99.
2018-04-18 23:01:13 +02:00
Bram Moolenaar
f98a39ca57 patch 8.0.1734: package directory not added to 'rtp' if prefix matches
Problem:    Package directory not added to 'rtp' if prefix matches.
Solution:   Check the match is a full match. (Ozaki Kiichi, closes #2817)
            Also handle different ways of spelling a path.
2018-04-18 22:18:23 +02:00
Bram Moolenaar
bad0ce7b26 patch 8.0.1733: incomplete testing for completion fix
Problem:    Incomplete testing for completion fix. (Lifepillar)
Solution:   Add a test with CTRL-P.
2018-04-17 23:31:05 +02:00
Bram Moolenaar
a997b45c7e patch 8.0.1732: crash when terminal API call deletes the buffer
Problem:    Crash when terminal API call deletes the buffer.
Solution:   Lock the buffer while calling a function. (closes #2813)
2018-04-17 23:24:06 +02:00
Bram Moolenaar
e87edf3b85 patch 8.0.1731: characters deleted on completion
Problem:    Characters deleted on completion. (Adrià Farrés)
Solution:   Also check the last item for the ORIGINAL_TEXT flag. (Christian
            Brabandt, closes #1645)
2018-04-17 22:14:32 +02:00
Bram Moolenaar
561f8a5a46 patch 8.0.1730: no configure check for the used C99 features
Problem:    No configure check for the used C99 features.
Solution:   Add a compilation check.  Tentatively document C99 features.
2018-04-17 22:02:45 +02:00
14 changed files with 565 additions and 113 deletions

View File

@@ -1,4 +1,4 @@
*develop.txt* For Vim version 8.0. Last change: 2017 Jul 31
*develop.txt* For Vim version 8.0. Last change: 2018 Apr 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -185,9 +185,40 @@ The basic steps to make changes to the code:
C COMPILER *style-compiler*
The minimal C compiler version supported is C89, also known as ANSI C.
Later standards don't add much and C89 is the widest supported.
Later standards, such as C99, are not widely supported, or at least not 100%
supported. Therefore we use only some of the C99 features and disallow some
(at least for now).
One restriction that this implies: no // comments, only /* comments */.
Please don't make changes everywhere to use the C99 features, it causes merge
problems for existing patches. Only use them for new and changed code.
Comments ~
Traditionally Vim uses /* comments */. We intend to keep it that way,
especially for file and function headers. For new code or lines of code that
change, it is allowed to use // comments. Especially when it comes after
code:
int some_var; // single line comment useful here
Enums ~
The last item in an enum may have a trailing comma. C89 didn't allow this.
Types ~
"long long" is allowed and can be expected to be 64 bits. Use %lld in printf
formats. Also "long long unsigned" with %llu.
Not to be used ~
These C99 features are not to be used, because not enough compilers support
them:
- Declaration after Statements (MSVC 2012 does not support it). All
declarations need to be at the start of the block.
- Variable length arrays (even in C11 this is an optional feature).
- _Bool and _Complex types.
- "inline" (it's hardly ever needed, let the optimizer do its work)
- flexible array members: Not supported by HP-UX C compiler (John Marriott)
USE OF COMMON FUNCTIONS *style-functions*

372
src/auto/configure vendored
View File

@@ -3454,81 +3454,167 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
if ${ac_cv_prog_cc_c89+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
if ${ac_cv_prog_cc_c99+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_prog_cc_c89=no
ac_cv_prog_cc_c99=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
char **p;
int i;
// Check varargs macros. These examples are taken from C99 6.10.3.5.
#define debug(...) fprintf (stderr, __VA_ARGS__)
#define showlist(...) puts (#__VA_ARGS__)
#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
static void
test_varargs_macros (void)
{
return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
char *s;
va_list v;
va_start (v,p);
s = g (p, va_arg (v,int));
va_end (v);
return s;
int x = 1234;
int y = 5678;
debug ("Flag");
debug ("X = %d\n", x);
showlist (The first, second, and third items.);
report (x>y, "x is %d but y is %d", x, y);
}
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
function prototypes and stuff, but not '\xHH' hex character constants.
These don't provoke an error unfortunately, instead are silently treated
as 'x'. The following induces an error, until -std is added to get
proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
array size at least. It's necessary to write '\x00'==0 to get something
that's true only with -std. */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];
// Check long long types.
#define BIG64 18446744073709551615ull
#define BIG32 4294967295ul
#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
#if !BIG_OK
your preprocessor is broken;
#endif
#if BIG_OK
#else
your preprocessor is broken;
#endif
static long long int bignum = -9223372036854775807LL;
static unsigned long long int ubignum = BIG64;
/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
inside strings and character constants. */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
struct incomplete_array
{
int datasize;
double data[];
};
struct named_init {
int number;
const wchar_t *name;
double average;
};
typedef const char *ccp;
static inline int
test_restrict (ccp restrict text)
{
// See if C++-style comments work.
// Iterate through items via the restricted pointer.
// Also check for declarations in for loops.
for (unsigned int i = 0; *(text+i) != '\0'; ++i)
continue;
return 0;
}
// Check varargs and va_copy.
static void
test_varargs (const char *format, ...)
{
va_list args;
va_start (args, format);
va_list args_copy;
va_copy (args_copy, args);
const char *str;
int number;
float fnumber;
while (*format)
{
switch (*format++)
{
case 's': // string
str = va_arg (args_copy, const char *);
break;
case 'd': // int
number = va_arg (args_copy, int);
break;
case 'f': // float
fnumber = va_arg (args_copy, double);
break;
default:
break;
}
}
va_end (args_copy);
va_end (args);
}
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
// Check bool.
_Bool success = false;
// Check restrict.
if (test_restrict ("String literal") == 0)
success = true;
char *restrict newvar = "Another string";
// Check varargs.
test_varargs ("s, d' f .", "string", 65, 34.234);
test_varargs_macros ();
// Check flexible array members.
struct incomplete_array *ia =
malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
ia->datasize = 10;
for (int i = 0; i < ia->datasize; ++i)
ia->data[i] = i * 1.234;
// Check named initializers.
struct named_init ni = {
.number = 34,
.name = L"Test wide string",
.average = 543.34343,
};
ni.number = 58;
int dynamic_array[ni.number];
dynamic_array[ni.number - 1] = 543;
// work around unused variable warnings
return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
|| dynamic_array[ni.number - 1] != 543);
;
return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
do
CC="$ac_save_CC $ac_arg"
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_c89=$ac_arg
ac_cv_prog_cc_c99=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
test "x$ac_cv_prog_cc_c89" != "xno" && break
test "x$ac_cv_prog_cc_c99" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC
fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in
case "x$ac_cv_prog_cc_c99" in
x)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
@@ -3536,11 +3622,11 @@ $as_echo "none needed" >&6; } ;;
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
*)
CC="$CC $ac_cv_prog_cc_c89"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
CC="$CC $ac_cv_prog_cc_c99"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c89" != xno; then :
if test "x$ac_cv_prog_cc_c99" != xno; then :
fi
@@ -4179,6 +4265,194 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
fi
if test x"$ac_cv_prog_cc_c99" != xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
$as_echo_n "checking for unsigned long long int... " >&6; }
if ${ac_cv_type_unsigned_long_long_int+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_type_unsigned_long_long_int=yes
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* For now, do not test the preprocessor; as of 2007 there are too many
implementations with broken preprocessors. Perhaps this can
be revisited in 2012. In the meantime, code should not expect
#if to work with literals wider than 32 bits. */
/* Test literals. */
long long int ll = 9223372036854775807ll;
long long int nll = -9223372036854775807LL;
unsigned long long int ull = 18446744073709551615ULL;
/* Test constant expressions. */
typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
? 1 : -1)];
typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
? 1 : -1)];
int i = 63;
int
main ()
{
/* Test availability of runtime routines for shift and division. */
long long int llmax = 9223372036854775807ll;
unsigned long long int ullmax = 18446744073709551615ull;
return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
| (llmax / ll) | (llmax % ll)
| (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
| (ullmax / ull) | (ullmax % ull));
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
else
ac_cv_type_unsigned_long_long_int=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
if test $ac_cv_type_unsigned_long_long_int = yes; then
$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
$as_echo_n "checking for long long int... " >&6; }
if ${ac_cv_type_long_long_int+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_type_long_long_int=yes
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
if test $ac_cv_type_long_long_int = yes; then
if test "$cross_compiling" = yes; then :
:
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <limits.h>
#ifndef LLONG_MAX
# define HALF \
(1LL << (sizeof (long long int) * CHAR_BIT - 2))
# define LLONG_MAX (HALF - 1 + HALF)
#endif
int
main ()
{
long long int n = 1;
int i;
for (i = 0; ; i++)
{
long long int m = n << i;
if (m >> i != n)
return 1;
if (LLONG_MAX / 2 < m)
break;
}
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
else
ac_cv_type_long_long_int=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
$as_echo "$ac_cv_type_long_long_int" >&6; }
if test $ac_cv_type_long_long_int = yes; then
$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
fi
if test "$ac_cv_type_long_long_int" = no; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Compiler does not support long long int
See \`config.log' for more details" "$LINENO" 5; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler supports trailing commas" >&5
$as_echo_n "checking if the compiler supports trailing commas... " >&6; }
trailing_commas=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
enum {
one,
};
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }; trailing_commas=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test "$trailing_commas" = no; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Compiler does not support trailing comma in enum
See \`config.log' for more details" "$LINENO" 5; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler supports C++ comments" >&5
$as_echo_n "checking if the compiler supports C++ comments... " >&6; }
slash_comments=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
// C++ comments?
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }; slash_comments=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test "$slash_comments" = no; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Compiler does not support C++ comments
See \`config.log' for more details" "$LINENO" 5; }
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --enable-fail-if-missing argument" >&5
$as_echo_n "checking --enable-fail-if-missing argument... " >&6; }

View File

@@ -417,6 +417,8 @@ buf_hashtab_remove(buf_T *buf)
hash_remove(&buf_hashtab, hi);
}
static char *e_buflocked = N_("E937: Attempt to delete a buffer that is in use");
/*
* Close the link to a buffer.
* "action" is used when there is no longer a window for the buffer.
@@ -476,8 +478,15 @@ close_buffer(
if (term_job_running(buf->b_term))
{
if (wipe_buf || unload_buf)
{
if (buf->b_locked)
{
EMSG(_(e_buflocked));
return;
}
/* Wiping out or unloading a terminal buffer kills the job. */
free_terminal(buf);
}
else
{
/* The job keeps running, hide the buffer. */
@@ -499,7 +508,7 @@ close_buffer(
* halfway a command that relies on it). Unloading is allowed. */
if (buf->b_locked > 0 && (del_buf || wipe_buf))
{
EMSG(_("E937: Attempt to delete a buffer that is in use"));
EMSG(_(e_buflocked));
return;
}
@@ -1356,6 +1365,12 @@ do_buffer(
int forward;
bufref_T bufref;
if (buf->b_locked)
{
EMSG(_(e_buflocked));
return FAIL;
}
set_bufref(&bufref, buf);
/* When unloading or deleting a buffer that's already unloaded and

View File

@@ -11,7 +11,7 @@ AC_DEFINE(UNIX)
AC_PROG_MAKE_SET
dnl Checks for programs.
AC_PROG_CC_C89 dnl required by almost everything
AC_PROG_CC_C99 dnl required by almost everything
AC_PROG_CPP dnl required by header file checks
AC_PROGRAM_EGREP dnl required by AC_EGREP_CPP
AC_PROG_FGREP dnl finds working grep -F
@@ -29,6 +29,39 @@ dnl in autoconf needs it, where it uses STDC_HEADERS.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
dnl Check that the C99 features that Vim uses are supported:
if test x"$ac_cv_prog_cc_c99" != xno; then
dnl If the compiler doesn't explicitly support C99, then check
dnl for the specific features Vim uses
AC_TYPE_LONG_LONG_INT
if test "$ac_cv_type_long_long_int" = no; then
AC_MSG_FAILURE([Compiler does not support long long int])
fi
AC_MSG_CHECKING([if the compiler supports trailing commas])
trailing_commas=no
AC_TRY_COMPILE([], [
enum {
one,
};],
[AC_MSG_RESULT(yes); trailing_commas=yes],
[AC_MSG_RESULT(no)])
if test "$trailing_commas" = no; then
AC_MSG_FAILURE([Compiler does not support trailing comma in enum])
fi
AC_MSG_CHECKING([if the compiler supports C++ comments])
slash_comments=no
AC_TRY_COMPILE([],
[// C++ comments?],
[AC_MSG_RESULT(yes); slash_comments=yes],
[AC_MSG_RESULT(no)])
if test "$slash_comments" = no; then
AC_MSG_FAILURE([Compiler does not support C++ comments])
fi
fi
dnl Check for the flag that fails if stuff are missing.
AC_MSG_CHECKING(--enable-fail-if-missing argument)

View File

@@ -3656,7 +3656,9 @@ ins_compl_set_original_text(char_u *str)
{
char_u *p;
/* Replace the original text entry. */
/* Replace the original text entry.
* The ORIGINAL_TEXT flag is either at the first item or might possibly be
* at the last item for backward completion */
if (compl_first_match->cp_flags & ORIGINAL_TEXT) /* safety check */
{
p = vim_strsave(str);
@@ -3666,6 +3668,16 @@ ins_compl_set_original_text(char_u *str)
compl_first_match->cp_str = p;
}
}
else if (compl_first_match->cp_prev != NULL
&& (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT))
{
p = vim_strsave(str);
if (p != NULL)
{
vim_free(compl_first_match->cp_prev->cp_str);
compl_first_match->cp_prev->cp_str = p;
}
}
}
/*

View File

@@ -3821,10 +3821,30 @@ static int APP_BOTH;
static void
add_pack_plugin(char_u *fname, void *cookie)
{
if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)fname) == NULL)
if (cookie != &APP_LOAD)
{
char_u *buf = alloc(MAXPATHL);
char_u *p;
int found = FALSE;
if (buf == NULL)
return;
p = p_rtp;
while (*p != NUL)
{
copy_option_part(&p, buf, MAXPATHL, ",");
if (pathcmp((char *)buf, (char *)fname, -1) == 0)
{
found = TRUE;
break;
}
}
vim_free(buf);
if (!found)
/* directory is not yet in 'runtimepath', add it */
if (add_pack_dir_to_rtp(fname) == FAIL)
return;
}
if (cookie != &APP_ADD_DIR)
load_pack_plugin(fname);

View File

@@ -40,9 +40,9 @@
#define MINIMAL_SIZE 20 /* minimal size for b_str */
static buffheader_T redobuff = {NULL, NULL, 0, 0};
static buffheader_T old_redobuff = {NULL, NULL, 0, 0};
static buffheader_T recordbuff = {NULL, NULL, 0, 0};
static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
static int typeahead_char = 0; /* typeahead char that's not flushed */
@@ -138,13 +138,12 @@ free_buff(buffheader_T *buf)
{
buffblock_T *p, *np;
for (p = buf->bh_first; p != NULL; p = np)
for (p = buf->bh_first.b_next; p != NULL; p = np)
{
np = p->b_next;
vim_free(p);
}
buf->bh_first = NULL;
buf->bh_curr = NULL;
buf->bh_first.b_next = NULL;
}
/*
@@ -163,13 +162,13 @@ get_buffcont(
buffblock_T *bp;
/* compute the total length of the string */
for (bp = buffer->bh_first; bp != NULL; bp = bp->b_next)
for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
count += (long_u)STRLEN(bp->b_str);
if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
{
p2 = p;
for (bp = buffer->bh_first; bp != NULL; bp = bp->b_next)
for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
for (str = bp->b_str; *str; )
*p2++ = *str++;
*p2 = NUL;
@@ -240,10 +239,10 @@ add_buff(
if (slen == 0) /* don't add empty strings */
return;
if (buf->bh_first == NULL) /* first add to list */
if (buf->bh_first.b_next == NULL) /* first add to list */
{
buf->bh_space = 0;
buf->bh_curr = NULL;
buf->bh_curr = &(buf->bh_first);
}
else if (buf->bh_curr == NULL) /* buffer has already been read */
{
@@ -251,9 +250,9 @@ add_buff(
return;
}
else if (buf->bh_index != 0)
mch_memmove(buf->bh_first->b_str,
buf->bh_first->b_str + buf->bh_index,
STRLEN(buf->bh_first->b_str + buf->bh_index) + 1);
mch_memmove(buf->bh_first.b_next->b_str,
buf->bh_first.b_next->b_str + buf->bh_index,
STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
buf->bh_index = 0;
if (buf->bh_space >= (int)slen)
@@ -268,26 +267,17 @@ add_buff(
len = MINIMAL_SIZE;
else
len = slen;
p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len + 1),
p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len),
TRUE);
if (p == NULL)
return; /* no space, just forget it */
buf->bh_space = (int)(len - slen);
vim_strncpy(p->b_str, s, (size_t)slen);
if (buf->bh_curr == NULL)
{
p->b_next = NULL;
buf->bh_first = p;
buf->bh_curr = p;
}
else
{
p->b_next = buf->bh_curr->b_next;
buf->bh_curr->b_next = p;
buf->bh_curr = p;
}
}
return;
}
@@ -358,10 +348,10 @@ add_char_buff(buffheader_T *buf, int c)
}
/* First read ahead buffer. Used for translated commands. */
static buffheader_T readbuf1 = {NULL, NULL, 0, 0};
static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0};
/* Second read ahead buffer. Used for redo. */
static buffheader_T readbuf2 = {NULL, NULL, 0, 0};
static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0};
/*
* Get one byte from the read buffers. Use readbuf1 one first, use readbuf2
@@ -386,17 +376,17 @@ read_readbuf(buffheader_T *buf, int advance)
char_u c;
buffblock_T *curr;
if (buf->bh_first == NULL) /* buffer is empty */
if (buf->bh_first.b_next == NULL) /* buffer is empty */
return NUL;
curr = buf->bh_first;
curr = buf->bh_first.b_next;
c = curr->b_str[buf->bh_index];
if (advance)
{
if (curr->b_str[++buf->bh_index] == NUL)
{
buf->bh_first = curr->b_next;
buf->bh_first.b_next = curr->b_next;
vim_free(curr);
buf->bh_index = 0;
}
@@ -410,14 +400,14 @@ read_readbuf(buffheader_T *buf, int advance)
static void
start_stuff(void)
{
if (readbuf1.bh_first != NULL)
if (readbuf1.bh_first.b_next != NULL)
{
readbuf1.bh_curr = readbuf1.bh_first;
readbuf1.bh_curr = &(readbuf1.bh_first);
readbuf1.bh_space = 0;
}
if (readbuf2.bh_first != NULL)
if (readbuf2.bh_first.b_next != NULL)
{
readbuf2.bh_curr = readbuf2.bh_first;
readbuf2.bh_curr = &(readbuf2.bh_first);
readbuf2.bh_space = 0;
}
}
@@ -428,8 +418,8 @@ start_stuff(void)
int
stuff_empty(void)
{
return (readbuf1.bh_first == NULL
&& readbuf2.bh_first == NULL);
return (readbuf1.bh_first.b_next == NULL
&& readbuf2.bh_first.b_next == NULL);
}
/*
@@ -439,7 +429,7 @@ stuff_empty(void)
int
readbuf1_empty(void)
{
return (readbuf1.bh_first == NULL);
return (readbuf1.bh_first.b_next == NULL);
}
/*
@@ -504,7 +494,7 @@ ResetRedobuff(void)
{
free_buff(&old_redobuff);
old_redobuff = redobuff;
redobuff.bh_first = NULL;
redobuff.bh_first.b_next = NULL;
}
}
@@ -519,7 +509,7 @@ CancelRedo(void)
{
free_buff(&redobuff);
redobuff = old_redobuff;
old_redobuff.bh_first = NULL;
old_redobuff.bh_first.b_next = NULL;
start_stuff();
while (read_readbuffers(TRUE) != NUL)
;
@@ -536,9 +526,9 @@ saveRedobuff(save_redo_T *save_redo)
char_u *s;
save_redo->sr_redobuff = redobuff;
redobuff.bh_first = NULL;
redobuff.bh_first.b_next = NULL;
save_redo->sr_old_redobuff = old_redobuff;
old_redobuff.bh_first = NULL;
old_redobuff.bh_first.b_next = NULL;
/* Make a copy, so that ":normal ." in a function works. */
s = get_buffcont(&save_redo->sr_redobuff, FALSE);
@@ -757,9 +747,9 @@ read_redo(int init, int old_redo)
if (init)
{
if (old_redo)
bp = old_redobuff.bh_first;
bp = old_redobuff.bh_first.b_next;
else
bp = redobuff.bh_first;
bp = redobuff.bh_first.b_next;
if (bp == NULL)
return FAIL;
p = bp->b_str;
@@ -1382,9 +1372,9 @@ save_typeahead(tasave_T *tp)
old_char = -1;
tp->save_readbuf1 = readbuf1;
readbuf1.bh_first = NULL;
readbuf1.bh_first.b_next = NULL;
tp->save_readbuf2 = readbuf2;
readbuf2.bh_first = NULL;
readbuf2.bh_first.b_next = NULL;
# ifdef USE_INPUT_BUF
tp->save_inputbuf = get_input_buf();
# endif

View File

@@ -511,7 +511,7 @@ typedef struct buffheader buffheader_T;
struct buffblock
{
buffblock_T *b_next; /* pointer to next buffblock */
char_u b_str[]; /* contents (flexible array) */
char_u b_str[1]; /* contents (actually longer) */
};
/*
@@ -519,7 +519,7 @@ struct buffblock
*/
struct buffheader
{
buffblock_T *bh_first; /* first block of the list */
buffblock_T bh_first; /* first (dummy) block of list */
buffblock_T *bh_curr; /* buffblock for appending */
int bh_index; /* index for reading */
int bh_space; /* space in bh_curr for appending */

View File

@@ -46,6 +46,9 @@
* switch to GUI, shell stops working. Scrollback seems wrong, command
* running in shell is still running.
* - GUI: when using tabs, focus in terminal, click on tab does not work.
* - handle_moverect() scrolls one line at a time. Postpone scrolling, count
* the number of lines, until a redraw happens. Then if scrolling many lines
* a redraw is faster.
* - Copy text in the vterm to the Vim buffer once in a while, so that
* completion works.
* - Redrawing is slow with Athena and Motif. Also other GUI? (Ramel Eshed)
@@ -3433,6 +3436,10 @@ parse_osc(const char *command, size_t cmdlen, void *user)
{
char_u *cmd = get_tv_string(&item->li_tv);
/* Make sure an invoked command doesn't delete the buffer (and the
* terminal) under our fingers. */
++term->tl_buffer->b_locked;
item = item->li_next;
if (item == NULL)
ch_log(channel, "Missing argument for %s", cmd);
@@ -3442,6 +3449,7 @@ parse_osc(const char *command, size_t cmdlen, void *user)
handle_call_command(term, channel, item);
else
ch_log(channel, "Invalid command received: %s", cmd);
--term->tl_buffer->b_locked;
}
}
else

View File

@@ -119,7 +119,9 @@ func Test_autocmd_bufunload_avoiding_SEGV_01()
exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
augroup END
call assert_fails('edit bb.txt', 'E937:')
" Todo: check for E937 generated first
" call assert_fails('edit bb.txt', 'E937:')
call assert_fails('edit bb.txt', 'E517:')
autocmd! test_autocmd_bufunload
augroup! test_autocmd_bufunload
@@ -316,7 +318,7 @@ func Test_three_windows()
e Xtestje2
sp Xtestje1
call assert_fails('e', 'E937:')
call assert_equal('Xtestje2', expand('%'))
call assert_equal('Xtestje1', expand('%'))
" Test changing buffers in a BufWipeout autocommand. If this goes wrong
" there are ml_line errors and/or a Crash.
@@ -338,7 +340,6 @@ func Test_three_windows()
au!
enew
bwipe! Xtestje1
call delete('Xtestje1')
call delete('Xtestje2')
call delete('Xtestje3')
@@ -1181,7 +1182,9 @@ endfunc
func Test_nocatch_wipe_all_buffers()
" Real nasty autocommand: wipe all buffers on any event.
au * * bwipe *
call assert_fails('next x', 'E93')
" Get E93 first?
" call assert_fails('next x', 'E93:')
call assert_fails('next x', 'E517:')
bwipe
au!
endfunc

View File

@@ -40,6 +40,15 @@ func Test_packadd()
call assert_match('/testdir/Xdir/pack/mine/opt/mytest\($\|,\)', &rtp)
call assert_match('/testdir/Xdir/pack/mine/opt/mytest/after$', &rtp)
" NOTE: '/.../opt/myte' forwardly matches with '/.../opt/mytest'
call mkdir(fnamemodify(s:plugdir, ':h') . '/myte', 'p')
let rtp = &rtp
packadd myte
" Check the path of 'myte' is added
call assert_true(len(&rtp) > len(rtp))
call assert_match('/testdir/Xdir/pack/mine/opt/myte\($\|,\)', &rtp)
" Check exception
call assert_fails("packadd directorynotfound", 'E919:')
call assert_fails("packadd", 'E471:')

View File

@@ -814,5 +814,24 @@ func Test_popup_command()
call delete('Xtest')
endfunc
func Test_popup_complete_backwards()
new
call setline(1, ['Post', 'Port', 'Po'])
let expected=['Post', 'Port', 'Port']
call cursor(3,2)
call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx')
call assert_equal(expected, getline(1,'$'))
bwipe!
endfunc
func Test_popup_complete_backwards_ctrl_p()
new
call setline(1, ['Post', 'Port', 'Po'])
let expected=['Post', 'Port', 'Port']
call cursor(3,2)
call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx')
call assert_equal(expected, getline(1,'$'))
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -1287,6 +1287,30 @@ func Test_terminal_api_call_fails()
call delete('Xlog')
endfunc
let s:caught_e937 = 0
func Tapi_Delete(bufnum, arg)
try
execute 'bdelete!' a:bufnum
catch /E937:/
let s:caught_e937 = 1
endtry
endfunc
func Test_terminal_api_call_fail_delete()
if !CanRunVimInTerminal()
return
endif
call WriteApiCall('Tapi_Delete')
let buf = RunVimInTerminal('-S Xscript', {})
call WaitFor({-> s:caught_e937 == 1})
call StopVimInTerminal(buf)
call delete('Xscript')
call ch_logfile('', '')
endfunc
func Test_terminal_ansicolors_default()
let colors = [
\ '#000000', '#e00000',

View File

@@ -762,6 +762,20 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1736,
/**/
1735,
/**/
1734,
/**/
1733,
/**/
1732,
/**/
1731,
/**/
1730,
/**/
1729,
/**/