aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/memline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/memline.c')
-rw-r--r--src/nvim/memline.c394
1 files changed, 227 insertions, 167 deletions
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 56342942db..10a8195e7a 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -39,19 +39,31 @@
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
+#include <stdio.h>
#include <string.h>
+#include <time.h>
+#include <uv.h>
+#include "auto/config.h"
+#include "klib/kvec.h"
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.h"
#include "nvim/change.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/fileio.h"
-#include "nvim/func_attr.h"
#include "nvim/getchar.h"
+#include "nvim/gettext.h"
+#include "nvim/globals.h"
+#include "nvim/highlight_defs.h"
#include "nvim/input.h"
+#include "nvim/macros.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
@@ -60,19 +72,21 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
+#include "nvim/os/fs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/process.h"
-#include "nvim/os_unix.h"
+#include "nvim/os/time.h"
#include "nvim/path.h"
-#include "nvim/sha256.h"
+#include "nvim/pos.h"
+#include "nvim/screen.h"
#include "nvim/spell.h"
#include "nvim/strings.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/vim.h"
-#include "nvim/window.h"
#ifndef UNIX // it's in os/unix_defs.h for Unix
# include <time.h>
@@ -83,10 +97,12 @@ typedef struct pointer_block PTR_BL; // contents of a pointer block
typedef struct data_block DATA_BL; // contents of a data block
typedef struct pointer_entry PTR_EN; // block/line-count pair
-#define DATA_ID (('d' << 8) + 'a') // data block id
-#define PTR_ID (('p' << 8) + 't') // pointer block id
-#define BLOCK0_ID0 'b' // block 0 id 0
-#define BLOCK0_ID1 '0' // block 0 id 1
+enum {
+ DATA_ID = (('d' << 8) + 'a'), // data block id
+ PTR_ID = (('p' << 8) + 't'), // pointer block id
+ BLOCK0_ID0 = 'b', // block 0 id 0
+ BLOCK0_ID1 = '0', // block 0 id 1
+};
// pointer to a block, used in a pointer block
struct pointer_entry {
@@ -115,7 +131,8 @@ struct data_block {
unsigned db_free; // free space available
unsigned db_txt_start; // byte where text starts
unsigned db_txt_end; // byte just after data block
- linenr_T db_line_count; // number of lines in this block
+ // linenr_T db_line_count;
+ long db_line_count; // number of lines in this block
unsigned db_index[1]; // index for start of line (actually bigger)
// followed by empty space up to db_txt_start
// followed by the text in the lines until
@@ -134,18 +151,22 @@ struct data_block {
#define INDEX_SIZE (sizeof(unsigned)) // size of one db_index entry
#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) // size of data block header
-#define B0_FNAME_SIZE_ORG 900 // what it was in older versions
-#define B0_FNAME_SIZE_NOCRYPT 898 // 2 bytes used for other things
-#define B0_FNAME_SIZE_CRYPT 890 // 10 bytes used for other things
-#define B0_UNAME_SIZE 40
-#define B0_HNAME_SIZE 40
+enum {
+ B0_FNAME_SIZE_ORG = 900, // what it was in older versions
+ B0_FNAME_SIZE_NOCRYPT = 898, // 2 bytes used for other things
+ B0_FNAME_SIZE_CRYPT = 890, // 10 bytes used for other things
+ B0_UNAME_SIZE = 40,
+ B0_HNAME_SIZE = 40,
+};
// Restrict the numbers to 32 bits, otherwise most compilers will complain.
// This won't detect a 64 bit machine that only swaps a byte in the top 32
// bits, but that is crazy anyway.
-#define B0_MAGIC_LONG 0x30313233L
-#define B0_MAGIC_INT 0x20212223L
-#define B0_MAGIC_SHORT 0x10111213L
-#define B0_MAGIC_CHAR 0x55
+enum {
+ B0_MAGIC_LONG = 0x30313233L,
+ B0_MAGIC_INT = 0x20212223L,
+ B0_MAGIC_SHORT = 0x10111213L,
+ B0_MAGIC_CHAR = 0x55,
+};
// Block zero holds all info about the swap file.
//
@@ -158,19 +179,19 @@ struct data_block {
// different machines. b0_magic_* is used to check the byte order and size of
// variables, because the rest of the swap file is not portable.
struct block0 {
- char_u b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1.
- char_u b0_version[10]; // Vim version string
- char_u b0_page_size[4]; // number of bytes per page
- char_u b0_mtime[4]; // last modification time of file
- char_u b0_ino[4]; // inode of b0_fname
- char_u b0_pid[4]; // process id of creator (or 0)
- char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name)
- char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name)
- char_u b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited
- long b0_magic_long; // check for byte order of long
- int b0_magic_int; // check for byte order of int
- short b0_magic_short; // check for byte order of short
- char_u b0_magic_char; // check for last char
+ char_u b0_id[2]; ///< ID for block 0: BLOCK0_ID0 and BLOCK0_ID1.
+ char b0_version[10]; // Vim version string
+ char_u b0_page_size[4]; // number of bytes per page
+ char_u b0_mtime[4]; // last modification time of file
+ char_u b0_ino[4]; // inode of b0_fname
+ char_u b0_pid[4]; // process id of creator (or 0)
+ char_u b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name)
+ char_u b0_hname[B0_HNAME_SIZE]; // host name (if it has a name)
+ char b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited
+ long b0_magic_long; // check for byte order of long
+ int b0_magic_int; // check for byte order of int
+ int16_t b0_magic_short; // check for byte order of short
+ char_u b0_magic_char; // check for last char
};
// Note: b0_dirty and b0_flags are put at the end of the file name. For very
@@ -205,10 +226,12 @@ struct block0 {
static linenr_T lowest_marked = 0;
// arguments for ml_find_line()
-#define ML_DELETE 0x11 // delete line
-#define ML_INSERT 0x12 // insert line
-#define ML_FIND 0x13 // just find the line
-#define ML_FLUSH 0x02 // flush locked block
+enum {
+ ML_DELETE = 0x11, // delete line
+ ML_INSERT = 0x12, // insert line
+ ML_FIND = 0x13, // just find the line
+ ML_FLUSH = 0x02, // flush locked block
+};
#define ML_SIMPLE(x) ((x) & 0x10) // DEL, INS or FIND
// argument for ml_upd_block0()
@@ -258,7 +281,6 @@ int ml_open(buf_T *buf)
buf->b_ml.ml_mfp = mfp;
buf->b_ml.ml_flags = ML_EMPTY;
buf->b_ml.ml_line_count = 1;
- curwin->w_nrwidth_line_count = 0;
// fill block0 struct and write page 0
hp = mf_new(mfp, false, 1);
@@ -271,15 +293,15 @@ int ml_open(buf_T *buf)
b0p->b0_id[0] = BLOCK0_ID0;
b0p->b0_id[1] = BLOCK0_ID1;
b0p->b0_magic_long = B0_MAGIC_LONG;
- b0p->b0_magic_int = (int)B0_MAGIC_INT;
- b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
+ b0p->b0_magic_int = B0_MAGIC_INT;
+ b0p->b0_magic_short = (int16_t)B0_MAGIC_SHORT;
b0p->b0_magic_char = B0_MAGIC_CHAR;
- xstrlcpy(xstpcpy((char *)b0p->b0_version, "VIM "), Version, 6);
+ xstrlcpy(xstpcpy(b0p->b0_version, "VIM "), Version, 6);
long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
if (!buf->b_spell) {
b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
- b0p->b0_flags = (uint8_t)(get_fileformat(buf) + 1);
+ b0p->b0_flags = (char)(get_fileformat(buf) + 1);
set_b0_fname(b0p, buf);
(void)os_get_username((char *)b0p->b0_uname, B0_UNAME_SIZE);
b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
@@ -437,7 +459,7 @@ void ml_open_file(buf_T *buf)
if (buf->b_spell) {
char *fname = vim_tempname();
if (fname != NULL) {
- (void)mf_open_file(mfp, (char *)fname); // consumes fname!
+ (void)mf_open_file(mfp, fname); // consumes fname!
}
buf->b_may_swap = false;
return;
@@ -616,9 +638,9 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
// If there is no user name or it is too long, don't use "~/"
int retval = os_get_username(uname, B0_UNAME_SIZE);
size_t ulen = strlen(uname);
- size_t flen = STRLEN(b0p->b0_fname);
+ size_t flen = strlen(b0p->b0_fname);
if (retval == FAIL || ulen + flen > B0_FNAME_SIZE_CRYPT - 1) {
- STRLCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT);
+ xstrlcpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT);
} else {
memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
memmove(b0p->b0_fname + 1, uname, ulen);
@@ -653,10 +675,10 @@ static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
/// not set.
static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
{
- if (same_directory((char_u *)buf->b_ml.ml_mfp->mf_fname, (char_u *)buf->b_ffname)) {
+ if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname)) {
b0p->b0_flags |= B0_SAME_DIR;
} else {
- b0p->b0_flags &= (uint8_t) ~B0_SAME_DIR;
+ b0p->b0_flags = (char)(b0p->b0_flags & ~B0_SAME_DIR);
}
}
@@ -666,8 +688,8 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
const int size = B0_FNAME_SIZE_NOCRYPT;
int n = (int)strlen(buf->b_p_fenc);
- if ((int)STRLEN(b0p->b0_fname) + n + 1 > size) {
- b0p->b0_flags &= (uint8_t) ~B0_HAS_FENC;
+ if ((int)strlen(b0p->b0_fname) + n + 1 > size) {
+ b0p->b0_flags = (char)(b0p->b0_flags & ~B0_HAS_FENC);
} else {
memmove((char *)b0p->b0_fname + size - n,
buf->b_p_fenc, (size_t)n);
@@ -676,6 +698,23 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
}
}
+/// Return true if the process with number "b0p->b0_pid" is still running.
+/// "swap_fname" is the name of the swap file, if it's from before a reboot then
+/// the result is false;
+static bool swapfile_process_running(const ZERO_BL *b0p, const char *swap_fname)
+{
+ FileInfo st;
+ double uptime;
+ // If the system rebooted after when the swap file was written then the
+ // process can't be running now.
+ if (os_fileinfo(swap_fname, &st)
+ && uv_uptime(&uptime) == 0
+ && (Timestamp)st.stat.st_mtim.tv_sec < os_time() - (Timestamp)uptime) {
+ return false;
+ }
+ return os_proc_running((int)char_to_long(b0p->b0_pid));
+}
+
/// Try to recover curbuf from the .swp file.
///
/// @param checkext if true, check the extension and detect whether it is a
@@ -710,7 +749,7 @@ void ml_recover(bool checkext)
int len = (int)strlen(fname);
if (checkext && len >= 4
&& STRNICMP(fname + len - 4, ".s", 2) == 0
- && vim_strchr("abcdefghijklmnopqrstuvw", TOLOWER_ASC(fname[len - 2])) != NULL
+ && vim_strchr("abcdefghijklmnopqrstuvw", TOLOWER_ASC((uint8_t)fname[len - 2])) != NULL
&& ASCII_ISALPHA(fname[len - 1])) {
directly = true;
fname_used = xstrdup(fname); // make a copy for mf_open()
@@ -718,7 +757,7 @@ void ml_recover(bool checkext)
directly = false;
// count the number of matching swap files
- len = recover_names((char_u *)fname, false, 0, NULL);
+ len = recover_names(fname, false, 0, NULL);
if (len == 0) { // no swap files found
semsg(_("E305: No swap file found for %s"), fname);
goto theend;
@@ -728,7 +767,7 @@ void ml_recover(bool checkext)
i = 1;
} else { // several swap files found, choose
// list the names of the swap files
- (void)recover_names((char_u *)fname, true, 0, NULL);
+ (void)recover_names(fname, true, 0, NULL);
msg_putchar('\n');
msg_puts(_("Enter number of swap file to use (0 to quit): "));
i = get_number(false, NULL);
@@ -737,7 +776,7 @@ void ml_recover(bool checkext)
}
}
// get the swap file name that will be used
- (void)recover_names((char_u *)fname, false, i, &fname_used);
+ (void)recover_names(fname, false, i, &fname_used);
}
if (fname_used == NULL) {
goto theend; // user chose invalid number.
@@ -788,7 +827,7 @@ void ml_recover(bool checkext)
goto theend;
}
b0p = hp->bh_data;
- if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0) {
+ if (strncmp(b0p->b0_version, "VIM 3.0", 7) == 0) {
msg_start();
msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
msg_puts_attr(_(" cannot be used with this version of Vim.\n"),
@@ -848,18 +887,18 @@ void ml_recover(bool checkext)
// If .swp file name given directly, use name from swap file for buffer.
if (directly) {
expand_env((char *)b0p->b0_fname, NameBuff, MAXPATHL);
- if (setfname(curbuf, (char *)NameBuff, NULL, true) == FAIL) {
+ if (setfname(curbuf, NameBuff, NULL, true) == FAIL) {
goto theend;
}
}
- home_replace(NULL, mfp->mf_fname, (char *)NameBuff, MAXPATHL, true);
+ home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, true);
smsg(_("Using swap file \"%s\""), NameBuff);
if (buf_spname(curbuf) != NULL) {
- STRLCPY(NameBuff, buf_spname(curbuf), MAXPATHL);
+ xstrlcpy(NameBuff, buf_spname(curbuf), MAXPATHL);
} else {
- home_replace(NULL, curbuf->b_ffname, (char *)NameBuff, MAXPATHL, true);
+ home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, true);
}
smsg(_("Original file \"%s\""), NameBuff);
msg_putchar('\n');
@@ -883,8 +922,8 @@ void ml_recover(bool checkext)
if (b0p->b0_flags & B0_HAS_FENC) {
int fnsize = B0_FNAME_SIZE_NOCRYPT;
- for (p = (char *)b0p->b0_fname + fnsize; (char_u *)p > b0p->b0_fname && p[-1] != NUL; p--) {}
- b0_fenc = xstrnsave(p, (size_t)(b0p->b0_fname + fnsize - (char_u *)p));
+ for (p = (char *)b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; p--) {}
+ b0_fenc = xstrnsave(p, (size_t)(b0p->b0_fname + fnsize - p));
}
mf_put(mfp, hp, false, false); // release block 0
@@ -1116,7 +1155,14 @@ void ml_recover(bool checkext)
} else {
msg(_("Recovery completed. Buffer contents equals file contents."));
}
- msg_puts(_("\nYou may want to delete the .swp file now.\n\n"));
+ msg_puts(_("\nYou may want to delete the .swp file now."));
+ if (swapfile_process_running(b0p, fname_used)) {
+ // Warn there could be an active Vim on the same file, the user may
+ // want to kill it.
+ msg_puts(_("\nNote: process STILL RUNNING: "));
+ msg_outnum(char_to_long(b0p->b0_pid));
+ }
+ msg_puts("\n\n");
cmdline_row = msg_row;
}
redraw_curbuf_later(UPD_NOT_VALID);
@@ -1155,24 +1201,24 @@ theend:
/// @param list when true, list the swap file names
/// @param nr when non-zero, return nr'th swap file name
/// @param fname_out result when "nr" > 0
-int recover_names(char_u *fname, int list, int nr, char **fname_out)
+int recover_names(char *fname, int list, int nr, char **fname_out)
{
int num_names;
char *(names[6]);
- char_u *tail;
+ char *tail;
char *p;
int file_count = 0;
char **files;
- char_u *fname_res = NULL;
+ char *fname_res = NULL;
#ifdef HAVE_READLINK
- char_u fname_buf[MAXPATHL];
+ char fname_buf[MAXPATHL];
#endif
if (fname != NULL) {
#ifdef HAVE_READLINK
// Expand symlink in the file name, because the swap file is created
// with the actual file instead of with the symlink.
- if (resolve_symlink((char *)fname, (char *)fname_buf) == OK) {
+ if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
} else
#endif
@@ -1193,7 +1239,7 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
// Isolate a directory name from *dirp and put it in dir_name (we know
// it is large enough, so use 31000 for length).
// Advance dirp to next directory name.
- (void)copy_option_part(&dirp, (char *)dir_name, 31000, ",");
+ (void)copy_option_part(&dirp, dir_name, 31000, ",");
if (dir_name[0] == '.' && dir_name[1] == NUL) { // check current dir
if (fname == NULL) {
@@ -1204,30 +1250,29 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
names[2] = xstrdup(".sw?");
num_names = 3;
} else {
- num_names = recov_file_names(names, (char *)fname_res, true);
+ num_names = recov_file_names(names, fname_res, true);
}
} else { // check directory dir_name
if (fname == NULL) {
- names[0] = concat_fnames((char *)dir_name, "*.sw?", true);
+ names[0] = concat_fnames(dir_name, "*.sw?", true);
// For Unix names starting with a dot are special. MS-Windows
// supports this too, on some file systems.
- names[1] = concat_fnames((char *)dir_name, ".*.sw?", true);
- names[2] = concat_fnames((char *)dir_name, ".sw?", true);
+ names[1] = concat_fnames(dir_name, ".*.sw?", true);
+ names[2] = concat_fnames(dir_name, ".sw?", true);
num_names = 3;
} else {
- int len = (int)STRLEN(dir_name);
+ int len = (int)strlen(dir_name);
p = dir_name + len;
- if (after_pathsep((char *)dir_name, (char *)p)
+ if (after_pathsep(dir_name, p)
&& len > 1
&& p[-1] == p[-2]) {
// Ends with '//', Use Full path for swap name
- tail = (char_u *)make_percent_swname((char *)dir_name,
- (char *)fname_res);
+ tail = make_percent_swname(dir_name, fname_res);
} else {
- tail = (char_u *)path_tail((char *)fname_res);
- tail = (char_u *)concat_fnames((char *)dir_name, (char *)tail, true);
+ tail = path_tail(fname_res);
+ tail = concat_fnames(dir_name, tail, true);
}
- num_names = recov_file_names(names, (char *)tail, false);
+ num_names = recov_file_names(names, tail, false);
xfree(tail);
}
}
@@ -1244,11 +1289,11 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
// not able to execute the shell).
// Try finding a swap file by simply adding ".swp" to the file name.
if (*dirp == NUL && file_count + num_files == 0 && fname != NULL) {
- char_u *swapname = (char_u *)modname((char *)fname_res, ".swp", true);
+ char *swapname = modname(fname_res, ".swp", true);
if (swapname != NULL) {
- if (os_path_exists((char *)swapname)) {
- files = xmalloc(sizeof(char_u *));
- files[0] = (char *)swapname;
+ if (os_path_exists(swapname)) {
+ files = xmalloc(sizeof(char *));
+ files[0] = swapname;
swapname = NULL;
num_files = 1;
}
@@ -1262,7 +1307,7 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
for (int i = 0; i < num_files; i++) {
// Do not expand wildcards, on Windows would try to expand
// "%tmp%" in "%tmp%file"
- if (path_full_compare((char *)p, files[i], true, false) & kEqualFiles) {
+ if (path_full_compare(p, files[i], true, false) & kEqualFiles) {
// Remove the name from files[i]. Move further entries
// down. When the array becomes empty free it here, since
// FreeWild() won't be called below.
@@ -1292,7 +1337,7 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
}
} else {
msg_puts(_(" In directory "));
- msg_home_replace((char *)dir_name);
+ msg_home_replace(dir_name);
msg_puts(":\n");
}
@@ -1303,7 +1348,7 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
msg_puts(". ");
msg_puts((const char *)path_tail(files[i]));
msg_putchar('\n');
- (void)swapfile_info((char_u *)files[i]);
+ (void)swapfile_info(files[i]);
}
} else {
msg_puts(_(" -- none --\n"));
@@ -1331,17 +1376,19 @@ char *make_percent_swname(const char *dir, const char *name)
{
char *d = NULL;
char *f = fix_fname(name != NULL ? name : "");
- if (f != NULL) {
- char *s = xstrdup(f);
- for (d = s; *d != NUL; MB_PTR_ADV(d)) {
- if (vim_ispathsep(*d)) {
- *d = '%';
- }
+ if (f == NULL) {
+ return NULL;
+ }
+
+ char *s = xstrdup(f);
+ for (d = s; *d != NUL; MB_PTR_ADV(d)) {
+ if (vim_ispathsep(*d)) {
+ *d = '%';
}
- d = concat_fnames(dir, s, true);
- xfree(s);
- xfree(f);
}
+ d = concat_fnames(dir, s, true);
+ xfree(s);
+ xfree(f);
return d;
}
@@ -1363,7 +1410,7 @@ void get_b0_dict(const char *fname, dict_T *d)
tv_dict_add_str(d, S_LEN("error"), "Magic number mismatch");
} else {
// We have swap information.
- tv_dict_add_str_len(d, S_LEN("version"), (char *)b0.b0_version, 10);
+ tv_dict_add_str_len(d, S_LEN("version"), b0.b0_version, 10);
tv_dict_add_str_len(d, S_LEN("user"), (char *)b0.b0_uname,
B0_UNAME_SIZE);
tv_dict_add_str_len(d, S_LEN("host"), (char *)b0.b0_hname,
@@ -1388,7 +1435,7 @@ void get_b0_dict(const char *fname, dict_T *d)
/// Give information about an existing swap file.
///
/// @return timestamp (0 when unknown).
-static time_t swapfile_info(char_u *fname)
+static time_t swapfile_info(char *fname)
{
assert(fname != NULL);
int fd;
@@ -1400,7 +1447,7 @@ static time_t swapfile_info(char_u *fname)
// print the swap file date
FileInfo file_info;
- if (os_fileinfo((char *)fname, &file_info)) {
+ if (os_fileinfo(fname, &file_info)) {
#ifdef UNIX
// print name of owner of the file
if (os_get_uname((uv_uid_t)file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
@@ -1414,15 +1461,15 @@ static time_t swapfile_info(char_u *fname)
msg_puts(_(" dated: "));
#endif
x = file_info.stat.st_mtim.tv_sec;
- char ctime_buf[50];
- msg_puts(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf)));
+ char ctime_buf[100]; // hopefully enough for every language
+ msg_puts(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf), true));
}
// print the original file name
- fd = os_open((char *)fname, O_RDONLY, 0);
+ fd = os_open(fname, O_RDONLY, 0);
if (fd >= 0) {
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0)) {
- if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0) {
+ if (strncmp(b0.b0_version, "VIM 3.0", 7) == 0) {
msg_puts(_(" [from Vim version 3.0]"));
} else if (ml_check_b0_id(&b0) == FAIL) {
msg_puts(_(" [does not look like a Vim swap file]"));
@@ -1456,7 +1503,7 @@ static time_t swapfile_info(char_u *fname)
if (char_to_long(b0.b0_pid) != 0L) {
msg_puts(_("\n process ID: "));
msg_outnum(char_to_long(b0.b0_pid));
- if (os_proc_running((int)char_to_long(b0.b0_pid))) {
+ if (swapfile_process_running(&b0, (const char *)fname)) {
msg_puts(_(" (STILL RUNNING)"));
process_still_running = true;
}
@@ -1511,14 +1558,27 @@ static bool swapfile_unchanged(char *fname)
ret = false;
}
+ // Host name must be known and must equal the current host name, otherwise
+ // comparing pid is meaningless.
+ if (*(b0.b0_hname) == NUL) {
+ ret = false;
+ } else {
+ char hostname[B0_HNAME_SIZE];
+ os_get_hostname(hostname, B0_HNAME_SIZE);
+ hostname[B0_HNAME_SIZE - 1] = NUL;
+ b0.b0_hname[B0_HNAME_SIZE - 1] = NUL; // in case of corruption
+ if (STRICMP(b0.b0_hname, hostname) != 0) {
+ ret = false;
+ }
+ }
+
// process must be known and not running.
- long pid = char_to_long(b0.b0_pid);
- if (pid == 0L || os_proc_running((int)pid)) {
+ if (char_to_long(b0.b0_pid) == 0L || swapfile_process_running(&b0, fname)) {
ret = false;
}
- // TODO(bram): Should we check if the swap file was created on the current
- // system? And the current user?
+ // We do not check the user, it should be irrelevant for whether the swap
+ // file is still useful.
close(fd);
return ret;
@@ -1543,7 +1603,7 @@ static int recov_file_names(char **names, char *path, int prepend_dot)
names[num_names] = concat_fnames(path, ".sw?", false);
if (num_names >= 1) { // check if we have the same name twice
char *p = names[num_names - 1];
- int i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
+ int i = (int)strlen(names[num_names - 1]) - (int)strlen(names[num_names]);
if (i > 0) {
p += i; // file name has been expanded to full path
}
@@ -1685,10 +1745,10 @@ char *ml_get(linenr_T lnum)
}
/// @return pointer to position "pos".
-char_u *ml_get_pos(const pos_T *pos)
+char *ml_get_pos(const pos_T *pos)
FUNC_ATTR_NONNULL_ALL
{
- return (char_u *)ml_get_buf(curbuf, pos->lnum, false) + pos->col;
+ return ml_get_buf(curbuf, pos->lnum, false) + pos->col;
}
/// @return codepoint at pos. pos must be either valid or have col set to MAXCOL!
@@ -1699,7 +1759,7 @@ int gchar_pos(pos_T *pos)
if (pos->col == MAXCOL) {
return NUL;
}
- return utf_ptr2char((char *)ml_get_pos(pos));
+ return utf_ptr2char(ml_get_pos(pos));
}
/// @param will_change true mark the buffer dirty (chars in the line will be changed)
@@ -1762,7 +1822,7 @@ errorret:
DATA_BL *dp = hp->bh_data;
char *ptr = (char *)dp + (dp->db_index[lnum - buf->b_ml.ml_locked_low] & DB_INDEX_MASK);
- buf->b_ml.ml_line_ptr = (char_u *)ptr;
+ buf->b_ml.ml_line_ptr = ptr;
buf->b_ml.ml_line_lnum = lnum;
buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
}
@@ -1771,7 +1831,7 @@ errorret:
ml_add_deleted_len_buf(buf, buf->b_ml.ml_line_ptr, -1);
}
- return (char *)buf->b_ml.ml_line_ptr;
+ return buf->b_ml.ml_line_ptr;
}
/// Check if a line that was just obtained by a call to ml_get
@@ -1806,7 +1866,7 @@ int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile)
if (curbuf->b_ml.ml_line_lnum != 0) {
ml_flush_line(curbuf);
}
- return ml_append_int(curbuf, lnum, (char_u *)line, len, newfile, false);
+ return ml_append_int(curbuf, lnum, line, len, newfile, false);
}
/// Like ml_append() but for an arbitrary buffer. The buffer must already have
@@ -1816,7 +1876,7 @@ int ml_append(linenr_T lnum, char *line, colnr_T len, bool newfile)
/// @param line text of the new line
/// @param len length of new line, including NUL, or 0
/// @param newfile flag, see above
-int ml_append_buf(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile)
+int ml_append_buf(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile)
FUNC_ATTR_NONNULL_ARG(1)
{
if (buf->b_ml.ml_mfp == NULL) {
@@ -1834,8 +1894,7 @@ int ml_append_buf(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool new
/// @param len length of line, including NUL, or 0
/// @param newfile flag, see above
/// @param mark mark the new line
-static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, bool newfile,
- int mark)
+static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, bool newfile, int mark)
{
// lnum out of range
if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) {
@@ -1847,7 +1906,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
}
if (len == 0) {
- len = (colnr_T)STRLEN(line) + 1; // space needed for the text
+ len = (colnr_T)strlen(line) + 1; // space needed for the text
}
int space_needed = len + (int)INDEX_SIZE; // space needed for text + index
@@ -2135,13 +2194,13 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
buf->b_ml.ml_stack_top = stack_idx + 1; // truncate stack
if (lineadd) {
- --(buf->b_ml.ml_stack_top);
+ (buf->b_ml.ml_stack_top)--;
// fix line count for rest of blocks in the stack
ml_lineadd(buf, lineadd);
// fix stack itself
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
lineadd;
- ++(buf->b_ml.ml_stack_top);
+ (buf->b_ml.ml_stack_top)++;
}
// We are finished, break the loop here.
@@ -2244,15 +2303,15 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
void ml_add_deleted_len(char *ptr, ssize_t len)
{
- ml_add_deleted_len_buf(curbuf, (char_u *)ptr, len);
+ ml_add_deleted_len_buf(curbuf, ptr, len);
}
-void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
+void ml_add_deleted_len_buf(buf_T *buf, char *ptr, ssize_t len)
{
if (inhibit_delete_count) {
return;
}
- ssize_t maxlen = (ssize_t)STRLEN(ptr);
+ ssize_t maxlen = (ssize_t)strlen(ptr);
if (len == -1 || len > maxlen) {
len = maxlen;
}
@@ -2309,10 +2368,10 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
}
if (readlen && kv_size(buf->update_callbacks)) {
- ml_add_deleted_len_buf(buf, (char_u *)ml_get_buf(buf, lnum, false), -1);
+ ml_add_deleted_len_buf(buf, ml_get_buf(buf, lnum, false), -1);
}
- buf->b_ml.ml_line_ptr = (char_u *)line;
+ buf->b_ml.ml_line_ptr = line;
buf->b_ml.ml_line_lnum = lnum;
buf->b_ml.ml_flags = (buf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
@@ -2386,7 +2445,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
// Line should always have an NL char internally (represented as NUL),
// even if 'noeol' is set.
assert(line_size >= 1);
- ml_add_deleted_len_buf(buf, (char_u *)dp + line_start, line_size - 1);
+ ml_add_deleted_len_buf(buf, (char *)dp + line_start, line_size - 1);
// special case: If there is only one line in the data block it becomes empty.
// Then we have to remove the entry, pointing to this data block, from the
@@ -2428,7 +2487,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
buf->b_ml.ml_locked_lineadd;
}
- ++(buf->b_ml.ml_stack_top);
+ (buf->b_ml.ml_stack_top)++;
break;
}
@@ -2574,7 +2633,7 @@ static void ml_flush_line(buf_T *buf)
buf->flush_count++;
linenr_T lnum = buf->b_ml.ml_line_lnum;
- char_u *new_line = buf->b_ml.ml_line_ptr;
+ char *new_line = buf->b_ml.ml_line_ptr;
bhdr_T *hp = ml_find_line(buf, lnum, ML_FIND);
if (hp == NULL) {
@@ -2583,14 +2642,14 @@ static void ml_flush_line(buf_T *buf)
DATA_BL *dp = hp->bh_data;
int idx = lnum - buf->b_ml.ml_locked_low;
int start = ((dp->db_index[idx]) & DB_INDEX_MASK);
- char_u *old_line = (char_u *)dp + start;
+ char *old_line = (char *)dp + start;
int old_len;
if (idx == 0) { // line is last in block
old_len = (int)dp->db_txt_end - start;
} else { // text of previous line follows
old_len = (int)(dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
}
- colnr_T new_len = (colnr_T)STRLEN(new_line) + 1;
+ colnr_T new_len = (colnr_T)strlen(new_line) + 1;
int extra = new_len - old_len; // negative if lines gets smaller
// if new line fits in data block, replace directly
@@ -2698,11 +2757,11 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
&& buf->b_ml.ml_locked_high >= lnum) {
// remember to update pointer blocks and stack later
if (action == ML_INSERT) {
- ++(buf->b_ml.ml_locked_lineadd);
- ++(buf->b_ml.ml_locked_high);
+ (buf->b_ml.ml_locked_lineadd)++;
+ (buf->b_ml.ml_locked_high)++;
} else if (action == ML_DELETE) {
- --(buf->b_ml.ml_locked_lineadd);
- --(buf->b_ml.ml_locked_high);
+ (buf->b_ml.ml_locked_lineadd)--;
+ (buf->b_ml.ml_locked_high)--;
}
return buf->b_ml.ml_locked;
}
@@ -2908,7 +2967,7 @@ int resolve_symlink(const char *fname, char *buf)
}
// Put the result so far in tmp[], starting with the original name.
- STRLCPY(tmp, fname, MAXPATHL);
+ xstrlcpy(tmp, fname, MAXPATHL);
for (;;) {
// Limit symlink depth to 100, catch recursive loops.
@@ -2940,11 +2999,11 @@ int resolve_symlink(const char *fname, char *buf)
// If it's relative, build a new path based on the directory
// portion of the filename (if any) and the path the symlink
// points to.
- if (path_is_absolute((char_u *)buf)) {
+ if (path_is_absolute(buf)) {
STRCPY(tmp, buf);
} else {
- char_u *tail = (char_u *)path_tail(tmp);
- if (STRLEN(tail) + strlen(buf) >= MAXPATHL) {
+ char *tail = path_tail(tmp);
+ if (strlen(tail) + strlen(buf) >= MAXPATHL) {
return FAIL;
}
STRCPY(tail, buf);
@@ -2961,41 +3020,41 @@ int resolve_symlink(const char *fname, char *buf)
/// Make swap file name out of the file name and a directory name.
///
/// @return pointer to allocated memory or NULL.
-char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
+char *makeswapname(char *fname, char *ffname, buf_T *buf, char *dir_name)
{
- char_u *fname_res = fname;
+ char *fname_res = fname;
#ifdef HAVE_READLINK
- char_u fname_buf[MAXPATHL];
+ char fname_buf[MAXPATHL];
// Expand symlink in the file name, so that we put the swap file with the
// actual file instead of with the symlink.
- if (resolve_symlink((char *)fname, (char *)fname_buf) == OK) {
+ if (resolve_symlink(fname, (char *)fname_buf) == OK) {
fname_res = fname_buf;
}
#endif
- int len = (int)STRLEN(dir_name);
+ int len = (int)strlen(dir_name);
- char_u *s = dir_name + len;
- if (after_pathsep((char *)dir_name, (char *)s)
+ char *s = dir_name + len;
+ if (after_pathsep(dir_name, s)
&& len > 1
&& s[-1] == s[-2]) { // Ends with '//', Use Full path
- char_u *r = NULL;
- s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname_res);
+ char *r = NULL;
+ s = make_percent_swname(dir_name, fname_res);
if (s != NULL) {
- r = (char_u *)modname((char *)s, ".swp", false);
+ r = modname(s, ".swp", false);
xfree(s);
}
return r;
}
// Prepend a '.' to the swap file name for the current directory.
- char_u *r = (char_u *)modname((char *)fname_res, ".swp",
- dir_name[0] == '.' && dir_name[1] == NUL);
+ char *r = modname(fname_res, ".swp",
+ dir_name[0] == '.' && dir_name[1] == NUL);
if (r == NULL) { // out of memory
return NULL;
}
- s = (char_u *)get_file_in_dir((char *)r, (char *)dir_name);
+ s = get_file_in_dir(r, dir_name);
xfree(r);
return s;
}
@@ -3042,14 +3101,14 @@ char *get_file_in_dir(char *fname, char *dname)
///
/// @param buf buffer being edited
/// @param fname swap file name
-static void attention_message(buf_T *buf, char_u *fname)
+static void attention_message(buf_T *buf, char *fname)
{
assert(buf->b_fname != NULL);
no_wait_return++;
(void)emsg(_("E325: ATTENTION"));
msg_puts(_("\nFound a swap file by the name \""));
- msg_home_replace((char *)fname);
+ msg_home_replace(fname);
msg_puts("\"\n");
const time_t swap_mtime = swapfile_info(fname);
msg_puts(_("While opening file \""));
@@ -3062,7 +3121,7 @@ static void attention_message(buf_T *buf, char_u *fname)
msg_puts(_(" dated: "));
time_t x = file_info.stat.st_mtim.tv_sec;
char ctime_buf[50];
- msg_puts(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf)));
+ msg_puts(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf), true));
if (swap_mtime != 0 && x > swap_mtime) {
msg_puts(_(" NEWER than swap file!\n"));
}
@@ -3078,7 +3137,7 @@ static void attention_message(buf_T *buf, char_u *fname)
msg_outtrans(buf->b_fname);
msg_puts(_("\"\n to recover the changes (see \":help recovery\").\n"));
msg_puts(_(" If you did this already, delete the swap file \""));
- msg_outtrans((char *)fname);
+ msg_outtrans(fname);
msg_puts(_("\"\n to avoid this message.\n"));
cmdline_row = msg_row;
no_wait_return--;
@@ -3094,9 +3153,9 @@ static void attention_message(buf_T *buf, char_u *fname)
/// 4: delete it
/// 5: quit
/// 6: abort
-static int do_swapexists(buf_T *buf, char_u *fname)
+static int do_swapexists(buf_T *buf, char *fname)
{
- set_vim_var_string(VV_SWAPNAME, (char *)fname, -1);
+ set_vim_var_string(VV_SWAPNAME, fname, -1);
set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
// Trigger SwapExists autocommands with <afile> set to the file being
@@ -3161,8 +3220,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
(void)copy_option_part(dirp, dir_name, dir_len, ",");
// we try different names until we find one that does not exist yet
- char *fname = (char *)makeswapname((char_u *)buf_fname, (char_u *)buf->b_ffname, buf,
- (char_u *)dir_name);
+ char *fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);
for (;;) {
if (fname == NULL) { // must be out of memory
@@ -3209,7 +3267,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
if (b0.b0_flags & B0_SAME_DIR) {
if (path_fnamecmp(path_tail(buf->b_ffname),
path_tail((char *)b0.b0_fname)) != 0
- || !same_directory((char_u *)fname, (char_u *)buf->b_ffname)) {
+ || !same_directory(fname, buf->b_ffname)) {
// Symlinks may point to the same file even
// when the name differs, need to check the
// inode too.
@@ -3254,12 +3312,12 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
if (choice == 0
&& swap_exists_action != SEA_NONE
&& has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf)) {
- choice = do_swapexists(buf, (char_u *)fname);
+ choice = do_swapexists(buf, fname);
}
if (choice == 0) {
// Show info about the existing swap file.
- attention_message(buf, (char_u *)fname);
+ attention_message(buf, fname);
// We don't want a 'q' typed at the more-prompt
// interrupt loading a file.
@@ -3375,8 +3433,8 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, bool *found_
static int b0_magic_wrong(ZERO_BL *b0p)
{
return b0p->b0_magic_long != B0_MAGIC_LONG
- || b0p->b0_magic_int != (int)B0_MAGIC_INT
- || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
+ || b0p->b0_magic_int != B0_MAGIC_INT
+ || b0p->b0_magic_short != (int16_t)B0_MAGIC_SHORT
|| b0p->b0_magic_char != B0_MAGIC_CHAR;
}
@@ -3485,7 +3543,7 @@ static void long_to_char(long n, char_u *s)
s[3] = (char_u)(n & 0xff);
}
-static long char_to_long(char_u *s)
+static long char_to_long(const char_u *s)
{
long retval;
@@ -3516,7 +3574,7 @@ void ml_setflags(buf_T *buf)
if (hp->bh_bnum == 0) {
b0p = hp->bh_data;
b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
- b0p->b0_flags = (uint8_t)((b0p->b0_flags & ~B0_FF_MASK) | (uint8_t)(get_fileformat(buf) + 1));
+ b0p->b0_flags = (char)((b0p->b0_flags & ~B0_FF_MASK) | (uint8_t)(get_fileformat(buf) + 1));
add_b0_fenc(b0p, buf);
hp->bh_flags |= BH_DIRTY;
mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
@@ -3525,8 +3583,10 @@ void ml_setflags(buf_T *buf)
}
}
-#define MLCS_MAXL 800 // max no of lines in chunk
-#define MLCS_MINL 400 // should be half of MLCS_MAXL
+enum {
+ MLCS_MAXL = 800, // max no of lines in chunk
+ MLCS_MINL = 400, // should be half of MLCS_MAXL
+};
/// Keep information for finding byte offset of a line
///
@@ -3566,7 +3626,7 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
buf->b_ml.ml_usedchunks = 1;
buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
buf->b_ml.ml_chunksize[0].mlcs_totalsize =
- (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
+ (long)strlen(buf->b_ml.ml_line_ptr) + 1;
return;
}
@@ -3906,7 +3966,7 @@ int inc(pos_T *lp)
{
// when searching position may be set to end of a line
if (lp->col != MAXCOL) {
- const char_u *const p = ml_get_pos(lp);
+ const char *const p = ml_get_pos(lp);
if (*p != NUL) { // still within line, move to next char (may be NUL)
const int l = utfc_ptr2len((char *)p);