Mercurial > vim
comparison src/evalfunc.c @ 19201:e7b4fff348dd v8.2.0159
patch 8.2.0159: non-materialized range() list causes problems
Commit: https://github.com/vim/vim/commit/50985eb1f0bd3c73ce727f9bbd66c839c92ef0da
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jan 27 22:09:39 2020 +0100
patch 8.2.0159: non-materialized range() list causes problems
Problem: Non-materialized range() list causes problems. (Fujiwara Takuya)
Solution: Materialize the list where needed.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 27 Jan 2020 22:15:07 +0100 |
parents | 94eda51ba9ba |
children | d776967d0f0d |
comparison
equal
deleted
inserted
replaced
19200:654ef8f794a6 | 19201:e7b4fff348dd |
---|---|
1854 n = argvars[0].vval.v_float == 0.0; | 1854 n = argvars[0].vval.v_float == 0.0; |
1855 break; | 1855 break; |
1856 #endif | 1856 #endif |
1857 case VAR_LIST: | 1857 case VAR_LIST: |
1858 n = argvars[0].vval.v_list == NULL | 1858 n = argvars[0].vval.v_list == NULL |
1859 || argvars[0].vval.v_list->lv_first == NULL; | 1859 || argvars[0].vval.v_list->lv_len == 0; |
1860 break; | 1860 break; |
1861 case VAR_DICT: | 1861 case VAR_DICT: |
1862 n = argvars[0].vval.v_dict == NULL | 1862 n = argvars[0].vval.v_dict == NULL |
1863 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; | 1863 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; |
1864 break; | 1864 break; |
2062 rettv->v_type = VAR_STRING; | 2062 rettv->v_type = VAR_STRING; |
2063 | 2063 |
2064 if (argvars[arg_off].v_type == VAR_LIST) | 2064 if (argvars[arg_off].v_type == VAR_LIST) |
2065 { | 2065 { |
2066 list = argvars[arg_off].vval.v_list; | 2066 list = argvars[arg_off].vval.v_list; |
2067 if (list == NULL || list->lv_first == NULL) | 2067 if (list == NULL || list->lv_len == 0) |
2068 // empty list, no commands, empty output | 2068 // empty list, no commands, empty output |
2069 return; | 2069 return; |
2070 ++list->lv_refcount; | 2070 ++list->lv_refcount; |
2071 } | 2071 } |
2072 else if (argvars[arg_off].v_type == VAR_JOB | 2072 else if (argvars[arg_off].v_type == VAR_JOB |
2112 | 2112 |
2113 if (cmd != NULL) | 2113 if (cmd != NULL) |
2114 do_cmdline_cmd(cmd); | 2114 do_cmdline_cmd(cmd); |
2115 else | 2115 else |
2116 { | 2116 { |
2117 listitem_T *item = list->lv_first; | 2117 listitem_T *item; |
2118 | 2118 |
2119 range_list_materialize(list); | |
2120 item = list->lv_first; | |
2119 do_cmdline(NULL, get_list_line, (void *)&item, | 2121 do_cmdline(NULL, get_list_line, (void *)&item, |
2120 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED); | 2122 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED); |
2121 --list->lv_refcount; | 2123 --list->lv_refcount; |
2122 } | 2124 } |
2123 | 2125 |
2641 goto theend; | 2643 goto theend; |
2642 } | 2644 } |
2643 for (i = 0; i < arg_len; i++) | 2645 for (i = 0; i < arg_len; i++) |
2644 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); | 2646 copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]); |
2645 if (lv_len > 0) | 2647 if (lv_len > 0) |
2648 { | |
2649 range_list_materialize(list); | |
2646 for (li = list->lv_first; li != NULL; | 2650 for (li = list->lv_first; li != NULL; |
2647 li = li->li_next) | 2651 li = li->li_next) |
2648 copy_tv(&li->li_tv, &pt->pt_argv[i++]); | 2652 copy_tv(&li->li_tv, &pt->pt_argv[i++]); |
2653 } | |
2649 } | 2654 } |
2650 | 2655 |
2651 // For "function(dict.func, [], dict)" and "func" is a partial | 2656 // For "function(dict.func, [], dict)" and "func" is a partial |
2652 // use "dict". That is backwards compatible. | 2657 // use "dict". That is backwards compatible. |
2653 if (dict_idx > 0) | 2658 if (dict_idx > 0) |
4056 } | 4061 } |
4057 | 4062 |
4058 l = argvars[0].vval.v_list; | 4063 l = argvars[0].vval.v_list; |
4059 if (l != NULL) | 4064 if (l != NULL) |
4060 { | 4065 { |
4066 range_list_materialize(l); | |
4061 item = l->lv_first; | 4067 item = l->lv_first; |
4062 if (argvars[2].v_type != VAR_UNKNOWN) | 4068 if (argvars[2].v_type != VAR_UNKNOWN) |
4063 { | 4069 { |
4064 // Start at specified item. Use the cached index that list_find() | 4070 // Start at specified item. Use the cached index that list_find() |
4065 // sets, so that a negative number also works. | 4071 // sets, so that a negative number also works. |
4137 * "inputlist()" function | 4143 * "inputlist()" function |
4138 */ | 4144 */ |
4139 static void | 4145 static void |
4140 f_inputlist(typval_T *argvars, typval_T *rettv) | 4146 f_inputlist(typval_T *argvars, typval_T *rettv) |
4141 { | 4147 { |
4148 list_T *l; | |
4142 listitem_T *li; | 4149 listitem_T *li; |
4143 int selected; | 4150 int selected; |
4144 int mouse_used; | 4151 int mouse_used; |
4145 | 4152 |
4146 #ifdef NO_CONSOLE_INPUT | 4153 #ifdef NO_CONSOLE_INPUT |
4159 msg_row = Rows - 1; // for when 'cmdheight' > 1 | 4166 msg_row = Rows - 1; // for when 'cmdheight' > 1 |
4160 lines_left = Rows; // avoid more prompt | 4167 lines_left = Rows; // avoid more prompt |
4161 msg_scroll = TRUE; | 4168 msg_scroll = TRUE; |
4162 msg_clr_eos(); | 4169 msg_clr_eos(); |
4163 | 4170 |
4164 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) | 4171 l = argvars[0].vval.v_list; |
4172 range_list_materialize(l); | |
4173 for (li = l->lv_first; li != NULL; li = li->li_next) | |
4165 { | 4174 { |
4166 msg_puts((char *)tv_get_string(&li->li_tv)); | 4175 msg_puts((char *)tv_get_string(&li->li_tv)); |
4167 msg_putchar('\n'); | 4176 msg_putchar('\n'); |
4168 } | 4177 } |
4169 | 4178 |
4642 | 4651 |
4643 if (argvars[0].v_type == VAR_LIST) | 4652 if (argvars[0].v_type == VAR_LIST) |
4644 { | 4653 { |
4645 if ((l = argvars[0].vval.v_list) == NULL) | 4654 if ((l = argvars[0].vval.v_list) == NULL) |
4646 goto theend; | 4655 goto theend; |
4656 range_list_materialize(l); | |
4647 li = l->lv_first; | 4657 li = l->lv_first; |
4648 } | 4658 } |
4649 else | 4659 else |
4650 { | 4660 { |
4651 expr = str = tv_get_string(&argvars[0]); | 4661 expr = str = tv_get_string(&argvars[0]); |
4871 listitem_T *li; | 4881 listitem_T *li; |
4872 | 4882 |
4873 l = argvars[0].vval.v_list; | 4883 l = argvars[0].vval.v_list; |
4874 if (l != NULL) | 4884 if (l != NULL) |
4875 { | 4885 { |
4886 range_list_materialize(l); | |
4876 li = l->lv_first; | 4887 li = l->lv_first; |
4877 if (li != NULL) | 4888 if (li != NULL) |
4878 { | 4889 { |
4879 n = tv_get_number_chk(&li->li_tv, &error); | 4890 n = tv_get_number_chk(&li->li_tv, &error); |
4880 for (;;) | 4891 for (;;) |
5320 // be called. | 5331 // be called. |
5321 list->lv_first = &range_list_item; | 5332 list->lv_first = &range_list_item; |
5322 list->lv_start = start; | 5333 list->lv_start = start; |
5323 list->lv_end = end; | 5334 list->lv_end = end; |
5324 list->lv_stride = stride; | 5335 list->lv_stride = stride; |
5325 list->lv_len = (end - start + 1) / stride; | 5336 list->lv_len = (end - start) / stride + 1; |
5326 } | 5337 } |
5327 } | 5338 } |
5328 | 5339 |
5329 /* | 5340 /* |
5330 * If "list" is a non-materialized list then materialize it now. | 5341 * If "list" is a non-materialized list then materialize it now. |
6788 return; | 6799 return; |
6789 curval = lstval; | 6800 curval = lstval; |
6790 allocval = lstval + len + 2; | 6801 allocval = lstval + len + 2; |
6791 curallocval = allocval; | 6802 curallocval = allocval; |
6792 | 6803 |
6793 for (li = ll == NULL ? NULL : ll->lv_first; li != NULL; | 6804 if (ll != NULL) |
6794 li = li->li_next) | 6805 { |
6795 { | 6806 range_list_materialize(ll); |
6796 strval = tv_get_string_buf_chk(&li->li_tv, buf); | 6807 for (li = ll->lv_first; li != NULL; li = li->li_next) |
6797 if (strval == NULL) | |
6798 goto free_lstval; | |
6799 if (strval == buf) | |
6800 { | 6808 { |
6801 // Need to make a copy, next tv_get_string_buf_chk() will | 6809 strval = tv_get_string_buf_chk(&li->li_tv, buf); |
6802 // overwrite the string. | |
6803 strval = vim_strsave(buf); | |
6804 if (strval == NULL) | 6810 if (strval == NULL) |
6805 goto free_lstval; | 6811 goto free_lstval; |
6806 *curallocval++ = strval; | 6812 if (strval == buf) |
6813 { | |
6814 // Need to make a copy, next tv_get_string_buf_chk() will | |
6815 // overwrite the string. | |
6816 strval = vim_strsave(buf); | |
6817 if (strval == NULL) | |
6818 goto free_lstval; | |
6819 *curallocval++ = strval; | |
6820 } | |
6821 *curval++ = strval; | |
6807 } | 6822 } |
6808 *curval++ = strval; | |
6809 } | 6823 } |
6810 *curval++ = NULL; | 6824 *curval++ = NULL; |
6811 | 6825 |
6812 write_reg_contents_lst(regname, lstval, -1, | 6826 write_reg_contents_lst(regname, lstval, -1, |
6813 append, yank_type, block_len); | 6827 append, yank_type, block_len); |