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(