Mercurial > vim
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 */ |