comparison src/dict.c @ 29978:34151eb6ae25 v9.0.0327

patch 9.0.0327: items() does not work on a list Commit: https://github.com/vim/vim/commit/976f859763b215050a03248dbc2bb62fa5d0d059 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Aug 30 14:34:52 2022 +0100 patch 9.0.0327: items() does not work on a list Problem: items() does not work on a list. (Sergey Vlasov) Solution: Make items() work on a list. (closes https://github.com/vim/vim/issues/11013)
author Bram Moolenaar <Bram@vim.org>
date Tue, 30 Aug 2022 15:45:03 +0200
parents 827d9f2b7a71
children 0ad8b72af148
comparison
equal deleted inserted replaced
29977:b6c19db0298b 29978:34151eb6ae25
1438 *rettv = di->di_tv; 1438 *rettv = di->di_tv;
1439 init_tv(&di->di_tv); 1439 init_tv(&di->di_tv);
1440 dictitem_remove(d, di); 1440 dictitem_remove(d, di);
1441 } 1441 }
1442 1442
1443 /* 1443 typedef enum {
1444 * Turn a dict into a list: 1444 DICT2LIST_KEYS,
1445 * "what" == 0: list of keys 1445 DICT2LIST_VALUES,
1446 * "what" == 1: list of values 1446 DICT2LIST_ITEMS,
1447 * "what" == 2: list of items 1447 } dict2list_T;
1448
1449 /*
1450 * Turn a dict into a list.
1448 */ 1451 */
1449 static void 1452 static void
1450 dict_list(typval_T *argvars, typval_T *rettv, int what) 1453 dict2list(typval_T *argvars, typval_T *rettv, dict2list_T what)
1451 { 1454 {
1452 list_T *l2; 1455 list_T *l2;
1453 dictitem_T *di; 1456 dictitem_T *di;
1454 hashitem_T *hi; 1457 hashitem_T *hi;
1455 listitem_T *li; 1458 listitem_T *li;
1458 int todo; 1461 int todo;
1459 1462
1460 if (rettv_list_alloc(rettv) == FAIL) 1463 if (rettv_list_alloc(rettv) == FAIL)
1461 return; 1464 return;
1462 1465
1463 if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL) 1466 if ((what == DICT2LIST_ITEMS
1467 ? check_for_list_or_dict_arg(argvars, 0)
1468 : check_for_dict_arg(argvars, 0)) == FAIL)
1464 return; 1469 return;
1465 1470
1466 if (argvars[0].v_type != VAR_DICT) 1471 d = argvars[0].vval.v_dict;
1467 { 1472 if (d == NULL)
1468 emsg(_(e_dictionary_required));
1469 return;
1470 }
1471
1472 if ((d = argvars[0].vval.v_dict) == NULL)
1473 // empty dict behaves like an empty dict 1473 // empty dict behaves like an empty dict
1474 return; 1474 return;
1475 1475
1476 todo = (int)d->dv_hashtab.ht_used; 1476 todo = (int)d->dv_hashtab.ht_used;
1477 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 1477 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
1484 li = listitem_alloc(); 1484 li = listitem_alloc();
1485 if (li == NULL) 1485 if (li == NULL)
1486 break; 1486 break;
1487 list_append(rettv->vval.v_list, li); 1487 list_append(rettv->vval.v_list, li);
1488 1488
1489 if (what == 0) 1489 if (what == DICT2LIST_KEYS)
1490 { 1490 {
1491 // keys() 1491 // keys()
1492 li->li_tv.v_type = VAR_STRING; 1492 li->li_tv.v_type = VAR_STRING;
1493 li->li_tv.v_lock = 0; 1493 li->li_tv.v_lock = 0;
1494 li->li_tv.vval.v_string = vim_strsave(di->di_key); 1494 li->li_tv.vval.v_string = vim_strsave(di->di_key);
1495 } 1495 }
1496 else if (what == 1) 1496 else if (what == DICT2LIST_VALUES)
1497 { 1497 {
1498 // values() 1498 // values()
1499 copy_tv(&di->di_tv, &li->li_tv); 1499 copy_tv(&di->di_tv, &li->li_tv);
1500 } 1500 }
1501 else 1501 else
1531 * "items(dict)" function 1531 * "items(dict)" function
1532 */ 1532 */
1533 void 1533 void
1534 f_items(typval_T *argvars, typval_T *rettv) 1534 f_items(typval_T *argvars, typval_T *rettv)
1535 { 1535 {
1536 dict_list(argvars, rettv, 2); 1536 if (argvars[0].v_type == VAR_LIST)
1537 list2items(argvars, rettv);
1538 else
1539 dict2list(argvars, rettv, DICT2LIST_ITEMS);
1537 } 1540 }
1538 1541
1539 /* 1542 /*
1540 * "keys()" function 1543 * "keys()" function
1541 */ 1544 */
1542 void 1545 void
1543 f_keys(typval_T *argvars, typval_T *rettv) 1546 f_keys(typval_T *argvars, typval_T *rettv)
1544 { 1547 {
1545 dict_list(argvars, rettv, 0); 1548 dict2list(argvars, rettv, DICT2LIST_KEYS);
1546 } 1549 }
1547 1550
1548 /* 1551 /*
1549 * "values(dict)" function 1552 * "values(dict)" function
1550 */ 1553 */
1551 void 1554 void
1552 f_values(typval_T *argvars, typval_T *rettv) 1555 f_values(typval_T *argvars, typval_T *rettv)
1553 { 1556 {
1554 dict_list(argvars, rettv, 1); 1557 dict2list(argvars, rettv, DICT2LIST_VALUES);
1555 } 1558 }
1556 1559
1557 /* 1560 /*
1558 * Make each item in the dict readonly (not the value of the item). 1561 * Make each item in the dict readonly (not the value of the item).
1559 */ 1562 */