Patch 9.0.0430

5 views
Skip to first unread message

Bram Moolenaar

unread,
Sep 9, 2022, 1:47:33 PM9/9/22
to vim...@googlegroups.com

Patch 9.0.0430
Problem: Cannot use repeat() with a blob.
Solution: Implement blob repeat. (closes #11090)
Files: runtime/doc/builtin.txt, src/errors.h, src/evalfunc.c,
src/typval.c, src/proto/typval.pro, src/testdir/test_blob.vim,
src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_func.vim


*** ../vim-9.0.0429/runtime/doc/builtin.txt 2022-09-07 21:30:40.139379052 +0100
--- runtime/doc/builtin.txt 2022-09-09 18:21:48.346091765 +0100
***************
*** 471,477 ****
remove bytes {idx}-{end} from {blob}
remove({dict}, {key}) any remove entry {key} from {dict}
rename({from}, {to}) Number rename (move) file from {from} to {to}
! repeat({expr}, {count}) String repeat {expr} {count} times
resolve({filename}) String get filename a shortcut points to
reverse({list}) List reverse {list} in-place
round({expr}) Float round off {expr}
--- 471,478 ----
remove bytes {idx}-{end} from {blob}
remove({dict}, {key}) any remove entry {key} from {dict}
rename({from}, {to}) Number rename (move) file from {from} to {to}
! repeat({expr}, {count}) List/Blob/String
! repeat {expr} {count} times
resolve({filename}) String get filename a shortcut points to
reverse({list}) List reverse {list} in-place
round({expr}) Float round off {expr}
***************
*** 7284,7291 ****
result. Example: >
:let separator = repeat('-', 80)
< When {count} is zero or negative the result is empty.
! When {expr} is a |List| the result is {expr} concatenated
! {count} times. Example: >
:let longlist = repeat(['a', 'b'], 3)
< Results in ['a', 'b', 'a', 'b', 'a', 'b'].

--- 7295,7302 ----
result. Example: >
:let separator = repeat('-', 80)
< When {count} is zero or negative the result is empty.
! When {expr} is a |List| or a |Blob| the result is {expr}
! concatenated {count} times. Example: >
:let longlist = repeat(['a', 'b'], 3)
< Results in ['a', 'b', 'a', 'b', 'a', 'b'].

*** ../vim-9.0.0429/src/errors.h 2022-09-05 21:21:21.135941382 +0100
--- src/errors.h 2022-09-09 18:25:20.473676112 +0100
***************
*** 3329,3332 ****
--- 3329,3334 ----
#ifdef FEAT_EVAL
EXTERN char e_cannot_use_partial_with_dictionary_for_defer[]
INIT(= N_("E1300: Cannot use a partial with dictionary for :defer"));
+ EXTERN char e_string_number_list_or_blob_required_for_argument_nr[]
+ INIT(= N_("E1301: String, Number, List or Blob required for argument %d"));
#endif
*** ../vim-9.0.0429/src/evalfunc.c 2022-09-04 12:29:22.144893115 +0100
--- src/evalfunc.c 2022-09-09 18:29:07.821193375 +0100
***************
*** 872,877 ****
--- 872,878 ----
|| type->tt_type == VAR_UNKNOWN
|| type->tt_type == VAR_STRING
|| type->tt_type == VAR_NUMBER
+ || type->tt_type == VAR_BLOB
|| type->tt_type == VAR_LIST)
return OK;

***************
*** 4400,4405 ****
--- 4401,4410 ----
#endif
}

