aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthieu Coudron <mattator@gmail.com>2020-04-12 20:37:57 +0200
committerGitHub <noreply@github.com>2020-04-12 20:37:57 +0200
commit46fdad255ead9ca484a6e512efe13b379b8fc8ab (patch)
tree9d0ecdf08a98c7ac179ebf93a3f2e3d6c53fec33 /src
parent1f56f9a4b32c7d7aebafea226c148e9ed8bbabdb (diff)
parent53fdd76181d2d1834aa38f4b47aa36f844d1e43f (diff)
downloadrneovim-46fdad255ead9ca484a6e512efe13b379b8fc8ab.tar.gz
rneovim-46fdad255ead9ca484a6e512efe13b379b8fc8ab.tar.bz2
rneovim-46fdad255ead9ca484a6e512efe13b379b8fc8ab.zip
Merge pull request #12033 from janlazo/vim-8.1.1313
[RFC]vim-patch:8.1.{1313,1567,1568}
Diffstat (limited to 'src')
-rw-r--r--src/nvim/hardcopy.c10
-rw-r--r--src/nvim/memline.c28
-rw-r--r--src/nvim/os/time.c55
-rw-r--r--src/nvim/testdir/test_functions.vim26
4 files changed, 91 insertions, 28 deletions
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index cb5c5338a1..6e241feab2 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -2416,9 +2416,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource)
int mch_print_begin(prt_settings_T *psettings)
{
- time_t now;
int bbox[4];
- char *p_time;
double left;
double right;
double top;
@@ -2442,10 +2440,10 @@ int mch_print_begin(prt_settings_T *psettings)
}
prt_dsc_textline("For", buffer);
prt_dsc_textline("Creator", longVersion);
- /* Note: to ensure Clean8bit I don't think we can use LC_TIME */
- now = time(NULL);
- p_time = ctime(&now);
- /* Note: ctime() adds a \n so we have to remove it :-( */
+ // Note: to ensure Clean8bit I don't think we can use LC_TIME
+ char ctime_buf[50];
+ char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf));
+ // Note: os_ctime() adds a \n so we have to remove it :-(
p = vim_strchr((char_u *)p_time, '\n');
if (p != NULL)
*p = NUL;
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index fa7c39cc65..b695d0e139 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -1504,16 +1504,15 @@ static time_t swapfile_info(char_u *fname)
int fd;
struct block0 b0;
time_t x = (time_t)0;
- char *p;
#ifdef UNIX
char uname[B0_UNAME_SIZE];
#endif
- /* print the swap file date */
+ // print the swap file date
FileInfo file_info;
if (os_fileinfo((char *)fname, &file_info)) {
#ifdef UNIX
- /* print name of owner of the file */
+ // print name of owner of the file
if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) {
MSG_PUTS(_(" owned by: "));
msg_outtrans((char_u *)uname);
@@ -1522,11 +1521,8 @@ static time_t swapfile_info(char_u *fname)
#endif
MSG_PUTS(_(" dated: "));
x = file_info.stat.st_mtim.tv_sec;
- p = ctime(&x); // includes '\n'
- if (p == NULL)
- MSG_PUTS("(invalid)\n");
- else
- MSG_PUTS(p);
+ char ctime_buf[50];
+ MSG_PUTS(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf)));
}
/*
@@ -3267,15 +3263,13 @@ attention_message (
)
{
assert(buf->b_fname != NULL);
- time_t x, sx;
- char *p;
++no_wait_return;
(void)EMSG(_("E325: ATTENTION"));
MSG_PUTS(_("\nFound a swap file by the name \""));
msg_home_replace(fname);
MSG_PUTS("\"\n");
- sx = swapfile_info(fname);
+ const time_t swap_mtime = swapfile_info(fname);
MSG_PUTS(_("While opening file \""));
msg_outtrans(buf->b_fname);
MSG_PUTS("\"\n");
@@ -3284,14 +3278,12 @@ attention_message (
MSG_PUTS(_(" CANNOT BE FOUND"));
} else {
MSG_PUTS(_(" dated: "));
- x = file_info.stat.st_mtim.tv_sec;
- p = ctime(&x); // includes '\n'
- if (p == NULL)
- MSG_PUTS("(invalid)\n");
- else
- MSG_PUTS(p);
- if (sx != 0 && x > sx)
+ 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)));
+ if (swap_mtime != 0 && x > swap_mtime) {
MSG_PUTS(_(" NEWER than swap file!\n"));
+ }
}
/* Some of these messages are long to allow translation to
* other languages. */
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 4dd0614fe2..346e40e02e 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -2,9 +2,6 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
#include <limits.h>
#include <uv.h>
@@ -13,7 +10,7 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/event/loop.h"
-#include "nvim/vim.h"
+#include "nvim/os/os.h"
#include "nvim/main.h"
static uv_mutex_t delay_mutex;
@@ -112,6 +109,10 @@ void os_microdelay(uint64_t us, bool ignoreinput)
uv_mutex_unlock(&delay_mutex);
}
+// Cache of the current timezone name as retrieved from TZ, or an empty string
+// where unset, up to 64 octets long including trailing null byte.
+static char tz_cache[64];
+
/// Portable version of POSIX localtime_r()
///
/// @return NULL in case of error
@@ -120,6 +121,19 @@ struct tm *os_localtime_r(const time_t *restrict clock,
{
#ifdef UNIX
// POSIX provides localtime_r() as a thread-safe version of localtime().
+ //
+ // Check to see if the environment variable TZ has changed since the last run.
+ // Call tzset(3) to update the global timezone variables if it has.
+ // POSIX standard doesn't require localtime_r() implementations to do that
+ // as it does with localtime(), and we don't want to call tzset() every time.
+ const char *tz = os_getenv("TZ");
+ if (tz == NULL) {
+ tz = "";
+ }
+ if (strncmp(tz_cache, tz, sizeof(tz_cache) - 1) != 0) {
+ tzset();
+ xstrlcpy(tz_cache, tz, sizeof(tz_cache));
+ }
return localtime_r(clock, result); // NOLINT(runtime/threadsafe_fn)
#else
// Windows version of localtime() is thread-safe.
@@ -144,6 +158,39 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL
return os_localtime_r(&rawtime, result);
}
+/// Portable version of POSIX ctime_r()
+///
+/// @param clock[in]
+/// @param result[out] Pointer to a 'char' where the result should be placed
+/// @param result_len length of result buffer
+/// @return human-readable string of current local time
+char *os_ctime_r(const time_t *restrict clock, char *restrict result,
+ size_t result_len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ struct tm clock_local;
+ struct tm *clock_local_ptr = os_localtime_r(clock, &clock_local);
+ // MSVC returns NULL for an invalid value of seconds.
+ if (clock_local_ptr == NULL) {
+ snprintf(result, result_len, "%s\n", _("(Invalid)"));
+ } else {
+ strftime(result, result_len, "%a %b %d %H:%M:%S %Y\n", clock_local_ptr);
+ }
+ return result;
+}
+
+/// Gets the current Unix timestamp and adjusts it to local time.
+///
+/// @param result[out] Pointer to a 'char' where the result should be placed
+/// @param result_len length of result buffer
+/// @return human-readable string of current local time
+char *os_ctime(char *result, size_t result_len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ time_t rawtime = time(NULL);
+ return os_ctime_r(&rawtime, result, result_len);
+}
+
/// Obtains the current Unix timestamp.
///
/// @return Seconds since epoch.
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 7822507f86..b75b095841 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -186,6 +186,32 @@ func Test_strftime()
call assert_fails('call strftime([])', 'E730:')
call assert_fails('call strftime("%Y", [])', 'E745:')
+
+ " Check that the time changes after we change the timezone
+ " Save previous timezone value, if any
+ if exists('$TZ')
+ let tz = $TZ
+ endif
+
+ " Force EST and then UTC, save the current hour (24-hour clock) for each
+ let $TZ = 'EST' | let est = strftime('%H')
+ let $TZ = 'UTC' | let utc = strftime('%H')
+
+ " Those hours should be two bytes long, and should not be the same; if they
+ " are, a tzset(3) call may have failed somewhere
+ call assert_equal(strlen(est), 2)
+ call assert_equal(strlen(utc), 2)
+ " TODO: this fails on MS-Windows
+ if has('unix')
+ call assert_notequal(est, utc)
+ endif
+
+ " If we cached a timezone value, put it back, otherwise clear it
+ if exists('tz')
+ let $TZ = tz
+ else
+ unlet $TZ
+ endif
endfunc
func Test_resolve()