comparison src/evalvars.c @ 17922:4d63d47d87ef v8.1.1957

patch 8.1.1957: more code can be moved to evalvars.c Commit: https://github.com/vim/vim/commit/da6c03342117fb7f4a8110bd9e8627b612a05a64 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 1 16:01:30 2019 +0200 patch 8.1.1957: more code can be moved to evalvars.c Problem: More code can be moved to evalvars.c. Solution: Move code to where it fits better. (Yegappan Lakshmanan, closes #4883)
author Bram Moolenaar <Bram@vim.org>
date Sun, 01 Sep 2019 16:15:03 +0200
parents e4d3b6c466d4
children 745c02392844
comparison
equal deleted inserted replaced
17921:14be395d672c 17922:4d63d47d87ef
16 #if defined(FEAT_EVAL) || defined(PROTO) 16 #if defined(FEAT_EVAL) || defined(PROTO)
17 17
18 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 18 static char *e_letunexp = N_("E18: Unexpected characters in :let");
19 19
20 static dictitem_T globvars_var; // variable used for g: 20 static dictitem_T globvars_var; // variable used for g:
21 static dict_T globvardict; // Dictionary with g: variables
22 #define globvarht globvardict.dv_hashtab
21 23
22 /* 24 /*
23 * Old Vim variables such as "v:version" are also available without the "v:". 25 * Old Vim variables such as "v:version" are also available without the "v:".
24 * Also in functions. We need a special hashtable for them. 26 * Also in functions. We need a special hashtable for them.
25 */ 27 */
152 #define vv_dict vv_di.di_tv.vval.v_dict 154 #define vv_dict vv_di.di_tv.vval.v_dict
153 #define vv_blob vv_di.di_tv.vval.v_blob 155 #define vv_blob vv_di.di_tv.vval.v_blob
154 #define vv_tv vv_di.di_tv 156 #define vv_tv vv_di.di_tv
155 157
156 static dictitem_T vimvars_var; // variable used for v: 158 static dictitem_T vimvars_var; // variable used for v:
159 static dict_T vimvardict; // Dictionary with v: variables
157 #define vimvarht vimvardict.dv_hashtab 160 #define vimvarht vimvardict.dv_hashtab
158 161
159 // for VIM_VERSION_ defines 162 // for VIM_VERSION_ defines
160 #include "version.h" 163 #include "version.h"
161 164
183 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int is_const, char_u *endchars, char_u *op); 186 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int is_const, char_u *endchars, char_u *op);
184 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); 187 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
185 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); 188 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
186 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); 189 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
187 static void item_lock(typval_T *tv, int deep, int lock); 190 static void item_lock(typval_T *tv, int deep, int lock);
191 static void delete_var(hashtab_T *ht, hashitem_T *hi);
188 static void list_one_var(dictitem_T *v, char *prefix, int *first); 192 static void list_one_var(dictitem_T *v, char *prefix, int *first);
189 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first); 193 static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first);
190 194
191 /* 195 /*
192 * Initialize global and vim special variables 196 * Initialize global and vim special variables
294 ga_clear(&ga_scripts); 298 ga_clear(&ga_scripts);
295 } 299 }
296 #endif 300 #endif
297 301
298 int 302 int
303 garbage_collect_globvars(int copyID)
304 {
305 return set_ref_in_ht(&globvarht, copyID, NULL);
306 }
307
308 int
299 garbage_collect_vimvars(int copyID) 309 garbage_collect_vimvars(int copyID)
300 { 310 {
301 return set_ref_in_ht(&vimvarht, copyID, NULL); 311 return set_ref_in_ht(&vimvarht, copyID, NULL);
302 } 312 }
303 313
332 set_var(name, tvp, FALSE); 342 set_var(name, tvp, FALSE);
333 free_tv(tvp); 343 free_tv(tvp);
334 } 344 }
335 } 345 }
336 } 346 }
347
348 int
349 eval_charconvert(
350 char_u *enc_from,
351 char_u *enc_to,
352 char_u *fname_from,
353 char_u *fname_to)
354 {
355 int err = FALSE;
356
357 set_vim_var_string(VV_CC_FROM, enc_from, -1);
358 set_vim_var_string(VV_CC_TO, enc_to, -1);
359 set_vim_var_string(VV_FNAME_IN, fname_from, -1);
360 set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
361 if (eval_to_bool(p_ccv, &err, NULL, FALSE))
362 err = TRUE;
363 set_vim_var_string(VV_CC_FROM, NULL, -1);
364 set_vim_var_string(VV_CC_TO, NULL, -1);
365 set_vim_var_string(VV_FNAME_IN, NULL, -1);
366 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
367
368 if (err)
369 return FAIL;
370 return OK;
371 }
372
373 # if defined(FEAT_POSTSCRIPT) || defined(PROTO)
374 int
375 eval_printexpr(char_u *fname, char_u *args)
376 {
377 int err = FALSE;
378
379 set_vim_var_string(VV_FNAME_IN, fname, -1);
380 set_vim_var_string(VV_CMDARG, args, -1);
381 if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
382 err = TRUE;
383 set_vim_var_string(VV_FNAME_IN, NULL, -1);
384 set_vim_var_string(VV_CMDARG, NULL, -1);
385
386 if (err)
387 {
388 mch_remove(fname);
389 return FAIL;
390 }
391 return OK;
392 }
393 # endif
394
395 # if defined(FEAT_DIFF) || defined(PROTO)
396 void
397 eval_diff(
398 char_u *origfile,
399 char_u *newfile,
400 char_u *outfile)
401 {
402 int err = FALSE;
403
404 set_vim_var_string(VV_FNAME_IN, origfile, -1);
405 set_vim_var_string(VV_FNAME_NEW, newfile, -1);
406 set_vim_var_string(VV_FNAME_OUT, outfile, -1);
407 (void)eval_to_bool(p_dex, &err, NULL, FALSE);
408 set_vim_var_string(VV_FNAME_IN, NULL, -1);
409 set_vim_var_string(VV_FNAME_NEW, NULL, -1);
410 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
411 }
412
413 void
414 eval_patch(
415 char_u *origfile,
416 char_u *difffile,
417 char_u *outfile)
418 {
419 int err;
420
421 set_vim_var_string(VV_FNAME_IN, origfile, -1);
422 set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
423 set_vim_var_string(VV_FNAME_OUT, outfile, -1);
424 (void)eval_to_bool(p_pex, &err, NULL, FALSE);
425 set_vim_var_string(VV_FNAME_IN, NULL, -1);
426 set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
427 set_vim_var_string(VV_FNAME_OUT, NULL, -1);
428 }
429 # endif
430
431 #if defined(FEAT_SPELL) || defined(PROTO)
432 /*
433 * Evaluate an expression to a list with suggestions.
434 * For the "expr:" part of 'spellsuggest'.
435 * Returns NULL when there is an error.
436 */
437 list_T *
438 eval_spell_expr(char_u *badword, char_u *expr)
439 {
440 typval_T save_val;
441 typval_T rettv;
442 list_T *list = NULL;
443 char_u *p = skipwhite(expr);
444
445 // Set "v:val" to the bad word.
446 prepare_vimvar(VV_VAL, &save_val);
447 set_vim_var_string(VV_VAL, badword, -1);
448 if (p_verbose == 0)
449 ++emsg_off;
450
451 if (eval1(&p, &rettv, TRUE) == OK)
452 {
453 if (rettv.v_type != VAR_LIST)
454 clear_tv(&rettv);
455 else
456 list = rettv.vval.v_list;
457 }
458
459 if (p_verbose == 0)
460 --emsg_off;
461 clear_tv(get_vim_var_tv(VV_VAL));
462 restore_vimvar(VV_VAL, &save_val);
463
464 return list;
465 }
466
467 /*
468 * "list" is supposed to contain two items: a word and a number. Return the
469 * word in "pp" and the number as the return value.
470 * Return -1 if anything isn't right.
471 * Used to get the good word and score from the eval_spell_expr() result.
472 */
473 int
474 get_spellword(list_T *list, char_u **pp)
475 {
476 listitem_T *li;
477
478 li = list->lv_first;
479 if (li == NULL)
480 return -1;
481 *pp = tv_get_string(&li->li_tv);
482
483 li = li->li_next;
484 if (li == NULL)
485 return -1;
486 return (int)tv_get_number(&li->li_tv);
487 }
488 #endif
337 489
338 /* 490 /*
339 * Prepare v: variable "idx" to be used. 491 * Prepare v: variable "idx" to be used.
340 * Save the current typeval in "save_tv". 492 * Save the current typeval in "save_tv".
341 * When not used yet add the variable to the v: hashtable. 493 * When not used yet add the variable to the v: hashtable.
1567 } 1719 }
1568 } 1720 }
1569 --recurse; 1721 --recurse;
1570 } 1722 }
1571 1723
1724 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
1725 /*
1726 * Delete all "menutrans_" variables.
1727 */
1728 void
1729 del_menutrans_vars(void)
1730 {
1731 hashitem_T *hi;
1732 int todo;
1733
1734 hash_lock(&globvarht);
1735 todo = (int)globvarht.ht_used;
1736 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
1737 {
1738 if (!HASHITEM_EMPTY(hi))
1739 {
1740 --todo;
1741 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
1742 delete_var(&globvarht, hi);
1743 }
1744 }
1745 hash_unlock(&globvarht);
1746 }
1747 #endif
1748
1572 /* 1749 /*
1573 * Local string buffer for the next two functions to store a variable name 1750 * Local string buffer for the next two functions to store a variable name
1574 * with its prefix. Allocated in cat_prefix_varname(), freed later in 1751 * with its prefix. Allocated in cat_prefix_varname(), freed later in
1575 * get_user_var_name(). 1752 * get_user_var_name().
1576 */ 1753 */
1684 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 1861 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
1685 1862
1686 VIM_CLEAR(varnamebuf); 1863 VIM_CLEAR(varnamebuf);
1687 varnamebuflen = 0; 1864 varnamebuflen = 0;
1688 return NULL; 1865 return NULL;
1866 }
1867
1868 char *
1869 get_var_special_name(int nr)
1870 {
1871 switch (nr)
1872 {
1873 case VVAL_FALSE: return "v:false";
1874 case VVAL_TRUE: return "v:true";
1875 case VVAL_NONE: return "v:none";
1876 case VVAL_NULL: return "v:null";
1877 }
1878 internal_error("get_var_special_name()");
1879 return "42";
1880 }
1881
1882 /*
1883 * Returns the global variable dictionary
1884 */
1885 dict_T *
1886 get_globvar_dict(void)
1887 {
1888 return &globvardict;
1889 }
1890
1891 /*
1892 * Returns the global variable hash table
1893 */
1894 hashtab_T *
1895 get_globvar_ht(void)
1896 {
1897 return &globvarht;
1898 }
1899
1900 /*
1901 * Returns the v: variable dictionary
1902 */
1903 dict_T *
1904 get_vimvar_dict(void)
1905 {
1906 return &vimvardict;
1689 } 1907 }
1690 1908
1691 /* 1909 /*
1692 * Set type of v: variable to "type". 1910 * Set type of v: variable to "type".
1693 */ 1911 */
2319 2537
2320 /* 2538 /*
2321 * Delete a variable from hashtab "ht" at item "hi". 2539 * Delete a variable from hashtab "ht" at item "hi".
2322 * Clear the variable value and free the dictitem. 2540 * Clear the variable value and free the dictitem.
2323 */ 2541 */
2324 void 2542 static void
2325 delete_var(hashtab_T *ht, hashitem_T *hi) 2543 delete_var(hashtab_T *ht, hashitem_T *hi)
2326 { 2544 {
2327 dictitem_T *di = HI2DI(hi); 2545 dictitem_T *di = HI2DI(hi);
2328 2546
2329 hash_remove(ht, hi); 2547 hash_remove(ht, hi);
2851 3069
2852 vim_free(tofree); 3070 vim_free(tofree);
2853 return n; 3071 return n;
2854 } 3072 }
2855 3073
3074 static lval_T *redir_lval = NULL;
3075 #define EVALCMD_BUSY (redir_lval == (lval_T *)&redir_lval)
3076 static garray_T redir_ga; // only valid when redir_lval is not NULL
3077 static char_u *redir_endp = NULL;
3078 static char_u *redir_varname = NULL;
3079
3080 /*
3081 * Start recording command output to a variable
3082 * When "append" is TRUE append to an existing variable.
3083 * Returns OK if successfully completed the setup. FAIL otherwise.
3084 */
3085 int
3086 var_redir_start(char_u *name, int append)
3087 {
3088 int save_emsg;
3089 int err;
3090 typval_T tv;
3091
3092 // Catch a bad name early.
3093 if (!eval_isnamec1(*name))
3094 {
3095 emsg(_(e_invarg));
3096 return FAIL;
3097 }
3098
3099 // Make a copy of the name, it is used in redir_lval until redir ends.
3100 redir_varname = vim_strsave(name);
3101 if (redir_varname == NULL)
3102 return FAIL;
3103
3104 redir_lval = ALLOC_CLEAR_ONE(lval_T);
3105 if (redir_lval == NULL)
3106 {
3107 var_redir_stop();
3108 return FAIL;
3109 }
3110
3111 // The output is stored in growarray "redir_ga" until redirection ends.
3112 ga_init2(&redir_ga, (int)sizeof(char), 500);
3113
3114 // Parse the variable name (can be a dict or list entry).
3115 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
3116 FNE_CHECK_START);
3117 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
3118 {
3119 clear_lval(redir_lval);
3120 if (redir_endp != NULL && *redir_endp != NUL)
3121 // Trailing characters are present after the variable name
3122 emsg(_(e_trailing));
3123 else
3124 emsg(_(e_invarg));
3125 redir_endp = NULL; // don't store a value, only cleanup
3126 var_redir_stop();
3127 return FAIL;
3128 }
3129
3130 // check if we can write to the variable: set it to or append an empty
3131 // string
3132 save_emsg = did_emsg;
3133 did_emsg = FALSE;
3134 tv.v_type = VAR_STRING;
3135 tv.vval.v_string = (char_u *)"";
3136 if (append)
3137 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)".");
3138 else
3139 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"=");
3140 clear_lval(redir_lval);
3141 err = did_emsg;
3142 did_emsg |= save_emsg;
3143 if (err)
3144 {
3145 redir_endp = NULL; // don't store a value, only cleanup
3146 var_redir_stop();
3147 return FAIL;
3148 }
3149
3150 return OK;
3151 }
3152
3153 /*
3154 * Append "value[value_len]" to the variable set by var_redir_start().
3155 * The actual appending is postponed until redirection ends, because the value
3156 * appended may in fact be the string we write to, changing it may cause freed
3157 * memory to be used:
3158 * :redir => foo
3159 * :let foo
3160 * :redir END
3161 */
3162 void
3163 var_redir_str(char_u *value, int value_len)
3164 {
3165 int len;
3166
3167 if (redir_lval == NULL)
3168 return;
3169
3170 if (value_len == -1)
3171 len = (int)STRLEN(value); // Append the entire string
3172 else
3173 len = value_len; // Append only "value_len" characters
3174
3175 if (ga_grow(&redir_ga, len) == OK)
3176 {
3177 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
3178 redir_ga.ga_len += len;
3179 }
3180 else
3181 var_redir_stop();
3182 }
3183
3184 /*
3185 * Stop redirecting command output to a variable.
3186 * Frees the allocated memory.
3187 */
3188 void
3189 var_redir_stop(void)
3190 {
3191 typval_T tv;
3192
3193 if (EVALCMD_BUSY)
3194 {
3195 redir_lval = NULL;
3196 return;
3197 }
3198
3199 if (redir_lval != NULL)
3200 {
3201 // If there was no error: assign the text to the variable.
3202 if (redir_endp != NULL)
3203 {
3204 ga_append(&redir_ga, NUL); // Append the trailing NUL.
3205 tv.v_type = VAR_STRING;
3206 tv.vval.v_string = redir_ga.ga_data;
3207 // Call get_lval() again, if it's inside a Dict or List it may
3208 // have changed.
3209 redir_endp = get_lval(redir_varname, NULL, redir_lval,
3210 FALSE, FALSE, 0, FNE_CHECK_START);
3211 if (redir_endp != NULL && redir_lval->ll_name != NULL)
3212 set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE,
3213 (char_u *)".");
3214 clear_lval(redir_lval);
3215 }
3216
3217 // free the collected output
3218 VIM_CLEAR(redir_ga.ga_data);
3219
3220 VIM_CLEAR(redir_lval);
3221 }
3222 VIM_CLEAR(redir_varname);
3223 }
3224
2856 /* 3225 /*
2857 * "gettabvar()" function 3226 * "gettabvar()" function
2858 */ 3227 */
2859 void 3228 void
2860 f_gettabvar(typval_T *argvars, typval_T *rettv) 3229 f_gettabvar(typval_T *argvars, typval_T *rettv)