From 8924e75f3477b20f0ef4e3df64b56bf496b197ae Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Thu, 2 Mar 2017 23:04:57 +0100 Subject: vim-patch:7.4.2170 Problem: Cannot get information about timers. Solution: Add timer_info(). https://github.com/vim/vim/commit/8e97bd74b5377753597e3d98e7123d8985c7fffd --- src/nvim/eval.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d4daffb469..537e9e696f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -17931,6 +17931,61 @@ static bool set_ref_in_callback(Callback *callback, int copyID, return false; } +static void add_timer_info(typval_T *rettv, timer_T *timer) +{ + list_T *list = rettv->vval.v_list; + dict_T *dict = dict_alloc(); + + list_append_dict(list, dict); + dict_add_nr_str(dict, "id", (long)timer->timer_id, NULL); + dict_add_nr_str(dict, "time", timer->timeout, NULL); + + dict_add_nr_str(dict, "repeat", + (long)(timer->repeat_count < 0 ? -1 : timer->repeat_count), + NULL); + + dictitem_T *di = dictitem_alloc((char_u *)"callback"); + if (dict_add(dict, di) == FAIL) { + xfree(di); + return; + } + + if (timer->callback.type == kCallbackPartial) { + di->di_tv.v_type = VAR_PARTIAL; + di->di_tv.vval.v_partial = timer->callback.data.partial; + timer->callback.data.partial->pt_refcount++; + } else if (timer->callback.type == kCallbackFuncref) { + di->di_tv.v_type = VAR_FUNC; + di->di_tv.vval.v_string = vim_strsave(timer->callback.data.funcref); + } + di->di_tv.v_lock = 0; +} + +static void add_timer_info_all(typval_T *rettv) +{ + timer_T *timer; + map_foreach_value(timers, timer, { + add_timer_info(rettv, timer); + }) +} + +/// "timer_info([timer])" function +static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + rettv_list_alloc(rettv); + if (argvars[0].v_type != VAR_UNKNOWN) { + if (argvars[0].v_type != VAR_NUMBER) { + EMSG(_(e_number_exp)); + } else { + timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); + if (timer != NULL) { + add_timer_info(rettv, timer); + } + } + } else { + add_timer_info_all(rettv); + } +} /// "timer_start(timeout, callback, opts)" function static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) -- cgit From 5b8ce2feed6b528bae4bceba6f234be000949971 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sun, 5 Mar 2017 16:25:40 +0100 Subject: vim-patch:7.4.2180 Problem: There is no easy way to stop all timers. There is no way to temporary pause a timer. Solution: Add timer_stopall() and timer_pause(). https://github.com/vim/vim/commit/b73598e2f022a22fec512ea681c70d2775e8fd87 --- src/nvim/eval.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 537e9e696f..062999e73b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -446,6 +446,7 @@ typedef struct { int refcount; long timeout; bool stopped; + bool paused; Callback callback; } timer_T; @@ -17939,6 +17940,7 @@ static void add_timer_info(typval_T *rettv, timer_T *timer) list_append_dict(list, dict); dict_add_nr_str(dict, "id", (long)timer->timer_id, NULL); dict_add_nr_str(dict, "time", timer->timeout, NULL); + dict_add_nr_str(dict, "paused", (long)timer->paused, NULL); dict_add_nr_str(dict, "repeat", (long)(timer->repeat_count < 0 ? -1 : timer->repeat_count), @@ -17965,7 +17967,9 @@ static void add_timer_info_all(typval_T *rettv) { timer_T *timer; map_foreach_value(timers, timer, { - add_timer_info(rettv, timer); + if (!timer->stopped) { + add_timer_info(rettv, timer); + } }) } @@ -17978,7 +17982,7 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_number_exp)); } else { timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); - if (timer != NULL) { + if (timer != NULL && !timer->stopped) { add_timer_info(rettv, timer); } } @@ -17987,6 +17991,20 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +/// "timer_pause(timer, paused)" function +static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) +{ + if (argvars[0].v_type != VAR_NUMBER) { + EMSG(_(e_number_exp)); + } else { + int paused = (bool)get_tv_number(&argvars[1]); + timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0])); + if (timer != NULL) { + timer->paused = paused; + } + } +} + /// "timer_start(timeout, callback, opts)" function static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) { @@ -18019,6 +18037,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) timer = xmalloc(sizeof *timer); timer->refcount = 1; timer->stopped = false; + timer->paused = false; timer->repeat_count = repeat; timer->timeout = timeout; timer->timer_id = last_timer_id++; @@ -18028,8 +18047,7 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr) timer->tw.events = multiqueue_new_child(main_loop.events); // if main loop is blocked, don't queue up multiple events timer->tw.blockable = true; - time_watcher_start(&timer->tw, timer_due_cb, timeout, - timeout * (repeat != 1)); + time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout); pmap_put(uint64_t)(timers, timer->timer_id, timer); rettv->vval.v_number = timer->timer_id; @@ -18053,13 +18071,19 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) timer_stop(timer); } +static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr) +{ + timer_teardown(); +} + // invoked on the main loop static void timer_due_cb(TimeWatcher *tw, void *data) { timer_T *timer = (timer_T *)data; - if (timer->stopped) { + if (timer->stopped || timer->paused) { return; } + timer->refcount++; // if repeat was negative repeat forever if (timer->repeat_count >= 0 && --timer->repeat_count == 0) { -- cgit From b2942d1e729c4cfa8ec9d3bedcdc7ad838a689ef Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 13 Apr 2017 19:16:32 +0300 Subject: eval: Change the point at which arg_errmsg and its length are changed Ref #6437 --- src/nvim/eval.c | 130 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 59 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 0663e19b9a..e81378bcaa 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2378,9 +2378,9 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, (const char *)lp->ll_name, - STRLEN(lp->ll_name)) + TV_CSTRING) && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name, - STRLEN(lp->ll_name)))) + TV_CSTRING))) && eexe_mod_op(&tv, rettv, (const char *)op) == OK) { set_var(lp->ll_name, lp->ll_name_len, &tv, false); } @@ -2393,7 +2393,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, } else if (tv_check_lock(lp->ll_newkey == NULL ? lp->ll_tv->v_lock : lp->ll_tv->vval.v_dict->dv_lock, - (const char *)lp->ll_name, STRLEN(lp->ll_name))) { + (const char *)lp->ll_name, TV_CSTRING)) { } else if (lp->ll_range) { listitem_T *ll_li = lp->ll_li; int ll_n1 = lp->ll_n1; @@ -2402,7 +2402,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, for (listitem_T *ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) { if (tv_check_lock(ll_li->li_tv.v_lock, (const char *)lp->ll_name, - STRLEN(lp->ll_name))) { + TV_CSTRING)) { return; } ri = ri->li_next; @@ -2992,14 +2992,14 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit) } if (hi != NULL && !HASHITEM_EMPTY(hi)) { dictitem_T *const di = TV_DICT_HI2DI(hi); - if (var_check_fixed(di->di_flags, (const char *)name, STRLEN(name)) - || var_check_ro(di->di_flags, (const char *)name, STRLEN(name)) - || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { + if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING) + || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING) + || tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) { return FAIL; } if (d == NULL - || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { + || tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) { return FAIL; } @@ -6553,10 +6553,8 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = 1; /* Default: Failed */ if (argvars[0].v_type == VAR_LIST) { - const char *const arg_errmsg = _("add() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, "add() argument", TV_TRANSLATE)) { tv_list_append_tv(l, &argvars[1]); tv_copy(&argvars[0], rettv); } @@ -8152,7 +8150,6 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) { const char *const arg_errmsg = N_("extend() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) { long before; @@ -8161,13 +8158,13 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) list_T *const l1 = argvars[0].vval.v_list; list_T *const l2 = argvars[1].vval.v_list; if (l1 == NULL) { - const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, arg_errmsg_len); + const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE); (void)locked; assert(locked == true); } else if (l2 == NULL) { // Do nothing tv_copy(&argvars[0], rettv); - } else if (!tv_check_lock(l1->lv_lock, arg_errmsg, arg_errmsg_len)) { + } else if (!tv_check_lock(l1->lv_lock, arg_errmsg, TV_TRANSLATE)) { listitem_T *item; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); @@ -8195,13 +8192,13 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) dict_T *const d1 = argvars[0].vval.v_dict; dict_T *const d2 = argvars[1].vval.v_dict; if (d1 == NULL) { - const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, arg_errmsg_len); + const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE); (void)locked; assert(locked == true); } else if (d2 == NULL) { // Do nothing tv_copy(&argvars[0], rettv); - } else if (!tv_check_lock(d1->dv_lock, arg_errmsg, arg_errmsg_len)) { + } else if (!tv_check_lock(d1->dv_lock, arg_errmsg, TV_TRANSLATE)) { const char *action = "force"; // Check the third argument. if (argvars[2].v_type != VAR_UNKNOWN) { @@ -8349,20 +8346,19 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) int todo; char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); const char *const arg_errmsg = (map - ? _("map() argument") - : _("filter() argument")); - const size_t arg_errmsg_len = strlen(arg_errmsg); + ? N_("map() argument") + : N_("filter() argument")); int save_did_emsg; int idx = 0; if (argvars[0].v_type == VAR_LIST) { if ((l = argvars[0].vval.v_list) == NULL - || (!map && tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len))) { + || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE))) { return; } } else if (argvars[0].v_type == VAR_DICT) { if ((d = argvars[0].vval.v_dict) == NULL - || (!map && tv_check_lock(d->dv_lock, arg_errmsg, arg_errmsg_len))) { + || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) { return; } } else { @@ -8395,8 +8391,8 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) di = TV_DICT_HI2DI(hi); if (map - && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, arg_errmsg_len) - || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len))) { + && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE) + || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) { break; } @@ -8407,8 +8403,8 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) break; } if (!map && rem) { - if (var_check_fixed(di->di_flags, arg_errmsg, arg_errmsg_len) - || var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { + if (var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE) + || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) { break; } tv_dict_item_remove(d, di); @@ -8421,7 +8417,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map) for (li = l->lv_first; li != NULL; li = nli) { if (map - && tv_check_lock(li->li_tv.v_lock, arg_errmsg, arg_errmsg_len)) { + && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TV_TRANSLATE)) { break; } nli = li->li_next; @@ -11158,13 +11154,12 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) { list_T *l; bool error = false; - const char *const arg_errmsg = _("insert() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); if (argvars[0].v_type != VAR_LIST) { EMSG2(_(e_listarg), "insert()"); } else if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, N_("insert() argument"), + TV_TRANSLATE)) { long before = 0; if (argvars[2].v_type != VAR_UNKNOWN) { before = tv_get_number_chk(&argvars[2], &error); @@ -13205,21 +13200,20 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) long end; dict_T *d; dictitem_T *di; - const char *const arg_errmsg = _("remove() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); + const char *const arg_errmsg = N_("remove() argument"); if (argvars[0].v_type == VAR_DICT) { if (argvars[2].v_type != VAR_UNKNOWN) { EMSG2(_(e_toomanyarg), "remove()"); } else if ((d = argvars[0].vval.v_dict) != NULL - && !tv_check_lock(d->dv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) { const char *key = tv_get_string_chk(&argvars[1]); if (key != NULL) { di = tv_dict_find(d, key, -1); if (di == NULL) { EMSG2(_(e_dictkey), key); - } else if (!var_check_fixed(di->di_flags, arg_errmsg, arg_errmsg_len) - && !var_check_ro(di->di_flags, arg_errmsg, arg_errmsg_len)) { + } else if (!var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE) + && !var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) { *rettv = di->di_tv; di->di_tv = TV_INITIAL_VALUE; tv_dict_item_remove(d, di); @@ -13232,7 +13226,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else if (argvars[0].v_type != VAR_LIST) { EMSG2(_(e_listdictarg), "remove()"); } else if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) { bool error = false; idx = tv_get_number_chk(&argvars[1], &error); @@ -13503,14 +13497,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - const char *const arg_errmsg = _("reverse() argument"); - const size_t arg_errmsg_len = strlen(arg_errmsg); - list_T *l; if (argvars[0].v_type != VAR_LIST) { EMSG2(_(e_listarg), "reverse()"); } else if ((l = argvars[0].vval.v_list) != NULL - && !tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + && !tv_check_lock(l->lv_lock, N_("reverse() argument"), + TV_TRANSLATE)) { listitem_T *li = l->lv_last; l->lv_first = l->lv_last = NULL; l->lv_len = 0; @@ -15202,16 +15194,14 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) sortinfo = &info; const char *const arg_errmsg = (sort - ? _("sort() argument") - : _("uniq() argument")); - const size_t arg_errmsg_len = strlen(arg_errmsg); + ? N_("sort() argument") + : N_("uniq() argument")); if (argvars[0].v_type != VAR_LIST) { EMSG2(_(e_listarg), sort ? "sort()" : "uniq()"); } else { l = argvars[0].vval.v_list; - if (l == NULL - || tv_check_lock(l->lv_lock, arg_errmsg, arg_errmsg_len)) { + if (l == NULL || tv_check_lock(l->lv_lock, arg_errmsg, TV_TRANSLATE)) { goto theend; } rettv->vval.v_list = l; @@ -18876,24 +18866,37 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv, /// /// @param[in] flags di_flags attribute value. /// @param[in] name Variable name, for use in error message. -/// @param[in] name_len Variable name length. +/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate +/// variable name and compute the length. Use #TV_CSTRING +/// to compute the length with strlen() without +/// translating. /// /// @return True if variable is read-only: either always or in sandbox when /// sandbox is enabled, false otherwise. -bool var_check_ro(const int flags, const char *const name, - const size_t name_len) +bool var_check_ro(const int flags, const char *name, + size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { + const char *error_message = NULL; if (flags & DI_FLAGS_RO) { - emsgf(_(e_readonlyvar), (int)name_len, name); - return true; + error_message = N_(e_readonlyvar); + } else if ((flags & DI_FLAGS_RO_SBX) && sandbox) { + error_message = N_("E794: Cannot set variable in the sandbox: \"%.*s\""); } - if ((flags & DI_FLAGS_RO_SBX) && sandbox) { - emsgf(_("E794: Cannot set variable in the sandbox: \"%.*s\""), - (int)name_len, name); - return true; + + if (error_message == NULL) { + return false; } - return false; + if (name_len == TV_TRANSLATE) { + name = _(name); + name_len = strlen(name); + } else if (name_len == TV_CSTRING) { + name_len = strlen(name); + } + + emsgf(_(error_message), (int)name_len, name); + + return true; } /// Check whether variable is fixed (DI_FLAGS_FIX) @@ -18902,14 +18905,23 @@ bool var_check_ro(const int flags, const char *const name, /// /// @param[in] flags di_flags attribute value. /// @param[in] name Variable name, for use in error message. -/// @param[in] name_len Variable name length. +/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate +/// variable name and compute the length. Use #TV_CSTRING +/// to compute the length with strlen() without +/// translating. /// /// @return True if variable is fixed, false otherwise. -static bool var_check_fixed(const int flags, const char *const name, - const size_t name_len) +static bool var_check_fixed(const int flags, const char *name, + size_t name_len) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { if (flags & DI_FLAGS_FIX) { + if (name_len == TV_TRANSLATE) { + name = _(name); + name_len = strlen(name); + } else if (name_len == TV_CSTRING) { + name_len = strlen(name); + } emsgf(_("E795: Cannot delete variable %.*s"), (int)name_len, name); return true; } @@ -19716,12 +19728,12 @@ void ex_function(exarg_T *eap) } if (fudi.fd_di == NULL) { if (tv_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg, - STRLEN(eap->arg))) { + TV_CSTRING)) { // Can't add a function to a locked dictionary goto erret; } } else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg, - STRLEN(eap->arg))) { + TV_CSTRING)) { // Can't change an existing function if it is locked goto erret; } -- cgit From 276ee1f7fb989b931a9ddfabfd4aaf1782bcbb77 Mon Sep 17 00:00:00 2001 From: ZyX Date: Thu, 13 Apr 2017 23:42:51 +0300 Subject: eval: Add comment regarding why special values are needed --- src/nvim/eval.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e81378bcaa..281b80a915 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -18871,6 +18871,12 @@ static void set_var(const char *name, const size_t name_len, typval_T *const tv, /// to compute the length with strlen() without /// translating. /// +/// Both #TV_… values are used for optimization purposes: +/// variable name with its length is needed only in case +/// of error, when no error occurs computing them is +/// a waste of CPU resources. This especially applies to +/// gettext. +/// /// @return True if variable is read-only: either always or in sandbox when /// sandbox is enabled, false otherwise. bool var_check_ro(const int flags, const char *name, @@ -18910,6 +18916,12 @@ bool var_check_ro(const int flags, const char *name, /// to compute the length with strlen() without /// translating. /// +/// Both #TV_… values are used for optimization purposes: +/// variable name with its length is needed only in case +/// of error, when no error occurs computing them is +/// a waste of CPU resources. This especially applies to +/// gettext. +/// /// @return True if variable is fixed, false otherwise. static bool var_check_fixed(const int flags, const char *name, size_t name_len) -- cgit From ec0fabd4d5129c7293c8b8fcf0d0946ae5bd5fd4 Mon Sep 17 00:00:00 2001 From: Jurica Bradaric Date: Sat, 15 Apr 2017 18:45:47 +0200 Subject: eval.c: Code style fixes --- src/nvim/eval.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6a18baf2e2..33a553436f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16696,11 +16696,11 @@ static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_UNKNOWN) { if (argvars[0].v_type != VAR_NUMBER) { EMSG(_(e_number_exp)); - } else { - timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); - if (timer != NULL && !timer->stopped) { - add_timer_info(rettv, timer); - } + return; + } + timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); + if (timer != NULL && !timer->stopped) { + add_timer_info(rettv, timer); } } else { add_timer_info_all(rettv); @@ -16712,12 +16712,12 @@ static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr) { if (argvars[0].v_type != VAR_NUMBER) { EMSG(_(e_number_exp)); - } else { - int paused = (bool)tv_get_number(&argvars[1]); - timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); - if (timer != NULL) { - timer->paused = paused; - } + return; + } + int paused = (bool)tv_get_number(&argvars[1]); + timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0])); + if (timer != NULL) { + timer->paused = paused; } } @@ -16790,7 +16790,7 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr) { - timer_teardown(); + timer_stop_all(); } // invoked on the main loop @@ -16853,7 +16853,7 @@ static void timer_decref(timer_T *timer) } } -void timer_teardown(void) +static void timer_stop_all(void) { timer_T *timer; map_foreach_value(timers, timer, { @@ -16861,6 +16861,11 @@ void timer_teardown(void) }) } +void timer_teardown(void) +{ + timer_stop_all(); +} + /* * "tolower(string)" function */ -- cgit From 05c1829a8ccf2df07927bec502467faa443d90d8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:55:49 +0300 Subject: eval: Silence eap->skip false positives `lnum` starts at `eap->line2` in case of skipping, so cycle is always run at least once. --- src/nvim/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 772994de31..49e3590185 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2747,7 +2747,7 @@ void ex_call(exarg_T *eap) } else lnum = eap->line1; for (; lnum <= eap->line2; ++lnum) { - if (!eap->skip && eap->addr_count > 0) { + if (!eap->skip && eap->addr_count > 0) { // -V560 curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; @@ -2768,7 +2768,7 @@ void ex_call(exarg_T *eap) } tv_clear(&rettv); - if (doesrange || eap->skip) { + if (doesrange || eap->skip) { // -V560 break; } -- cgit From 97a1ccf8e7470d8c781c86253f8a7795fe50dc50 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 19:56:55 +0300 Subject: eval: Fix V547: `d == NULL` was already checked at line 2986 --- src/nvim/eval.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 49e3590185..4cc400799d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2999,8 +2999,7 @@ int do_unlet(const char *const name, const size_t name_len, const int forceit) return FAIL; } - if (d == NULL - || tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { + if (tv_check_lock(d->dv_lock, (const char *)name, STRLEN(name))) { return FAIL; } -- cgit From 7c9e3d6cadb441aaa40c8539de41e302228196a9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:02:06 +0300 Subject: eval: Refactor f_char2nr With has_mbyte equal to 1 and &encoding always UTF-8 second argument is no longer useful: utf_ptr2char is the same as mb_ptr2char. Also changes function behaviour a bit: now if second argument is not a number it immediately returns with error, without bothering to get a character. --- src/nvim/eval.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4cc400799d..bfc9f6eaa6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7305,18 +7305,14 @@ static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - if (has_mbyte) { - int utf8 = 0; - - if (argvars[1].v_type != VAR_UNKNOWN) { - utf8 = tv_get_number_chk(&argvars[1], NULL); + if (argvars[1].v_type != VAR_UNKNOWN) { + if (!tv_check_num(&argvars[1])) { + return; } - - rettv->vval.v_number = (utf8 ? *utf_ptr2char : *mb_ptr2char)( - (const char_u *)tv_get_string(&argvars[0])); - } else { - rettv->vval.v_number = (uint8_t)(tv_get_string(&argvars[0])[0]); } + + rettv->vval.v_number = utf_ptr2char( + (const char_u *)tv_get_string(&argvars[0])); } /* -- cgit From 31190879cc85cb3e8a056d544ea0c3ed63ce21df Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:07:54 +0300 Subject: eval: Fix useless NULL check partial_name() as it is written now really cannot return NULL --- src/nvim/eval.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index bfc9f6eaa6..f8afc03c1c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8977,13 +8977,10 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (strcmp(what, "func") == 0 || strcmp(what, "name") == 0) { rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING); const char *const n = (const char *)partial_name(pt); - if (n == NULL) { - rettv->vval.v_string = NULL; - } else { - rettv->vval.v_string = (char_u *)xstrdup(n); - if (rettv->v_type == VAR_FUNC) { - func_ref(rettv->vval.v_string); - } + assert(n != NULL); + rettv->vval.v_string = (char_u *)xstrdup(n); + if (rettv->v_type == VAR_FUNC) { + func_ref(rettv->vval.v_string); } } else if (strcmp(what, "dict") == 0) { rettv->v_type = VAR_DICT; -- cgit From 3c5f4b382f62d9f3cf5d54720592ff75d3a1f86d Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:08:56 +0300 Subject: eval: Silence octal constant warning --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index f8afc03c1c..a259bbf0eb 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12538,7 +12538,7 @@ static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int prot = 0755; + int prot = 0755; // -V536 rettv->vval.v_number = FAIL; if (check_restricted() || check_secure()) -- cgit From fbdef2e6f2d65d3cc6f3c8a8dcd8b3cddf41c474 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:16:32 +0300 Subject: eval: Refactor nr2char() Adds error messages, checks type and ignores the second argument. Currently utf_char2bytes is able to handle any 31-bit character, not limited by a unicode range. So checking for INT_MAX and not for something else: function yet uses `int`. --- src/nvim/eval.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a259bbf0eb..71af801986 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12763,25 +12763,32 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u buf[NUMBUFLEN]; - - if (has_mbyte) { - int utf8 = 0; - - if (argvars[1].v_type != VAR_UNKNOWN) { - utf8 = tv_get_number_chk(&argvars[1], NULL); - } - if (utf8) { - buf[(*utf_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; - } else { - buf[(*mb_char2bytes)((int)tv_get_number(&argvars[0]), buf)] = NUL; + if (argvars[1].v_type != VAR_UNKNOWN) { + if (!tv_check_num(&argvars[1])) { + return; } - } else { - buf[0] = (char_u)tv_get_number(&argvars[0]); - buf[1] = NUL; } + + bool error = false; + const varnumber_T num = tv_get_number_chk(&argvars[0], &error); + if (error) { + return; + } + if (num < 0) { + emsgf(_("E5070: Character number could not be less then zero")); + return; + } + if (num > INT_MAX) { + emsgf(_("E5071: Character number could not be greater then INT_MAX (%i)"), + INT_MAX); + return; + } + + char buf[MB_MAXBYTES]; + const int len = utf_char2bytes((int)num, (char_u *)buf); + rettv->v_type = VAR_STRING; - rettv->vval.v_string = vim_strsave(buf); + rettv->vval.v_string = xmemdupz(buf, (size_t)len); } /* -- cgit From 787d71a3afbe619a301ba7898e2c43fdcffdc8ec Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:19:10 +0300 Subject: eval: Fix condition in f_serverstop --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 71af801986..2a725c49f7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14306,7 +14306,7 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - if (argvars[0].v_type == VAR_UNKNOWN || argvars[0].v_type != VAR_STRING) { + if (argvars[0].v_type != VAR_STRING) { EMSG(_(e_invarg)); return; } -- cgit From 9b1dd084257fc2b5f50e29b283be698c13d4a509 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:20:38 +0300 Subject: eval: Remove unneeded varp check --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2a725c49f7..6e204be481 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14330,7 +14330,7 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) buf_T *const buf = get_buf_tv(&argvars[0], false); typval_T *varp = &argvars[2]; - if (buf != NULL && varname != NULL && varp != NULL) { + if (buf != NULL && varname != NULL) { if (*varname == '&') { long numval; bool error = false; -- cgit From 9dd1926df01a27c913dd19ef0a4f79d06842508a Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:20:53 +0300 Subject: eval: Remove unneeded varp check --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6e204be481..30b776c887 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -14874,7 +14874,7 @@ static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *const varname = tv_get_string_chk(&argvars[1]); typval_T *const varp = &argvars[2]; - if (varname != NULL && varp != NULL && tp != NULL) { + if (varname != NULL && tp != NULL) { tabpage_T *const save_curtab = curtab; goto_tabpage_tp(tp, false, false); -- cgit From 1bc080078793aafcecfae95620f6dac917c737dc Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:22:12 +0300 Subject: eval: Remove unneeded !eap->skip check Already checked in the outer if(). --- src/nvim/eval.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 30b776c887..67d5465896 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19462,8 +19462,9 @@ void ex_function(exarg_T *eap) * interrupt, or an exception. */ if (!aborting()) { - if (!eap->skip && fudi.fd_newkey != NULL) + if (fudi.fd_newkey != NULL) { EMSG2(_(e_dictkey), fudi.fd_newkey); + } xfree(fudi.fd_newkey); return; } else -- cgit From c5010c98ae8532f7f2778ce0e89a01d9e1ca68f9 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 20:22:58 +0300 Subject: eval: Fix position of buf declaration --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 67d5465896..cf55b42bdf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -21048,8 +21048,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, char *s = tofree; emsg_off--; if (s != NULL) { + char buf[MSG_BUF_LEN]; if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) { - char buf[MSG_BUF_LEN]; trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, sizeof(buf)); s = buf; -- cgit From 58300d70d26969546e204983f8b4e505771ec8dd Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 16 Apr 2017 22:20:19 +0300 Subject: *: Fix linter errors --- src/nvim/eval.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cf55b42bdf..7c5b23f567 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2742,11 +2742,12 @@ void ex_call(exarg_T *eap) * call, and the loop is broken. */ if (eap->skip) { - ++emsg_skip; - lnum = eap->line2; /* do it once, also with an invalid range */ - } else + emsg_skip++; + lnum = eap->line2; // Do it once, also with an invalid range. + } else { lnum = eap->line1; - for (; lnum <= eap->line2; ++lnum) { + } + for (; lnum <= eap->line2; lnum++) { if (!eap->skip && eap->addr_count > 0) { // -V560 curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; -- cgit From c2f3e361c52ec4e7149ea1d8c6a1202e0873da8e Mon Sep 17 00:00:00 2001 From: ZyX Date: Wed, 19 Apr 2017 19:11:50 +0300 Subject: *: Add comment to all C files --- src/nvim/eval.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index dcbd7ab152..16f054957f 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + /* * eval.c: Expression evaluation. */ -- cgit From c5d7eaf66468d5f71049a602e820c19d8ad8c772 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 15 Apr 2017 13:21:38 -0400 Subject: vim-patch:7.4.2152 Problem: No proper translation of messages with a count. Solution: Use ngettext(). (Sergey Alyoshin) https://github.com/vim/vim/commit/ee695f787ade7fd88fc5f5497553d95c0c3645b5 --- src/nvim/eval.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index dcbd7ab152..60c4e725b7 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8663,7 +8663,6 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *r; int len; char *txt; - long count; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -8691,8 +8690,8 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) s = skipwhite(s + 1); } } - count = (long)(foldend - foldstart + 1); - txt = _("+-%s%3ld lines: "); + unsigned long count = (unsigned long)(foldend - foldstart + 1); + txt = ngettext("+-%s%3ld line: ", "+-%s%3ld lines: ", count); r = xmalloc(STRLEN(txt) + STRLEN(dashes) // for %s + 20 // for %3ld @@ -8712,7 +8711,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char_u *text; - char_u buf[51]; + char_u buf[FOLD_TEXT_LEN]; foldinfo_T foldinfo; int fold_count; -- cgit From cb02137dfac7357650a2e9cc32acb66326e59058 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 15 Apr 2017 13:54:40 -0400 Subject: vim-patch:7.4.2209 Problem: Cannot map . (Stephen Riehm) Solution: Solve the memory access problem in another way. (Dominique Pelle) Allow for using in a string. https://github.com/vim/vim/commit/35a4cfa200917dd171b1fff3cd5b6cee9add673d --- src/nvim/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 60c4e725b7..9f56d8db0c 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -4764,7 +4764,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) // Special key, e.g.: "\" case '<': - extra = trans_special((const char_u **) &p, STRLEN(p), name, true); + extra = trans_special((const char_u **)&p, STRLEN(p), name, true, true); if (extra != 0) { name += extra; break; -- cgit From 5c9860a0a2bf27d409c986673f0a74542561c4c3 Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Wed, 1 Mar 2017 10:43:47 +0100 Subject: api: Do not truncate errors <1 MB. #6237 Closes #5984 --- src/nvim/eval.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7cef0d81ed..56dc35c31d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6524,6 +6524,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_array(args); api_free_object(result); + xfree(err.msg); } /* @@ -13794,6 +13795,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_object(result); + xfree(err.msg); } // "rpcstart()" function (DEPRECATED) @@ -16523,7 +16525,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) curbuf->b_p_swf = false; (void)setfname(curbuf, (char_u *)buf, NULL, true); // Save the job id and pid in b:terminal_job_{id,pid} - Error err; + Error err = ERROR_INIT; dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"), INTEGER_OBJ(rettv->vval.v_number), false, false, &err); dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"), @@ -16532,6 +16534,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) Terminal *term = terminal_open(topts); data->term = term; data->refcount++; + xfree(err.msg); return; } -- cgit From 2a49163103827465f25810f5f4e3d4305159f209 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 15:59:59 +0200 Subject: api_clear_error() --- src/nvim/eval.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 56dc35c31d..1e174712a3 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6524,7 +6524,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_array(args); api_free_object(result); - xfree(err.msg); + api_clear_error(&err); } /* @@ -13795,7 +13795,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) end: api_free_object(result); - xfree(err.msg); + api_clear_error(&err); } // "rpcstart()" function (DEPRECATED) @@ -16528,13 +16528,14 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) Error err = ERROR_INIT; dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"), INTEGER_OBJ(rettv->vval.v_number), false, false, &err); + api_clear_error(&err); dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"), INTEGER_OBJ(pid), false, false, &err); + api_clear_error(&err); Terminal *term = terminal_open(topts); data->term = term; data->refcount++; - xfree(err.msg); return; } -- cgit From 2ed91f222f1dddda10fbdc9cb80df2be7d4c2da3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 23 Apr 2017 19:58:13 +0200 Subject: api/internal: Remove `set` field from Error type. --- src/nvim/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1e174712a3..d7feed8bfd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6512,7 +6512,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr) Error err = ERROR_INIT; Object result = fn(INTERNAL_CALL, args, &err); - if (err.set) { + if (ERROR_SET(&err)) { nvim_err_writeln(cstr_as_string(err.msg)); goto end; } @@ -13784,7 +13784,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr) restore_funccal(save_funccalp); } - if (err.set) { + if (ERROR_SET(&err)) { nvim_err_writeln(cstr_as_string(err.msg)); goto end; } -- cgit From 8dc3eca49ba4203fb28ae4d70f3bfac35442199a Mon Sep 17 00:00:00 2001 From: Patrick Jackson Date: Mon, 24 Apr 2017 03:39:48 -0700 Subject: api/dispatch: Mark generated functions table readonly (#6576) --- src/nvim/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index d7feed8bfd..c02d172458 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -6009,7 +6009,7 @@ char_u *get_expr_name(expand_T *xp, int idx) /// @param[in] name Name of the function. /// /// Returns pointer to the function definition or NULL if not found. -static VimLFuncDef *find_internal_func(const char *const name) +static const VimLFuncDef *find_internal_func(const char *const name) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL { size_t len = strlen(name); @@ -6378,7 +6378,7 @@ call_func( } } else { // Find the function name in the table, call its implementation. - VimLFuncDef *const fdef = find_internal_func((const char *)fname); + const VimLFuncDef *const fdef = find_internal_func((const char *)fname); if (fdef != NULL) { if (argcount < fdef->min_argc) { error = ERROR_TOOFEW; -- cgit From 3ea10077534cb1dcb1597ffcf85e601fa0c0e27b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 13 Mar 2017 15:02:37 +0100 Subject: api: nvim_get_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asynchronous API functions are served immediately, which means pending input could change the state of Nvim shortly after an async API function result is returned. nvim_get_mode() is different: - If RPCs are known to be blocked, it responds immediately (without flushing the input/event queue) - else it is handled just-in-time before waiting for input, after pending input was processed. This makes the result more reliable (but not perfect). Internally this is handled as a special case, but _semantically_ nothing has changed: API users never know when input flushes, so this internal special-case doesn't violate that. As far as API users are concerned, nvim_get_mode() is just another asynchronous API function. In all cases nvim_get_mode() never blocks for more than the time it takes to flush the input/event queue (~µs). Note: This doesn't address #6166; nvim_get_mode() will provoke #6166 if e.g. `d` is operator-pending. Closes #6159 --- src/nvim/eval.c | 55 +++++++------------------------------------------------ 1 file changed, 7 insertions(+), 48 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c02d172458..b0f47d8e45 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -12575,59 +12575,18 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } -/* - * "mode()" function - */ +/// "mode()" function static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u buf[3]; + char *mode = get_mode(); - buf[1] = NUL; - buf[2] = NUL; - - if (VIsual_active) { - if (VIsual_select) - buf[0] = VIsual_mode + 's' - 'v'; - else - buf[0] = VIsual_mode; - } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE - || State == CONFIRM) { - buf[0] = 'r'; - if (State == ASKMORE) - buf[1] = 'm'; - else if (State == CONFIRM) - buf[1] = '?'; - } else if (State == EXTERNCMD) - buf[0] = '!'; - else if (State & INSERT) { - if (State & VREPLACE_FLAG) { - buf[0] = 'R'; - buf[1] = 'v'; - } else if (State & REPLACE_FLAG) - buf[0] = 'R'; - else - buf[0] = 'i'; - } else if (State & CMDLINE) { - buf[0] = 'c'; - if (exmode_active) - buf[1] = 'v'; - } else if (exmode_active) { - buf[0] = 'c'; - buf[1] = 'e'; - } else if (State & TERM_FOCUS) { - buf[0] = 't'; - } else { - buf[0] = 'n'; - if (finish_op) - buf[1] = 'o'; + // Clear out the minor mode when the argument is not a non-zero number or + // non-empty string. + if (!non_zero_arg(&argvars[0])) { + mode[1] = NUL; } - /* Clear out the minor mode when the argument is not a non-zero number or - * non-empty string. */ - if (!non_zero_arg(&argvars[0])) - buf[1] = NUL; - - rettv->vval.v_string = vim_strsave(buf); + rettv->vval.v_string = (char_u *)mode; rettv->v_type = VAR_STRING; } -- cgit From dbdc2d40bb7a950e294c6e50906f546707ccf390 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 28 Apr 2017 21:04:17 -0400 Subject: vim-patch:7.4.2231 Problem: ":oldfiles" output is a very long list. Solution: Add a pattern argument. (Coot, closes vim/vim#575) https://github.com/vim/vim/commit/e11d61a3b1cdedf3144de697a2b38af62c3a78d8 --- src/nvim/eval.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) (limited to 'src/nvim/eval.c') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b0f47d8e45..1bf85ccd8b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -21779,52 +21779,6 @@ void last_set_msg(scid_T scriptID) } } -/* - * List v:oldfiles in a nice way. - */ -void ex_oldfiles(exarg_T *eap) -{ - list_T *l = get_vim_var_list(VV_OLDFILES); - listitem_T *li; - long nr = 0; - - if (l == NULL) - msg((char_u *)_("No old files")); - else { - msg_start(); - msg_scroll = TRUE; - for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) { - msg_outnum(++nr); - MSG_PUTS(": "); - msg_outtrans((char_u *)tv_get_string(&li->li_tv)); - msg_clr_eos(); - msg_putchar('\n'); - ui_flush(); /* output one line at a time */ - os_breakcheck(); - } - /* Assume "got_int" was set to truncate the listing. */ - got_int = FALSE; - - // File selection prompt on ":browse oldfiles" - if (cmdmod.browse) { - quit_more = false; - nr = prompt_for_number(false); - msg_starthere(); - if (nr > 0 && nr <= l->lv_len) { - const char *const p = tv_list_find_str(l, nr - 1); - if (p == NULL) { - return; - } - char *const s = (char *)expand_env_save((char_u *)p); - eap->arg = (char_u *)s; - eap->cmdidx = CMD_edit; - do_exedit(eap, NULL); - xfree(s); - } - } - } -} - // reset v:option_new, v:option_old and v:option_type void reset_v_option_vars(void) { -- cgit