diff options
-rw-r--r-- | clint-files.txt | 2 | ||||
-rw-r--r-- | src/eval.c | 10 | ||||
-rw-r--r-- | src/log.c | 147 | ||||
-rw-r--r-- | src/log.h | 57 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/misc1.h | 4 | ||||
-rw-r--r-- | src/os/time.c | 25 | ||||
-rw-r--r-- | src/os/time.h | 11 | ||||
-rw-r--r-- | src/regexp_nfa.c | 81 | ||||
-rw-r--r-- | src/undo.c | 9 |
10 files changed, 296 insertions, 52 deletions
diff --git a/clint-files.txt b/clint-files.txt index 68c2358f85..76da1f3656 100644 --- a/clint-files.txt +++ b/clint-files.txt @@ -1,5 +1,7 @@ src/indent.c src/indent.h +src/log.c +src/log.h src/os/env.c src/os/event.c src/os/event_defs.h diff --git a/src/eval.c b/src/eval.c index 61a33c04d9..ed246c363b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -65,6 +65,7 @@ #include "os/job.h" #include "os/rstream.h" #include "os/rstream_defs.h" +#include "os/time.h" #if defined(FEAT_FLOAT) # include <math.h> @@ -14163,7 +14164,6 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv) static void f_strftime(typval_T *argvars, typval_T *rettv) { char_u result_buf[256]; - struct tm *curtime; time_t seconds; char_u *p; @@ -14174,9 +14174,11 @@ static void f_strftime(typval_T *argvars, typval_T *rettv) seconds = time(NULL); else seconds = (time_t)get_tv_number(&argvars[1]); - curtime = localtime(&seconds); + + struct tm curtime; + struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime); /* MSVC returns NULL for an invalid value of seconds. */ - if (curtime == NULL) + if (curtime_ptr == NULL) rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); else { vimconv_T conv; @@ -14189,7 +14191,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv) p = string_convert(&conv, p, NULL); if (p != NULL) (void)strftime((char *)result_buf, sizeof(result_buf), - (char *)p, curtime); + (char *)p, curtime_ptr); else result_buf[0] = NUL; diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000000..5d536c62e5 --- /dev/null +++ b/src/log.c @@ -0,0 +1,147 @@ +#include <assert.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/time.h> +#include <unistd.h> + +#include "log.h" +#include "misc1.h" +#include "types.h" +#include "os/os.h" +#include "os/time.h" + +#define USR_LOG_FILE "$HOME/.nvimlog" + + +static FILE *open_log_file(void); +static bool do_log_to_file(FILE *log_file, int log_level, + const char *func_name, int line_num, + const char* fmt, ...); +static bool v_do_log_to_file(FILE *log_file, int log_level, + const char *func_name, int line_num, + const char* fmt, va_list args); + +bool do_log(int log_level, const char *func_name, int line_num, + const char* fmt, ...) +{ + FILE *log_file = open_log_file(); + + if (log_file == NULL) { + return false; + } + + va_list args; + va_start(args, fmt); + bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, fmt, + args); + va_end(args); + + if (log_file != stderr && log_file != stdout) { + fclose(log_file); + } + return ret; +} + +/// Open the log file for appending. +/// +/// @return The FILE* specified by the USR_LOG_FILE path or stderr in case of +/// error +static FILE *open_log_file(void) +{ + static bool opening_log_file = false; + + // check if it's a recursive call + if (opening_log_file) { + do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, + "Trying to LOG() recursively! Please fix it."); + return stderr; + } + + // expand USR_LOG_FILE and open the file + FILE *log_file; + opening_log_file = true; + { + static char expanded_log_file_path[MAXPATHL + 1]; + + expand_env((char_u *)USR_LOG_FILE, (char_u *)expanded_log_file_path, + MAXPATHL); + // if the log file path expansion failed then fall back to stderr + if (strcmp(USR_LOG_FILE, expanded_log_file_path) == 0) { + goto open_log_file_error; + } + + log_file = fopen(expanded_log_file_path, "a"); + if (log_file == NULL) { + goto open_log_file_error; + } + } + opening_log_file = false; + + return log_file; + +open_log_file_error: + opening_log_file = false; + + do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, + "Couldn't open USR_LOG_FILE, logging to stderr! This may be " + "caused by attempting to LOG() before initialization " + "functions are called (e.g. init_homedir())."); + return stderr; +} + +static bool do_log_to_file(FILE *log_file, int log_level, + const char *func_name, int line_num, + const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, fmt, + args); + va_end(args); + + return ret; +} + +static bool v_do_log_to_file(FILE *log_file, int log_level, + const char *func_name, int line_num, + const char* fmt, va_list args) +{ + static const char *log_levels[] = { + [DEBUG_LOG_LEVEL] = "debug", + [INFO_LOG_LEVEL] = "info", + [WARNING_LOG_LEVEL] = "warning", + [ERROR_LOG_LEVEL] = "error" + }; + assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL); + + // format current timestamp in local time + struct tm local_time; + if (os_get_localtime(&local_time) == NULL) { + return false; + } + char date_time[20]; + if (strftime(date_time, sizeof(date_time), "%Y/%m/%d %H:%M:%S", + &local_time) == 0) { + return false; + } + + // print the log message prefixed by the current timestamp and pid + int64_t pid = os_get_pid(); + if (fprintf(log_file, "%s [%s @ %s:%d] %" PRId64 " - ", date_time, + log_levels[log_level], func_name, line_num, pid) < 0) { + return false; + } + if (vfprintf(log_file, fmt, args) < 0) { + return false; + } + fputc('\n', log_file); + if (fflush(log_file) == EOF) { + return false; + } + + return true; +} + diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000000..45c8fdbfd8 --- /dev/null +++ b/src/log.h @@ -0,0 +1,57 @@ +#ifndef NEOVIM_LOG_H +#define NEOVIM_LOG_H + +#include <stdbool.h> + +#include "func_attr.h" + +#define DEBUG_LOG_LEVEL 0 +#define INFO_LOG_LEVEL 1 +#define WARNING_LOG_LEVEL 2 +#define ERROR_LOG_LEVEL 3 + +bool do_log(int log_level, const char *func_name, int line_num, + const char* fmt, ...) FUNC_ATTR_UNUSED; + +#define DLOG(...) +#define ILOG(...) +#define WLOG(...) +#define ELOG(...) + +// Logging is disabled if NDEBUG or DISABLE_LOG is defined. +#ifdef NDEBUG +# define DISABLE_LOG +#endif + +// MIN_LOG_LEVEL can be defined during compilation to adjust the desired level +// of logging. DEBUG_LOG_LEVEL is used by default. +#ifndef MIN_LOG_LEVEL +# define MIN_LOG_LEVEL DEBUG_LOG_LEVEL +#endif + +#ifndef DISABLE_LOG + +# if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL +# undef DLOG +# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, __VA_ARGS__) +# endif + +# if MIN_LOG_LEVEL <= INFO_LOG_LEVEL +# undef ILOG +# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, __VA_ARGS__) +# endif + +# if MIN_LOG_LEVEL <= WARNING_LOG_LEVEL +# undef WLOG +# define WLOG(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, __VA_ARGS__) +# endif + +# if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL +# undef ELOG +# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, __VA_ARGS__) +# endif + +#endif + +#endif // NEOVIM_LOG_H + diff --git a/src/main.c b/src/main.c index acbe67ebc1..9fd97b23a5 100644 --- a/src/main.c +++ b/src/main.c @@ -33,6 +33,7 @@ #include "misc2.h" #include "crypt.h" #include "garray.h" +#include "log.h" #include "memory.h" #include "move.h" #include "normal.h" @@ -578,6 +579,7 @@ main_loop ( linenr_T conceal_new_cursor_line = 0; int conceal_update_lines = FALSE; + ILOG("Starting Neovim main loop."); clear_oparg(&oa); while (!cmdwin diff --git a/src/misc1.h b/src/misc1.h index a68b9d3b6f..a46b305fae 100644 --- a/src/misc1.h +++ b/src/misc1.h @@ -1,6 +1,8 @@ #ifndef NEOVIM_MISC1_H #define NEOVIM_MISC1_H -/* misc1.c */ + +#include "vim.h" + int open_line(int dir, int flags, int second_line_indent); int get_leader_len(char_u *line, char_u **flags, int backward, int include_space); diff --git a/src/os/time.c b/src/os/time.c index 0f7c990e23..1dc7ca68d4 100644 --- a/src/os/time.c +++ b/src/os/time.c @@ -1,5 +1,6 @@ #include <stdint.h> #include <stdbool.h> +#include <sys/time.h> #include <uv.h> @@ -59,3 +60,27 @@ static void microdelay(uint64_t microseconds) uv_mutex_unlock(&delay_mutex); } + +struct tm *os_localtime_r(const time_t *clock, struct tm *result) +{ +#ifdef UNIX + // POSIX provides localtime_r() as a thread-safe version of localtime(). + return localtime_r(clock, result); +#else + // Windows version of localtime() is thread-safe. + // See http://msdn.microsoft.com/en-us/library/bf12f0hc%28VS.80%29.aspx + struct tm *local_time = localtime(clock); // NOLINT + *result = *local_time; +return result; +#endif +} + +struct tm *os_get_localtime(struct tm *result) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + return NULL; + } + + return os_localtime_r(&tv.tv_sec, result); +} diff --git a/src/os/time.h b/src/os/time.h index 42feaa3eba..ef795d03be 100644 --- a/src/os/time.h +++ b/src/os/time.h @@ -19,6 +19,17 @@ void os_delay(uint64_t milliseconds, bool ignoreinput); /// @param ignoreinput If true, allow a SIGINT to interrupt us void os_microdelay(uint64_t microseconds, bool ignoreinput); +/// Portable version of POSIX localtime_r() +/// +/// @return NULL in case of error +struct tm *os_localtime_r(const time_t *clock, struct tm *result); + +/// Obtains the current UNIX timestamp and adjusts it to local time +/// +/// @param result Pointer to a 'struct tm' where the result should be placed +/// @return A pointer to a 'struct tm' in the current time zone (the 'result' +/// argument) or NULL in case of error +struct tm *os_get_localtime(struct tm *result); #endif // NEOVIM_OS_TIME_H diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index a9960cbae0..9d119a2bd3 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -25,7 +25,6 @@ */ #ifdef REGEXP_DEBUG # define NFA_REGEXP_ERROR_LOG "nfa_regexp_error.log" -# define ENABLE_LOG # define NFA_REGEXP_DUMP_LOG "nfa_regexp_dump.log" # define NFA_REGEXP_RUN_LOG "nfa_regexp_run.log" # define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log" @@ -2304,7 +2303,7 @@ static void nfa_set_code(int c) } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG static FILE *log_fd; /* @@ -2424,7 +2423,7 @@ static void nfa_dump(nfa_regprog_T *prog) fclose(debugf); } } -#endif /* ENABLE_LOG */ +#endif /* REGEXP_DEBUG */ #endif /* REGEXP_DEBUG */ /* @@ -3433,7 +3432,7 @@ typedef struct { int has_pim; /* TRUE when any state has a PIM */ } nfa_list_T; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG static void log_subsexpr(regsubs_T *subs); static void log_subexpr(regsub_T *sub); static char *pim_info(nfa_pim_T *pim); @@ -3632,7 +3631,7 @@ static int sub_equal(regsub_T *sub1, regsub_T *sub2) return TRUE; } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG static void report_state(char *action, regsub_T *sub, nfa_state_T *state, @@ -3835,7 +3834,7 @@ addstate ( regsub_T *sub; regsubs_T *subs = subs_arg; static regsubs_T temp_subs; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG int did_print = FALSE; #endif @@ -3914,7 +3913,7 @@ addstate ( * when there is a PIM. */ if (!nfa_has_backref && pim == NULL && !l->has_pim) { skip_add: -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG nfa_set_code(state->c); fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", abs(state->id), l->id, state->c, code); @@ -3959,13 +3958,13 @@ skip_add: copy_sub(&thread->subs.norm, &subs->norm); if (nfa_has_zsubexpr) copy_sub(&thread->subs.synt, &subs->synt); -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG report_state("Adding", &thread->subs.norm, state, l->id, pim); did_print = TRUE; #endif } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG if (!did_print) report_state("Processing", &subs->norm, state, l->id, pim); #endif @@ -4515,7 +4514,7 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T } } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG if (log_fd != stderr) fclose(log_fd); log_fd = NULL; @@ -4561,7 +4560,7 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T nfa_endp = save_nfa_endp; nfa_listid = save_nfa_listid; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG log_fd = fopen(NFA_REGEXP_RUN_LOG, "a"); if (log_fd != NULL) { fprintf(log_fd, "****************************\n"); @@ -4859,7 +4858,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm list[1].t = (nfa_thread_T *)lalloc(size, TRUE); list[1].len = nstate + 1; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG log_fd = fopen(NFA_REGEXP_RUN_LOG, "a"); if (log_fd != NULL) { fprintf(log_fd, "**********************************\n"); @@ -4880,7 +4879,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm nextlist = &list[1]; nextlist->n = 0; nextlist->has_pim = FALSE; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "(---) STARTSTATE first\n"); #endif thislist->id = nfa_listid + 1; @@ -4932,7 +4931,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm thislist->id = nfa_listid; nextlist->id = nfa_listid + 1; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "------------------------------------------\n"); fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput); fprintf(log_fd, @@ -4965,7 +4964,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm nfa_set_code(t->state->c); fprintf(debug, "%s, ", code); #endif -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG { int col; @@ -4996,7 +4995,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm copy_sub(&submatch->norm, &t->subs.norm); if (nfa_has_zsubexpr) copy_sub(&submatch->synt, &t->subs.synt); -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG log_subsexpr(&t->subs); #endif /* Found the left-most longest match, do not look at any other @@ -5022,7 +5021,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm * in the position in "nfa_endp". * Submatches are stored in *m, and used in the parent call. */ -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG if (nfa_endp != NULL) { if (REG_MULTI) fprintf( @@ -5053,7 +5052,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm if (nfa_has_zsubexpr) copy_sub(&m->synt, &t->subs.synt); } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "Match found:\n"); log_subsexpr(m); #endif @@ -5072,7 +5071,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm case NFA_START_INVISIBLE_BEFORE_NEG: case NFA_START_INVISIBLE_BEFORE_NEG_FIRST: { -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "Failure chance invisible: %d, what follows: %d\n", failure_chance(t->state->out, 0), failure_chance(t->state->out1->out, 0)); @@ -5153,7 +5152,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm case NFA_START_PATTERN: { nfa_state_T *skip = NULL; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG int skip_lid = 0; #endif @@ -5161,24 +5160,24 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm * output state is not going to be added to the list. */ if (state_in_list(nextlist, t->state->out1->out, &t->subs)) { skip = t->state->out1->out; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG skip_lid = nextlist->id; #endif } else if (state_in_list(nextlist, t->state->out1->out->out, &t->subs)) { skip = t->state->out1->out->out; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG skip_lid = nextlist->id; #endif } else if (state_in_list(thislist, t->state->out1->out->out, &t->subs)) { skip = t->state->out1->out->out; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG skip_lid = thislist->id; #endif } if (skip != NULL) { -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG nfa_set_code(skip->c); fprintf( log_fd, @@ -5199,7 +5198,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm if (result) { int bytelen; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "NFA_START_PATTERN matches:\n"); log_subsexpr(m); #endif @@ -5216,7 +5215,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm else bytelen = (int)(m->norm.list.line[0].end - reginput); -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "NFA_START_PATTERN length: %d\n", bytelen); #endif if (bytelen == 0) { @@ -5424,7 +5423,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm c1 = state->val; state = state->out; /* advance to NFA_RANGE_MAX */ c2 = state->val; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n", curc, c1, c2); #endif @@ -5835,7 +5834,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm * without advancing and before the end of the line. */ if (pim != NULL && (clen == 0 || match_follows(add_state, 0))) { if (pim->result == NFA_PIM_TODO) { -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "\n"); fprintf(log_fd, "==================================\n"); fprintf(log_fd, "Postponed recursive nfa_regmatch()\n"); @@ -5859,7 +5858,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm } } else { result = (pim->result == NFA_PIM_MATCH); -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "\n"); fprintf( log_fd, @@ -5930,7 +5929,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm && (int)(reginput - regline) < nfa_endp->se_u.pos.col)) : reginput < nfa_endp->se_u.ptr)))) { -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, "(---) STARTSTATE\n"); #endif /* Inline optimized code for addstate() if we know the state is @@ -5947,7 +5946,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm * character that must appear at the start. */ if (skip_to_start(prog->regstart, &col) == FAIL) break; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, " Skipping ahead %d bytes to regstart\n", col - ((colnr_T)(reginput - regline) + clen)); #endif @@ -5958,7 +5957,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm c = PTR2CHAR(reginput + clen); if (c != prog->regstart && (!ireg_ic || vim_tolower(c) != vim_tolower(prog->regstart))) { -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, " Skipping start state, regstart does not match\n"); #endif @@ -5979,7 +5978,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm addstate(nextlist, start, m, NULL, clen); } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG fprintf(log_fd, ">>> Thislist had %d states available: ", thislist->n); { int i; @@ -6002,7 +6001,7 @@ nextchar: break; } -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG if (log_fd != stderr) fclose(log_fd); log_fd = NULL; @@ -6029,13 +6028,13 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col) int i; regsubs_T subs, m; nfa_state_T *start = prog->start; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG FILE *f; #endif reginput = regline + col; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG f = fopen(NFA_REGEXP_RUN_LOG, "a"); if (f != NULL) { fprintf(f, @@ -6263,7 +6262,7 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) * 1. first pass to count size (so we can allocate space) * 2. second to emit code */ -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG { FILE *f = fopen(NFA_REGEXP_RUN_LOG, "a"); @@ -6309,7 +6308,7 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) prog->regstart = nfa_get_regstart(prog->start, 0); prog->match_text = nfa_get_match_text(prog->start); -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG nfa_postfix_dump(expr, OK); nfa_dump(prog); #endif @@ -6329,7 +6328,7 @@ out: fail: free(prog); prog = NULL; -#ifdef ENABLE_LOG +#ifdef REGEXP_DEBUG nfa_postfix_dump(expr, FAIL); #endif #ifdef REGEXP_DEBUG @@ -6426,7 +6425,3 @@ proftime_T *tm; /* timeout limit or NULL */ return nfa_regexec_both(NULL, col); } - -#ifdef REGEXP_DEBUG -# undef ENABLE_LOG -#endif diff --git a/src/undo.c b/src/undo.c index 0f547f475b..660fe83fdd 100644 --- a/src/undo.c +++ b/src/undo.c @@ -103,6 +103,7 @@ #include "screen.h" #include "sha256.h" #include "os/os.h" +#include "os/time.h" static long get_undolevel(void); static void u_unch_branch(u_header_T *uhp); @@ -2455,16 +2456,16 @@ void ex_undolist(exarg_T *eap) */ static void u_add_time(char_u *buf, size_t buflen, time_t tt) { - struct tm *curtime; + struct tm curtime; if (time(NULL) - tt >= 100) { - curtime = localtime(&tt); + os_localtime_r(&tt, &curtime); if (time(NULL) - tt < (60L * 60L * 12L)) /* within 12 hours */ - (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime); + (void)strftime((char *)buf, buflen, "%H:%M:%S", &curtime); else /* longer ago */ - (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime); + (void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", &curtime); } else vim_snprintf((char *)buf, buflen, _("%" PRId64 " seconds ago"), (int64_t)(time(NULL) - tt)); |