Mercurial > vim
comparison src/list.c @ 23588:510088f8c66f v8.2.2336
patch 8.2.2336: Vim9: not possible to extend dictionary with different type
Commit: https://github.com/vim/vim/commit/b0e6b513648db7035046613431a4aa9d71ef4653
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 12 20:23:40 2021 +0100
patch 8.2.2336: Vim9: not possible to extend dictionary with different type
Problem: Vim9: it is not possible to extend a dictionary with different
item types.
Solution: Add extendnew(). (closes #7666)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 12 Jan 2021 20:30:07 +0100 |
parents | 34aa2907082a |
children | 1816ea68c022 |
comparison
equal
deleted
inserted
replaced
23587:901fb2bf09d1 | 23588:510088f8c66f |
---|---|
2452 semsg(_(e_listdictarg), "count()"); | 2452 semsg(_(e_listdictarg), "count()"); |
2453 rettv->vval.v_number = n; | 2453 rettv->vval.v_number = n; |
2454 } | 2454 } |
2455 | 2455 |
2456 /* | 2456 /* |
2457 * "extend(list, list [, idx])" function | 2457 * "extend()" or "extendnew()" function. "is_new" is TRUE for extendnew(). |
2458 * "extend(dict, dict [, action])" function | 2458 */ |
2459 */ | 2459 static void |
2460 void | 2460 extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new) |
2461 f_extend(typval_T *argvars, typval_T *rettv) | 2461 { |
2462 { | |
2463 char_u *arg_errmsg = (char_u *)N_("extend() argument"); | |
2464 | |
2465 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) | 2462 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) |
2466 { | 2463 { |
2467 list_T *l1, *l2; | 2464 list_T *l1, *l2; |
2468 listitem_T *item; | 2465 listitem_T *item; |
2469 long before; | 2466 long before; |
2474 { | 2471 { |
2475 emsg(_(e_cannot_extend_null_list)); | 2472 emsg(_(e_cannot_extend_null_list)); |
2476 return; | 2473 return; |
2477 } | 2474 } |
2478 l2 = argvars[1].vval.v_list; | 2475 l2 = argvars[1].vval.v_list; |
2479 if (!value_check_lock(l1->lv_lock, arg_errmsg, TRUE) && l2 != NULL) | 2476 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE)) |
2480 { | 2477 && l2 != NULL) |
2478 { | |
2479 if (is_new) | |
2480 { | |
2481 l1 = list_copy(l1, FALSE, get_copyID()); | |
2482 if (l1 == NULL) | |
2483 return; | |
2484 } | |
2485 | |
2481 if (argvars[2].v_type != VAR_UNKNOWN) | 2486 if (argvars[2].v_type != VAR_UNKNOWN) |
2482 { | 2487 { |
2483 before = (long)tv_get_number_chk(&argvars[2], &error); | 2488 before = (long)tv_get_number_chk(&argvars[2], &error); |
2484 if (error) | 2489 if (error) |
2485 return; // type error; errmsg already given | 2490 return; // type error; errmsg already given |
2498 } | 2503 } |
2499 else | 2504 else |
2500 item = NULL; | 2505 item = NULL; |
2501 list_extend(l1, l2, item); | 2506 list_extend(l1, l2, item); |
2502 | 2507 |
2503 copy_tv(&argvars[0], rettv); | 2508 if (is_new) |
2509 { | |
2510 rettv->v_type = VAR_LIST; | |
2511 rettv->vval.v_list = l1; | |
2512 rettv->v_lock = FALSE; | |
2513 } | |
2514 else | |
2515 copy_tv(&argvars[0], rettv); | |
2504 } | 2516 } |
2505 } | 2517 } |
2506 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) | 2518 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) |
2507 { | 2519 { |
2508 dict_T *d1, *d2; | 2520 dict_T *d1, *d2; |
2514 { | 2526 { |
2515 emsg(_(e_cannot_extend_null_dict)); | 2527 emsg(_(e_cannot_extend_null_dict)); |
2516 return; | 2528 return; |
2517 } | 2529 } |
2518 d2 = argvars[1].vval.v_dict; | 2530 d2 = argvars[1].vval.v_dict; |
2519 if (!value_check_lock(d1->dv_lock, arg_errmsg, TRUE) && d2 != NULL) | 2531 if ((is_new || !value_check_lock(d1->dv_lock, arg_errmsg, TRUE)) |
2520 { | 2532 && d2 != NULL) |
2533 { | |
2534 if (is_new) | |
2535 { | |
2536 d1 = dict_copy(d1, FALSE, get_copyID()); | |
2537 if (d1 == NULL) | |
2538 return; | |
2539 } | |
2540 | |
2521 // Check the third argument. | 2541 // Check the third argument. |
2522 if (argvars[2].v_type != VAR_UNKNOWN) | 2542 if (argvars[2].v_type != VAR_UNKNOWN) |
2523 { | 2543 { |
2524 static char *(av[]) = {"keep", "force", "error"}; | 2544 static char *(av[]) = {"keep", "force", "error"}; |
2525 | 2545 |
2538 else | 2558 else |
2539 action = (char_u *)"force"; | 2559 action = (char_u *)"force"; |
2540 | 2560 |
2541 dict_extend(d1, d2, action); | 2561 dict_extend(d1, d2, action); |
2542 | 2562 |
2543 copy_tv(&argvars[0], rettv); | 2563 if (is_new) |
2564 { | |
2565 rettv->v_type = VAR_DICT; | |
2566 rettv->vval.v_dict = d1; | |
2567 rettv->v_lock = FALSE; | |
2568 } | |
2569 else | |
2570 copy_tv(&argvars[0], rettv); | |
2544 } | 2571 } |
2545 } | 2572 } |
2546 else | 2573 else |
2547 semsg(_(e_listdictarg), "extend()"); | 2574 semsg(_(e_listdictarg), is_new ? "extendnew()" : "extend()"); |
2575 } | |
2576 | |
2577 /* | |
2578 * "extend(list, list [, idx])" function | |
2579 * "extend(dict, dict [, action])" function | |
2580 */ | |
2581 void | |
2582 f_extend(typval_T *argvars, typval_T *rettv) | |
2583 { | |
2584 char_u *errmsg = (char_u *)N_("extend() argument"); | |
2585 | |
2586 extend(argvars, rettv, errmsg, FALSE); | |
2587 } | |
2588 | |
2589 /* | |
2590 * "extendnew(list, list [, idx])" function | |
2591 * "extendnew(dict, dict [, action])" function | |
2592 */ | |
2593 void | |
2594 f_extendnew(typval_T *argvars, typval_T *rettv) | |
2595 { | |
2596 char_u *errmsg = (char_u *)N_("extendnew() argument"); | |
2597 | |
2598 extend(argvars, rettv, errmsg, TRUE); | |
2548 } | 2599 } |
2549 | 2600 |
2550 /* | 2601 /* |
2551 * "insert()" function | 2602 * "insert()" function |
2552 */ | 2603 */ |