]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.2343: Vim9: return type of readfile() is any v8.2.2343
authorBram Moolenaar <Bram@vim.org>
Wed, 13 Jan 2021 19:38:03 +0000 (20:38 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 13 Jan 2021 19:38:03 +0000 (20:38 +0100)
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)

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
src/version.c

index 76c55485327e29d361c8f2cd854b49c50770766c..01a1235653d5cb23f38810af0baf5854fc793cd0 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 8.2.  Last change: 2021 Jan 10
+*eval.txt*     For Vim version 8.2.  Last change: 2021 Jan 13
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2775,6 +2775,7 @@ pyxeval({expr})                   any     evaluate |python_x| expression
 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}]])
@@ -8265,6 +8266,14 @@ rand([{expr}])                                           *rand()* *random*
                        :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
@@ -8379,6 +8388,7 @@ readdirex({directory} [, {expr} [, {dict}]])                      *readdirex()*
                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
@@ -8390,8 +8400,6 @@ readfile({fname} [, {type} [, {max}]])
                - 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.
@@ -8409,6 +8417,9 @@ readfile({fname} [, {type} [, {max}]])
                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()|.
@@ -11295,9 +11306,11 @@ win_execute({id}, {command} [, {silent}])              *win_execute()*
                        call win_execute(winid, 'set syntax=python')
 <              Doing the same with `setwinvar()` would not trigger
                autocommands and not actually show syntax highlighting.
+
                                                        *E994*
                Not all commands are allowed in popup windows.
-               When window {id} does not exist then no error is given.
+               When window {id} does not exist then no error is given and
+               an empty string is returned.
 
                Can also be used as a |method|, the base is passed as the
                second argument: >
index 5f9c8e1bdcd334e5ca0398b3ff853bf02fd41226..bac064cf7d46f4559cafb5a7c86129e6d3dba660 100644 (file)
@@ -820,6 +820,7 @@ System functions and manipulation of files:
        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
index 59fa2b1cf63c242b04d016c852979b52b086c46c..a891378ee8670d626e942e7f6e469dd8e169e806 100644 (file)
@@ -1344,12 +1344,14 @@ static funcentry_T global_functions[] =
                        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_any,            f_readfile},
+                       ret_list_string,    f_readfile},
     {"reduce",         2, 3, FEARG_1,      NULL,
                        ret_any,            f_reduce},
     {"reg_executing",  0, 0, 0,            NULL,
index 0db0dcfb1fd101eb22c483674d61ba562fc9cf34..81fe74924b70fb4d497c18fdca83272e61b2e9f3 100644 (file)
@@ -1640,11 +1640,11 @@ f_readdirex(typval_T *argvars, typval_T *rettv)
 /*
  * "readfile()" function
  */
-    void
-f_readfile(typval_T *argvars, typval_T *rettv)
+    static void
+read_file_or_blob(typval_T *argvars, typval_T *rettv, int always_blob)
 {
     int                binary = FALSE;
-    int                blob = FALSE;
+    int                blob = always_blob;
     int                failed = FALSE;
     char_u     *fname;
     FILE       *fd;
@@ -1796,7 +1796,8 @@ f_readfile(typval_T *argvars, typval_T *rettv)
 
                        if (dest < buf)
                        {
-                           adjust_prevlen = (int)(buf - dest); // must be 1 or 2
+                           // must be 1 or 2
+                           adjust_prevlen = (int)(buf - dest);
                            dest = buf;
                        }
                        if (readlen > p - buf + 1)
@@ -1866,6 +1867,24 @@ f_readfile(typval_T *argvars, typval_T *rettv)
     fclose(fd);
 }
 
+/*
+ * "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
  */
index b502b8e49453f23207c98bdcb8c042a8cbe0b1c7..62612117db0948de7e4086b3eb718d2c2ad1a4cc 100644 (file)
@@ -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,10 +22,10 @@ void f_glob2regpat(typval_T *argvars, typval_T *rettv);
 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_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);
index 40cfdcbb14378c67f629cbbbe9394747ff053434..3d474f3ed8ec25a19a48f8c2a9532dbf842c17ce 100644 (file)
@@ -623,6 +623,32 @@ def Test_readdir()
    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<string> = readblob('Xreadblob')
+  END
+  CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected list<string> but got blob', 1)
+  delete('Xreadblob')
+enddef
+
+def Test_readfile()
+  var text = ['aaa', 'bbb', 'ccc']
+  writefile(text, 'Xreadfile')
+  var read: list<string> = readfile('Xreadfile')
+  assert_equal(text, read)
+
+  var lines =<< trim END
+      var read: dict<string> = readfile('Xreadfile')
+  END
+  CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected dict<string> but got list<string>', 1)
+  delete('Xreadfile')
+enddef
+
 def Test_remove_return_type()
   var l = remove({one: [1, 2], two: [3, 4]}, 'one')
   var res = 0
index aae7bf58da706f0255aa900069891544262a6c69..07df2f30b7307aecdddd16cc8c7d09f8b551507f 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2343,
 /**/
     2342,
 /**/