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 | |
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>
-rw-r--r-- | src/nvim/eval.c | 55 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 54 |
2 files changed, 60 insertions, 49 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 930cda4bd4..c0756c1ed6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3641,6 +3641,7 @@ static int eval_index_inner(typval_T *rettv, bool is_range, typval_T *var1, typv case VAR_PARTIAL: case VAR_UNKNOWN: break; // Not evaluating, skipping over subscript + case VAR_NUMBER: case VAR_STRING: { const char *const s = tv_get_string(rettv); @@ -3689,56 +3690,11 @@ static int eval_index_inner(typval_T *rettv, bool is_range, typval_T *var1, typv rettv->vval.v_string = v; break; } - case VAR_BLOB: { - 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 blob = tv_blob_alloc(); - ga_grow(&blob->bv_ga, (int)(n2 - n1 + 1)); - blob->bv_ga.ga_len = (int)(n2 - n1 + 1); - for (int i = (int)n1; i <= (int)n2; i++) { - tv_blob_set(blob, i - (int)n1, tv_blob_get(rettv->vval.v_blob, i)); - } - tv_clear(rettv); - tv_blob_set_ret(rettv, 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); - } - } + + case VAR_BLOB: + tv_blob_slice_or_index(rettv->vval.v_blob, is_range, n1, n2, exclusive, rettv); break; - } + case VAR_LIST: if (var1 == NULL) { n1 = 0; @@ -3751,6 +3707,7 @@ static int eval_index_inner(typval_T *rettv, bool is_range, typval_T *var1, typv return FAIL; } break; + case VAR_DICT: { if (key == NULL) { key = tv_get_string_chk(var1); 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) { |