diff options
-rw-r--r-- | runtime/doc/eval.txt | 9 | ||||
-rw-r--r-- | src/nvim/eval.c | 62 | ||||
-rw-r--r-- | src/nvim/eval/encode.c | 56 | ||||
-rw-r--r-- | src/nvim/eval/typval_encode.h | 2 | ||||
-rw-r--r-- | src/nvim/eval_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 |
6 files changed, 71 insertions, 62 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index fd1c1f2cf2..585b016c7d 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -154,9 +154,6 @@ passed to the function. Example: > This will invoke the function as if using: > call myDict.Callback('foo') -This is very useful when passing a function around, e.g. in the arguments of -|ch_open()|. - Note that binding a function to a Dictionary also happens when the function is a member of the Dictionary: > @@ -164,8 +161,8 @@ a member of the Dictionary: > call myDict.myFunction() Here MyFunction() will get myDict passed as "self". This happens when the -"myFunction" member is accessed. When making assigning "myFunction" to -otherDict and calling it, it will be bound to otherDict: > +"myFunction" member is accessed. When assigning "myFunction" to otherDict +and calling it, it will be bound to otherDict: > let otherDict.myFunction = myDict.myFunction call otherDict.myFunction() @@ -3588,7 +3585,7 @@ get({dict}, {key} [, {default}]) item is not available return {default}. Return zero when {default} is omitted. get({func}, {what}) - Get an item with from Funcref {func}. Possible values for + Get item {what} from Funcref {func}. Possible values for {what} are: 'name' The function name 'func' The function diff --git a/src/nvim/eval.c b/src/nvim/eval.c index afc2e36704..e764117f1a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2759,7 +2759,7 @@ void ex_call(exarg_T *eap) typval_T rettv; linenr_T lnum; int doesrange; - int failed = false; + bool failed = false; funcdict_T fudi; partial_T *partial = NULL; @@ -4915,9 +4915,7 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) static void partial_free(partial_T *pt) { - int i; - - for (i = 0; i < pt->pt_argc; i++) { + for (int i = 0; i < pt->pt_argc; i++) { clear_tv(&pt->pt_argv[i]); } xfree(pt->pt_argv); @@ -5170,15 +5168,14 @@ dict_equal ( static int tv_equal_recurse_limit; -static int func_equal( +static bool func_equal( typval_T *tv1, typval_T *tv2, - int ic // ignore case + bool ic // ignore case ) { char_u *s1, *s2; dict_T *d1, *d2; int a1, a2; - int i; // empty and NULL function name considered the same s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string @@ -5216,7 +5213,7 @@ static int func_equal( if (a1 != a2) { return false; } - for (i = 0; i < a1; i++) { + for (int i = 0; i < a1; i++) { if (!tv_equal(tv1->vval.v_partial->pt_argv + i, tv2->vval.v_partial->pt_argv + i, ic, true)) { return false; @@ -6147,7 +6144,6 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, switch (tv->v_type) { case VAR_DICT: { dict_T *dd = tv->vval.v_dict; - if (dd != NULL && dd->dv_copyID != copyID) { // Didn't see this dict yet. dd->dv_copyID = copyID; @@ -6201,7 +6197,6 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, case VAR_PARTIAL: { partial_T *pt = tv->vval.v_partial; - int i; // A partial does not have a copyID, because it cannot contain itself. if (pt != NULL) { @@ -6213,7 +6208,7 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack); } - for (i = 0; i < pt->pt_argc; i++) { + for (int i = 0; i < pt->pt_argc; i++) { abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID, ht_stack, list_stack); } @@ -6356,7 +6351,6 @@ static void dict_free_contents(dict_T *d) { dictitem_T *di; - /* Lock the hashtab, we don't want it to resize while freeing items. */ hash_lock(&d->dv_hashtab); assert(d->dv_hashtab.ht_locked > 0); @@ -6969,7 +6963,7 @@ static VimLFuncDef *find_internal_func(const char *const name) /// "partialp". static char_u *deref_func_name( char_u *name, int *lenp, - partial_T **partialp, int no_autoload + partial_T **partialp, bool no_autoload ) { dictitem_T *v; @@ -7102,17 +7096,16 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) { if (current_SID <= 0) { *error = ERROR_SCRIPT; } else { - vim_snprintf((char *)fname_buf + 3, ARRAY_SIZE(fname_buf) - 3, - "%" PRId64 "_", (int64_t)current_SID); + snprintf((char *)fname_buf + 3, FLEN_FIXED + 1, "%" PRId64 "_", + (int64_t)current_SID); i = (int)STRLEN(fname_buf); } } - if (i + STRLEN(name + llen) < FLEN_FIXED) { STRCPY(fname_buf + i, name + llen); fname = fname_buf; } else { - fname = xmalloc((unsigned)(i + STRLEN(name + llen) + 1)); + fname = xmalloc(i + STRLEN(name + llen) + 1); if (fname == NULL) { *error = ERROR_OTHER; } else { @@ -7142,14 +7135,14 @@ call_func( linenr_T firstline, // first line of range linenr_T lastline, // last line of range int *doesrange, // return: function handled range - int evaluate, + bool evaluate, partial_T *partial, // optional, can be NULL dict_T *selfdict_in // Dictionary for "self" ) { int ret = FAIL; int error = ERROR_NONE; - ufunc_T *fp; + ufunc_T *fp; char_u fname_buf[FLEN_FIXED + 1]; char_u *tofree = NULL; char_u *fname; @@ -7169,7 +7162,7 @@ call_func( fname = fname_trans_sid(name, fname_buf, &tofree, &error); - *doesrange = FALSE; + *doesrange = false; if (partial != NULL) { // When the function has a partial with a dict and there is a dict @@ -7180,12 +7173,10 @@ call_func( selfdict = partial->pt_dict; } if (error == ERROR_NONE && partial->pt_argc > 0) { - int i; - for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) { copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); } - for (i = 0; i < argcount_in; i++) { + for (int i = 0; i < argcount_in; i++) { argv[i + argv_clear] = argvars_in[i]; } argvars = argv; @@ -8133,7 +8124,7 @@ static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr) selfdict = argvars[2].vval.v_dict; } - (void)func_call(func, &argvars[1], partial, selfdict, rettv); + func_call(func, &argvars[1], partial, selfdict, rettv); } /* @@ -9611,7 +9602,6 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr) use_string = true; } - s = get_tv_string(&argvars[0]); if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))) { EMSG2(_(e_invarg2), s); } else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL @@ -9622,7 +9612,6 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr) int dict_idx = 0; int arg_idx = 0; list_T *list = NULL; - if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0) { char sid_buf[25]; int off = *s == 's' ? 2 : 5; @@ -9633,7 +9622,7 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr) // printable text. snprintf(sid_buf, sizeof(sid_buf), "<SNR>%" PRId64 "_", (int64_t)current_SID); - name = xmalloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); + name = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1); if (name != NULL) { STRCPY(name, sid_buf); STRCAT(name, s + off); @@ -15570,11 +15559,10 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) si2 = (sortItem_T *)s2; if (partial == NULL) { - func_name = sortinfo->item_compare_func; + func_name = sortinfo->item_compare_func; } else { - func_name = partial->pt_name; + func_name = partial->pt_name; } - // Copy the values. This is needed to be able to set v_lock to VAR_FIXED // in the copy without changing the original list items. copy_tv(&si1->item->li_tv, &argv[0]); @@ -18573,8 +18561,7 @@ handle_subscript ( pt->pt_auto = true; selfdict = NULL; if (rettv->v_type == VAR_FUNC) { - // Just a function: Take over the function name and use - // selfdict. + // Just a function: Take over the function name and use selfdict. pt->pt_name = rettv->vval.v_string; } else { partial_T *ret_pt = rettv->vval.v_partial; @@ -18692,6 +18679,8 @@ void free_tv(typval_T *varp) #define TYPVAL_ENCODE_CONV_PARTIAL(pt) \ do { \ + partial_unref(pt); \ + pt = NULL; \ tv->v_lock = VAR_UNLOCKED; \ } while (0) @@ -19020,11 +19009,10 @@ static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload) return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); } -/* - * Find variable "varname" in hashtab "ht" with name "htname". - * Returns NULL if not found. - */ -static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload) +/// Find variable "varname" in hashtab "ht" with name "htname". +/// Returns NULL if not found. +static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, + char_u *varname, bool no_autoload) { hashitem_T *hi; diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 65570a6f30..51393e5337 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -315,34 +315,58 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, ga_append(gap, ')'); \ } while (0) -#define TYPVAL_ENCODE_CONV_PARTIAL(partial) \ +#define TYPVAL_ENCODE_CONV_PARTIAL(pt) \ do { \ - partial_T *pt = tv->vval.v_partial; \ - garray_T ga; \ int i; \ - ga_init(&ga, 1, 100); \ - ga_concat(&ga, (char_u *)"function("); \ + ga_concat(gap, "function("); \ if (&pt->pt_name != NULL) { \ - TYPVAL_ENCODE_CONV_STRING((char *)pt->pt_name, sizeof(pt->pt_name)); \ + size_t len; \ + char_u *p; \ + len = 3; \ + len += STRLEN(pt->pt_name); \ + for (p = pt->pt_name; *p != NUL; mb_ptr_adv(p)) { \ + if (*p == '\'') { \ + len++; \ + } \ + } \ + char_u *r, *s; \ + s = r = xmalloc(len); \ + if (r != NULL) { \ + *r++ = '\''; \ + for (p = pt->pt_name; *p != NUL; ) { \ + if (*p == '\'') { \ + *r++ = '\''; \ + } \ + MB_COPY_CHAR(p, r); \ + } \ + *r++ = '\''; \ + *r++ = NUL; \ + } \ + ga_concat(gap, s); \ + xfree(s); \ } \ - if (pt != NULL && pt->pt_argc > 0) { \ - ga_concat(&ga, (char_u *)", ["); \ + if (pt->pt_argc > 0) { \ + ga_concat(gap, ", ["); \ for (i = 0; i < pt->pt_argc; i++) { \ if (i > 0) { \ - ga_concat(&ga, (char_u *)", "); \ + ga_concat(gap, ", "); \ } \ - ga_concat(&ga, encode_tv2string(&pt->pt_argv[i], NULL)); \ + char *tofree = encode_tv2string(&pt->pt_argv[i], NULL); \ + ga_concat(gap, tofree); \ + xfree(tofree); \ } \ - ga_concat(&ga, (char_u *)"]"); \ + ga_append(gap, ']'); \ } \ - if (pt != NULL && pt->pt_dict != NULL) { \ + if (pt->pt_dict != NULL) { \ typval_T dtv; \ - ga_concat(&ga, (char_u *)", "); \ + ga_concat(gap, ", "); \ dtv.v_type = VAR_DICT; \ dtv.vval.v_dict = pt->pt_dict; \ - ga_concat(&ga, encode_tv2string(&dtv, NULL)); \ + char *tofree = encode_tv2string(&dtv, NULL); \ + ga_concat(gap, tofree); \ + xfree(tofree); \ } \ - ga_concat(&ga, (char_u *)")"); \ + ga_append(gap, ')'); \ } while (0) #define TYPVAL_ENCODE_CONV_EMPTY_LIST() \ @@ -692,7 +716,7 @@ static inline int convert_to_json_string(garray_T *const gap, mpstack, objname) #undef TYPVAL_ENCODE_CONV_PARTIAL -#define TYPVAL_ENCODE_CONV_PARTIAL(partial) \ +#define TYPVAL_ENCODE_CONV_PARTIAL(pt) \ return conv_error(_("E474: Error while dumping %s, %s: " \ "attempt to dump partial"), \ mpstack, objname) diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h index ce3bb0ee08..b79158b30c 100644 --- a/src/nvim/eval/typval_encode.h +++ b/src/nvim/eval/typval_encode.h @@ -72,7 +72,7 @@ /// @def TYPVAL_ENCODE_CONV_PARTIAL /// @brief Macros used to convert a partial /// -/// @param partial Partial name. +/// @param pt Partial name. /// @def TYPVAL_ENCODE_CONV_EMPTY_LIST /// @brief Macros used to convert an empty list diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h index 74d0782356..f478d19ca1 100644 --- a/src/nvim/eval_defs.h +++ b/src/nvim/eval_defs.h @@ -37,12 +37,12 @@ typedef enum { VAR_NUMBER, ///< Number, .v_number is used. VAR_STRING, ///< String, .v_string is used. VAR_FUNC, ///< Function reference, .v_string is used as function name. - VAR_PARTIAL, ///< Partial, .v_partial is used. VAR_LIST, ///< List, .v_list is used. VAR_DICT, ///< Dictionary, .v_dict is used. VAR_FLOAT, ///< Floating-point value, .v_float is used. VAR_SPECIAL, ///< Special value (true, false, null), .v_special ///< is used. + VAR_PARTIAL, ///< Partial, .v_partial is used. } VarType; /// Structure that holds an internal variable value diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 85ec305778..f7edeed933 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1235,7 +1235,7 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */ EXTERN int ignored; EXTERN char *ignoredp; -EXTERN int in_free_unref_items INIT(= false); +EXTERN bool in_free_unref_items INIT(= false); // If a msgpack-rpc channel should be started over stdin/stdout EXTERN bool embedded_mode INIT(= false); |