Mercurial > vim
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 } |