diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-02-28 15:45:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-28 15:45:56 +0800 |
commit | 8acb3d742ce68adadf1def9e1d1bb5bfd671988c (patch) | |
tree | 76c130f2443612e2b5ebd0eafda8f74818205fc8 | |
parent | befb47f2e11a3f1035e6825b6f9fa7574c37ed0e (diff) | |
parent | 761a559dbfed99e588d7f306c89331907b2d5a92 (diff) | |
download | rneovim-8acb3d742ce68adadf1def9e1d1bb5bfd671988c.tar.gz rneovim-8acb3d742ce68adadf1def9e1d1bb5bfd671988c.tar.bz2 rneovim-8acb3d742ce68adadf1def9e1d1bb5bfd671988c.zip |
Merge pull request #22447 from zeertzjq/vim-8.2.2777
vim-patch:8.2.{1890,2777}
-rw-r--r-- | src/nvim/eval.c | 66 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 17 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_blob.vim | 214 |
4 files changed, 206 insertions, 97 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index cce7b9a13c..f8110aa545 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2556,6 +2556,39 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) return OK; } +/// Make a copy of blob "tv1" and append blob "tv2". +static void eval_addblob(typval_T *tv1, typval_T *tv2) +{ + const blob_T *const b1 = tv1->vval.v_blob; + const blob_T *const b2 = tv2->vval.v_blob; + blob_T *const b = tv_blob_alloc(); + + for (int i = 0; i < tv_blob_len(b1); i++) { + ga_append(&b->bv_ga, tv_blob_get(b1, i)); + } + for (int i = 0; i < tv_blob_len(b2); i++) { + ga_append(&b->bv_ga, tv_blob_get(b2, i)); + } + + tv_clear(tv1); + tv_blob_set_ret(tv1, b); +} + +/// Make a copy of list "tv1" and append list "tv2". +static int eval_addlist(typval_T *tv1, typval_T *tv2) +{ + typval_T var3; + // Concatenate Lists. + if (tv_list_concat(tv1->vval.v_list, tv2->vval.v_list, &var3) == FAIL) { + tv_clear(tv1); + tv_clear(tv2); + return FAIL; + } + tv_clear(tv1); + *tv1 = var3; + return OK; +} + /// Handle fourth level expression: /// + number addition, concatenation of list or blob /// - number subtraction @@ -2569,7 +2602,6 @@ static int eval4(char **arg, typval_T *rettv, int evaluate) static int eval5(char **arg, typval_T *rettv, int evaluate) { typval_T var2; - typval_T var3; varnumber_T n1, n2; float_T f1 = 0, f2 = 0; char *p; @@ -2587,7 +2619,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) } if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) - && (op == '.' || rettv->v_type != VAR_FLOAT)) { + && (op == '.' || rettv->v_type != VAR_FLOAT) && evaluate) { // For "list + ...", an illegal use of the first operand as // a number cannot be determined before evaluating the 2nd // operand: if this is also a list, all is ok. @@ -2595,7 +2627,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) // we know that the first operand needs to be a string or number // without evaluating the 2nd operand. So check before to avoid // side effects after an error. - if (evaluate && !tv_check_str(rettv)) { + if ((op == '.' && !tv_check_str(rettv)) || (op != '.' && !tv_check_num(rettv))) { tv_clear(rettv); return FAIL; } @@ -2628,32 +2660,12 @@ static int eval5(char **arg, typval_T *rettv, int evaluate) tv_clear(rettv); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; - } else if (op == '+' && rettv->v_type == VAR_BLOB - && var2.v_type == VAR_BLOB) { - const blob_T *const b1 = rettv->vval.v_blob; - const blob_T *const b2 = var2.vval.v_blob; - blob_T *const b = tv_blob_alloc(); - - for (int i = 0; i < tv_blob_len(b1); i++) { - ga_append(&b->bv_ga, tv_blob_get(b1, i)); - } - for (int i = 0; i < tv_blob_len(b2); i++) { - ga_append(&b->bv_ga, tv_blob_get(b2, i)); - } - - tv_clear(rettv); - tv_blob_set_ret(rettv, b); - } else if (op == '+' && rettv->v_type == VAR_LIST - && var2.v_type == VAR_LIST) { - // Concatenate Lists. - if (tv_list_concat(rettv->vval.v_list, var2.vval.v_list, &var3) - == FAIL) { - tv_clear(rettv); - tv_clear(&var2); + } else if (op == '+' && rettv->v_type == VAR_BLOB && var2.v_type == VAR_BLOB) { + eval_addblob(rettv, &var2); + } else if (op == '+' && rettv->v_type == VAR_LIST && var2.v_type == VAR_LIST) { + if (eval_addlist(rettv, &var2) == FAIL) { return FAIL; } - tv_clear(rettv); - *rettv = var3; } else { bool error = false; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 7e94e03823..d56efe30da 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2750,6 +2750,23 @@ int tv_blob_set_range(blob_T *dest, long n1, long n2, typval_T *src) return OK; } +/// Store one byte "byte" in blob "blob" at "idx". +/// Append one byte if needed. +void tv_blob_set_append(blob_T *blob, int idx, uint8_t byte) +{ + garray_T *gap = &blob->bv_ga; + + // Allow for appending a byte. Setting a byte beyond + // the end is an error otherwise. + if (idx <= gap->ga_len) { + if (idx == gap->ga_len) { + ga_grow(gap, 1); + gap->ga_len++; + } + tv_blob_set(blob, idx, byte); + } +} + /// "remove({blob})" function void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg) { diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 3f59cd3547..4a2654f03e 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -372,7 +372,7 @@ static inline uint8_t tv_blob_get(const blob_T *const b, int idx) return ((uint8_t *)b->bv_ga.ga_data)[idx]; } -static inline void tv_blob_set(blob_T *b, int idx, uint8_t c) +static inline void tv_blob_set(blob_T *blob, int idx, uint8_t c) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; /// Store the byte `c` at index `idx` in the blob. @@ -380,9 +380,9 @@ static inline void tv_blob_set(blob_T *b, int idx, uint8_t c) /// @param[in] b Blob to index. Cannot be NULL. /// @param[in] idx Index in a blob. Must be valid. /// @param[in] c Value to store. -static inline void tv_blob_set(blob_T *const b, int idx, uint8_t c) +static inline void tv_blob_set(blob_T *const blob, int idx, uint8_t c) { - ((uint8_t *)b->bv_ga.ga_data)[idx] = c; + ((uint8_t *)blob->bv_ga.ga_data)[idx] = c; } /// Initialize VimL object diff --git a/src/nvim/testdir/test_blob.vim b/src/nvim/testdir/test_blob.vim index 86e16b372b..e9d694e4c6 100644 --- a/src/nvim/testdir/test_blob.vim +++ b/src/nvim/testdir/test_blob.vim @@ -120,86 +120,166 @@ func Test_blob_assign() endfunc func Test_blob_get_range() + let lines =<< trim END + VAR b = 0z0011223344 + call assert_equal(0z2233, b[2 : 3]) + call assert_equal(0z223344, b[2 : -1]) + call assert_equal(0z00, b[0 : -5]) + call assert_equal(0z, b[0 : -11]) + call assert_equal(0z44, b[-1 :]) + call assert_equal(0z0011223344, b[:]) + call assert_equal(0z0011223344, b[: -1]) + call assert_equal(0z, b[5 : 6]) + call assert_equal(0z0011, b[-10 : 1]) + END + call CheckLegacyAndVim9Success(lines) + + " legacy script white space let b = 0z0011223344 call assert_equal(0z2233, b[2:3]) - call assert_equal(0z223344, b[2:-1]) - call assert_equal(0z00, b[0:-5]) - call assert_equal(0z, b[0:-11]) - call assert_equal(0z44, b[-1:]) - call assert_equal(0z0011223344, b[:]) - call assert_equal(0z0011223344, b[:-1]) - call assert_equal(0z, b[5:6]) - call assert_equal(0z0011, b[-10:1]) endfunc func Test_blob_get() - let b = 0z0011223344 - call assert_equal(0x00, get(b, 0)) - call assert_equal(0x22, get(b, 2, 999)) - call assert_equal(0x44, get(b, 4)) - call assert_equal(0x44, get(b, -1)) - call assert_equal(-1, get(b, 5)) - call assert_equal(999, get(b, 5, 999)) - call assert_equal(-1, get(b, -8)) - call assert_equal(999, get(b, -8, 999)) - call assert_equal(10, get(v:_null_blob, 2, 10)) - - call assert_equal(0x00, b[0]) - call assert_equal(0x22, b[2]) - call assert_equal(0x44, b[4]) - call assert_equal(0x44, b[-1]) - call assert_fails('echo b[5]', 'E979:') - call assert_fails('echo b[-8]', 'E979:') + let lines =<< trim END + VAR b = 0z0011223344 + call assert_equal(0x00, get(b, 0)) + call assert_equal(0x22, get(b, 2, 999)) + call assert_equal(0x44, get(b, 4)) + call assert_equal(0x44, get(b, -1)) + call assert_equal(-1, get(b, 5)) + call assert_equal(999, get(b, 5, 999)) + call assert_equal(-1, get(b, -8)) + call assert_equal(999, get(b, -8, 999)) + call assert_equal(10, get(v:_null_blob, 2, 10)) + + call assert_equal(0x00, b[0]) + call assert_equal(0x22, b[2]) + call assert_equal(0x44, b[4]) + call assert_equal(0x44, b[-1]) + END + call CheckLegacyAndVim9Success(lines) + + let lines =<< trim END + VAR b = 0z0011223344 + echo b[5] + END + call CheckLegacyAndVim9Failure(lines, 'E979:') + + let lines =<< trim END + VAR b = 0z0011223344 + echo b[-8] + END + call CheckLegacyAndVim9Failure(lines, 'E979:') endfunc func Test_blob_to_string() - let b = 0z00112233445566778899aabbccdd - call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b)) - call assert_equal(b, eval(string(b))) - call remove(b, 4, -1) - call assert_equal('0z00112233', string(b)) - call remove(b, 0, 3) - call assert_equal('0z', string(b)) + let lines =<< trim END + VAR b = 0z00112233445566778899aabbccdd + call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b)) + call assert_equal(b, eval(string(b))) + call remove(b, 4, -1) + call assert_equal('0z00112233', string(b)) + call remove(b, 0, 3) + call assert_equal('0z', string(b)) + call assert_equal('0z', string(v:_null_blob)) + END + call CheckLegacyAndVim9Success(lines) endfunc func Test_blob_compare() - let b1 = 0z0011 - let b2 = 0z1100 - let b3 = 0z001122 - call assert_true(b1 == b1) - call assert_false(b1 == b2) - call assert_false(b1 == b3) - call assert_true(b1 != b2) - call assert_true(b1 != b3) - call assert_true(b1 == 0z0011) - call assert_fails('echo b1 == 9', 'E977:') - call assert_fails('echo b1 != 9', 'E977:') - - call assert_false(b1 is b2) - let b2 = b1 - call assert_true(b1 == b2) - call assert_true(b1 is b2) - let b2 = copy(b1) - call assert_true(b1 == b2) - call assert_false(b1 is b2) - let b2 = b1[:] - call assert_true(b1 == b2) - call assert_false(b1 is b2) - - call assert_fails('let x = b1 > b2') - call assert_fails('let x = b1 < b2') - call assert_fails('let x = b1 - b2') - call assert_fails('let x = b1 / b2') - call assert_fails('let x = b1 * b2') + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR b3 = 0z001122 + call assert_true(b1 == b1) + call assert_false(b1 == b2) + call assert_false(b1 == b3) + call assert_true(b1 != b2) + call assert_true(b1 != b3) + call assert_true(b1 == 0z0011) + + call assert_false(b1 is b2) + LET b2 = b1 + call assert_true(b1 == b2) + call assert_true(b1 is b2) + LET b2 = copy(b1) + call assert_true(b1 == b2) + call assert_false(b1 is b2) + LET b2 = b1[:] + call assert_true(b1 == b2) + call assert_false(b1 is b2) + call assert_true(b1 isnot b2) + END + call CheckLegacyAndVim9Success(lines) + + let lines =<< trim END + VAR b1 = 0z0011 + echo b1 == 9 + END + call CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072']) + + let lines =<< trim END + VAR b1 = 0z0011 + echo b1 != 9 + END + call CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072']) + + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR x = b1 > b2 + END + call CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:']) + + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR x = b1 < b2 + END + call CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:']) + + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR x = b1 - b2 + END + call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:']) + + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR x = b1 / b2 + END + call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:']) + + let lines =<< trim END + VAR b1 = 0z0011 + VAR b2 = 0z1100 + VAR x = b1 * b2 + END + call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:']) endfunc -" test for range assign -func Test_blob_range_assign() - let b = 0z00 - let b[1] = 0x11 - let b[2] = 0x22 - call assert_equal(0z001122, b) - call assert_fails('let b[4] = 0x33', 'E979:') +func Test_blob_index_assign() + let lines =<< trim END + VAR b = 0z00 + LET b[1] = 0x11 + LET b[2] = 0x22 + call assert_equal(0z001122, b) + END + call CheckLegacyAndVim9Success(lines) + + let lines =<< trim END + VAR b = 0z00 + LET b[2] = 0x33 + END + call CheckLegacyAndVim9Failure(lines, 'E979:') + + let lines =<< trim END + VAR b = 0z00 + LET b[-2] = 0x33 + END + call CheckLegacyAndVim9Failure(lines, 'E979:') endfunc func Test_blob_for_loop() |