diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-05-04 17:51:14 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-05-04 17:59:21 +0800 |
commit | 8752da89b83281426e81e5c4a392308848f4bfb6 (patch) | |
tree | b198a34d1a29f25bb8d2f207f857be06a7838d8d /src/nvim/eval/typval.c | |
parent | 3724e65c30f7d1ef803ac4e34eab7d4a9531b1a8 (diff) | |
download | rneovim-8752da89b83281426e81e5c4a392308848f4bfb6.tar.gz rneovim-8752da89b83281426e81e5c4a392308848f4bfb6.tar.bz2 rneovim-8752da89b83281426e81e5c4a392308848f4bfb6.zip |
vim-patch:8.2.2756: Vim9: blob index and slice not implemented yet
Problem: Vim9: blob index and slice not implemented yet.
Solution: Implement blob index and slice.
https://github.com/vim/vim/commit/cfc3023cb6ce5aaec13f49bc4b821feb05e3fb03
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/eval/typval.c')
-rw-r--r-- | src/nvim/eval/typval.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 794debf771..8b51500e18 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2776,6 +2776,60 @@ bool tv_blob_equal(const blob_T *const b1, const blob_T *const b2) return true; } +int tv_blob_slice_or_index(const blob_T *blob, int is_range, varnumber_T n1, varnumber_T n2, + bool exclusive, typval_T *rettv) +{ + int len = tv_blob_len(rettv->vval.v_blob); + if (is_range) { + // The resulting variable is a sub-blob. If the indexes + // are out of range the result is empty. + if (n1 < 0) { + n1 = len + n1; + if (n1 < 0) { + n1 = 0; + } + } + if (n2 < 0) { + n2 = len + n2; + } else if (n2 >= len) { + n2 = len - (exclusive ? 0 : 1); + } + if (exclusive) { + n2--; + } + if (n1 >= len || n2 < 0 || n1 > n2) { + tv_clear(rettv); + rettv->v_type = VAR_BLOB; + rettv->vval.v_blob = NULL; + } else { + blob_T *const new_blob = tv_blob_alloc(); + ga_grow(&new_blob->bv_ga, (int)(n2 - n1 + 1)); + new_blob->bv_ga.ga_len = (int)(n2 - n1 + 1); + for (int i = (int)n1; i <= (int)n2; i++) { + tv_blob_set(new_blob, i - (int)n1, tv_blob_get(rettv->vval.v_blob, i)); + } + tv_clear(rettv); + tv_blob_set_ret(rettv, new_blob); + } + } else { + // The resulting variable is a byte value. + // If the index is too big or negative that is an error. + if (n1 < 0) { + n1 = len + n1; + } + if (n1 < len && n1 >= 0) { + const int v = (int)tv_blob_get(rettv->vval.v_blob, (int)n1); + tv_clear(rettv); + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = v; + } else { + semsg(_(e_blobidx), (int64_t)n1); + return FAIL; + } + } + return OK; +} + /// Check if "n1" is a valid index for a blob with length "bloblen". int tv_blob_check_index(int bloblen, varnumber_T n1, bool quiet) { |