diff --git a/src/channel.c b/src/channel.c index 74c71466ee..871e2ddb8f 100644 --- a/src/channel.c +++ b/src/channel.c @@ -465,8 +465,8 @@ channel_open(char *hostname, int port_in, int waittime, void (*close_cb)(void)) FD_ZERO(&wfds); FD_SET(sd, &rfds); FD_SET(sd, &wfds); - tv.tv_sec = waittime; - tv.tv_usec = 0; + tv.tv_sec = waittime / 1000; + tv.tv_usec = (waittime % 1000) * 1000; ret = select((int)sd+1, &rfds, &wfds, NULL, &tv); if (ret < 0) { diff --git a/src/eval.c b/src/eval.c index 80f3faf09e..5d85a15222 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op) case VAR_DICT: case VAR_FUNC: case VAR_SPECIAL: + case VAR_UNKNOWN: break; case VAR_LIST: @@ -3837,6 +3838,14 @@ item_lock(typval_T *tv, int deep, int lock) switch (tv->v_type) { + case VAR_UNKNOWN: + case VAR_NUMBER: + case VAR_STRING: + case VAR_FUNC: + case VAR_FLOAT: + case VAR_SPECIAL: + break; + case VAR_LIST: if ((l = tv->vval.v_list) != NULL) { @@ -5317,23 +5326,32 @@ eval_index( char_u *s; char_u *key = NULL; - if (rettv->v_type == VAR_FUNC) + switch (rettv->v_type) { - if (verbose) - EMSG(_("E695: Cannot index a Funcref")); - return FAIL; - } + case VAR_FUNC: + if (verbose) + EMSG(_("E695: Cannot index a Funcref")); + return FAIL; + case VAR_FLOAT: #ifdef FEAT_FLOAT - else if (rettv->v_type == VAR_FLOAT) - { - if (verbose) - EMSG(_(e_float_as_string)); - return FAIL; - } + if (verbose) + EMSG(_(e_float_as_string)); + return FAIL; #endif - else if (rettv->v_type == VAR_SPECIAL) - { - return FAIL; + case VAR_SPECIAL: + if (verbose) + EMSG(_("E909: Cannot index a special variable")); + return FAIL; + case VAR_UNKNOWN: + if (evaluate) + return FAIL; + /* FALLTHROUGH */ + + case VAR_STRING: + case VAR_NUMBER: + case VAR_LIST: + case VAR_DICT: + break; } init_tv(&var1); @@ -5428,6 +5446,12 @@ eval_index( switch (rettv->v_type) { + case VAR_SPECIAL: + case VAR_FUNC: + case VAR_FLOAT: + case VAR_UNKNOWN: + break; /* not evaluating, skipping over subscript */ + case VAR_NUMBER: case VAR_STRING: s = get_tv_string(rettv); @@ -6143,6 +6167,9 @@ tv_equal( switch (tv1->v_type) { + case VAR_UNKNOWN: + break; + case VAR_LIST: ++recursive_cnt; r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); @@ -6177,8 +6204,9 @@ tv_equal( return tv1->vval.v_number == tv2->vval.v_number; } - EMSG2(_(e_intern2), "tv_equal()"); - return TRUE; + /* VAR_UNKNOWN can be the result of a invalid expression, let's say it + * does not equal anything, not even itself. */ + return FALSE; } /* @@ -7047,59 +7075,56 @@ set_ref_in_item( list_T *ll; int abort = FALSE; - switch (tv->v_type) + if (tv->v_type == VAR_DICT) { - case VAR_DICT: - dd = tv->vval.v_dict; - if (dd != NULL && dd->dv_copyID != copyID) + dd = tv->vval.v_dict; + if (dd != NULL && dd->dv_copyID != copyID) + { + /* Didn't see this dict yet. */ + dd->dv_copyID = copyID; + if (ht_stack == NULL) { - /* Didn't see this dict yet. */ - dd->dv_copyID = copyID; - if (ht_stack == NULL) - { - abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); - } + abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); + } + else + { + ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T)); + if (newitem == NULL) + abort = TRUE; else { - ht_stack_T *newitem = (ht_stack_T*)malloc( - sizeof(ht_stack_T)); - if (newitem == NULL) - abort = TRUE; - else - { - newitem->ht = &dd->dv_hashtab; - newitem->prev = *ht_stack; - *ht_stack = newitem; - } + newitem->ht = &dd->dv_hashtab; + newitem->prev = *ht_stack; + *ht_stack = newitem; } } - break; - - case VAR_LIST: - ll = tv->vval.v_list; - if (ll != NULL && ll->lv_copyID != copyID) + } + } + else if (tv->v_type == VAR_LIST) + { + ll = tv->vval.v_list; + if (ll != NULL && ll->lv_copyID != copyID) + { + /* Didn't see this list yet. */ + ll->lv_copyID = copyID; + if (list_stack == NULL) { - /* Didn't see this list yet. */ - ll->lv_copyID = copyID; - if (list_stack == NULL) - { - abort = set_ref_in_list(ll, copyID, ht_stack); - } - else - { - list_stack_T *newitem = (list_stack_T*)malloc( + abort = set_ref_in_list(ll, copyID, ht_stack); + } + else + { + list_stack_T *newitem = (list_stack_T*)malloc( sizeof(list_stack_T)); - if (newitem == NULL) - abort = TRUE; - else - { - newitem->list = ll; - newitem->prev = *list_stack; - *list_stack = newitem; - } + if (newitem == NULL) + abort = TRUE; + else + { + newitem->list = ll; + newitem->prev = *list_stack; + *list_stack = newitem; } } - break; + } } return abort; } @@ -7763,6 +7788,7 @@ echo_string( case VAR_STRING: case VAR_NUMBER: + case VAR_UNKNOWN: *tofree = NULL; r = get_tv_string_buf(tv, numbuf); break; @@ -7779,10 +7805,6 @@ echo_string( *tofree = NULL; r = (char_u *)get_var_special_name(tv->vval.v_number); break; - - default: - EMSG2(_(e_intern2), "echo_string()"); - *tofree = NULL; } if (--recurse == 0) @@ -7822,9 +7844,8 @@ tv2string( case VAR_LIST: case VAR_DICT: case VAR_SPECIAL: + case VAR_UNKNOWN: break; - default: - EMSG2(_(e_intern2), "tv2string()"); } return echo_string(tv, tofree, numbuf, copyID); } @@ -9195,6 +9216,9 @@ assert_bool(typval_T *argvars, int isTrue) int error = FALSE; garray_T ga; + if (argvars[0].v_type == VAR_SPECIAL + && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) + return; if (argvars[0].v_type != VAR_NUMBER || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue || error) @@ -10528,9 +10552,10 @@ f_empty(typval_T *argvars, typval_T *rettv) n = argvars[0].vval.v_number != VVAL_TRUE; break; - default: - EMSG2(_(e_intern2), "f_empty()"); - n = 0; + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "f_empty(UNKNOWN)"); + n = TRUE; + break; } rettv->vval.v_number = n; @@ -14285,7 +14310,10 @@ f_len(typval_T *argvars, typval_T *rettv) case VAR_DICT: rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); break; - default: + case VAR_UNKNOWN: + case VAR_SPECIAL: + case VAR_FLOAT: + case VAR_FUNC: EMSG(_("E701: Invalid type for len()")); break; } @@ -19651,13 +19679,16 @@ f_type(typval_T *argvars, typval_T *rettv) case VAR_FLOAT: n = 5; break; #endif case VAR_SPECIAL: - if (argvars[0].vval.v_number == VVAL_FALSE - || argvars[0].vval.v_number == VVAL_TRUE) - n = 6; - else - n = 7; - break; - default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; + if (argvars[0].vval.v_number == VVAL_FALSE + || argvars[0].vval.v_number == VVAL_TRUE) + n = 6; + else + n = 7; + break; + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "f_type(UNKNOWN)"); + n = -1; + break; } rettv->vval.v_number = n; } @@ -21027,9 +21058,6 @@ free_tv(typval_T *varp) case VAR_UNKNOWN: case VAR_SPECIAL: break; - default: - EMSG2(_(e_intern2), "free_tv()"); - break; } vim_free(varp); } @@ -21071,8 +21099,6 @@ clear_tv(typval_T *varp) #endif case VAR_UNKNOWN: break; - default: - EMSG2(_(e_intern2), "clear_tv()"); } varp->v_lock = 0; } @@ -21135,8 +21161,8 @@ get_tv_number_chk(typval_T *varp, int *denote) case VAR_SPECIAL: return varp->vval.v_number == VVAL_TRUE ? 1 : 0; break; - default: - EMSG2(_(e_intern2), "get_tv_number()"); + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); break; } if (denote == NULL) /* useful for values that must be unsigned */ @@ -21157,7 +21183,6 @@ get_tv_float(typval_T *varp) #ifdef FEAT_FLOAT case VAR_FLOAT: return varp->vval.v_float; - break; #endif case VAR_FUNC: EMSG(_("E891: Using a Funcref as a Float")); @@ -21171,8 +21196,11 @@ get_tv_float(typval_T *varp) case VAR_DICT: EMSG(_("E894: Using a Dictionary as a Float")); break; - default: - EMSG2(_(e_intern2), "get_tv_float()"); + case VAR_SPECIAL: + EMSG(_("E907: Using a special value as a Float")); + break; + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); break; } return 0; @@ -21283,9 +21311,8 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf) case VAR_SPECIAL: STRCPY(buf, get_var_special_name(varp->vval.v_number)); return buf; - - default: - EMSG2(_(e_intern2), "get_tv_string_buf()"); + case VAR_UNKNOWN: + EMSG(_("E908: using an invalid value as a String")); break; } return NULL; @@ -21937,8 +21964,8 @@ copy_tv(typval_T *from, typval_T *to) ++to->vval.v_dict->dv_refcount; } break; - default: - EMSG2(_(e_intern2), "copy_tv()"); + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "copy_tv(UNKNOWN)"); break; } } @@ -22010,8 +22037,8 @@ item_copy( if (to->vval.v_dict == NULL) ret = FAIL; break; - default: - EMSG2(_(e_intern2), "item_copy()"); + case VAR_UNKNOWN: + EMSG2(_(e_intern2), "item_copy(UNKNOWN)"); ret = FAIL; } --recurse; @@ -24559,6 +24586,7 @@ read_viminfo_varlist(vir_T *virp, int writing) #endif case 'D': type = VAR_DICT; break; case 'L': type = VAR_LIST; break; + case 'X': type = VAR_SPECIAL; break; } tab = vim_strchr(tab, '\t'); @@ -24644,7 +24672,11 @@ write_viminfo_varlist(FILE *fp) #endif case VAR_DICT: s = "DIC"; break; case VAR_LIST: s = "LIS"; break; - default: continue; + case VAR_SPECIAL: s = "XPL"; break; + + case VAR_UNKNOWN: + case VAR_FUNC: + continue; } fprintf(fp, "!%s\t%s\t", this_var->di_key, s); p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 3efdf8bbbb..78d9f95613 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3268,6 +3268,7 @@ do_ecmd( int did_get_winopts = FALSE; #endif int readfile_flags = 0; + int did_inc_redrawing_disabled = FALSE; if (eap != NULL) command = eap->do_ecmd_cmd; @@ -3600,6 +3601,11 @@ do_ecmd( oldbuf = (flags & ECMD_OLDBUF); } + /* Don't redraw until the cursor is in the right line, otherwise + * autocommands may cause ml_get errors. */ + ++RedrawingDisabled; + did_inc_redrawing_disabled = TRUE; + #ifdef FEAT_AUTOCMD buf = curbuf; #endif @@ -3697,9 +3703,6 @@ do_ecmd( /* * If we get here we are sure to start editing */ - /* don't redraw until the cursor is in the right line */ - ++RedrawingDisabled; - /* Assume success now */ retval = OK; @@ -3899,6 +3902,7 @@ do_ecmd( #endif --RedrawingDisabled; + did_inc_redrawing_disabled = FALSE; if (!skip_redraw) { n = p_so; @@ -3933,6 +3937,8 @@ do_ecmd( #endif theend: + if (did_inc_redrawing_disabled) + --RedrawingDisabled; #ifdef FEAT_AUTOCMD if (did_set_swapcommand) set_vim_var_string(VV_SWAPCOMMAND, NULL, -1); diff --git a/src/if_py_both.h b/src/if_py_both.h index e8a5f5de9c..6ae3fe7f6b 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -5831,11 +5831,10 @@ convert_dl(PyObject *obj, typval_T *tv, } /* As we are not using copy_tv which increments reference count we must * do it ourself. */ - switch(tv->v_type) - { - case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break; - case VAR_LIST: ++tv->vval.v_list->lv_refcount; break; - } + if (tv->v_type == VAR_DICT) + ++tv->vval.v_dict->dv_refcount; + else if (tv->v_type == VAR_LIST) + ++tv->vval.v_list->lv_refcount; } else { diff --git a/src/if_python.c b/src/if_python.c index 508113c25d..acf97d6203 100644 --- a/src/if_python.c +++ b/src/if_python.c @@ -1560,6 +1560,11 @@ do_pyeval (char_u *str, typval_T *rettv) rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; break; + case VAR_NUMBER: + case VAR_STRING: + case VAR_FLOAT: + case VAR_SPECIAL: + break; } } diff --git a/src/if_python3.c b/src/if_python3.c index 569aca8570..9ba2f28a08 100644 --- a/src/if_python3.c +++ b/src/if_python3.c @@ -1649,6 +1649,11 @@ do_py3eval (char_u *str, typval_T *rettv) rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; break; + case VAR_NUMBER: + case VAR_STRING: + case VAR_FLOAT: + case VAR_SPECIAL: + break; } } diff --git a/src/json.c b/src/json.c index b6fce02dc7..6688437aee 100644 --- a/src/json.c +++ b/src/json.c @@ -16,7 +16,7 @@ #include "vim.h" #if defined(FEAT_EVAL) || defined(PROTO) -static int json_encode_item(garray_T *gap, typval_T *val, int copyID); +static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none); static int json_decode_item(js_read_T *reader, typval_T *res); /* @@ -29,7 +29,7 @@ json_encode(typval_T *val) /* Store bytes in the growarray. */ ga_init2(&ga, 1, 4000); - json_encode_item(&ga, val, get_copyID()); + json_encode_item(&ga, val, get_copyID(), TRUE); return ga.ga_data; } @@ -121,7 +121,7 @@ write_string(garray_T *gap, char_u *str) * Return FAIL or OK. */ static int -json_encode_item(garray_T *gap, typval_T *val, int copyID) +json_encode_item(garray_T *gap, typval_T *val, int copyID, int allow_none) { char_u numbuf[NUMBUFLEN]; char_u *res; @@ -135,7 +135,10 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID) { case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break; case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break; - case VVAL_NONE: break; + case VVAL_NONE: if (!allow_none) + /* TODO: better error */ + EMSG(_(e_invarg)); + break; case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break; } break; @@ -152,7 +155,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID) break; case VAR_FUNC: - /* no JSON equivalent */ + /* no JSON equivalent TODO: better error */ EMSG(_(e_invarg)); return FAIL; @@ -172,7 +175,8 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID) ga_append(gap, '['); for (li = l->lv_first; li != NULL && !got_int; ) { - if (json_encode_item(gap, &li->li_tv, copyID) == FAIL) + if (json_encode_item(gap, &li->li_tv, copyID, TRUE) + == FAIL) return FAIL; li = li->li_next; if (li != NULL) @@ -213,7 +217,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID) write_string(gap, hi->hi_key); ga_append(gap, ':'); if (json_encode_item(gap, &dict_lookup(hi)->di_tv, - copyID) == FAIL) + copyID, FALSE) == FAIL) return FAIL; } ga_append(gap, '}'); diff --git a/src/structs.h b/src/structs.h index ea99e1b202..eaa9b15f58 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1111,12 +1111,24 @@ typedef double float_T; typedef struct listvar_S list_T; typedef struct dictvar_S dict_T; +typedef enum +{ + VAR_UNKNOWN = 0, + VAR_NUMBER, /* "v_number" is used */ + VAR_STRING, /* "v_string" is used */ + VAR_FUNC, /* "v_string" is function name */ + VAR_LIST, /* "v_list" is used */ + VAR_DICT, /* "v_dict" is used */ + VAR_FLOAT, /* "v_float" is used */ + VAR_SPECIAL /* "v_number" is used */ +} vartype_T; + /* * Structure to hold an internal variable without a name. */ typedef struct { - char v_type; /* see below: VAR_NUMBER, VAR_STRING, etc. */ + vartype_T v_type; char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */ union { @@ -1130,16 +1142,6 @@ typedef struct } vval; } typval_T; -/* Values for "v_type". */ -#define VAR_UNKNOWN 0 -#define VAR_NUMBER 1 /* "v_number" is used */ -#define VAR_STRING 2 /* "v_string" is used */ -#define VAR_FUNC 3 /* "v_string" is function name */ -#define VAR_LIST 4 /* "v_list" is used */ -#define VAR_DICT 5 /* "v_dict" is used */ -#define VAR_FLOAT 6 /* "v_float" is used */ -#define VAR_SPECIAL 7 /* "v_number" is used */ - /* Values for "dv_scope". */ #define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */ #define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim index 22046e2b8d..6d2f80094a 100644 --- a/src/testdir/test_assert.vim +++ b/src/testdir/test_assert.vim @@ -2,11 +2,13 @@ func Test_assert_false() call assert_false(0) + call assert_false(v:false) endfunc func Test_assert_true() call assert_true(1) call assert_true(123) + call assert_true(v:true) endfunc func Test_assert_equal() diff --git a/src/testdir/test_json.vim b/src/testdir/test_json.vim index beabec883e..05c3949687 100644 --- a/src/testdir/test_json.vim +++ b/src/testdir/test_json.vim @@ -74,6 +74,7 @@ func Test_encode() call assert_fails('echo jsonencode(function("tr"))', 'E474:') call assert_fails('echo jsonencode([function("tr")])', 'E474:') + call assert_fails('echo jsonencode({"key":v:none})', 'E474:') endfunc func Test_decode() diff --git a/src/version.c b/src/version.c index 5ecf8509e6..5fca3b9a0a 100644 --- a/src/version.c +++ b/src/version.c @@ -757,6 +757,22 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1273, +/**/ + 1272, +/**/ + 1271, +/**/ + 1270, +/**/ + 1269, +/**/ + 1268, +/**/ + 1267, +/**/ + 1266, /**/ 1265, /**/