diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-01-26 15:56:19 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-01-26 15:56:19 +0100 |
commit | 8a7d6542b33e5d2b352262305c3bfdb2d14e1cf8 (patch) | |
tree | 8e5f241129a1c690ea81d697a72fb4c1704c0cb6 /src | |
parent | 1d9215b9aaa120b9d78fee49488556f73007ce78 (diff) |
patch 8.2.0149: maintaining a Vim9 branch separately is more workv8.2.0149
Problem: Maintaining a Vim9 branch separately is more work.
Solution: Merge the Vim9 script changes.
Diffstat (limited to 'src')
56 files changed, 10861 insertions, 1332 deletions
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index f89d8dd366..639f3e5dcb 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -788,6 +788,9 @@ OBJ = \ $(OUTDIR)/usercmd.o \ $(OUTDIR)/userfunc.o \ $(OUTDIR)/version.o \ + $(OUTDIR)/vim9compile.o \ + $(OUTDIR)/vim9execute.o \ + $(OUTDIR)/vim9script.o \ $(OUTDIR)/viminfo.o \ $(OUTDIR)/winclip.o \ $(OUTDIR)/window.o @@ -1153,6 +1156,12 @@ $(OUTDIR)/netbeans.o: netbeans.c $(INCL) version.h $(OUTDIR)/version.o: version.c $(INCL) version.h +$(OUTDIR)/vim9compile.o: vim9compile.c $(INCL) version.h + +$(OUTDIR)/vim9execute.o: vim9execute.c $(INCL) version.h + +$(OUTDIR)/vim9script.o: vim9script.c $(INCL) version.h + $(OUTDIR)/viminfo.o: viminfo.c $(INCL) version.h $(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp gui_dwrite.h diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index 87b716952d..3e8eae168f 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -791,6 +791,9 @@ OBJ = \ $(OUTDIR)\undo.obj \ $(OUTDIR)\usercmd.obj \ $(OUTDIR)\userfunc.obj \ + $(OUTDIR)\vim9compile.obj \ + $(OUTDIR)\vim9execute.obj \ + $(OUTDIR)\vim9script.obj \ $(OUTDIR)\viminfo.obj \ $(OUTDIR)\winclip.obj \ $(OUTDIR)\window.obj \ @@ -1726,6 +1729,12 @@ $(OUTDIR)/userfunc.obj: $(OUTDIR) userfunc.c $(INCL) $(OUTDIR)/version.obj: $(OUTDIR) version.c $(INCL) version.h +$(OUTDIR)/vim9compile.obj: $(OUTDIR) vim9compile.c $(INCL) + +$(OUTDIR)/vim9execute.obj: $(OUTDIR) vim9execute.c $(INCL) + +$(OUTDIR)/vim9script.obj: $(OUTDIR) vim9script.c $(INCL) + $(OUTDIR)/viminfo.obj: $(OUTDIR) viminfo.c $(INCL) version.h $(OUTDIR)/window.obj: $(OUTDIR) window.c $(INCL) @@ -1907,6 +1916,9 @@ proto.h: \ proto/undo.pro \ proto/usercmd.pro \ proto/userfunc.pro \ + proto/vim9compile.pro \ + proto/vim9execute.pro \ + proto/vim9script.pro \ proto/viminfo.pro \ proto/window.pro \ $(SOUND_PRO) \ diff --git a/src/Makefile b/src/Makefile index 08a3277543..912098f8b3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1623,6 +1623,7 @@ BASIC_SRC = \ main.c \ map.c \ mark.c \ + mbyte.c \ memfile.c \ memline.c \ menu.c \ @@ -1631,7 +1632,6 @@ BASIC_SRC = \ misc2.c \ mouse.c \ move.c \ - mbyte.c \ normal.c \ ops.c \ option.c \ @@ -1645,8 +1645,8 @@ BASIC_SRC = \ quickfix.c \ regexp.c \ register.c \ - scriptfile.c \ screen.c \ + scriptfile.c \ search.c \ session.c \ sha256.c \ @@ -1666,6 +1666,9 @@ BASIC_SRC = \ usercmd.c \ userfunc.c \ version.c \ + vim9compile.c \ + vim9execute.c \ + vim9script.c \ viminfo.c \ window.c \ bufwrite.c \ @@ -1761,13 +1764,13 @@ OBJ_COMMON = \ objects/list.o \ objects/map.o \ objects/mark.o \ + objects/mbyte.o \ objects/memline.o \ objects/menu.o \ objects/misc1.o \ objects/misc2.o \ objects/mouse.o \ objects/move.o \ - objects/mbyte.o \ objects/normal.o \ objects/ops.o \ objects/option.o \ @@ -1781,8 +1784,8 @@ OBJ_COMMON = \ objects/quickfix.o \ objects/regexp.o \ objects/register.o \ - objects/scriptfile.o \ objects/screen.o \ + objects/scriptfile.o \ objects/search.o \ objects/session.o \ objects/sha256.o \ @@ -1802,6 +1805,9 @@ OBJ_COMMON = \ objects/usercmd.o \ objects/userfunc.o \ objects/version.o \ + objects/vim9compile.o \ + objects/vim9execute.o \ + objects/vim9script.o \ objects/viminfo.o \ objects/window.o \ objects/bufwrite.o \ @@ -1873,9 +1879,12 @@ PRO_AUTO = \ arabic.pro \ arglist.pro \ autocmd.pro \ + beval.pro \ blowfish.pro \ buffer.pro \ + bufwrite.pro \ change.pro \ + channel.pro \ charset.pro \ cindent.pro \ cmdexpand.pro \ @@ -1904,6 +1913,7 @@ PRO_AUTO = \ findfile.pro \ fold.pro \ getchar.pro \ + gui_beval.pro \ hardcopy.pro \ hashtab.pro \ highlight.pro \ @@ -1930,6 +1940,7 @@ PRO_AUTO = \ misc2.pro \ mouse.pro \ move.pro \ + netbeans.pro \ normal.pro \ ops.pro \ option.pro \ @@ -1943,8 +1954,8 @@ PRO_AUTO = \ quickfix.pro \ regexp.pro \ register.pro \ - scriptfile.pro \ screen.pro \ + scriptfile.pro \ search.pro \ session.pro \ sha256.pro \ @@ -1965,13 +1976,11 @@ PRO_AUTO = \ usercmd.pro \ userfunc.pro \ version.pro \ + vim9compile.pro \ + vim9execute.pro \ + vim9script.pro \ viminfo.pro \ window.pro \ - bufwrite.pro \ - beval.pro \ - gui_beval.pro \ - netbeans.pro \ - channel.pro \ $(ALL_GUI_PRO) \ $(TCL_PRO) @@ -3079,6 +3088,9 @@ objects/blowfish.o: blowfish.c objects/buffer.o: buffer.c $(CCC) -o $@ buffer.c +objects/bufwrite.o: bufwrite.c + $(CCC) -o $@ bufwrite.c + objects/change.o: change.c $(CCC) -o $@ change.c @@ -3433,15 +3445,21 @@ objects/usercmd.o: usercmd.c objects/userfunc.o: userfunc.c $(CCC) -o $@ userfunc.c +objects/vim9compile.o: vim9compile.c + $(CCC) -o $@ vim9compile.c + +objects/vim9execute.o: vim9execute.c + $(CCC) -o $@ vim9execute.c + +objects/vim9script.o: vim9script.c + $(CCC) -o $@ vim9script.c + objects/viminfo.o: viminfo.c $(CCC) -o $@ viminfo.c objects/window.o: window.c $(CCC) -o $@ window.c -objects/bufwrite.o: bufwrite.c - $(CCC) -o $@ bufwrite.c - objects/netbeans.o: netbeans.c $(CCC) -o $@ netbeans.c @@ -3787,6 +3805,10 @@ objects/mark.o: mark.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/mbyte.o: mbyte.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/memfile.o: memfile.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3819,10 +3841,6 @@ objects/move.o: move.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h -objects/mbyte.o: mbyte.c vim.h protodef.h auto/config.h feature.h os_unix.h \ - auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ - proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ - proto.h globals.h objects/normal.o: normal.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3875,14 +3893,14 @@ objects/register.o: register.c vim.h protodef.h auto/config.h feature.h os_unix. auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h -objects/scriptfile.o: scriptfile.c vim.h protodef.h auto/config.h feature.h \ - os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ - proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ - proto.h globals.h objects/screen.o: screen.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/scriptfile.o: scriptfile.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/search.o: search.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ @@ -3961,6 +3979,18 @@ objects/version.o: version.c vim.h protodef.h auto/config.h feature.h os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h version.h +objects/vim9compile.o: vim9compile.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h vim9.h +objects/vim9execute.o: vim9execute.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h vim9.h +objects/vim9script.o: vim9script.c vim.h protodef.h auto/config.h feature.h \ + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h vim9.h objects/viminfo.o: viminfo.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/blob.c b/src/blob.c index 2a7ec3a73a..f105170cfb 100644 --- a/src/blob.c +++ b/src/blob.c @@ -58,24 +58,24 @@ rettv_blob_set(typval_T *rettv, blob_T *b) } int -blob_copy(typval_T *from, typval_T *to) +blob_copy(blob_T *from, typval_T *to) { int ret = OK; to->v_type = VAR_BLOB; to->v_lock = 0; - if (from->vval.v_blob == NULL) + if (from == NULL) to->vval.v_blob = NULL; else if (rettv_blob_alloc(to) == FAIL) ret = FAIL; else { - int len = from->vval.v_blob->bv_ga.ga_len; + int len = from->bv_ga.ga_len; if (len > 0) { to->vval.v_blob->bv_ga.ga_data = - vim_memsave(from->vval.v_blob->bv_ga.ga_data, len); + vim_memsave(from->bv_ga.ga_data, len); if (to->vval.v_blob->bv_ga.ga_data == NULL) len = 0; } diff --git a/src/channel.c b/src/channel.c index 3aec7c8008..5f03068734 100644 --- a/src/channel.c +++ b/src/channel.c @@ -2263,7 +2263,10 @@ channel_get_json( while (item != NULL) { list_T *l = item->jq_value->vval.v_list; - typval_T *tv = &l->lv_first->li_tv; + typval_T *tv; + + range_list_materialize(l); + tv = &l->lv_first->li_tv; if ((without_callback || !item->jq_no_callback) && ((id > 0 && tv->v_type == VAR_NUMBER && tv->vval.v_number == id) diff --git a/src/dict.c b/src/dict.c index f3f3521672..2ff4ae37f7 100644 --- a/src/dict.c +++ b/src/dict.c @@ -826,7 +826,7 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal) if (**arg != ':') { - semsg(_("E720: Missing colon in Dictionary: %s"), *arg); + semsg(_(e_missing_dict_colon), *arg); clear_tv(&tvkey); goto failret; } @@ -853,7 +853,7 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal) item = dict_find(d, key, -1); if (item != NULL) { - semsg(_("E721: Duplicate key in Dictionary: \"%s\""), key); + semsg(_(e_duplicate_key), key); clear_tv(&tvkey); clear_tv(&tv); goto failret; @@ -873,7 +873,7 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal) break; if (**arg != ',') { - semsg(_("E722: Missing comma in Dictionary: %s"), *arg); + semsg(_(e_missing_dict_comma), *arg); goto failret; } *arg = skipwhite(*arg + 1); @@ -881,7 +881,7 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal) if (**arg != '}') { - semsg(_("E723: Missing end of Dictionary '}': %s"), *arg); + semsg(_(e_missing_dict_end), *arg); failret: if (d != NULL) dict_free(d); diff --git a/src/eval.c b/src/eval.c index fe6dee1f1b..72f932498b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -20,12 +20,10 @@ # include <float.h> #endif -static char *e_missbrac = N_("E111: Missing ']'"); static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); #ifdef FEAT_FLOAT static char *e_float_as_string = N_("E806: using Float as a String"); #endif -static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); #define NAMESPACE_CHAR (char_u *)"abglstvw" @@ -60,10 +58,7 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp); -static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); -static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); static int free_unref_items(int copyID); -static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); @@ -222,6 +217,11 @@ eval1_emsg(char_u **arg, typval_T *rettv, int evaluate) return ret; } +/* + * Evaluate an expression, which can be a function, partial or string. + * Pass arguments "argv[argc]". + * Return the result in "rettv" and OK or FAIL. + */ int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) { @@ -243,14 +243,22 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) { partial_T *partial = expr->vval.v_partial; - s = partial_name(partial); - if (s == NULL || *s == NUL) - return FAIL; - vim_memset(&funcexe, 0, sizeof(funcexe)); - funcexe.evaluate = TRUE; - funcexe.partial = partial; - if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) - return FAIL; + if (partial->pt_func != NULL && partial->pt_func->uf_dfunc_idx >= 0) + { + if (call_def_function(partial->pt_func, argc, argv, rettv) == FAIL) + return FAIL; + } + else + { + s = partial_name(partial); + if (s == NULL || *s == NUL) + return FAIL; + vim_memset(&funcexe, 0, sizeof(funcexe)); + funcexe.evaluate = TRUE; + funcexe.partial = partial; + if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) + return FAIL; + } } else { @@ -652,6 +660,7 @@ get_lval( // Find the end of the name. p = find_name_end(name, &expr_start, &expr_end, fne_flags); + lp->ll_name_end = p; if (expr_start != NULL) { // Don't expand the name when we already know there is an error. @@ -678,8 +687,20 @@ get_lval( lp->ll_name = lp->ll_exp_name; } else + { lp->ll_name = name; + if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && *p == ':') + { + scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid); + char_u *tp = skipwhite(p + 1); + + // parse the type after the name + lp->ll_type = parse_type(&tp, &si->sn_type_list); + lp->ll_name_end = tp; + } + } + // Without [idx] or .key we are done. if ((*p != '[' && *p != '.') || lp->ll_name == NULL) return p; @@ -1002,6 +1023,7 @@ get_lval( } clear_tv(&var1); + lp->ll_name_end = p; return p; } @@ -1027,7 +1049,7 @@ set_var_lval( char_u *endp, typval_T *rettv, int copy, - int is_const, // Disallow to modify existing variable for :const + int flags, // LET_IS_CONST and/or LET_NO_COMMAND char_u *op) { int cc; @@ -1093,7 +1115,7 @@ set_var_lval( { typval_T tv; - if (is_const) + if (flags & LET_IS_CONST) { emsg(_(e_cannot_mod)); *endp = cc; @@ -1114,7 +1136,7 @@ set_var_lval( } } else - set_var_const(lp->ll_name, rettv, copy, is_const); + set_var_const(lp->ll_name, lp->ll_type, rettv, copy, flags); *endp = cc; } else if (var_check_lock(lp->ll_newkey == NULL @@ -1126,7 +1148,7 @@ set_var_lval( listitem_T *ll_li = lp->ll_li; int ll_n1 = lp->ll_n1; - if (is_const) + if (flags & LET_IS_CONST) { emsg(_("E996: Cannot lock a range")); return; @@ -1185,7 +1207,7 @@ set_var_lval( /* * Assign to a List or Dictionary item. */ - if (is_const) + if (flags & LET_IS_CONST) { emsg(_("E996: Cannot lock a list or dict")); return; @@ -1250,6 +1272,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op) switch (tv1->v_type) { case VAR_UNKNOWN: + case VAR_VOID: case VAR_DICT: case VAR_FUNC: case VAR_PARTIAL: @@ -1392,14 +1415,14 @@ eval_for_line( if (fi == NULL) return NULL; - expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); + expr = skip_var_list(arg, TRUE, &fi->fi_varcount, &fi->fi_semicolon); if (expr == NULL) return fi; expr = skipwhite(expr); if (expr[0] != 'i' || expr[1] != 'n' || !VIM_ISWHITE(expr[2])) { - emsg(_("E690: Missing \"in\" after :for")); + emsg(_(e_missing_in)); return fi; } @@ -1420,6 +1443,9 @@ eval_for_line( } else { + // Need a real list here. + range_list_materialize(l); + // No need to increment the refcount, it's already set for // the list being used in "tv". fi->fi_list = l; @@ -1436,7 +1462,7 @@ eval_for_line( // Make a copy, so that the iteration still works when the // blob is changed. - blob_copy(&tv, &btv); + blob_copy(tv.vval.v_blob, &btv); fi->fi_blob = btv.vval.v_blob; } clear_tv(&tv); @@ -1478,7 +1504,7 @@ next_for_item(void *fi_void, char_u *arg) tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi); ++fi->fi_bi; return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, - fi->fi_varcount, FALSE, NULL) == OK; + fi->fi_varcount, 0, NULL) == OK; } item = fi->fi_lw.lw_item; @@ -1488,7 +1514,7 @@ next_for_item(void *fi_void, char_u *arg) { fi->fi_lw.lw_item = item->li_next; result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon, - fi->fi_varcount, FALSE, NULL) == OK); + fi->fi_varcount, 0, NULL) == OK); } return result; } @@ -1814,7 +1840,7 @@ eval1(char_u **arg, typval_T *rettv, int evaluate) */ if ((*arg)[0] != ':') { - emsg(_("E109: Missing ':' after '?'")); + emsg(_(e_missing_colon)); if (evaluate && result) clear_tv(rettv); return FAIL; @@ -2089,6 +2115,43 @@ eval4(char_u **arg, typval_T *rettv, int evaluate) return OK; } + void +eval_addblob(typval_T *tv1, typval_T *tv2) +{ + blob_T *b1 = tv1->vval.v_blob; + blob_T *b2 = tv2->vval.v_blob; + blob_T *b = blob_alloc(); + int i; + + if (b != NULL) + { + for (i = 0; i < blob_len(b1); i++) + ga_append(&b->bv_ga, blob_get(b1, i)); + for (i = 0; i < blob_len(b2); i++) + ga_append(&b->bv_ga, blob_get(b2, i)); + + clear_tv(tv1); + rettv_blob_set(tv1, b); + } +} + + int +eval_addlist(typval_T *tv1, typval_T *tv2) +{ + typval_T var3; + + // concatenate Lists + if (list_concat(tv1->vval.v_list, tv2->vval.v_list, &var3) == FAIL) + { + clear_tv(tv1); + clear_tv(tv2); + return FAIL; + } + clear_tv(tv1); + *tv1 = var3; + return OK; +} + /* * Handle fourth level expression: * + number addition @@ -2105,7 +2168,6 @@ eval4(char_u **arg, typval_T *rettv, int evaluate) eval5(char_u **arg, typval_T *rettv, int evaluate) { typval_T var2; - typval_T var3; int op; varnumber_T n1, n2; #ifdef FEAT_FLOAT @@ -2189,36 +2251,12 @@ eval5(char_u **arg, typval_T *rettv, int evaluate) } else if (op == '+' && rettv->v_type == VAR_BLOB && var2.v_type == VAR_BLOB) - { - blob_T *b1 = rettv->vval.v_blob; - blob_T *b2 = var2.vval.v_blob; - blob_T *b = blob_alloc(); - int i; - - if (b != NULL) - { - for (i = 0; i < blob_len(b1); i++) - ga_append(&b->bv_ga, blob_get(b1, i)); - for (i = 0; i < blob_len(b2); i++) - ga_append(&b->bv_ga, blob_get(b2, i)); - - clear_tv(rettv); - rettv_blob_set(rettv, b); - } - } + eval_addblob(rettv, &var2); else if (op == '+' && rettv->v_type == VAR_LIST && var2.v_type == VAR_LIST) { - // concatenate Lists - if (list_concat(rettv->vval.v_list, var2.vval.v_list, - &var3) == FAIL) - { - clear_tv(rettv); - clear_tv(&var2); + |