Patch 8.2.2780
Problem: Vim9: for loop over blob doesn't work.
Solution: Make it work.
Files: src/vim9compile.c, src/vim9execute.c, src/testdir/test_blob.vim
*** ../vim-8.2.2779/src/vim9compile.c 2021-04-17 20:44:52.438520729 +0200
--- src/vim9compile.c 2021-04-18 13:10:48.610166634 +0200
***************
*** 7508,7520 ****
}
arg_end = arg;
! // If we know the type of "var" and it is a not a list or string we can
// give an error now.
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
! && vartype->tt_type != VAR_ANY)
{
- // TODO: support Blob
semsg(_(e_for_loop_on_str_not_supported),
vartype_name(vartype->tt_type));
drop_scope(cctx);
--- 7508,7519 ----
}
arg_end = arg;
! // If we know the type of "var" and it is a not a supported type we can
// give an error now.
vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (vartype->tt_type != VAR_LIST && vartype->tt_type != VAR_STRING
! && vartype->tt_type != VAR_BLOB && vartype->tt_type != VAR_ANY)
{
semsg(_(e_for_loop_on_str_not_supported),
vartype_name(vartype->tt_type));
drop_scope(cctx);
***************
*** 7523,7528 ****
--- 7522,7529 ----
if (vartype->tt_type == VAR_STRING)
item_type = &t_string;
+ else if (vartype->tt_type == VAR_BLOB)
+ item_type = &t_number;
else if (vartype->tt_type == VAR_LIST
&& vartype->tt_member->tt_type != VAR_ANY)
{
***************
*** 7530,7536 ****
item_type = vartype->tt_member;
else if (vartype->tt_member->tt_type == VAR_LIST
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
! // TODO: should get the type from
item_type = vartype->tt_member->tt_member;
}
--- 7531,7537 ----
item_type = vartype->tt_member;
else if (vartype->tt_member->tt_type == VAR_LIST
&& vartype->tt_member->tt_member->tt_type != VAR_ANY)
! // TODO: should get the type for each lhs
item_type = vartype->tt_member->tt_member;
}
*** ../vim-8.2.2779/src/vim9execute.c 2021-04-17 20:44:52.442520718 +0200
--- src/vim9execute.c 2021-04-18 13:14:50.845114758 +0200
***************
*** 2900,2907 ****
{
char_u *str = ltv->vval.v_string;
! // Push the next character from the string. The index
! // is for the last byte of the previous character.
++idxtv->vval.v_number;
if (str == NULL || str[idxtv->vval.v_number] == NUL)
{
--- 2900,2907 ----
{
char_u *str = ltv->vval.v_string;
! // The index is for the last byte of the previous
! // character.
++idxtv->vval.v_number;
if (str == NULL || str[idxtv->vval.v_number] == NUL)
{
***************
*** 2913,2918 ****
--- 2913,2919 ----
{
int clen = mb_ptr2len(str + idxtv->vval.v_number);
+ // Push the next character from the string.
tv = STACK_TV_BOT(0);
tv->v_type = VAR_STRING;
tv->vval.v_string = vim_strnsave(
***************
*** 2921,2929 ****
idxtv->vval.v_number += clen - 1;
}
}
else
{
- // TODO: support Blob
semsg(_(e_for_loop_on_str_not_supported),
vartype_name(ltv->v_type));
goto failed;
--- 2922,2962 ----
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
{
semsg(_(e_for_loop_on_str_not_supported),
vartype_name(ltv->v_type));
goto failed;
*** ../vim-8.2.2779/src/testdir/test_blob.vim 2021-04-17 20:44:52.442520718
+0200
--- src/testdir/test_blob.vim 2021-04-18 13:01:39.892653660 +0200
***************
*** 283,315 ****
endfunc
func Test_blob_for_loop()
! let blob = 0z00010203
! let i = 0
! for byte in blob
! call assert_equal(i, byte)
! let i += 1
! endfor
! call assert_equal(4, i)
! let blob = 0z00
! call remove(blob, 0)
! call assert_equal(0, len(blob))
! for byte in blob
! call assert_error('loop over empty blob')
! endfor
!
! let blob = 0z0001020304
! let i = 0
! for byte in blob
! call assert_equal(i, byte)
! if i == 1
call remove(blob, 0)
! elseif i == 3
! call remove(blob, 3)
! endif
! let i += 1
! endfor
! call assert_equal(5, i)
endfunc
func Test_blob_concatenate()
--- 283,318 ----
endfunc
func Test_blob_for_loop()
! let lines =<< trim END
! VAR blob = 0z00010203
! VAR i = 0
! for byte in blob
! call assert_equal(i, byte)
! LET i += 1
! endfor
! call assert_equal(4, i)
! LET blob = 0z00
call remove(blob, 0)
! call assert_equal(0, len(blob))
! for byte in blob
! call assert_report('loop over empty blob')
! endfor
!
! LET blob = 0z0001020304
! LET i = 0
! for byte in blob
! call assert_equal(i, byte)
! if i == 1
! call remove(blob, 0)
! elseif i == 3
! call remove(blob, 3)
! endif
! LET i += 1
! endfor
! call assert_equal(5, i)
! END
! call CheckLegacyAndVim9Success(lines)
endfunc
func Test_blob_concatenate()
*** ../vim-8.2.2779/src/version.c 2021-04-17 21:22:46.351232494 +0200
--- src/version.c 2021-04-18 12:53:17.195236010 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2780,
/**/
--
hundred-and-one symptoms of being an internet addict:
117. You are more comfortable typing in html.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202104181116.13IBGqKl293369%40masaka.moolenaar.net.