Mercurial > vim
comparison src/list.c @ 26578:06693d1afc48
patch 8.2.3818: cannot filter or map characters in a string
Commit: https://github.com/vim/vim/commit/c479ce032f5d4d14bab9e479acbf42d758879893
Author: rbtnn <naru123456789@gmail.com>
Date: Wed Dec 15 19:14:54 2021 +0000
patch 8.2.3818: cannot filter or map characters in a string
Problem: Cannot filter or map characters in a string.
Solution: Make filter() and map() work on a string. (Naruhiko Nishino,
closes #9327)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 15 Dec 2021 20:15:03 +0100 |
parents | 28745eec1dda |
children | 0d2a709e2ff0 |
comparison
equal
deleted
inserted
replaced
26577:61af645a0725 | 26578:06693d1afc48 |
---|---|
2327 if ((d = argvars[0].vval.v_dict) == NULL | 2327 if ((d = argvars[0].vval.v_dict) == NULL |
2328 || (filtermap == FILTERMAP_FILTER | 2328 || (filtermap == FILTERMAP_FILTER |
2329 && value_check_lock(d->dv_lock, arg_errmsg, TRUE))) | 2329 && value_check_lock(d->dv_lock, arg_errmsg, TRUE))) |
2330 goto theend; | 2330 goto theend; |
2331 } | 2331 } |
2332 else if (argvars[0].v_type == VAR_STRING) | |
2333 { | |
2334 rettv->v_type = VAR_STRING; | |
2335 rettv->vval.v_string = NULL; | |
2336 } | |
2332 else | 2337 else |
2333 { | 2338 { |
2334 semsg(_(e_listdictblobarg), func_name); | 2339 semsg(_(e_argument_of_str_must_be_list_string_dictionary_or_blob), |
2340 func_name); | |
2335 goto theend; | 2341 goto theend; |
2336 } | 2342 } |
2337 | 2343 |
2338 expr = &argvars[1]; | 2344 expr = &argvars[1]; |
2339 // On type errors, the preceding call has already displayed an error | 2345 // On type errors, the preceding call has already displayed an error |
2478 --i; | 2484 --i; |
2479 } | 2485 } |
2480 ++idx; | 2486 ++idx; |
2481 } | 2487 } |
2482 } | 2488 } |
2489 else if (argvars[0].v_type == VAR_STRING) | |
2490 { | |
2491 char_u *p; | |
2492 typval_T tv; | |
2493 garray_T ga; | |
2494 char_u buf[MB_MAXBYTES + 1]; | |
2495 int len; | |
2496 | |
2497 // set_vim_var_nr() doesn't set the type | |
2498 set_vim_var_type(VV_KEY, VAR_NUMBER); | |
2499 | |
2500 ga_init2(&ga, (int)sizeof(char), 80); | |
2501 for (p = tv_get_string(&argvars[0]); *p != NUL; p += len) | |
2502 { | |
2503 typval_T newtv; | |
2504 | |
2505 if (has_mbyte) | |
2506 len = mb_ptr2len(p); | |
2507 else | |
2508 len = 1; | |
2509 | |
2510 STRNCPY(buf, p, len); | |
2511 buf[len] = NUL; | |
2512 | |
2513 tv.v_type = VAR_STRING; | |
2514 tv.vval.v_string = vim_strsave(buf); | |
2515 | |
2516 set_vim_var_nr(VV_KEY, idx); | |
2517 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL | |
2518 || did_emsg) | |
2519 break; | |
2520 if (did_emsg) | |
2521 { | |
2522 clear_tv(&newtv); | |
2523 clear_tv(&tv); | |
2524 break; | |
2525 } | |
2526 else if (filtermap != FILTERMAP_FILTER) | |
2527 { | |
2528 if (newtv.v_type != VAR_STRING) | |
2529 { | |
2530 clear_tv(&newtv); | |
2531 clear_tv(&tv); | |
2532 emsg(_(e_stringreq)); | |
2533 break; | |
2534 } | |
2535 else | |
2536 ga_concat(&ga, newtv.vval.v_string); | |
2537 } | |
2538 else if (!rem) | |
2539 ga_concat(&ga, tv.vval.v_string); | |
2540 | |
2541 clear_tv(&newtv); | |
2542 clear_tv(&tv); | |
2543 | |
2544 ++idx; | |
2545 } | |
2546 ga_append(&ga, NUL); | |
2547 rettv->vval.v_string = ga.ga_data; | |
2548 } | |
2483 else // argvars[0].v_type == VAR_LIST | 2549 else // argvars[0].v_type == VAR_LIST |
2484 { | 2550 { |
2485 int prev_lock = l->lv_lock; | 2551 int prev_lock = l->lv_lock; |
2486 list_T *l_ret = NULL; | 2552 list_T *l_ret = NULL; |
2487 | 2553 |