To: vim_dev@googlegroups.com Subject: Patch 7.4.242 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.242 Problem: getreg() does not distinguish between a NL used for a line break and a NL used for a NUL character. Solution: Add another argument to return a list. (ZyX) Files: runtime/doc/eval.txt, src/eval.c src/ops.c, src/proto/ops.pro, src/vim.h, src/Makefile, src/testdir/test_eval.in, src/testdir/test_eval.ok, src/testdir/Make_amiga.mak, src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, src/testdir/Make_os2.mak, src/testdir/Make_vms.mms *** ../vim-7.4.241/runtime/doc/eval.txt 2014-04-02 19:00:53.035644100 +0200 --- runtime/doc/eval.txt 2014-04-02 19:15:31.847632011 +0200 *************** *** 1818,1824 **** getpid() Number process ID of Vim getpos( {expr}) List position of cursor, mark, etc. getqflist() List list of quickfix items ! getreg( [{regname} [, 1]]) String contents of register getregtype( [{regname}]) String type of register gettabvar( {nr}, {varname} [, {def}]) any variable {varname} in tab {nr} or {def} --- 1819,1826 ---- getpid() Number process ID of Vim getpos( {expr}) List position of cursor, mark, etc. getqflist() List list of quickfix items ! getreg( [{regname} [, 1 [, {list}]]]) ! String or List contents of register getregtype( [{regname}]) String type of register gettabvar( {nr}, {varname} [, {def}]) any variable {varname} in tab {nr} or {def} *************** *** 3466,3472 **** :endfor ! getreg([{regname} [, 1]]) *getreg()* The result is a String, which is the contents of register {regname}. Example: > :let cliptext = getreg('*') --- 3468,3474 ---- :endfor ! getreg([{regname} [, 1 [, {list}]]]) *getreg()* The result is a String, which is the contents of register {regname}. Example: > :let cliptext = getreg('*') *************** *** 3475,3480 **** --- 3477,3487 ---- getreg('=', 1) returns the expression itself, so that it can be restored with |setreg()|. For other registers the extra argument is ignored, thus you can always give it. + If {list} is present and non-zero result type is changed to + |List|. Each list item is one text line. Use it if you care + about zero bytes possibly present inside register: without + third argument both NLs and zero bytes are represented as NLs + (see |NL-used-for-Nul|). If {regname} is not specified, |v:register| is used. *** ../vim-7.4.241/src/eval.c 2014-04-02 19:00:53.043644100 +0200 --- src/eval.c 2014-04-02 19:35:54.919615187 +0200 *************** *** 2458,2464 **** p = get_tv_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { ! s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); if (s != NULL) { p = ptofree = concat_str(s, p); --- 2458,2464 ---- p = get_tv_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { ! s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); if (s != NULL) { p = ptofree = concat_str(s, p); *************** *** 5121,5127 **** if (evaluate) { rettv->v_type = VAR_STRING; ! rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); } if (**arg != NUL) ++*arg; --- 5121,5128 ---- if (evaluate) { rettv->v_type = VAR_STRING; ! rettv->vval.v_string = get_reg_contents(**arg, ! GREG_EXPR_SRC); } if (**arg != NUL) ++*arg; *************** *** 7970,7976 **** {"getpid", 0, 0, f_getpid}, {"getpos", 1, 1, f_getpos}, {"getqflist", 0, 0, f_getqflist}, ! {"getreg", 0, 2, f_getreg}, {"getregtype", 0, 1, f_getregtype}, {"gettabvar", 2, 3, f_gettabvar}, {"gettabwinvar", 3, 4, f_gettabwinvar}, --- 7971,7977 ---- {"getpid", 0, 0, f_getpid}, {"getpos", 1, 1, f_getpos}, {"getqflist", 0, 0, f_getqflist}, ! {"getreg", 0, 3, f_getreg}, {"getregtype", 0, 1, f_getregtype}, {"gettabvar", 2, 3, f_gettabvar}, {"gettabwinvar", 3, 4, f_gettabwinvar}, *************** *** 11799,11804 **** --- 11800,11806 ---- char_u *strregname; int regname; int arg2 = FALSE; + int return_list = FALSE; int error = FALSE; if (argvars[0].v_type != VAR_UNKNOWN) *************** *** 11806,11822 **** strregname = get_tv_string_chk(&argvars[0]); error = strregname == NULL; if (argvars[1].v_type != VAR_UNKNOWN) arg2 = get_tv_number_chk(&argvars[1], &error); } else strregname = vimvars[VV_REG].vv_str; regname = (strregname == NULL ? '"' : *strregname); if (regname == 0) regname = '"'; ! rettv->v_type = VAR_STRING; ! rettv->vval.v_string = error ? NULL : ! get_reg_contents(regname, TRUE, arg2); } /* --- 11808,11841 ---- strregname = get_tv_string_chk(&argvars[0]); error = strregname == NULL; if (argvars[1].v_type != VAR_UNKNOWN) + { arg2 = get_tv_number_chk(&argvars[1], &error); + if (!error && argvars[2].v_type != VAR_UNKNOWN) + return_list = get_tv_number_chk(&argvars[2], &error); + } } else strregname = vimvars[VV_REG].vv_str; + + if (error) + return; + regname = (strregname == NULL ? '"' : *strregname); if (regname == 0) regname = '"'; ! if (return_list) ! { ! rettv->v_type = VAR_LIST; ! rettv->vval.v_list = (list_T *)get_reg_contents(regname, ! (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST); ! } ! else ! { ! rettv->v_type = VAR_STRING; ! rettv->vval.v_string = get_reg_contents(regname, ! arg2 ? GREG_EXPR_SRC : 0); ! } } /* *************** *** 17891,17899 **** typval_T *rettv; { int error = FALSE; - char_u **match; - char_u **s; - listitem_T *li; int no; int retList = 0; --- 17910,17915 ---- *** ../vim-7.4.241/src/ops.c 2014-03-23 15:12:29.931264336 +0100 --- src/ops.c 2014-04-02 19:36:08.831614995 +0200 *************** *** 6166,6181 **** return MAUTO; } /* * Return the contents of a register as a single allocated string. * Used for "@r" in expressions and for getreg(). * Returns NULL for error. */ char_u * ! get_reg_contents(regname, allowexpr, expr_src) int regname; ! int allowexpr; /* allow "=" register */ ! int expr_src; /* get expression for "=" register */ { long i; char_u *retval; --- 6166,6214 ---- return MAUTO; } + static char_u *getreg_wrap_one_line __ARGS((char_u *s, int flags)); + + /* + * When "flags" has GREG_LIST return a list with text "s". + * Otherwise just return "s". + */ + static char_u * + getreg_wrap_one_line(s, flags) + char_u *s; + int flags; + { + if (flags & GREG_LIST) + { + list_T *list = list_alloc(); + + if (list != NULL) + { + if (list_append_string(list, NULL, -1) == FAIL) + { + list_free(list, TRUE); + return NULL; + } + list->lv_first->li_tv.vval.v_string = s; + } + return (char_u *)list; + } + return s; + } + /* * Return the contents of a register as a single allocated string. * Used for "@r" in expressions and for getreg(). * Returns NULL for error. + * Flags: + * GREG_NO_EXPR Do not allow expression register + * GREG_EXPR_SRC For the expression register: return expression itself, + * not the result of its evaluation. + * GREG_LIST Return a list of lines in place of a single string. */ char_u * ! get_reg_contents(regname, flags) int regname; ! int flags; { long i; char_u *retval; *************** *** 6185,6197 **** /* Don't allow using an expression register inside an expression */ if (regname == '=') { ! if (allowexpr) ! { ! if (expr_src) ! return get_expr_line_src(); ! return get_expr_line(); ! } ! return NULL; } if (regname == '@') /* "@@" is used for unnamed register */ --- 6218,6228 ---- /* Don't allow using an expression register inside an expression */ if (regname == '=') { ! if (flags & GREG_NO_EXPR) ! return NULL; ! if (flags & GREG_EXPR_SRC) ! return getreg_wrap_one_line(get_expr_line_src(), flags); ! return getreg_wrap_one_line(get_expr_line(), flags); } if (regname == '@') /* "@@" is used for unnamed register */ *************** *** 6209,6223 **** { if (retval == NULL) return NULL; ! if (!allocated) ! retval = vim_strsave(retval); ! return retval; } get_yank_register(regname, FALSE); if (y_current->y_array == NULL) return NULL; /* * Compute length of resulting string. */ --- 6240,6272 ---- { if (retval == NULL) return NULL; ! if (allocated) ! return getreg_wrap_one_line(retval, flags); ! return getreg_wrap_one_line(vim_strsave(retval), flags); } get_yank_register(regname, FALSE); if (y_current->y_array == NULL) return NULL; + if (flags & GREG_LIST) + { + list_T *list = list_alloc(); + int error = FALSE; + + if (list == NULL) + return NULL; + for (i = 0; i < y_current->y_size; ++i) + if (list_append_string(list, y_current->y_array[i], -1) == FAIL) + error = TRUE; + if (error) + { + list_free(list, TRUE); + return NULL; + } + return (char_u *)list; + } + /* * Compute length of resulting string. */ *** ../vim-7.4.241/src/proto/ops.pro 2013-08-10 13:37:22.000000000 +0200 --- src/proto/ops.pro 2014-04-02 19:17:22.407630490 +0200 *************** *** 53,59 **** int clip_convert_selection __ARGS((char_u **str, long_u *len, VimClipboard *cbd)); void dnd_yank_drag_data __ARGS((char_u *str, long len)); char_u get_reg_type __ARGS((int regname, long *reglen)); ! char_u *get_reg_contents __ARGS((int regname, int allowexpr, int expr_src)); void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_append)); void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len)); void clear_oparg __ARGS((oparg_T *oap)); --- 53,59 ---- int clip_convert_selection __ARGS((char_u **str, long_u *len, VimClipboard *cbd)); void dnd_yank_drag_data __ARGS((char_u *str, long len)); char_u get_reg_type __ARGS((int regname, long *reglen)); ! char_u *get_reg_contents __ARGS((int regname, int flags)); void write_reg_contents __ARGS((int name, char_u *str, int maxlen, int must_append)); void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len)); void clear_oparg __ARGS((oparg_T *oap)); *** ../vim-7.4.241/src/vim.h 2014-04-01 19:55:46.252787300 +0200 --- src/vim.h 2014-04-02 19:17:22.407630490 +0200 *************** *** 2259,2264 **** --- 2259,2269 ---- #define SREQ_WIN 1 /* Request window-local option */ #define SREQ_BUF 2 /* Request buffer-local option */ + /* Flags for get_reg_contents */ + #define GREG_NO_EXPR 1 /* Do not allow expression register */ + #define GREG_EXPR_SRC 2 /* Return expression itself for "=" register */ + #define GREG_LIST 4 /* Return list */ + /* Character used as separated in autoload function/variable names. */ #define AUTOLOAD_CHAR '#' *** ../vim-7.4.241/src/Makefile 2014-04-01 14:08:14.685074130 +0200 --- src/Makefile 2014-04-02 19:42:21.931609863 +0200 *************** *** 1880,1885 **** --- 1880,1886 ---- # Run individual test, assuming that Vim was already compiled. test1 test2 test3 test4 test5 test6 test7 test8 test9 \ + test_eval \ test_options \ test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \ test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \ *** ../vim-7.4.241/src/testdir/test_eval.in 2014-04-02 19:51:32.391602291 +0200 --- src/testdir/test_eval.in 2014-04-02 19:47:13.607605851 +0200 *************** *** 0 **** --- 1,21 ---- + Test for various eval features. + + STARTTEST + :so small.vim + :" + :" test getreg() + /^one + "ay3j:$put =string(getreg('a')) + :$put =string(getreg('a', 1, 1)) + :" + :/^result/,$w! test.out + :qa! + ENDTEST + + one + two + three + four + five + + result *** ../vim-7.4.241/src/testdir/test_eval.ok 2014-04-02 19:51:32.399602291 +0200 --- src/testdir/test_eval.ok 2014-04-02 19:48:51.595604503 +0200 *************** *** 0 **** --- 1,7 ---- + result + 'one + two + three + four + ' + ['one', 'two', 'three', 'four'] *** ../vim-7.4.241/src/testdir/Make_amiga.mak 2014-04-01 14:08:14.685074130 +0200 --- src/testdir/Make_amiga.mak 2014-04-02 19:41:24.331610655 +0200 *************** *** 36,41 **** --- 36,42 ---- test94.out test95.out test96.out test97.out test98.out \ test99.out test100.out test101.out test102.out test103.out \ test104.out test105.out test106.out \ + test_eval.out \ test_options.out .SUFFIXES: .in .out *************** *** 159,162 **** --- 160,164 ---- test104.out: test104.in test105.out: test105.in test106.out: test106.in + test_eval.out: test_eval.in test_options.out: test_options.in *** ../vim-7.4.241/src/testdir/Make_dos.mak 2014-04-01 14:08:14.685074130 +0200 --- src/testdir/Make_dos.mak 2014-04-02 19:41:34.419610516 +0200 *************** *** 35,40 **** --- 35,41 ---- test94.out test95.out test96.out test98.out test99.out \ test100.out test101.out test102.out test103.out test104.out \ test105.out test106.out \ + test_eval.out \ test_options.out SCRIPTS32 = test50.out test70.out *** ../vim-7.4.241/src/testdir/Make_ming.mak 2014-04-01 14:08:14.685074130 +0200 --- src/testdir/Make_ming.mak 2014-04-02 19:41:43.131610397 +0200 *************** *** 55,60 **** --- 55,61 ---- test94.out test95.out test96.out test98.out test99.out \ test100.out test101.out test102.out test103.out test104.out \ test105.out test106.out \ + test_eval.out \ test_options.out SCRIPTS32 = test50.out test70.out *** ../vim-7.4.241/src/testdir/Make_os2.mak 2014-04-01 14:08:14.685074130 +0200 --- src/testdir/Make_os2.mak 2014-04-02 19:41:50.659610293 +0200 *************** *** 37,42 **** --- 37,43 ---- test94.out test95.out test96.out test98.out test99.out \ test100.out test101.out test102.out test103.out test104.out \ test105.out test106.out \ + test_eval.out \ test_options.out .SUFFIXES: .in .out *** ../vim-7.4.241/src/testdir/Make_vms.mms 2014-04-01 14:08:14.689074130 +0200 --- src/testdir/Make_vms.mms 2014-04-02 19:41:58.971610179 +0200 *************** *** 96,101 **** --- 96,102 ---- test95.out test96.out test98.out test99.out \ test100.out test101.out test103.out test104.out \ test105.out test106.out \ + test_eval.out \ test_options.out # Known problems: *** ../vim-7.4.241/src/version.c 2014-04-02 19:00:53.047644099 +0200 --- src/version.c 2014-04-02 19:46:41.867606287 +0200 *************** *** 736,737 **** --- 736,739 ---- { /* Add new patch number below this line */ + /**/ + 242, /**/ -- Don't Panic! -- The Hitchhiker's Guide to the Galaxy /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///