vim-patch:8.2.1466: Vim9: cannot index or slice a variable with type "any"

Problem:    Vim9: cannot index or slice a variable with type "any".
Solution:   Add runtime index and slice.

cc673e746a

Missing changes from the last PR.

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq 2023-05-04 17:20:48 +08:00
parent f5cefd70e4
commit 62351ff3d2

View File

@ -7289,8 +7289,8 @@ char *char_from_string(char *str, varnumber_T index)
/// "str_len". /// "str_len".
/// If going over the end return "str_len". /// If going over the end return "str_len".
/// If "idx" is negative count from the end, -1 is the last character. /// If "idx" is negative count from the end, -1 is the last character.
/// When going over the start return zero. /// When going over the start return -1.
static size_t char_idx2byte(char *str, size_t str_len, varnumber_T idx) static ssize_t char_idx2byte(char *str, size_t str_len, varnumber_T idx)
{ {
varnumber_T nchar = idx; varnumber_T nchar = idx;
size_t nbyte = 0; size_t nbyte = 0;
@ -7307,8 +7307,11 @@ static size_t char_idx2byte(char *str, size_t str_len, varnumber_T idx)
nbyte -= (size_t)utf_head_off(str, str + nbyte); nbyte -= (size_t)utf_head_off(str, str + nbyte);
nchar++; nchar++;
} }
if (nchar < 0) {
return -1;
}
} }
return nbyte; return (ssize_t)nbyte;
} }
/// Return the slice "str[first:last]" using character indexes. /// Return the slice "str[first:last]" using character indexes.
@ -7319,22 +7322,25 @@ char *string_slice(char *str, varnumber_T first, varnumber_T last)
return NULL; return NULL;
} }
size_t slen = strlen(str); size_t slen = strlen(str);
size_t start_byte = char_idx2byte(str, slen, first); ssize_t start_byte = char_idx2byte(str, slen, first);
size_t end_byte; if (start_byte < 0) {
start_byte = 0; // first index very negative: use zero
}
ssize_t end_byte;
if (last == -1) { if (last == -1) {
end_byte = slen; end_byte = (ssize_t)slen;
} else { } else {
end_byte = char_idx2byte(str, slen, last); end_byte = char_idx2byte(str, slen, last);
if (end_byte < slen) { if (end_byte >= 0 && end_byte < (ssize_t)slen) {
// end index is inclusive // end index is inclusive
end_byte += (size_t)utf_ptr2len(str + end_byte); end_byte += utf_ptr2len(str + end_byte);
} }
} }
if (start_byte >= slen || end_byte <= start_byte) { if (start_byte >= (ssize_t)slen || end_byte <= start_byte) {
return NULL; return NULL;
} }
return xstrnsave(str + start_byte, end_byte - start_byte); return xstrnsave(str + start_byte, (size_t)(end_byte - start_byte));
} }
/// Handle: /// Handle: