comparison src/vim9execute.c @ 24480:943e9b1d2d16 v8.2.2780

patch 8.2.2780: Vim9: for loop over blob doesn't work Commit: https://github.com/vim/vim/commit/d551d6c268e435e2fbba22775510fbd0a54477f6 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 18 13:15:58 2021 +0200 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.
author Bram Moolenaar <Bram@vim.org>
date Sun, 18 Apr 2021 13:30:03 +0200
parents 96905804bf5a
children 3d5a66e478f8
comparison
equal deleted inserted replaced
24479:22651692d78e 24480:943e9b1d2d16
2898 } 2898 }
2899 else if (ltv->v_type == VAR_STRING) 2899 else if (ltv->v_type == VAR_STRING)
2900 { 2900 {
2901 char_u *str = ltv->vval.v_string; 2901 char_u *str = ltv->vval.v_string;
2902 2902
2903 // Push the next character from the string. The index 2903 // The index is for the last byte of the previous
2904 // is for the last byte of the previous character. 2904 // character.
2905 ++idxtv->vval.v_number; 2905 ++idxtv->vval.v_number;
2906 if (str == NULL || str[idxtv->vval.v_number] == NUL) 2906 if (str == NULL || str[idxtv->vval.v_number] == NUL)
2907 { 2907 {
2908 // past the end of the string, jump to "endfor" 2908 // past the end of the string, jump to "endfor"
2909 ectx.ec_iidx = iptr->isn_arg.forloop.for_end; 2909 ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
2911 } 2911 }
2912 else 2912 else
2913 { 2913 {
2914 int clen = mb_ptr2len(str + idxtv->vval.v_number); 2914 int clen = mb_ptr2len(str + idxtv->vval.v_number);
2915 2915
2916 // Push the next character from the string.
2916 tv = STACK_TV_BOT(0); 2917 tv = STACK_TV_BOT(0);
2917 tv->v_type = VAR_STRING; 2918 tv->v_type = VAR_STRING;
2918 tv->vval.v_string = vim_strnsave( 2919 tv->vval.v_string = vim_strnsave(
2919 str + idxtv->vval.v_number, clen); 2920 str + idxtv->vval.v_number, clen);
2920 ++ectx.ec_stack.ga_len; 2921 ++ectx.ec_stack.ga_len;
2921 idxtv->vval.v_number += clen - 1; 2922 idxtv->vval.v_number += clen - 1;
2922 } 2923 }
2923 } 2924 }
2925 else if (ltv->v_type == VAR_BLOB)
2926 {
2927 blob_T *blob = ltv->vval.v_blob;
2928
2929 // When we get here the first time make a copy of the
2930 // blob, so that the iteration still works when it is
2931 // changed.
2932 if (idxtv->vval.v_number == -1 && blob != NULL)
2933 {
2934 blob_copy(blob, ltv);
2935 blob_unref(blob);
2936 blob = ltv->vval.v_blob;
2937 }
2938
2939 // The index is for the previous byte.
2940 ++idxtv->vval.v_number;
2941 if (blob == NULL
2942 || idxtv->vval.v_number >= blob_len(blob))
2943 {
2944 // past the end of the blob, jump to "endfor"
2945 ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
2946 may_restore_cmdmod(&funclocal);
2947 }
2948 else
2949 {
2950 // Push the next byte from the blob.
2951 tv = STACK_TV_BOT(0);
2952 tv->v_type = VAR_NUMBER;
2953 tv->vval.v_number = blob_get(blob,
2954 idxtv->vval.v_number);
2955 ++ectx.ec_stack.ga_len;
2956 }
2957 }
2924 else 2958 else
2925 { 2959 {
2926 // TODO: support Blob
2927 semsg(_(e_for_loop_on_str_not_supported), 2960 semsg(_(e_for_loop_on_str_not_supported),
2928 vartype_name(ltv->v_type)); 2961 vartype_name(ltv->v_type));
2929 goto failed; 2962 goto failed;
2930 } 2963 }
2931 } 2964 }