To: vim_dev@googlegroups.com Subject: Patch 8.2.2343 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2343 Problem: Vim9: return type of readfile() is any. Solution: Add readblob() so that readfile() can be expected to always return a list of strings. (closes #7671) Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c, src/filepath.c, src/proto/filepath.pro, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.2342/runtime/doc/eval.txt 2021-01-12 21:48:55.875132009 +0100 --- runtime/doc/eval.txt 2021-01-13 20:22:46.810640290 +0100 *************** *** 2739,2744 **** --- 2775,2781 ---- rand([{expr}]) Number get pseudo-random number range({expr} [, {max} [, {stride}]]) List items from {expr} to {max} + readblob({fname}) Blob read a |Blob| from {fname} readdir({dir} [, {expr} [, {dict}]]) List file names in {dir} selected by {expr} readdirex({dir} [, {expr} [, {dict}]]) *************** *** 8191,8196 **** --- 8266,8279 ---- :echo rand(seed) :echo rand(seed) % 16 " random number 0 - 15 < + + readblob({fname}) *readblob()* + Read file {fname} in binary mode and return a |Blob|. + When the file can't be opened an error message is given and + the result is an empty |Blob|. + Also see |readfile()| and |writefile()|. + + readdir({directory} [, {expr} [, {dict}]]) *readdir()* Return a list with file and directory names in {directory}. You can also use |glob()| if you don't need to do complicated *************** *** 8291,8297 **** If {expr} results in 1 then this entry will be added to the list. The entries "." and ".." are always excluded. ! Each time {expr} is evaluated |v:val| is set to a Dictionary of the entry. When {expr} is a function the entry is passed as the argument. For example, to get a list of files ending in ".txt": > --- 8374,8380 ---- If {expr} results in 1 then this entry will be added to the list. The entries "." and ".." are always excluded. ! Each time {expr} is evaluated |v:val| is set to a |Dictionary| of the entry. When {expr} is a function the entry is passed as the argument. For example, to get a list of files ending in ".txt": > *************** *** 8305,8310 **** --- 8388,8394 ---- Can also be used as a |method|: > GetDirName()->readdirex() < + *readfile()* readfile({fname} [, {type} [, {max}]]) Read file {fname} and return a |List|, each line of the file *************** *** 8316,8323 **** - When the last line ends in a NL an extra empty list item is added. - No CR characters are removed. - When {type} contains "B" a |Blob| is returned with the binary - data of the file unmodified. Otherwise: - CR characters that appear before a NL are removed. - Whether the last line ends in a NL or not does not matter. --- 8400,8405 ---- *************** *** 8335,8340 **** --- 8417,8425 ---- Note that without {max} the whole file is read into memory. Also note that there is no recognition of encoding. Read a file into a buffer if you need to. + Deprecated (use |readblob()| instead): When {type} contains + "B" a |Blob| is returned with the binary data of the file + unmodified. When the file can't be opened an error message is given and the result is an empty list. Also see |writefile()|. *** ../vim-8.2.2342/runtime/doc/usr_41.txt 2021-01-12 21:48:55.879131998 +0100 --- runtime/doc/usr_41.txt 2021-01-13 20:24:27.034354189 +0100 *************** *** 812,817 **** --- 820,826 ---- setenv() set an environment variable hostname() name of the system readfile() read a file into a List of lines + readblob() read a file into a Blob readdir() get a List of file names in a directory readdirex() get a List of file information in a directory writefile() write a List of lines or Blob into a file *** ../vim-8.2.2342/src/evalfunc.c 2021-01-13 20:08:34.733054890 +0100 --- src/evalfunc.c 2021-01-13 20:25:03.590249764 +0100 *************** *** 1344,1355 **** ret_number, f_rand}, {"range", 1, 3, FEARG_1, NULL, ret_list_number, f_range}, {"readdir", 1, 3, FEARG_1, NULL, ret_list_string, f_readdir}, {"readdirex", 1, 3, FEARG_1, NULL, ret_list_dict_any, f_readdirex}, {"readfile", 1, 3, FEARG_1, NULL, ! ret_any, f_readfile}, {"reduce", 2, 3, FEARG_1, NULL, ret_any, f_reduce}, {"reg_executing", 0, 0, 0, NULL, --- 1344,1357 ---- ret_number, f_rand}, {"range", 1, 3, FEARG_1, NULL, ret_list_number, f_range}, + {"readblob", 1, 1, FEARG_1, NULL, + ret_blob, f_readblob}, {"readdir", 1, 3, FEARG_1, NULL, ret_list_string, f_readdir}, {"readdirex", 1, 3, FEARG_1, NULL, ret_list_dict_any, f_readdirex}, {"readfile", 1, 3, FEARG_1, NULL, ! ret_list_string, f_readfile}, {"reduce", 2, 3, FEARG_1, NULL, ret_any, f_reduce}, {"reg_executing", 0, 0, 0, NULL, *** ../vim-8.2.2342/src/filepath.c 2020-12-13 12:25:32.080270459 +0100 --- src/filepath.c 2021-01-13 20:27:29.709832106 +0100 *************** *** 1640,1650 **** /* * "readfile()" function */ ! void ! f_readfile(typval_T *argvars, typval_T *rettv) { int binary = FALSE; ! int blob = FALSE; int failed = FALSE; char_u *fname; FILE *fd; --- 1640,1650 ---- /* * "readfile()" function */ ! static void ! read_file_or_blob(typval_T *argvars, typval_T *rettv, int always_blob) { int binary = FALSE; ! int blob = always_blob; int failed = FALSE; char_u *fname; FILE *fd; *************** *** 1796,1802 **** if (dest < buf) { ! adjust_prevlen = (int)(buf - dest); // must be 1 or 2 dest = buf; } if (readlen > p - buf + 1) --- 1796,1803 ---- if (dest < buf) { ! // must be 1 or 2 ! adjust_prevlen = (int)(buf - dest); dest = buf; } if (readlen > p - buf + 1) *************** *** 1867,1872 **** --- 1868,1891 ---- } /* + * "readblob()" function + */ + void + f_readblob(typval_T *argvars, typval_T *rettv) + { + read_file_or_blob(argvars, rettv, TRUE); + } + + /* + * "readfile()" function + */ + void + f_readfile(typval_T *argvars, typval_T *rettv) + { + read_file_or_blob(argvars, rettv, FALSE); + } + + /* * "resolve()" function */ void *** ../vim-8.2.2342/src/proto/filepath.pro 2020-09-25 22:42:43.852669232 +0200 --- src/proto/filepath.pro 2021-01-13 20:27:36.965811372 +0100 *************** *** 1,5 **** --- 1,6 ---- /* filepath.c */ int modify_fname(char_u *src, int tilde_file, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen); + void shorten_dir(char_u *str); void f_chdir(typval_T *argvars, typval_T *rettv); void f_delete(typval_T *argvars, typval_T *rettv); void f_executable(typval_T *argvars, typval_T *rettv); *************** *** 21,30 **** void f_globpath(typval_T *argvars, typval_T *rettv); void f_isdirectory(typval_T *argvars, typval_T *rettv); void f_mkdir(typval_T *argvars, typval_T *rettv); - void shorten_dir(char_u *str); void f_pathshorten(typval_T *argvars, typval_T *rettv); void f_readdir(typval_T *argvars, typval_T *rettv); void f_readdirex(typval_T *argvars, typval_T *rettv); void f_readfile(typval_T *argvars, typval_T *rettv); void f_resolve(typval_T *argvars, typval_T *rettv); void f_tempname(typval_T *argvars, typval_T *rettv); --- 22,31 ---- void f_globpath(typval_T *argvars, typval_T *rettv); void f_isdirectory(typval_T *argvars, typval_T *rettv); void f_mkdir(typval_T *argvars, typval_T *rettv); void f_pathshorten(typval_T *argvars, typval_T *rettv); void f_readdir(typval_T *argvars, typval_T *rettv); void f_readdirex(typval_T *argvars, typval_T *rettv); + void f_readblob(typval_T *argvars, typval_T *rettv); void f_readfile(typval_T *argvars, typval_T *rettv); void f_resolve(typval_T *argvars, typval_T *rettv); void f_tempname(typval_T *argvars, typval_T *rettv); *** ../vim-8.2.2342/src/testdir/test_vim9_builtin.vim 2021-01-12 22:08:50.087871728 +0100 --- src/testdir/test_vim9_builtin.vim 2021-01-13 20:31:13.345010822 +0100 *************** *** 623,628 **** --- 623,654 ---- eval expand('sautest')->readdirex((e) => e.name[0] !=# '.') enddef + def Test_readblob() + var blob = 0z12341234 + writefile(blob, 'Xreadblob') + var read: blob = readblob('Xreadblob') + assert_equal(blob, read) + + var lines =<< trim END + var read: list = readblob('Xreadblob') + END + CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list but got blob', 1) + delete('Xreadblob') + enddef + + def Test_readfile() + var text = ['aaa', 'bbb', 'ccc'] + writefile(text, 'Xreadfile') + var read: list = readfile('Xreadfile') + assert_equal(text, read) + + var lines =<< trim END + var read: dict = readfile('Xreadfile') + END + CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict but got list', 1) + delete('Xreadfile') + enddef + def Test_remove_return_type() var l = remove({one: [1, 2], two: [3, 4]}, 'one') var res = 0 *** ../vim-8.2.2342/src/version.c 2021-01-13 20:08:34.733054890 +0100 --- src/version.c 2021-01-13 20:36:01.235994028 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2343, /**/ -- The coffee just wasn't strong enough to defend itself -- Tom Waits /// 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 ///