+ /*
+ * "function()" function
+ * "funcref()" function
+ */
static void
common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
{
***************
*** 8399,8416 ****
f_repeat(typval_T *argvars, typval_T *rettv)
{
char_u *p;
! int n;
int slen;
int len;
char_u *r;
int i;

if (in_vim9script()
! && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL
|| check_for_number_arg(argvars, 1) == FAIL))
return;

! n = (int)tv_get_number(&argvars[1]);
if (argvars[0].v_type == VAR_LIST)
{
if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
--- 8404,8422 ----
f_repeat(typval_T *argvars, typval_T *rettv)
{
char_u *p;
! varnumber_T n;
int slen;
int len;
char_u *r;
int i;

if (in_vim9script()
! && (check_for_string_or_number_or_list_or_blob_arg(argvars, 0)
! == FAIL
|| check_for_number_arg(argvars, 1) == FAIL))
return;

! n = tv_get_number(&argvars[1]);
if (argvars[0].v_type == VAR_LIST)
{
if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
***************
*** 8419,8424 ****
--- 8425,8459 ----
argvars[0].vval.v_list, NULL) == FAIL)
break;
}
+ else if (argvars[0].v_type == VAR_BLOB)
+ {
+ if (rettv_blob_alloc(rettv) == FAIL
+ || argvars[0].vval.v_blob == NULL
+ || n <= 0)
+ return;
+
+ slen = argvars[0].vval.v_blob->bv_ga.ga_len;
+ len = (int)slen * n;
+ if (len <= 0)
+ return;
+
+ if (ga_grow(&rettv->vval.v_blob->bv_ga, len) == FAIL)
+ return;
+
+ rettv->vval.v_blob->bv_ga.ga_len = len;
+
+ for (i = 0; i < slen; ++i)
+ if (blob_get(argvars[0].vval.v_blob, i) != 0)
+ break;
+
+ if (i == slen)
+ // No need to copy since all bytes are already zero
+ return;
+
+ for (i = 0; i < n; ++i)
+ blob_set_range(rettv->vval.v_blob,
+ (long)i * slen, ((long)i + 1) * slen - 1, argvars);
+ }
else
{
p = tv_get_string(&argvars[0]);
*** ../vim-9.0.0429/src/typval.c 2022-09-01 12:22:19.747659165 +0100
--- src/typval.c 2022-09-09 18:21:48.350091758 +0100
***************
*** 792,797 ****
--- 792,815 ----
}

/*
+ * Give an error and return FAIL unless "args[idx]" is a string or a number
+ * or a list or a blob.
+ */
+ int
+ check_for_string_or_number_or_list_or_blob_arg(typval_T *args, int idx)
+ {
+ if (args[idx].v_type != VAR_STRING
+ && args[idx].v_type != VAR_NUMBER
+ && args[idx].v_type != VAR_LIST
+ && args[idx].v_type != VAR_BLOB)
+ {
+ semsg(_(e_string_number_list_or_blob_required_for_argument_nr), idx + 1);
+ return FAIL;
+ }
+ return OK;
+ }
+
+ /*
* Give an error and return FAIL unless "args[idx]" is a string or a list
* or a dict.
*/
*** ../vim-9.0.0429/src/proto/typval.pro 2022-09-01 12:22:19.747659165 +0100
--- src/proto/typval.pro 2022-09-09 18:38:24.503922543 +0100
***************
*** 42,47 ****
--- 42,48 ----
int check_for_string_or_dict_arg(typval_T *args, int idx);
int check_for_string_or_number_or_list_arg(typval_T *args, int idx);
int check_for_opt_string_or_number_or_list_arg(typval_T *args, int idx);
+ int check_for_string_or_number_or_list_or_blob_arg(typval_T *args, int idx);
int check_for_string_or_list_or_dict_arg(typval_T *args, int idx);
int check_for_string_or_func_arg(typval_T *args, int idx);
int check_for_list_or_blob_arg(typval_T *args, int idx);
*** ../vim-9.0.0429/src/testdir/test_blob.vim 2022-08-14 12:07:06.918862666 +0100
--- src/testdir/test_blob.vim 2022-09-09 18:43:44.291164347 +0100
***************
*** 725,730 ****
--- 725,742 ----
call assert_equal(v, string(b))
endfunc

+ func Test_blob_repeat()
+ call assert_equal(0z, repeat(0z00, 0))
+ call assert_equal(0z00, repeat(0z00, 1))
+ call assert_equal(0z0000, repeat(0z00, 2))
+ call assert_equal(0z00000000, repeat(0z0000, 2))
+
+ call assert_equal(0z, repeat(0z12, 0))
+ call assert_equal(0z, repeat(0z1234, 0))
+ call assert_equal(0z1234, repeat(0z1234, 1))
+ call assert_equal(0z12341234, repeat(0z1234, 2))
+ endfunc
+
" Test for blob allocation failure
func Test_blob_alloc_failure()
" blob variable
*** ../vim-9.0.0429/src/testdir/test_vim9_builtin.vim 2022-09-02 15:15:11.067569180 +0100
--- src/testdir/test_vim9_builtin.vim 2022-09-09 18:25:49.801615672 +0100
***************
*** 3329,3340 ****
enddef

def Test_repeat()
! v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1224: String, Number or List required for argument 1'])
! v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1224: String, Number or List required for argument 1'])
var lines =<< trim END
assert_equal('aaa', repeat('a', 3))
assert_equal('111', repeat(1, 3))
assert_equal([1, 1, 1], repeat([1], 3))
var s = '-'
s ..= repeat(5, 3)
assert_equal('-555', s)
--- 3329,3342 ----
enddef

def Test_repeat()
! v9.CheckDefAndScriptFailure(['repeat(1.1, 2)'], ['E1013: Argument 1: type mismatch, expected string but got float', 'E1301: String, Number, List or Blob required for argument 1'])
! v9.CheckDefAndScriptFailure(['repeat({a: 10}, 2)'], ['E1013: Argument 1: type mismatch, expected string but got dict<', 'E1301: String, Number, List or Blob required for argument 1'])
var lines =<< trim END
assert_equal('aaa', repeat('a', 3))
assert_equal('111', repeat(1, 3))
assert_equal([1, 1, 1], repeat([1], 3))
+ assert_equal(0z000102000102000102, repeat(0z000102, 3))
+ assert_equal(0z000000, repeat(0z00, 3))
var s = '-'
s ..= repeat(5, 3)
assert_equal('-555', s)
*** ../vim-9.0.0429/src/testdir/test_vim9_func.vim 2022-09-03 21:35:50.188158217 +0100
--- src/testdir/test_vim9_func.vim 2022-09-09 18:21:48.350091758 +0100
***************
*** 2534,2539 ****
--- 2534,2545 ----
res->assert_equal(3)

res = 0
+ for n in repeat(0z01, 3)->blob2list()
+ res += n
+ endfor
+ res->assert_equal(3)
+
+ res = 0
for n in add([1, 2], 3)
res += n
endfor
*** ../vim-9.0.0429/src/version.c 2022-09-09 17:38:58.836061268 +0100
--- src/version.c 2022-09-09 18:24:46.401745513 +0100
***************
*** 705,706 ****
--- 705,708 ----
{ /* Add new patch number below this line */
+ /**/
+ 430,
/**/

--
Have you heard about the new Beowulf cluster? It's so fast, it executes
an infinite loop in 6 seconds.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages