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