Mercurial > vim
comparison src/eval.c @ 24234:7ffc795288dd v8.2.2658
patch 8.2.2658: :for cannot loop over a string
Commit: https://github.com/vim/vim/commit/74e54fcb447e5db32f9c2df34c0554bbecdccca2
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Mar 26 20:41:29 2021 +0100
patch 8.2.2658: :for cannot loop over a string
Problem: :for cannot loop over a string.
Solution: Accept a string argument and iterate over its characters.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 26 Mar 2021 20:45:02 +0100 |
parents | 9f64c420f280 |
children | 2194227d034a |
comparison
equal
deleted
inserted
replaced
24233:a4ebdfa35a69 | 24234:7ffc795288dd |
---|---|
39 int fi_break_count; // nr of line breaks encountered | 39 int fi_break_count; // nr of line breaks encountered |
40 listwatch_T fi_lw; // keep an eye on the item used. | 40 listwatch_T fi_lw; // keep an eye on the item used. |
41 list_T *fi_list; // list being used | 41 list_T *fi_list; // list being used |
42 int fi_bi; // index of blob | 42 int fi_bi; // index of blob |
43 blob_T *fi_blob; // blob being used | 43 blob_T *fi_blob; // blob being used |
44 char_u *fi_string; // copy of string being used | |
45 int fi_byte_idx; // byte index in fi_string | |
44 } forinfo_T; | 46 } forinfo_T; |
45 | 47 |
46 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); | 48 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); |
47 static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg); | 49 static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg); |
48 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg); | 50 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg); |
1736 blob_copy(tv.vval.v_blob, &btv); | 1738 blob_copy(tv.vval.v_blob, &btv); |
1737 fi->fi_blob = btv.vval.v_blob; | 1739 fi->fi_blob = btv.vval.v_blob; |
1738 } | 1740 } |
1739 clear_tv(&tv); | 1741 clear_tv(&tv); |
1740 } | 1742 } |
1743 else if (tv.v_type == VAR_STRING) | |
1744 { | |
1745 fi->fi_byte_idx = 0; | |
1746 fi->fi_string = tv.vval.v_string; | |
1747 tv.vval.v_string = NULL; | |
1748 if (fi->fi_string == NULL) | |
1749 fi->fi_string = vim_strsave((char_u *)""); | |
1750 } | |
1741 else | 1751 else |
1742 { | 1752 { |
1743 emsg(_(e_listreq)); | 1753 emsg(_(e_listreq)); |
1744 clear_tv(&tv); | 1754 clear_tv(&tv); |
1745 } | 1755 } |
1788 tv.v_type = VAR_NUMBER; | 1798 tv.v_type = VAR_NUMBER; |
1789 tv.v_lock = VAR_FIXED; | 1799 tv.v_lock = VAR_FIXED; |
1790 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi); | 1800 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi); |
1791 ++fi->fi_bi; | 1801 ++fi->fi_bi; |
1792 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, | 1802 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, |
1793 fi->fi_varcount, flag, NULL) == OK; | 1803 fi->fi_varcount, flag, NULL) == OK; |
1804 } | |
1805 | |
1806 if (fi->fi_string != NULL) | |
1807 { | |
1808 typval_T tv; | |
1809 int len; | |
1810 | |
1811 len = mb_ptr2len(fi->fi_string + fi->fi_byte_idx); | |
1812 if (len == 0) | |
1813 return FALSE; | |
1814 tv.v_type = VAR_STRING; | |
1815 tv.v_lock = VAR_FIXED; | |
1816 tv.vval.v_string = vim_strnsave(fi->fi_string + fi->fi_byte_idx, len); | |
1817 fi->fi_byte_idx += len; | |
1818 return ex_let_vars(arg, &tv, TRUE, fi->fi_semicolon, | |
1819 fi->fi_varcount, flag, NULL) == OK; | |
1794 } | 1820 } |
1795 | 1821 |
1796 item = fi->fi_lw.lw_item; | 1822 item = fi->fi_lw.lw_item; |
1797 if (item == NULL) | 1823 if (item == NULL) |
1798 result = FALSE; | 1824 result = FALSE; |
1799 else | 1825 else |
1800 { | 1826 { |
1801 fi->fi_lw.lw_item = item->li_next; | 1827 fi->fi_lw.lw_item = item->li_next; |
1802 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon, | 1828 result = (ex_let_vars(arg, &item->li_tv, TRUE, fi->fi_semicolon, |
1803 fi->fi_varcount, flag, NULL) == OK); | 1829 fi->fi_varcount, flag, NULL) == OK); |
1804 } | 1830 } |
1805 return result; | 1831 return result; |
1806 } | 1832 } |
1807 | 1833 |
1808 /* | 1834 /* |
1811 void | 1837 void |
1812 free_for_info(void *fi_void) | 1838 free_for_info(void *fi_void) |
1813 { | 1839 { |
1814 forinfo_T *fi = (forinfo_T *)fi_void; | 1840 forinfo_T *fi = (forinfo_T *)fi_void; |
1815 | 1841 |
1816 if (fi != NULL && fi->fi_list != NULL) | 1842 if (fi == NULL) |
1843 return; | |
1844 if (fi->fi_list != NULL) | |
1817 { | 1845 { |
1818 list_rem_watch(fi->fi_list, &fi->fi_lw); | 1846 list_rem_watch(fi->fi_list, &fi->fi_lw); |
1819 list_unref(fi->fi_list); | 1847 list_unref(fi->fi_list); |
1820 } | 1848 } |
1821 if (fi != NULL && fi->fi_blob != NULL) | 1849 else if (fi->fi_blob != NULL) |
1822 blob_unref(fi->fi_blob); | 1850 blob_unref(fi->fi_blob); |
1851 else | |
1852 vim_free(fi->fi_string); | |
1823 vim_free(fi); | 1853 vim_free(fi); |
1824 } | 1854 } |
1825 | 1855 |
1826 void | 1856 void |
1827 set_context_for_expression( | 1857 set_context_for_expression( |