forked from aniani/vim
patch 8.2.2780: Vim9: for loop over blob doesn't work
Problem: Vim9: for loop over blob doesn't work. Solution: Make it work.
This commit is contained in:
@@ -283,23 +283,24 @@ func Test_blob_index_assign()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_blob_for_loop()
|
func Test_blob_for_loop()
|
||||||
let blob = 0z00010203
|
let lines =<< trim END
|
||||||
let i = 0
|
VAR blob = 0z00010203
|
||||||
|
VAR i = 0
|
||||||
for byte in blob
|
for byte in blob
|
||||||
call assert_equal(i, byte)
|
call assert_equal(i, byte)
|
||||||
let i += 1
|
LET i += 1
|
||||||
endfor
|
endfor
|
||||||
call assert_equal(4, i)
|
call assert_equal(4, i)
|
||||||
|
|
||||||
let blob = 0z00
|
LET blob = 0z00
|
||||||
call remove(blob, 0)
|
call remove(blob, 0)
|
||||||
call assert_equal(0, len(blob))
|
call assert_equal(0, len(blob))
|
||||||
for byte in blob
|
for byte in blob
|
||||||
call assert_error('loop over empty blob')
|
call assert_report('loop over empty blob')
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
let blob = 0z0001020304
|
LET blob = 0z0001020304
|
||||||
let i = 0
|
LET i = 0
|
||||||
for byte in blob
|
for byte in blob
|
||||||
call assert_equal(i, byte)
|
call assert_equal(i, byte)
|
||||||
if i == 1
|
if i == 1
|
||||||
@@ -307,9 +308,11 @@ func Test_blob_for_loop()
|
|||||||
elseif i == 3
|
elseif i == 3
|
||||||
call remove(blob, 3)
|
call remove(blob, 3)
|
||||||
endif
|
endif
|
||||||
let i += 1
|
LET i += 1
|
||||||
endfor
|
endfor
|
||||||
call assert_equal(5, i)
|
call assert_equal(5, i)
|
||||||
|
END
|
||||||
|
call CheckLegacyAndVim9Success(lines)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_blob_concatenate()
|
func Test_blob_concatenate()
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2780,
|
||||||
/**/
|
/**/
|
||||||
2779,
|
2779,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -7508,13 +7508,12 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
arg_end = arg;
|
arg_end = arg;
|
||||||
|
|
||||||
// If we know the type of "var" and it is a not a list or string we can
|
// If we know the type of "var" and it is a not a supported type we can
|
||||||
// give an error now.
|
// give an error now.
|
||||||
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||||
if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
|
if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
|
||||||
&& vartype->tt_type != VAR_ANY)
|
&& vartype->tt_type != VAR_BLOB && vartype->tt_type != VAR_ANY)
|
||||||
{
|
{
|
||||||
// TODO: support Blob
|
|
||||||
semsg(_(e_for_loop_on_str_not_supported),
|
semsg(_(e_for_loop_on_str_not_supported),
|
||||||
vartype_name(vartype->tt_type));
|
vartype_name(vartype->tt_type));
|
||||||
drop_scope(cctx);
|
drop_scope(cctx);
|
||||||
@@ -7523,6 +7522,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
|
|
||||||
if (vartype->tt_type == VAR_STRING)
|
if (vartype->tt_type == VAR_STRING)
|
||||||
item_type = &t_string;
|
item_type = &t_string;
|
||||||
|
else if (vartype->tt_type == VAR_BLOB)
|
||||||
|
item_type = &t_number;
|
||||||
else if (vartype->tt_type == VAR_LIST
|
else if (vartype->tt_type == VAR_LIST
|
||||||
&& vartype->tt_member->tt_type != VAR_ANY)
|
&& vartype->tt_member->tt_type != VAR_ANY)
|
||||||
{
|
{
|
||||||
@@ -7530,7 +7531,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
|||||||
item_type = vartype->tt_member;
|
item_type = vartype->tt_member;
|
||||||
else if (vartype->tt_member->tt_type == VAR_LIST
|
else if (vartype->tt_member->tt_type == VAR_LIST
|
||||||
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
|
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
|
||||||
// TODO: should get the type from
|
// TODO: should get the type for each lhs
|
||||||
item_type = vartype->tt_member->tt_member;
|
item_type = vartype->tt_member->tt_member;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2900,8 +2900,8 @@ call_def_function(
|
|||||||
{
|
{
|
||||||
char_u *str = ltv->vval.v_string;
|
char_u *str = ltv->vval.v_string;
|
||||||
|
|
||||||
// Push the next character from the string. The index
|
// The index is for the last byte of the previous
|
||||||
// is for the last byte of the previous character.
|
// character.
|
||||||
++idxtv->vval.v_number;
|
++idxtv->vval.v_number;
|
||||||
if (str == NULL || str[idxtv->vval.v_number] == NUL)
|
if (str == NULL || str[idxtv->vval.v_number] == NUL)
|
||||||
{
|
{
|
||||||
@@ -2913,6 +2913,7 @@ call_def_function(
|
|||||||
{
|
{
|
||||||
int clen = mb_ptr2len(str + idxtv->vval.v_number);
|
int clen = mb_ptr2len(str + idxtv->vval.v_number);
|
||||||
|
|
||||||
|
// Push the next character from the string.
|
||||||
tv = STACK_TV_BOT(0);
|
tv = STACK_TV_BOT(0);
|
||||||
tv->v_type = VAR_STRING;
|
tv->v_type = VAR_STRING;
|
||||||
tv->vval.v_string = vim_strnsave(
|
tv->vval.v_string = vim_strnsave(
|
||||||
@@ -2921,9 +2922,41 @@ call_def_function(
|
|||||||
idxtv->vval.v_number += clen - 1;
|
idxtv->vval.v_number += clen - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ltv->v_type == VAR_BLOB)
|
||||||
|
{
|
||||||
|
blob_T *blob = ltv->vval.v_blob;
|
||||||
|
|
||||||
|
// When we get here the first time make a copy of the
|
||||||
|
// blob, so that the iteration still works when it is
|
||||||
|
// changed.
|
||||||
|
if (idxtv->vval.v_number == -1 && blob != NULL)
|
||||||
|
{
|
||||||
|
blob_copy(blob, ltv);
|
||||||
|
blob_unref(blob);
|
||||||
|
blob = ltv->vval.v_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The index is for the previous byte.
|
||||||
|
++idxtv->vval.v_number;
|
||||||
|
if (blob == NULL
|
||||||
|
|| idxtv->vval.v_number >= blob_len(blob))
|
||||||
|
{
|
||||||
|
// past the end of the blob, jump to "endfor"
|
||||||
|
ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
|
||||||
|
may_restore_cmdmod(&funclocal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Push the next byte from the blob.
|
||||||
|
tv = STACK_TV_BOT(0);
|
||||||
|
tv->v_type = VAR_NUMBER;
|
||||||
|
tv->vval.v_number = blob_get(blob,
|
||||||
|
idxtv->vval.v_number);
|
||||||
|
++ectx.ec_stack.ga_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: support Blob
|
|
||||||
semsg(_(e_for_loop_on_str_not_supported),
|
semsg(_(e_for_loop_on_str_not_supported),
|
||||||
vartype_name(ltv->v_type));
|
vartype_name(ltv->v_type));
|
||||||
goto failed;
|
goto failed;
|
||||||
|
Reference in New Issue
Block a user