Mercurial > vim
comparison src/list.c @ 26638:6fd15d82e898 v8.2.3848
patch 8.2.3848: cannot use reduce() for a string
Commit: https://github.com/vim/vim/commit/0ccb5842f5fb103763d106c7aa364d758343c35a
Author: rbtnn <naru123456789@gmail.com>
Date: Sat Dec 18 18:33:46 2021 +0000
patch 8.2.3848: cannot use reduce() for a string
Problem: Cannot use reduce() for a string.
Solution: Make reduce() work with a string. (Naruhiko Nishino, closes https://github.com/vim/vim/issues/9366)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 18 Dec 2021 19:45:03 +0100 |
parents | 0d2a709e2ff0 |
children | 7c055fdd6200 |
comparison
equal
deleted
inserted
replaced
26637:eeac85e187e7 | 26638:6fd15d82e898 |
---|---|
309 */ | 309 */ |
310 listitem_T * | 310 listitem_T * |
311 listitem_alloc(void) | 311 listitem_alloc(void) |
312 { | 312 { |
313 return ALLOC_ONE(listitem_T); | 313 return ALLOC_ONE(listitem_T); |
314 } | |
315 | |
316 /* | |
317 * Make a typval_T of the first character of "input" and store it in "output". | |
318 * Return OK or FAIL. | |
319 */ | |
320 static int | |
321 tv_get_first_char(char_u *input, typval_T *output) | |
322 { | |
323 char_u buf[MB_MAXBYTES + 1]; | |
324 int len; | |
325 | |
326 if (input == NULL || output == NULL) | |
327 return FAIL; | |
328 | |
329 len = has_mbyte ? mb_ptr2len(input) : 1; | |
330 STRNCPY(buf, input, len); | |
331 buf[len] = NUL; | |
332 output->v_type = VAR_STRING; | |
333 output->vval.v_string = vim_strsave(buf); | |
334 | |
335 return output->vval.v_string == NULL ? FAIL : OK; | |
314 } | 336 } |
315 | 337 |
316 /* | 338 /* |
317 * Free a list item, unless it was allocated together with the list itself. | 339 * Free a list item, unless it was allocated together with the list itself. |
318 * Does not clear the value. Does not notify watchers. | 340 * Does not clear the value. Does not notify watchers. |
2490 else if (argvars[0].v_type == VAR_STRING) | 2512 else if (argvars[0].v_type == VAR_STRING) |
2491 { | 2513 { |
2492 char_u *p; | 2514 char_u *p; |
2493 typval_T tv; | 2515 typval_T tv; |
2494 garray_T ga; | 2516 garray_T ga; |
2495 char_u buf[MB_MAXBYTES + 1]; | |
2496 int len; | 2517 int len; |
2497 | 2518 |
2498 // set_vim_var_nr() doesn't set the type | 2519 // set_vim_var_nr() doesn't set the type |
2499 set_vim_var_type(VV_KEY, VAR_NUMBER); | 2520 set_vim_var_type(VV_KEY, VAR_NUMBER); |
2500 | 2521 |
2501 ga_init2(&ga, (int)sizeof(char), 80); | 2522 ga_init2(&ga, (int)sizeof(char), 80); |
2502 for (p = tv_get_string(&argvars[0]); *p != NUL; p += len) | 2523 for (p = tv_get_string(&argvars[0]); *p != NUL; p += len) |
2503 { | 2524 { |
2504 typval_T newtv; | 2525 typval_T newtv; |
2505 | 2526 |
2506 if (has_mbyte) | 2527 if (tv_get_first_char(p, &tv) == FAIL) |
2507 len = mb_ptr2len(p); | 2528 break; |
2508 else | 2529 len = STRLEN(tv.vval.v_string); |
2509 len = 1; | |
2510 | |
2511 STRNCPY(buf, p, len); | |
2512 buf[len] = NUL; | |
2513 | |
2514 tv.v_type = VAR_STRING; | |
2515 tv.vval.v_string = vim_strsave(buf); | |
2516 | 2530 |
2517 set_vim_var_nr(VV_KEY, idx); | 2531 set_vim_var_nr(VV_KEY, idx); |
2518 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL | 2532 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL |
2519 || did_emsg) | 2533 || did_emsg) |
2520 break; | 2534 break; |
3246 typval_T initial; | 3260 typval_T initial; |
3247 char_u *func_name; | 3261 char_u *func_name; |
3248 partial_T *partial = NULL; | 3262 partial_T *partial = NULL; |
3249 funcexe_T funcexe; | 3263 funcexe_T funcexe; |
3250 typval_T argv[3]; | 3264 typval_T argv[3]; |
3251 | 3265 int r; |
3252 if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) | 3266 int called_emsg_start = called_emsg; |
3253 { | 3267 |
3254 emsg(_(e_listblobreq)); | 3268 if (in_vim9script() |
3269 && check_for_string_or_list_or_blob_arg(argvars, 0) == FAIL) | |
3255 return; | 3270 return; |
3256 } | 3271 |
3272 if (argvars[0].v_type != VAR_STRING | |
3273 && argvars[0].v_type != VAR_LIST | |
3274 && argvars[0].v_type != VAR_BLOB) | |
3275 semsg(_(e_string_list_or_blob_required), "reduce()"); | |
3257 | 3276 |
3258 if (argvars[1].v_type == VAR_FUNC) | 3277 if (argvars[1].v_type == VAR_FUNC) |
3259 func_name = argvars[1].vval.v_string; | 3278 func_name = argvars[1].vval.v_string; |
3260 else if (argvars[1].v_type == VAR_PARTIAL) | 3279 else if (argvars[1].v_type == VAR_PARTIAL) |
3261 { | 3280 { |
3276 | 3295 |
3277 if (argvars[0].v_type == VAR_LIST) | 3296 if (argvars[0].v_type == VAR_LIST) |
3278 { | 3297 { |
3279 list_T *l = argvars[0].vval.v_list; | 3298 list_T *l = argvars[0].vval.v_list; |
3280 listitem_T *li = NULL; | 3299 listitem_T *li = NULL; |
3281 int r; | |
3282 int called_emsg_start = called_emsg; | |
3283 | 3300 |
3284 if (l != NULL) | 3301 if (l != NULL) |
3285 CHECK_LIST_MATERIALIZE(l); | 3302 CHECK_LIST_MATERIALIZE(l); |
3286 if (argvars[2].v_type == VAR_UNKNOWN) | 3303 if (argvars[2].v_type == VAR_UNKNOWN) |
3287 { | 3304 { |
3317 break; | 3334 break; |
3318 } | 3335 } |
3319 l->lv_lock = prev_locked; | 3336 l->lv_lock = prev_locked; |
3320 } | 3337 } |
3321 } | 3338 } |
3339 else if (argvars[0].v_type == VAR_STRING) | |
3340 { | |
3341 char_u *p = tv_get_string(&argvars[0]); | |
3342 int len; | |
3343 | |
3344 if (argvars[2].v_type == VAR_UNKNOWN) | |
3345 { | |
3346 if (*p == NUL) | |
3347 { | |
3348 semsg(_(e_reduceempty), "String"); | |
3349 return; | |
3350 } | |
3351 if (tv_get_first_char(p, rettv) == FAIL) | |
3352 return; | |
3353 p += STRLEN(rettv->vval.v_string); | |
3354 } | |
3355 else if (argvars[2].v_type != VAR_STRING) | |
3356 { | |
3357 semsg(_(e_string_expected_for_argument_nr), 3); | |
3358 return; | |
3359 } | |
3360 else | |
3361 copy_tv(&argvars[2], rettv); | |
3362 | |
3363 for ( ; *p != NUL; p += len) | |
3364 { | |
3365 argv[0] = *rettv; | |
3366 if (tv_get_first_char(p, &argv[1]) == FAIL) | |
3367 break; | |
3368 len = STRLEN(argv[1].vval.v_string); | |
3369 r = call_func(func_name, -1, rettv, 2, argv, &funcexe); | |
3370 clear_tv(&argv[0]); | |
3371 clear_tv(&argv[1]); | |
3372 if (r == FAIL || called_emsg != called_emsg_start) | |
3373 break; | |
3374 } | |
3375 } | |
3322 else | 3376 else |
3323 { | 3377 { |
3324 blob_T *b = argvars[0].vval.v_blob; | 3378 blob_T *b = argvars[0].vval.v_blob; |
3325 int i; | 3379 int i; |
3326 | 3380 |