1/* vi:set ts=8 sts=4 sw=4: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10/* 11 * eval.c: Expression evaluation. 12 */ 13#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64) 14# include "vimio.h" /* for mch_open(), must be before vim.h */ 15#endif 16 17#include "vim.h" 18 19#if defined(FEAT_EVAL) || defined(PROTO) 20 21#ifdef AMIGA 22# include <time.h> /* for strftime() */ 23#endif 24 25#ifdef VMS 26# include <float.h> 27#endif 28 29#ifdef MACOS 30# include <time.h> /* for time_t */ 31#endif 32 33#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) 34# include <math.h> 35#endif 36 37#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 38 39#define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not 40 be freed. */ 41 42/* 43 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 44 * This avoids adding a pointer to the hashtab item. 45 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 46 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 47 * HI2DI() converts a hashitem pointer to a dictitem pointer. 48 */ 49static dictitem_T dumdi; 50#define DI2HIKEY(di) ((di)->di_key) 51#define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 52#define HI2DI(hi) HIKEY2DI((hi)->hi_key) 53 54/* 55 * Structure returned by get_lval() and used by set_var_lval(). 56 * For a plain name: 57 * "name" points to the variable name. 58 * "exp_name" is NULL. 59 * "tv" is NULL 60 * For a magic braces name: 61 * "name" points to the expanded variable name. 62 * "exp_name" is non-NULL, to be freed later. 63 * "tv" is NULL 64 * For an index in a list: 65 * "name" points to the (expanded) variable name. 66 * "exp_name" NULL or non-NULL, to be freed later. 67 * "tv" points to the (first) list item value 68 * "li" points to the (first) list item 69 * "range", "n1", "n2" and "empty2" indicate what items are used. 70 * For an existing Dict item: 71 * "name" points to the (expanded) variable name. 72 * "exp_name" NULL or non-NULL, to be freed later. 73 * "tv" points to the dict item value 74 * "newkey" is NULL 75 * For a non-existing Dict item: 76 * "name" points to the (expanded) variable name. 77 * "exp_name" NULL or non-NULL, to be freed later. 78 * "tv" points to the Dictionary typval_T 79 * "newkey" is the key for the new item. 80 */ 81typedef struct lval_S 82{ 83 char_u *ll_name; /* start of variable name (can be NULL) */ 84 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 85 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 86 isn't NULL it's the Dict to which to add 87 the item. */ 88 listitem_T *ll_li; /* The list item or NULL. */ 89 list_T *ll_list; /* The list or NULL. */ 90 int ll_range; /* TRUE when a [i:j] range was used */ 91 long ll_n1; /* First index for list */ 92 long ll_n2; /* Second index for list range */ 93 int ll_empty2; /* Second index is empty: [i:] */ 94 dict_T *ll_dict; /* The Dictionary or NULL */ 95 dictitem_T *ll_di; /* The dictitem or NULL */ 96 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 97} lval_T; 98 99 100static char *e_letunexp = N_("E18: Unexpected characters in :let"); 101static char *e_listidx = N_("E684: list index out of range: %ld"); 102static char *e_undefvar = N_("E121: Undefined variable: %s"); 103static char *e_missbrac = N_("E111: Missing ']'"); 104static char *e_listarg = N_("E686: Argument of %s must be a List"); 105static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 106static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 107static char *e_listreq = N_("E714: List required"); 108static char *e_dictreq = N_("E715: Dictionary required"); 109static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 110static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 111static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 112static char *e_funcdict = N_("E717: Dictionary entry already exists"); 113static char *e_funcref = N_("E718: Funcref required"); 114static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 115static char *e_letwrong = N_("E734: Wrong variable type for %s="); 116static char *e_nofunc = N_("E130: Unknown function: %s"); 117static char *e_illvar = N_("E461: Illegal variable name: %s"); 118 119/* 120 * All user-defined global variables are stored in dictionary "globvardict". 121 * "globvars_var" is the variable that is used for "g:". 122 */ 123static dict_T globvardict; 124static dictitem_T globvars_var; 125#define globvarht globvardict.dv_hashtab 126 127/* 128 * Old Vim variables such as "v:version" are also available without the "v:". 129 * Also in functions. We need a special hashtable for them. 130 */ 131static hashtab_T compat_hashtab; 132 133/* When using exists() don't auto-load a script. */ 134static int no_autoload = FALSE; 135 136/* 137 * When recursively copying lists and dicts we need to remember which ones we 138 * have done to avoid endless recursiveness. This unique ID is used for that. 139 * The last bit is used for previous_funccal, ignored when comparing. 140 */ 141static int current_copyID = 0; 142#define COPYID_INC 2 143#define COPYID_MASK (~0x1) 144 145/* 146 * Array to hold the hashtab with variables local to each sourced script. 147 * Each item holds a variable (nameless) that points to the dict_T. 148 */ 149typedef struct 150{ 151 dictitem_T sv_var; 152 dict_T sv_dict; 153} scriptvar_T; 154 155static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; 156#define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) 157#define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) 158 159static int echo_attr = 0; /* attributes used for ":echo" */ 160 161/* Values for trans_function_name() argument: */ 162#define TFN_INT 1 /* internal function name OK */ 163#define TFN_QUIET 2 /* no error messages */ 164 165/* 166 * Structure to hold info for a user function. 167 */ 168typedef struct ufunc ufunc_T; 169 170struct ufunc 171{ 172 int uf_varargs; /* variable nr of arguments */ 173 int uf_flags; 174 int uf_calls; /* nr of active calls */ 175 garray_T uf_args; /* arguments */ 176 garray_T uf_lines; /* function lines */ 177#ifdef FEAT_PROFILE 178 int uf_profiling; /* TRUE when func is being profiled */ 179 /* profiling the function as a whole */ 180 int uf_tm_count; /* nr of calls */ 181 proftime_T uf_tm_total; /* time spent in function + children */ 182 proftime_T uf_tm_self; /* time spent in function itself */ 183 proftime_T uf_tm_children; /* time spent in children this call */ 184 /* profiling the function per line */ 185 int *uf_tml_count; /* nr of times line was executed */ 186 proftime_T *uf_tml_total; /* time spent in a line + children */ 187 proftime_T *uf_tml_self; /* time spent in a line itself */ 188 proftime_T uf_tml_start; /* start time for current line */ 189 proftime_T uf_tml_children; /* time spent in children for this line */ 190 proftime_T uf_tml_wait; /* start wait time for current line */ 191 int uf_tml_idx; /* index of line being timed; -1 if none */ 192 int uf_tml_execed; /* line being timed was executed */ 193#endif 194 scid_T uf_script_ID; /* ID of script where function was defined, 195 used for s: variables */ 196 int uf_refcount; /* for numbered function: reference count */ 197 char_u uf_name[1]; /* name of function (actually longer); can 198 start with <SNR>123_ (<SNR> is K_SPECIAL 199 KS_EXTRA KE_SNR) */ 200}; 201 202/* function flags */ 203#define FC_ABORT 1 /* abort function on error */ 204#define FC_RANGE 2 /* function accepts range */ 205#define FC_DICT 4 /* Dict function, uses "self" */ 206 207/* 208 * All user-defined functions are found in this hashtable. 209 */ 210static hashtab_T func_hashtab; 211 212/* The names of packages that once were loaded are remembered. */ 213static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 214 215/* list heads for garbage collection */ 216static dict_T *first_dict = NULL; /* list of all dicts */ 217static list_T *first_list = NULL; /* list of all lists */ 218 219/* From user function to hashitem and back. */ 220static ufunc_T dumuf; 221#define UF2HIKEY(fp) ((fp)->uf_name) 222#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 223#define HI2UF(hi) HIKEY2UF((hi)->hi_key) 224 225#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 226#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 227 228#define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 229#define VAR_SHORT_LEN 20 /* short variable name length */ 230#define FIXVAR_CNT 12 /* number of fixed variables */ 231 232/* structure to hold info for a function that is currently being executed. */ 233typedef struct funccall_S funccall_T; 234 235struct funccall_S 236{ 237 ufunc_T *func; /* function being called */ 238 int linenr; /* next line to be executed */ 239 int returned; /* ":return" used */ 240 struct /* fixed variables for arguments */ 241 { 242 dictitem_T var; /* variable (without room for name) */ 243 char_u room[VAR_SHORT_LEN]; /* room for the name */ 244 } fixvar[FIXVAR_CNT]; 245 dict_T l_vars; /* l: local function variables */ 246 dictitem_T l_vars_var; /* variable for l: scope */ 247 dict_T l_avars; /* a: argument variables */ 248 dictitem_T l_avars_var; /* variable for a: scope */ 249 list_T l_varlist; /* list for a:000 */ 250 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 251 typval_T *rettv; /* return value */ 252 linenr_T breakpoint; /* next line with breakpoint or zero */ 253 int dbg_tick; /* debug_tick when breakpoint was set */ 254 int level; /* top nesting level of executed function */ 255#ifdef FEAT_PROFILE 256 proftime_T prof_child; /* time spent in a child */ 257#endif 258 funccall_T *caller; /* calling function or NULL */ 259}; 260 261/* 262 * Info used by a ":for" loop. 263 */ 264typedef struct 265{ 266 int fi_semicolon; /* TRUE if ending in '; var]' */ 267 int fi_varcount; /* nr of variables in the list */ 268 listwatch_T fi_lw; /* keep an eye on the item used. */ 269 list_T *fi_list; /* list being used */ 270} forinfo_T; 271 272/* 273 * Struct used by trans_function_name() 274 */ 275typedef struct 276{ 277 dict_T *fd_dict; /* Dictionary used */ 278 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 279 dictitem_T *fd_di; /* Dictionary item used */ 280} funcdict_T; 281 282 283/* 284 * Array to hold the value of v: variables. 285 * The value is in a dictitem, so that it can also be used in the v: scope. 286 * The reason to use this table anyway is for very quick access to the 287 * variables with the VV_ defines. 288 */ 289#include "version.h" 290 291/* values for vv_flags: */ 292#define VV_COMPAT 1 /* compatible, also used without "v:" */ 293#define VV_RO 2 /* read-only */ 294#define VV_RO_SBX 4 /* read-only in the sandbox */ 295 296#define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}, {0} 297 298static struct vimvar 299{ 300 char *vv_name; /* name of variable, without v: */ 301 dictitem_T vv_di; /* value and name for key */ 302 char vv_filler[16]; /* space for LONGEST name below!!! */ 303 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 304} vimvars[VV_LEN] = 305{ 306 /* 307 * The order here must match the VV_ defines in vim.h! 308 * Initializing a union does not work, leave tv.vval empty to get zero's. 309 */ 310 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 311 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 312 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 313 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 314 {VV_NAME("warningmsg", VAR_STRING), 0}, 315 {VV_NAME("statusmsg", VAR_STRING), 0}, 316 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 317 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 318 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 319 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 320 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 321 {VV_NAME("fname", VAR_STRING), VV_RO}, 322 {VV_NAME("lang", VAR_STRING), VV_RO}, 323 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 324 {VV_NAME("ctype", VAR_STRING), VV_RO}, 325 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 326 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 327 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 328 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 329 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 330 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 331 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 332 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 333 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 334 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 335 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 336 {VV_NAME("progname", VAR_STRING), VV_RO}, 337 {VV_NAME("servername", VAR_STRING), VV_RO}, 338 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 339 {VV_NAME("exception", VAR_STRING), VV_RO}, 340 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 341 {VV_NAME("register", VAR_STRING), VV_RO}, 342 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 343 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 344 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 345 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 346 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 347 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 348 {VV_NAME("fcs_choice", VAR_STRING), 0}, 349 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 350 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 351 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 352 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 353 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 354 {VV_NAME("scrollstart", VAR_STRING), 0}, 355 {VV_NAME("swapname", VAR_STRING), VV_RO}, 356 {VV_NAME("swapchoice", VAR_STRING), 0}, 357 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 358 {VV_NAME("char", VAR_STRING), VV_RO}, 359 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 360 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 361 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 362 {VV_NAME("operator", VAR_STRING), VV_RO}, 363 {VV_NAME("searchforward", VAR_NUMBER), 0}, 364 {VV_NAME("oldfiles", VAR_LIST), 0}, 365}; 366 367/* shorthand */ 368#define vv_type vv_di.di_tv.v_type 369#define vv_nr vv_di.di_tv.vval.v_number 370#define vv_float vv_di.di_tv.vval.v_float 371#define vv_str vv_di.di_tv.vval.v_string 372#define vv_list vv_di.di_tv.vval.v_list 373#define vv_tv vv_di.di_tv 374 375/* 376 * The v: variables are stored in dictionary "vimvardict". 377 * "vimvars_var" is the variable that is used for the "l:" scope. 378 */ 379static dict_T vimvardict; 380static dictitem_T vimvars_var; 381#define vimvarht vimvardict.dv_hashtab 382 383static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 384static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 385#if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 386static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 387#endif 388static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 389static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 390static char_u *skip_var_one __ARGS((char_u *arg)); 391static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first)); 392static void list_glob_vars __ARGS((int *first)); 393static void list_buf_vars __ARGS((int *first)); 394static void list_win_vars __ARGS((int *first)); 395#ifdef FEAT_WINDOWS 396static void list_tab_vars __ARGS((int *first)); 397#endif 398static void list_vim_vars __ARGS((int *first)); 399static void list_script_vars __ARGS((int *first)); 400static void list_func_vars __ARGS((int *first)); 401static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); 402static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 403static int check_changedtick __ARGS((char_u *arg)); 404static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 405static void clear_lval __ARGS((lval_T *lp)); 406static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 407static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 408static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 409static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 410static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 411static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 412static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 413static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 414static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 415static int tv_islocked __ARGS((typval_T *tv)); 416 417static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 418static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 419static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 420static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 421static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 422static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 423static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 424static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate, int want_string)); 425 426static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 427static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 428static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 429static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 430static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 431static int rettv_list_alloc __ARGS((typval_T *rettv)); 432static listitem_T *listitem_alloc __ARGS((void)); 433static void listitem_free __ARGS((listitem_T *item)); 434static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 435static long list_len __ARGS((list_T *l)); 436static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 437static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 438static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 439static listitem_T *list_find __ARGS((list_T *l, long n)); 440static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 441static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 442static void list_append __ARGS((list_T *l, listitem_T *item)); 443static int list_append_number __ARGS((list_T *l, varnumber_T n)); 444static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 445static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 446static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 447static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 448static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 449static char_u *list2string __ARGS((typval_T *tv, int copyID)); 450static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 451static int free_unref_items __ARGS((int copyID)); 452static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 453static void set_ref_in_list __ARGS((list_T *l, int copyID)); 454static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 455static int rettv_dict_alloc __ARGS((typval_T *rettv)); 456static void dict_unref __ARGS((dict_T *d)); 457static void dict_free __ARGS((dict_T *d, int recurse)); 458static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 459static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 460static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 461static long dict_len __ARGS((dict_T *d)); 462static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 463static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 464static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 465static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 466static char_u *string_quote __ARGS((char_u *str, int function)); 467#ifdef FEAT_FLOAT 468static int string2float __ARGS((char_u *text, float_T *value)); 469#endif 470static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 471static int find_internal_func __ARGS((char_u *name)); 472static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 473static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 474static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 475static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 476static int non_zero_arg __ARGS((typval_T *argvars)); 477 478#ifdef FEAT_FLOAT 479static void f_abs __ARGS((typval_T *argvars, typval_T *rettv)); 480static void f_acos __ARGS((typval_T *argvars, typval_T *rettv)); 481#endif 482static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 483static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 484static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 485static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 486static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 487#ifdef FEAT_FLOAT 488static void f_asin __ARGS((typval_T *argvars, typval_T *rettv)); 489static void f_atan __ARGS((typval_T *argvars, typval_T *rettv)); 490static void f_atan2 __ARGS((typval_T *argvars, typval_T *rettv)); 491#endif 492static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 493static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 494static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 495static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 496static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 497static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 498static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 499static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 500static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 501static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 502static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 503#ifdef FEAT_FLOAT 504static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); 505#endif 506static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 507static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 508static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 509static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv)); 510static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 511#if defined(FEAT_INS_EXPAND) 512static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 513static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 514static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 515#endif 516static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 517static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 518#ifdef FEAT_FLOAT 519static void f_cos __ARGS((typval_T *argvars, typval_T *rettv)); 520static void f_cosh __ARGS((typval_T *argvars, typval_T *rettv)); 521#endif 522static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 523static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 524static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 525static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 526static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 527static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 528static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 529static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 530static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 531static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 532static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 533static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 534static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 535static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 536#ifdef FEAT_FLOAT 537static void f_exp __ARGS((typval_T *argvars, typval_T *rettv)); 538#endif 539static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 540static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 541static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 542static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 543static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 544static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 545static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 546static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 547#ifdef FEAT_FLOAT 548static void f_float2nr __ARGS((typval_T *argvars, typval_T *rettv)); 549static void f_floor __ARGS((typval_T *argvars, typval_T *rettv)); 550static void f_fmod __ARGS((typval_T *argvars, typval_T *rettv)); 551#endif 552static void f_fnameescape __ARGS((typval_T *argvars, typval_T *rettv)); 553static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 554static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 555static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 556static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 557static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 558static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 559static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 560static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 561static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 562static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 563static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 564static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 565static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 566static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 567static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 568static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 569static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 570static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 571static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 572static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 573static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 574static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 575static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 576static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 577static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv)); 578static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv)); 579static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 580static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 581static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 582static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 583static void f_gettabvar __ARGS((typval_T *argvars, typval_T *rettv)); 584static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 585static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 586static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 587static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 588static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 589static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 590static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 591static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 592static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 593static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 594static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 595static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 596static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 597static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 598static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 599static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 600static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 601static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 602static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 603static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 604static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 605static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 606static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 607static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 608static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 609static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 610static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 611static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 612static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 613static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 614static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 615static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 616static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 617static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 618static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 619static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 620static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 621static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 622static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 623static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 624#ifdef FEAT_FLOAT 625static void f_log __ARGS((typval_T *argvars, typval_T *rettv)); 626static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv)); 627#endif 628static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 629static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 630static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 631static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 632static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv)); 633static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 634static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv)); 635static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 636static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 637static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 638static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 639static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 640#ifdef vim_mkdir 641static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 642#endif 643static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 644#ifdef FEAT_MZSCHEME 645static void f_mzeval __ARGS((typval_T *argvars, typval_T *rettv)); 646#endif 647static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 648static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 649static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 650#ifdef FEAT_FLOAT 651static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); 652#endif 653static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 654static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 655static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 656static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 657static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 658static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 659static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 660static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 661static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 662static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 663static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 664static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 665static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 666static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 667static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 668static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 669static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 670#ifdef FEAT_FLOAT 671static void f_round __ARGS((typval_T *argvars, typval_T *rettv)); 672#endif 673static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 674static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 675static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 676static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 677static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 678static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 679static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 680static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 681static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 682static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 683static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 684static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv)); 685static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 686static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 687static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 688static void f_settabvar __ARGS((typval_T *argvars, typval_T *rettv)); 689static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 690static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 691static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 692static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 693#ifdef FEAT_FLOAT 694static void f_sin __ARGS((typval_T *argvars, typval_T *rettv)); 695static void f_sinh __ARGS((typval_T *argvars, typval_T *rettv)); 696#endif 697static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 698static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 699static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 700static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 701static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 702#ifdef FEAT_FLOAT 703static void f_sqrt __ARGS((typval_T *argvars, typval_T *rettv)); 704static void f_str2float __ARGS((typval_T *argvars, typval_T *rettv)); 705#endif 706static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 707static void f_strchars __ARGS((typval_T *argvars, typval_T *rettv)); 708#ifdef HAVE_STRFTIME 709static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 710#endif 711static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 712static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 713static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 714static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 715static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 716static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 717static void f_strdisplaywidth __ARGS((typval_T *argvars, typval_T *rettv)); 718static void f_strwidth __ARGS((typval_T *argvars, typval_T *rettv)); 719static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 720static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 721static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 722static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 723static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 724static void f_synstack __ARGS((typval_T *argvars, typval_T *rettv)); 725static void f_synconcealed __ARGS((typval_T *argvars, typval_T *rettv)); 726static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 727static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 728static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 729static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 730static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 731static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 732static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 733static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 734#ifdef FEAT_FLOAT 735static void f_tan __ARGS((typval_T *argvars, typval_T *rettv)); 736static void f_tanh __ARGS((typval_T *argvars, typval_T *rettv)); 737#endif 738static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 739static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 740static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 741#ifdef FEAT_FLOAT 742static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv)); 743#endif 744static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 745static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv)); 746static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv)); 747static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 748static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 749static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 750static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 751static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 752static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 753static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 754static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 755static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 756static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 757static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 758static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 759static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 760 761static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 762static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); 763static int get_env_len __ARGS((char_u **arg)); 764static int get_id_len __ARGS((char_u **arg)); 765static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 766static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 767#define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 768#define FNE_CHECK_START 2 /* find_name_end(): check name starts with 769 valid character */ 770static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 771static int eval_isnamec __ARGS((int c)); 772static int eval_isnamec1 __ARGS((int c)); 773static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 774static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 775static typval_T *alloc_tv __ARGS((void)); 776static typval_T *alloc_string_tv __ARGS((char_u *string)); 777static void init_tv __ARGS((typval_T *varp)); 778static long get_tv_number __ARGS((typval_T *varp)); 779static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 780static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 781static char_u *get_tv_string __ARGS((typval_T *varp)); 782static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 783static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 784static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 785static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 786static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 787static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 788static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 789static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first)); 790static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first)); 791static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 792static int var_check_ro __ARGS((int flags, char_u *name)); 793static int var_check_fixed __ARGS((int flags, char_u *name)); 794static int tv_check_lock __ARGS((int lock, char_u *name)); 795static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 796static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 797static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 798static int eval_fname_script __ARGS((char_u *p)); 799static int eval_fname_sid __ARGS((char_u *p)); 800static void list_func_head __ARGS((ufunc_T *fp, int indent)); 801static ufunc_T *find_func __ARGS((char_u *name)); 802static int function_exists __ARGS((char_u *name)); 803static int builtin_function __ARGS((char_u *name)); 804#ifdef FEAT_PROFILE 805static void func_do_profile __ARGS((ufunc_T *fp)); 806static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 807static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 808static int 809# ifdef __BORLANDC__ 810 _RTLENTRYF 811# endif 812 prof_total_cmp __ARGS((const void *s1, const void *s2)); 813static int 814# ifdef __BORLANDC__ 815 _RTLENTRYF 816# endif 817 prof_self_cmp __ARGS((const void *s1, const void *s2)); 818#endif 819static int script_autoload __ARGS((char_u *name, int reload)); 820static char_u *autoload_name __ARGS((char_u *name)); 821static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 822static void func_free __ARGS((ufunc_T *fp)); 823static void func_unref __ARGS((char_u *name)); 824static void func_ref __ARGS((char_u *name)); 825static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict)); 826static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; 827static void free_funccal __ARGS((funccall_T *fc, int free_val)); 828static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 829static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 830static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 831static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 832static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 833static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 834 835 836#ifdef EBCDIC 837static int compare_func_name __ARGS((const void *s1, const void *s2)); 838static void sortFunctions __ARGS(()); 839#endif 840 841 842/* Character used as separated in autoload function/variable names. */ 843#define AUTOLOAD_CHAR '#' 844 845/* 846 * Initialize the global and v: variables. 847 */ 848 void 849eval_init() 850{ 851 int i; 852 struct vimvar *p; 853 854 init_var_dict(&globvardict, &globvars_var); 855 init_var_dict(&vimvardict, &vimvars_var); 856 hash_init(&compat_hashtab); 857 hash_init(&func_hashtab); 858 859 for (i = 0; i < VV_LEN; ++i) 860 { 861 p = &vimvars[i]; 862 STRCPY(p->vv_di.di_key, p->vv_name); 863 if (p->vv_flags & VV_RO) 864 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 865 else if (p->vv_flags & VV_RO_SBX) 866 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 867 else 868 p->vv_di.di_flags = DI_FLAGS_FIX; 869 870 /* add to v: scope dict, unless the value is not always available */ 871 if (p->vv_type != VAR_UNKNOWN) 872 hash_add(&vimvarht, p->vv_di.di_key); 873 if (p->vv_flags & VV_COMPAT) 874 /* add to compat scope dict */ 875 hash_add(&compat_hashtab, p->vv_di.di_key); 876 } 877 set_vim_var_nr(VV_SEARCHFORWARD, 1L); 878 879#ifdef EBCDIC 880 /* 881 * Sort the function table, to enable binary sort. 882 */ 883 sortFunctions(); 884#endif 885} 886 887#if defined(EXITFREE) || defined(PROTO) 888 void 889eval_clear() 890{ 891 int i; 892 struct vimvar *p; 893 894 for (i = 0; i < VV_LEN; ++i) 895 { 896 p = &vimvars[i]; 897 if (p->vv_di.di_tv.v_type == VAR_STRING) 898 { 899 vim_free(p->vv_str); 900 p->vv_str = NULL; 901 } 902 else if (p->vv_di.di_tv.v_type == VAR_LIST) 903 { 904 list_unref(p->vv_list); 905 p->vv_list = NULL; 906 } 907 } 908 hash_clear(&vimvarht); 909 hash_init(&vimvarht); /* garbage_collect() will access it */ 910 hash_clear(&compat_hashtab); 911 912 free_scriptnames(); 913 914 /* global variables */ 915 vars_clear(&globvarht); 916 917 /* autoloaded script names */ 918 ga_clear_strings(&ga_loaded); 919 920 /* script-local variables */ 921 for (i = 1; i <= ga_scripts.ga_len; ++i) 922 { 923 vars_clear(&SCRIPT_VARS(i)); 924 vim_free(SCRIPT_SV(i)); 925 } 926 ga_clear(&ga_scripts); 927 928 /* unreferenced lists and dicts */ 929 (void)garbage_collect(); 930 931 /* functions */ 932 free_all_functions(); 933 hash_clear(&func_hashtab); 934} 935#endif 936 937/* 938 * Return the name of the executed function. 939 */ 940 char_u * 941func_name(cookie) 942 void *cookie; 943{ 944 return ((funccall_T *)cookie)->func->uf_name; 945} 946 947/* 948 * Return the address holding the next breakpoint line for a funccall cookie. 949 */ 950 linenr_T * 951func_breakpoint(cookie) 952 void *cookie; 953{ 954 return &((funccall_T *)cookie)->breakpoint; 955} 956 957/* 958 * Return the address holding the debug tick for a funccall cookie. 959 */ 960 int * 961func_dbg_tick(cookie) 962 void *cookie; 963{ 964 return &((funccall_T *)cookie)->dbg_tick; 965} 966 967/* 968 * Return the nesting level for a funccall cookie. 969 */ 970 int 971func_level(cookie) 972 void *cookie; 973{ 974 return ((funccall_T *)cookie)->level; 975} 976 977/* pointer to funccal for currently active function */ 978funccall_T *current_funccal = NULL; 979 980/* pointer to list of previously used funccal, still around because some 981 * item in it is still being used. */ 982funccall_T *previous_funccal = NULL; 983 984/* 985 * Return TRUE when a function was ended by a ":return" command. 986 */ 987 int 988current_func_returned() 989{ 990 return current_funccal->returned; 991} 992 993 994/* 995 * Set an internal variable to a string value. Creates the variable if it does 996 * not already exist. 997 */ 998 void 999set_internal_string_var(name, value) 1000 char_u *name; 1001 char_u *value; 1002{ 1003 char_u *val; 1004 typval_T *tvp; 1005 1006 val = vim_strsave(value); 1007 if (val != NULL) 1008 { 1009 tvp = alloc_string_tv(val); 1010 if (tvp != NULL) 1011 { 1012 set_var(name, tvp, FALSE); 1013 free_tv(tvp); 1014 } 1015 } 1016} 1017 1018static lval_T *redir_lval = NULL; 1019static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 1020static char_u *redir_endp = NULL; 1021static char_u *redir_varname = NULL; 1022 1023/* 1024 * Start recording command output to a variable 1025 * Returns OK if successfully completed the setup. FAIL otherwise. 1026 */ 1027 int 1028var_redir_start(name, append) 1029 char_u *name; 1030 int append; /* append to an existing variable */ 1031{ 1032 int save_emsg; 1033 int err; 1034 typval_T tv; 1035 1036 /* Catch a bad name early. */ 1037 if (!eval_isnamec1(*name)) 1038 { 1039 EMSG(_(e_invarg)); 1040 return FAIL; 1041 } 1042 1043 /* Make a copy of the name, it is used in redir_lval until redir ends. */ 1044 redir_varname = vim_strsave(name); 1045 if (redir_varname == NULL) 1046 return FAIL; 1047 1048 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 1049 if (redir_lval == NULL) 1050 { 1051 var_redir_stop(); 1052 return FAIL; 1053 } 1054 1055 /* The output is stored in growarray "redir_ga" until redirection ends. */ 1056 ga_init2(&redir_ga, (int)sizeof(char), 500); 1057 1058 /* Parse the variable name (can be a dict or list entry). */ 1059 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 1060 FNE_CHECK_START); 1061 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 1062 { 1063 clear_lval(redir_lval); 1064 if (redir_endp != NULL && *redir_endp != NUL) 1065 /* Trailing characters are present after the variable name */ 1066 EMSG(_(e_trailing)); 1067 else 1068 EMSG(_(e_invarg)); 1069 redir_endp = NULL; /* don't store a value, only cleanup */ 1070 var_redir_stop(); 1071 return FAIL; 1072 } 1073 1074 /* check if we can write to the variable: set it to or append an empty 1075 * string */ 1076 save_emsg = did_emsg; 1077 did_emsg = FALSE; 1078 tv.v_type = VAR_STRING; 1079 tv.vval.v_string = (char_u *)""; 1080 if (append) 1081 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 1082 else 1083 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 1084 clear_lval(redir_lval); 1085 err = did_emsg; 1086 did_emsg |= save_emsg; 1087 if (err) 1088 { 1089 redir_endp = NULL; /* don't store a value, only cleanup */ 1090 var_redir_stop(); 1091 return FAIL; 1092 } 1093 1094 return OK; 1095} 1096 1097/* 1098 * Append "value[value_len]" to the variable set by var_redir_start(). 1099 * The actual appending is postponed until redirection ends, because the value 1100 * appended may in fact be the string we write to, changing it may cause freed 1101 * memory to be used: 1102 * :redir => foo 1103 * :let foo 1104 * :redir END 1105 */ 1106 void 1107var_redir_str(value, value_len) 1108 char_u *value; 1109 int value_len; 1110{ 1111 int len; 1112 1113 if (redir_lval == NULL) 1114 return; 1115 1116 if (value_len == -1) 1117 len = (int)STRLEN(value); /* Append the entire string */ 1118 else 1119 len = value_len; /* Append only "value_len" characters */ 1120 1121 if (ga_grow(&redir_ga, len) == OK) 1122 { 1123 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1124 redir_ga.ga_len += len; 1125 } 1126 else 1127 var_redir_stop(); 1128} 1129 1130/* 1131 * Stop redirecting command output to a variable. 1132 * Frees the allocated memory. 1133 */ 1134 void 1135var_redir_stop() 1136{ 1137 typval_T tv; 1138 1139 if (redir_lval != NULL) 1140 { 1141 /* If there was no error: assign the text to the variable. */ 1142 if (redir_endp != NULL) 1143 { 1144 ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ 1145 tv.v_type = VAR_STRING; 1146 tv.vval.v_string = redir_ga.ga_data; 1147 /* Call get_lval() again, if it's inside a Dict or List it may 1148 * have changed. */ 1149 redir_endp = get_lval(redir_varname, NULL, redir_lval, 1150 FALSE, FALSE, FALSE, FNE_CHECK_START); 1151 if (redir_endp != NULL && redir_lval->ll_name != NULL) 1152 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1153 clear_lval(redir_lval); 1154 } 1155 1156 /* free the collected output */ 1157 vim_free(redir_ga.ga_data); 1158 redir_ga.ga_data = NULL; 1159 1160 vim_free(redir_lval); 1161 redir_lval = NULL; 1162 } 1163 vim_free(redir_varname); 1164 redir_varname = NULL; 1165} 1166 1167# if defined(FEAT_MBYTE) || defined(PROTO) 1168 int 1169eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1170 char_u *enc_from; 1171 char_u *enc_to; 1172 char_u *fname_from; 1173 char_u *fname_to; 1174{ 1175 int err = FALSE; 1176 1177 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1178 set_vim_var_string(VV_CC_TO, enc_to, -1); 1179 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1180 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1181 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1182 err = TRUE; 1183 set_vim_var_string(VV_CC_FROM, NULL, -1); 1184 set_vim_var_string(VV_CC_TO, NULL, -1); 1185 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1186 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1187 1188 if (err) 1189 return FAIL; 1190 return OK; 1191} 1192# endif 1193 1194# if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1195 int 1196eval_printexpr(fname, args) 1197 char_u *fname; 1198 char_u *args; 1199{ 1200 int err = FALSE; 1201 1202 set_vim_var_string(VV_FNAME_IN, fname, -1); 1203 set_vim_var_string(VV_CMDARG, args, -1); 1204 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1205 err = TRUE; 1206 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1207 set_vim_var_string(VV_CMDARG, NULL, -1); 1208 1209 if (err) 1210 { 1211 mch_remove(fname); 1212 return FAIL; 1213 } 1214 return OK; 1215} 1216# endif 1217 1218# if defined(FEAT_DIFF) || defined(PROTO) 1219 void 1220eval_diff(origfile, newfile, outfile) 1221 char_u *origfile; 1222 char_u *newfile; 1223 char_u *outfile; 1224{ 1225 int err = FALSE; 1226 1227 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1228 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1229 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1230 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1231 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1232 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1233 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1234} 1235 1236 void 1237eval_patch(origfile, difffile, outfile) 1238 char_u *origfile; 1239 char_u *difffile; 1240 char_u *outfile; 1241{ 1242 int err; 1243 1244 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1245 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1246 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1247 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1248 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1249 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1250 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1251} 1252# endif 1253 1254/* 1255 * Top level evaluation function, returning a boolean. 1256 * Sets "error" to TRUE if there was an error. 1257 * Return TRUE or FALSE. 1258 */ 1259 int 1260eval_to_bool(arg, error, nextcmd, skip) 1261 char_u *arg; 1262 int *error; 1263 char_u **nextcmd; 1264 int skip; /* only parse, don't execute */ 1265{ 1266 typval_T tv; 1267 int retval = FALSE; 1268 1269 if (skip) 1270 ++emsg_skip; 1271 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1272 *error = TRUE; 1273 else 1274 { 1275 *error = FALSE; 1276 if (!skip) 1277 { 1278 retval = (get_tv_number_chk(&tv, error) != 0); 1279 clear_tv(&tv); 1280 } 1281 } 1282 if (skip) 1283 --emsg_skip; 1284 1285 return retval; 1286} 1287 1288/* 1289 * Top level evaluation function, returning a string. If "skip" is TRUE, 1290 * only parsing to "nextcmd" is done, without reporting errors. Return 1291 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1292 */ 1293 char_u * 1294eval_to_string_skip(arg, nextcmd, skip) 1295 char_u *arg; 1296 char_u **nextcmd; 1297 int skip; /* only parse, don't execute */ 1298{ 1299 typval_T tv; 1300 char_u *retval; 1301 1302 if (skip) 1303 ++emsg_skip; 1304 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1305 retval = NULL; 1306 else 1307 { 1308 retval = vim_strsave(get_tv_string(&tv)); 1309 clear_tv(&tv); 1310 } 1311 if (skip) 1312 --emsg_skip; 1313 1314 return retval; 1315} 1316 1317/* 1318 * Skip over an expression at "*pp". 1319 * Return FAIL for an error, OK otherwise. 1320 */ 1321 int 1322skip_expr(pp) 1323 char_u **pp; 1324{ 1325 typval_T rettv; 1326 1327 *pp = skipwhite(*pp); 1328 return eval1(pp, &rettv, FALSE); 1329} 1330 1331/* 1332 * Top level evaluation function, returning a string. 1333 * When "convert" is TRUE convert a List into a sequence of lines and convert 1334 * a Float to a String. 1335 * Return pointer to allocated memory, or NULL for failure. 1336 */ 1337 char_u * 1338eval_to_string(arg, nextcmd, convert) 1339 char_u *arg; 1340 char_u **nextcmd; 1341 int convert; 1342{ 1343 typval_T tv; 1344 char_u *retval; 1345 garray_T ga; 1346#ifdef FEAT_FLOAT 1347 char_u numbuf[NUMBUFLEN]; 1348#endif 1349 1350 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1351 retval = NULL; 1352 else 1353 { 1354 if (convert && tv.v_type == VAR_LIST) 1355 { 1356 ga_init2(&ga, (int)sizeof(char), 80); 1357 if (tv.vval.v_list != NULL) 1358 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1359 ga_append(&ga, NUL); 1360 retval = (char_u *)ga.ga_data; 1361 } 1362#ifdef FEAT_FLOAT 1363 else if (convert && tv.v_type == VAR_FLOAT) 1364 { 1365 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); 1366 retval = vim_strsave(numbuf); 1367 } 1368#endif 1369 else 1370 retval = vim_strsave(get_tv_string(&tv)); 1371 clear_tv(&tv); 1372 } 1373 1374 return retval; 1375} 1376 1377/* 1378 * Call eval_to_string() without using current local variables and using 1379 * textlock. When "use_sandbox" is TRUE use the sandbox. 1380 */ 1381 char_u * 1382eval_to_string_safe(arg, nextcmd, use_sandbox) 1383 char_u *arg; 1384 char_u **nextcmd; 1385 int use_sandbox; 1386{ 1387 char_u *retval; 1388 void *save_funccalp; 1389 1390 save_funccalp = save_funccal(); 1391 if (use_sandbox) 1392 ++sandbox; 1393 ++textlock; 1394 retval = eval_to_string(arg, nextcmd, FALSE); 1395 if (use_sandbox) 1396 --sandbox; 1397 --textlock; 1398 restore_funccal(save_funccalp); 1399 return retval; 1400} 1401 1402/* 1403 * Top level evaluation function, returning a number. 1404 * Evaluates "expr" silently. 1405 * Returns -1 for an error. 1406 */ 1407 int 1408eval_to_number(expr) 1409 char_u *expr; 1410{ 1411 typval_T rettv; 1412 int retval; 1413 char_u *p = skipwhite(expr); 1414 1415 ++emsg_off; 1416 1417 if (eval1(&p, &rettv, TRUE) == FAIL) 1418 retval = -1; 1419 else 1420 { 1421 retval = get_tv_number_chk(&rettv, NULL); 1422 clear_tv(&rettv); 1423 } 1424 --emsg_off; 1425 1426 return retval; 1427} 1428 1429/* 1430 * Prepare v: variable "idx" to be used. 1431 * Save the current typeval in "save_tv". 1432 * When not used yet add the variable to the v: hashtable. 1433 */ 1434 static void 1435prepare_vimvar(idx, save_tv) 1436 int idx; 1437 typval_T *save_tv; 1438{ 1439 *save_tv = vimvars[idx].vv_tv; 1440 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1441 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1442} 1443 1444/* 1445 * Restore v: variable "idx" to typeval "save_tv". 1446 * When no longer defined, remove the variable from the v: hashtable. 1447 */ 1448 static void 1449restore_vimvar(idx, save_tv) 1450 int idx; 1451 typval_T *save_tv; 1452{ 1453 hashitem_T *hi; 1454 1455 vimvars[idx].vv_tv = *save_tv; 1456 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1457 { 1458 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1459 if (HASHITEM_EMPTY(hi)) 1460 EMSG2(_(e_intern2), "restore_vimvar()"); 1461 else 1462 hash_remove(&vimvarht, hi); 1463 } 1464} 1465 1466#if defined(FEAT_SPELL) || defined(PROTO) 1467/* 1468 * Evaluate an expression to a list with suggestions. 1469 * For the "expr:" part of 'spellsuggest'. 1470 * Returns NULL when there is an error. 1471 */ 1472 list_T * 1473eval_spell_expr(badword, expr) 1474 char_u *badword; 1475 char_u *expr; 1476{ 1477 typval_T save_val; 1478 typval_T rettv; 1479 list_T *list = NULL; 1480 char_u *p = skipwhite(expr); 1481 1482 /* Set "v:val" to the bad word. */ 1483 prepare_vimvar(VV_VAL, &save_val); 1484 vimvars[VV_VAL].vv_type = VAR_STRING; 1485 vimvars[VV_VAL].vv_str = badword; 1486 if (p_verbose == 0) 1487 ++emsg_off; 1488 1489 if (eval1(&p, &rettv, TRUE) == OK) 1490 { 1491 if (rettv.v_type != VAR_LIST) 1492 clear_tv(&rettv); 1493 else 1494 list = rettv.vval.v_list; 1495 } 1496 1497 if (p_verbose == 0) 1498 --emsg_off; 1499 restore_vimvar(VV_VAL, &save_val); 1500 1501 return list; 1502} 1503 1504/* 1505 * "list" is supposed to contain two items: a word and a number. Return the 1506 * word in "pp" and the number as the return value. 1507 * Return -1 if anything isn't right. 1508 * Used to get the good word and score from the eval_spell_expr() result. 1509 */ 1510 int 1511get_spellword(list, pp) 1512 list_T *list; 1513 char_u **pp; 1514{ 1515 listitem_T *li; 1516 1517 li = list->lv_first; 1518 if (li == NULL) 1519 return -1; 1520 *pp = get_tv_string(&li->li_tv); 1521 1522 li = li->li_next; 1523 if (li == NULL) 1524 return -1; 1525 return get_tv_number(&li->li_tv); 1526} 1527#endif 1528 1529/* 1530 * Top level evaluation function. 1531 * Returns an allocated typval_T with the result. 1532 * Returns NULL when there is an error. 1533 */ 1534 typval_T * 1535eval_expr(arg, nextcmd) 1536 char_u *arg; 1537 char_u **nextcmd; 1538{ 1539 typval_T *tv; 1540 1541 tv = (typval_T *)alloc(sizeof(typval_T)); 1542 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1543 { 1544 vim_free(tv); 1545 tv = NULL; 1546 } 1547 1548 return tv; 1549} 1550 1551 1552#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \ 1553 || defined(FEAT_COMPL_FUNC) || defined(PROTO) 1554/* 1555 * Call some vimL function and return the result in "*rettv". 1556 * Uses argv[argc] for the function arguments. Only Number and String 1557 * arguments are currently supported. 1558 * Returns OK or FAIL. 1559 */ 1560 static int 1561call_vim_function(func, argc, argv, safe, rettv) 1562 char_u *func; 1563 int argc; 1564 char_u **argv; 1565 int safe; /* use the sandbox */ 1566 typval_T *rettv; 1567{ 1568 typval_T *argvars; 1569 long n; 1570 int len; 1571 int i; 1572 int doesrange; 1573 void *save_funccalp = NULL; 1574 int ret; 1575 1576 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1577 if (argvars == NULL) 1578 return FAIL; 1579 1580 for (i = 0; i < argc; i++) 1581 { 1582 /* Pass a NULL or empty argument as an empty string */ 1583 if (argv[i] == NULL || *argv[i] == NUL) 1584 { 1585 argvars[i].v_type = VAR_STRING; 1586 argvars[i].vval.v_string = (char_u *)""; 1587 continue; 1588 } 1589 1590 /* Recognize a number argument, the others must be strings. */ 1591 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1592 if (len != 0 && len == (int)STRLEN(argv[i])) 1593 { 1594 argvars[i].v_type = VAR_NUMBER; 1595 argvars[i].vval.v_number = n; 1596 } 1597 else 1598 { 1599 argvars[i].v_type = VAR_STRING; 1600 argvars[i].vval.v_string = argv[i]; 1601 } 1602 } 1603 1604 if (safe) 1605 { 1606 save_funccalp = save_funccal(); 1607 ++sandbox; 1608 } 1609 1610 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1611 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1612 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1613 &doesrange, TRUE, NULL); 1614 if (safe) 1615 { 1616 --sandbox; 1617 restore_funccal(save_funccalp); 1618 } 1619 vim_free(argvars); 1620 1621 if (ret == FAIL) 1622 clear_tv(rettv); 1623 1624 return ret; 1625} 1626 1627# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1628/* 1629 * Call vimL function "func" and return the result as a string. 1630 * Returns NULL when calling the function fails. 1631 * Uses argv[argc] for the function arguments. 1632 */ 1633 void * 1634call_func_retstr(func, argc, argv, safe) 1635 char_u *func; 1636 int argc; 1637 char_u **argv; 1638 int safe; /* use the sandbox */ 1639{ 1640 typval_T rettv; 1641 char_u *retval; 1642 1643 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1644 return NULL; 1645 1646 retval = vim_strsave(get_tv_string(&rettv)); 1647 clear_tv(&rettv); 1648 return retval; 1649} 1650# endif 1651 1652# if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1653/* 1654 * Call vimL function "func" and return the result as a number. 1655 * Returns -1 when calling the function fails. 1656 * Uses argv[argc] for the function arguments. 1657 */ 1658 long 1659call_func_retnr(func, argc, argv, safe) 1660 char_u *func; 1661 int argc; 1662 char_u **argv; 1663 int safe; /* use the sandbox */ 1664{ 1665 typval_T rettv; 1666 long retval; 1667 1668 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1669 return -1; 1670 1671 retval = get_tv_number_chk(&rettv, NULL); 1672 clear_tv(&rettv); 1673 return retval; 1674} 1675# endif 1676 1677/* 1678 * Call vimL function "func" and return the result as a List. 1679 * Uses argv[argc] for the function arguments. 1680 * Returns NULL when there is something wrong. 1681 */ 1682 void * 1683call_func_retlist(func, argc, argv, safe) 1684 char_u *func; 1685 int argc; 1686 char_u **argv; 1687 int safe; /* use the sandbox */ 1688{ 1689 typval_T rettv; 1690 1691 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1692 return NULL; 1693 1694 if (rettv.v_type != VAR_LIST) 1695 { 1696 clear_tv(&rettv); 1697 return NULL; 1698 } 1699 1700 return rettv.vval.v_list; 1701} 1702#endif 1703 1704 1705/* 1706 * Save the current function call pointer, and set it to NULL. 1707 * Used when executing autocommands and for ":source". 1708 */ 1709 void * 1710save_funccal() 1711{ 1712 funccall_T *fc = current_funccal; 1713 1714 current_funccal = NULL; 1715 return (void *)fc; 1716} 1717 1718 void 1719restore_funccal(vfc) 1720 void *vfc; 1721{ 1722 funccall_T *fc = (funccall_T *)vfc; 1723 1724 current_funccal = fc; 1725} 1726 1727#if defined(FEAT_PROFILE) || defined(PROTO) 1728/* 1729 * Prepare profiling for entering a child or something else that is not 1730 * counted for the script/function itself. 1731 * Should always be called in pair with prof_child_exit(). 1732 */ 1733 void 1734prof_child_enter(tm) 1735 proftime_T *tm; /* place to store waittime */ 1736{ 1737 funccall_T *fc = current_funccal; 1738 1739 if (fc != NULL && fc->func->uf_profiling) 1740 profile_start(&fc->prof_child); 1741 script_prof_save(tm); 1742} 1743 1744/* 1745 * Take care of time spent in a child. 1746 * Should always be called after prof_child_enter(). 1747 */ 1748 void 1749prof_child_exit(tm) 1750 proftime_T *tm; /* where waittime was stored */ 1751{ 1752 funccall_T *fc = current_funccal; 1753 1754 if (fc != NULL && fc->func->uf_profiling) 1755 { 1756 profile_end(&fc->prof_child); 1757 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1758 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1759 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1760 } 1761 script_prof_restore(tm); 1762} 1763#endif 1764 1765 1766#ifdef FEAT_FOLDING 1767/* 1768 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1769 * it in "*cp". Doesn't give error messages. 1770 */ 1771 int 1772eval_foldexpr(arg, cp) 1773 char_u *arg; 1774 int *cp; 1775{ 1776 typval_T tv; 1777 int retval; 1778 char_u *s; 1779 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1780 OPT_LOCAL); 1781 1782 ++emsg_off; 1783 if (use_sandbox) 1784 ++sandbox; 1785 ++textlock; 1786 *cp = NUL; 1787 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1788 retval = 0; 1789 else 1790 { 1791 /* If the result is a number, just return the number. */ 1792 if (tv.v_type == VAR_NUMBER) 1793 retval = tv.vval.v_number; 1794 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1795 retval = 0; 1796 else 1797 { 1798 /* If the result is a string, check if there is a non-digit before 1799 * the number. */ 1800 s = tv.vval.v_string; 1801 if (!VIM_ISDIGIT(*s) && *s != '-') 1802 *cp = *s++; 1803 retval = atol((char *)s); 1804 } 1805 clear_tv(&tv); 1806 } 1807 --emsg_off; 1808 if (use_sandbox) 1809 --sandbox; 1810 --textlock; 1811 1812 return retval; 1813} 1814#endif 1815 1816/* 1817 * ":let" list all variable values 1818 * ":let var1 var2" list variable values 1819 * ":let var = expr" assignment command. 1820 * ":let var += expr" assignment command. 1821 * ":let var -= expr" assignment command. 1822 * ":let var .= expr" assignment command. 1823 * ":let [var1, var2] = expr" unpack list. 1824 */ 1825 void 1826ex_let(eap) 1827 exarg_T *eap; 1828{ 1829 char_u *arg = eap->arg; 1830 char_u *expr = NULL; 1831 typval_T rettv; 1832 int i; 1833 int var_count = 0; 1834 int semicolon = 0; 1835 char_u op[2]; 1836 char_u *argend; 1837 int first = TRUE; 1838 1839 argend = skip_var_list(arg, &var_count, &semicolon); 1840 if (argend == NULL) 1841 return; 1842 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1843 --argend; 1844 expr = vim_strchr(argend, '='); 1845 if (expr == NULL) 1846 { 1847 /* 1848 * ":let" without "=": list variables 1849 */ 1850 if (*arg == '[') 1851 EMSG(_(e_invarg)); 1852 else if (!ends_excmd(*arg)) 1853 /* ":let var1 var2" */ 1854 arg = list_arg_vars(eap, arg, &first); 1855 else if (!eap->skip) 1856 { 1857 /* ":let" */ 1858 list_glob_vars(&first); 1859 list_buf_vars(&first); 1860 list_win_vars(&first); 1861#ifdef FEAT_WINDOWS 1862 list_tab_vars(&first); 1863#endif 1864 list_script_vars(&first); 1865 list_func_vars(&first); 1866 list_vim_vars(&first); 1867 } 1868 eap->nextcmd = check_nextcmd(arg); 1869 } 1870 else 1871 { 1872 op[0] = '='; 1873 op[1] = NUL; 1874 if (expr > argend) 1875 { 1876 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1877 op[0] = expr[-1]; /* +=, -= or .= */ 1878 } 1879 expr = skipwhite(expr + 1); 1880 1881 if (eap->skip) 1882 ++emsg_skip; 1883 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1884 if (eap->skip) 1885 { 1886 if (i != FAIL) 1887 clear_tv(&rettv); 1888 --emsg_skip; 1889 } 1890 else if (i != FAIL) 1891 { 1892 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1893 op); 1894 clear_tv(&rettv); 1895 } 1896 } 1897} 1898 1899/* 1900 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1901 * Handles both "var" with any type and "[var, var; var]" with a list type. 1902 * When "nextchars" is not NULL it points to a string with characters that 1903 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1904 * or concatenate. 1905 * Returns OK or FAIL; 1906 */ 1907 static int 1908ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1909 char_u *arg_start; 1910 typval_T *tv; 1911 int copy; /* copy values from "tv", don't move */ 1912 int semicolon; /* from skip_var_list() */ 1913 int var_count; /* from skip_var_list() */ 1914 char_u *nextchars; 1915{ 1916 char_u *arg = arg_start; 1917 list_T *l; 1918 int i; 1919 listitem_T *item; 1920 typval_T ltv; 1921 1922 if (*arg != '[') 1923 { 1924 /* 1925 * ":let var = expr" or ":for var in list" 1926 */ 1927 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1928 return FAIL; 1929 return OK; 1930 } 1931 1932 /* 1933 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1934 */ 1935 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1936 { 1937 EMSG(_(e_listreq)); 1938 return FAIL; 1939 } 1940 1941 i = list_len(l); 1942 if (semicolon == 0 && var_count < i) 1943 { 1944 EMSG(_("E687: Less targets than List items")); 1945 return FAIL; 1946 } 1947 if (var_count - semicolon > i) 1948 { 1949 EMSG(_("E688: More targets than List items")); 1950 return FAIL; 1951 } 1952 1953 item = l->lv_first; 1954 while (*arg != ']') 1955 { 1956 arg = skipwhite(arg + 1); 1957 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1958 item = item->li_next; 1959 if (arg == NULL) 1960 return FAIL; 1961 1962 arg = skipwhite(arg); 1963 if (*arg == ';') 1964 { 1965 /* Put the rest of the list (may be empty) in the var after ';'. 1966 * Create a new list for this. */ 1967 l = list_alloc(); 1968 if (l == NULL) 1969 return FAIL; 1970 while (item != NULL) 1971 { 1972 list_append_tv(l, &item->li_tv); 1973 item = item->li_next; 1974 } 1975 1976 ltv.v_type = VAR_LIST; 1977 ltv.v_lock = 0; 1978 ltv.vval.v_list = l; 1979 l->lv_refcount = 1; 1980 1981 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1982 (char_u *)"]", nextchars); 1983 clear_tv(<v); 1984 if (arg == NULL) 1985 return FAIL; 1986 break; 1987 } 1988 else if (*arg != ',' && *arg != ']') 1989 { 1990 EMSG2(_(e_intern2), "ex_let_vars()"); 1991 return FAIL; 1992 } 1993 } 1994 1995 return OK; 1996} 1997 1998/* 1999 * Skip over assignable variable "var" or list of variables "[var, var]". 2000 * Used for ":let varvar = expr" and ":for varvar in expr". 2001 * For "[var, var]" increment "*var_count" for each variable. 2002 * for "[var, var; var]" set "semicolon". 2003 * Return NULL for an error. 2004 */ 2005 static char_u * 2006skip_var_list(arg, var_count, semicolon) 2007 char_u *arg; 2008 int *var_count; 2009 int *semicolon; 2010{ 2011 char_u *p, *s; 2012 2013 if (*arg == '[') 2014 { 2015 /* "[var, var]": find the matching ']'. */ 2016 p = arg; 2017 for (;;) 2018 { 2019 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 2020 s = skip_var_one(p); 2021 if (s == p) 2022 { 2023 EMSG2(_(e_invarg2), p); 2024 return NULL; 2025 } 2026 ++*var_count; 2027 2028 p = skipwhite(s); 2029 if (*p == ']') 2030 break; 2031 else if (*p == ';') 2032 { 2033 if (*semicolon == 1) 2034 { 2035 EMSG(_("Double ; in list of variables")); 2036 return NULL; 2037 } 2038 *semicolon = 1; 2039 } 2040 else if (*p != ',') 2041 { 2042 EMSG2(_(e_invarg2), p); 2043 return NULL; 2044 } 2045 } 2046 return p + 1; 2047 } 2048 else 2049 return skip_var_one(arg); 2050} 2051 2052/* 2053 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 2054 * l[idx]. 2055 */ 2056 static char_u * 2057skip_var_one(arg) 2058 char_u *arg; 2059{ 2060 if (*arg == '@' && arg[1] != NUL) 2061 return arg + 2; 2062 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 2063 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2064} 2065 2066/* 2067 * List variables for hashtab "ht" with prefix "prefix". 2068 * If "empty" is TRUE also list NULL strings as empty strings. 2069 */ 2070 static void 2071list_hashtable_vars(ht, prefix, empty, first) 2072 hashtab_T *ht; 2073 char_u *prefix; 2074 int empty; 2075 int *first; 2076{ 2077 hashitem_T *hi; 2078 dictitem_T *di; 2079 int todo; 2080 2081 todo = (int)ht->ht_used; 2082 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 2083 { 2084 if (!HASHITEM_EMPTY(hi)) 2085 { 2086 --todo; 2087 di = HI2DI(hi); 2088 if (empty || di->di_tv.v_type != VAR_STRING 2089 || di->di_tv.vval.v_string != NULL) 2090 list_one_var(di, prefix, first); 2091 } 2092 } 2093} 2094 2095/* 2096 * List global variables. 2097 */ 2098 static void 2099list_glob_vars(first) 2100 int *first; 2101{ 2102 list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); 2103} 2104 2105/* 2106 * List buffer variables. 2107 */ 2108 static void 2109list_buf_vars(first) 2110 int *first; 2111{ 2112 char_u numbuf[NUMBUFLEN]; 2113 2114 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", 2115 TRUE, first); 2116 2117 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 2118 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, 2119 numbuf, first); 2120} 2121 2122/* 2123 * List window variables. 2124 */ 2125 static void 2126list_win_vars(first) 2127 int *first; 2128{ 2129 list_hashtable_vars(&curwin->w_vars.dv_hashtab, 2130 (char_u *)"w:", TRUE, first); 2131} 2132 2133#ifdef FEAT_WINDOWS 2134/* 2135 * List tab page variables. 2136 */ 2137 static void 2138list_tab_vars(first) 2139 int *first; 2140{ 2141 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, 2142 (char_u *)"t:", TRUE, first); 2143} 2144#endif 2145 2146/* 2147 * List Vim variables. 2148 */ 2149 static void 2150list_vim_vars(first) 2151 int *first; 2152{ 2153 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); 2154} 2155 2156/* 2157 * List script-local variables, if there is a script. 2158 */ 2159 static void 2160list_script_vars(first) 2161 int *first; 2162{ 2163 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2164 list_hashtable_vars(&SCRIPT_VARS(current_SID), 2165 (char_u *)"s:", FALSE, first); 2166} 2167 2168/* 2169 * List function variables, if there is a function. 2170 */ 2171 static void 2172list_func_vars(first) 2173 int *first; 2174{ 2175 if (current_funccal != NULL) 2176 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2177 (char_u *)"l:", FALSE, first); 2178} 2179 2180/* 2181 * List variables in "arg". 2182 */ 2183 static char_u * 2184list_arg_vars(eap, arg, first) 2185 exarg_T *eap; 2186 char_u *arg; 2187 int *first; 2188{ 2189 int error = FALSE; 2190 int len; 2191 char_u *name; 2192 char_u *name_start; 2193 char_u *arg_subsc; 2194 char_u *tofree; 2195 typval_T tv; 2196 2197 while (!ends_excmd(*arg) && !got_int) 2198 { 2199 if (error || eap->skip) 2200 { 2201 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2202 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2203 { 2204 emsg_severe = TRUE; 2205 EMSG(_(e_trailing)); 2206 break; 2207 } 2208 } 2209 else 2210 { 2211 /* get_name_len() takes care of expanding curly braces */ 2212 name_start = name = arg; 2213 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2214 if (len <= 0) 2215 { 2216 /* This is mainly to keep test 49 working: when expanding 2217 * curly braces fails overrule the exception error message. */ 2218 if (len < 0 && !aborting()) 2219 { 2220 emsg_severe = TRUE; 2221 EMSG2(_(e_invarg2), arg); 2222 break; 2223 } 2224 error = TRUE; 2225 } 2226 else 2227 { 2228 if (tofree != NULL) 2229 name = tofree; 2230 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2231 error = TRUE; 2232 else 2233 { 2234 /* handle d.key, l[idx], f(expr) */ 2235 arg_subsc = arg; 2236 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2237 error = TRUE; 2238 else 2239 { 2240 if (arg == arg_subsc && len == 2 && name[1] == ':') 2241 { 2242 switch (*name) 2243 { 2244 case 'g': list_glob_vars(first); break; 2245 case 'b': list_buf_vars(first); break; 2246 case 'w': list_win_vars(first); break; 2247#ifdef FEAT_WINDOWS 2248 case 't': list_tab_vars(first); break; 2249#endif 2250 case 'v': list_vim_vars(first); break; 2251 case 's': list_script_vars(first); break; 2252 case 'l': list_func_vars(first); break; 2253 default: 2254 EMSG2(_("E738: Can't list variables for %s"), name); 2255 } 2256 } 2257 else 2258 { 2259 char_u numbuf[NUMBUFLEN]; 2260 char_u *tf; 2261 int c; 2262 char_u *s; 2263 2264 s = echo_string(&tv, &tf, numbuf, 0); 2265 c = *arg; 2266 *arg = NUL; 2267 list_one_var_a((char_u *)"", 2268 arg == arg_subsc ? name : name_start, 2269 tv.v_type, 2270 s == NULL ? (char_u *)"" : s, 2271 first); 2272 *arg = c; 2273 vim_free(tf); 2274 } 2275 clear_tv(&tv); 2276 } 2277 } 2278 } 2279 2280 vim_free(tofree); 2281 } 2282 2283 arg = skipwhite(arg); 2284 } 2285 2286 return arg; 2287} 2288 2289/* 2290 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2291 * Returns a pointer to the char just after the var name. 2292 * Returns NULL if there is an error. 2293 */ 2294 static char_u * 2295ex_let_one(arg, tv, copy, endchars, op) 2296 char_u *arg; /* points to variable name */ 2297 typval_T *tv; /* value to assign to variable */ 2298 int copy; /* copy value from "tv" */ 2299 char_u *endchars; /* valid chars after variable name or NULL */ 2300 char_u *op; /* "+", "-", "." or NULL*/ 2301{ 2302 int c1; 2303 char_u *name; 2304 char_u *p; 2305 char_u *arg_end = NULL; 2306 int len; 2307 int opt_flags; 2308 char_u *tofree = NULL; 2309 2310 /* 2311 * ":let $VAR = expr": Set environment variable. 2312 */ 2313 if (*arg == '$') 2314 { 2315 /* Find the end of the name. */ 2316 ++arg; 2317 name = arg; 2318 len = get_env_len(&arg); 2319 if (len == 0) 2320 EMSG2(_(e_invarg2), name - 1); 2321 else 2322 { 2323 if (op != NULL && (*op == '+' || *op == '-')) 2324 EMSG2(_(e_letwrong), op); 2325 else if (endchars != NULL 2326 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2327 EMSG(_(e_letunexp)); 2328 else 2329 { 2330 c1 = name[len]; 2331 name[len] = NUL; 2332 p = get_tv_string_chk(tv); 2333 if (p != NULL && op != NULL && *op == '.') 2334 { 2335 int mustfree = FALSE; 2336 char_u *s = vim_getenv(name, &mustfree); 2337 2338 if (s != NULL) 2339 { 2340 p = tofree = concat_str(s, p); 2341 if (mustfree) 2342 vim_free(s); 2343 } 2344 } 2345 if (p != NULL) 2346 { 2347 vim_setenv(name, p); 2348 if (STRICMP(name, "HOME") == 0) 2349 init_homedir(); 2350 else if (didset_vim && STRICMP(name, "VIM") == 0) 2351 didset_vim = FALSE; 2352 else if (didset_vimruntime 2353 && STRICMP(name, "VIMRUNTIME") == 0) 2354 didset_vimruntime = FALSE; 2355 arg_end = arg; 2356 } 2357 name[len] = c1; 2358 vim_free(tofree); 2359 } 2360 } 2361 } 2362 2363 /* 2364 * ":let &option = expr": Set option value. 2365 * ":let &l:option = expr": Set local option value. 2366 * ":let &g:option = expr": Set global option value. 2367 */ 2368 else if (*arg == '&') 2369 { 2370 /* Find the end of the name. */ 2371 p = find_option_end(&arg, &opt_flags); 2372 if (p == NULL || (endchars != NULL 2373 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2374 EMSG(_(e_letunexp)); 2375 else 2376 { 2377 long n; 2378 int opt_type; 2379 long numval; 2380 char_u *stringval = NULL; 2381 char_u *s; 2382 2383 c1 = *p; 2384 *p = NUL; 2385 2386 n = get_tv_number(tv); 2387 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2388 if (s != NULL && op != NULL && *op != '=') 2389 { 2390 opt_type = get_option_value(arg, &numval, 2391 &stringval, opt_flags); 2392 if ((opt_type == 1 && *op == '.') 2393 || (opt_type == 0 && *op != '.')) 2394 EMSG2(_(e_letwrong), op); 2395 else 2396 { 2397 if (opt_type == 1) /* number */ 2398 { 2399 if (*op == '+') 2400 n = numval + n; 2401 else 2402 n = numval - n; 2403 } 2404 else if (opt_type == 0 && stringval != NULL) /* string */ 2405 { 2406 s = concat_str(stringval, s); 2407 vim_free(stringval); 2408 stringval = s; 2409 } 2410 } 2411 } 2412 if (s != NULL) 2413 { 2414 set_option_value(arg, n, s, opt_flags); 2415 arg_end = p; 2416 } 2417 *p = c1; 2418 vim_free(stringval); 2419 } 2420 } 2421 2422 /* 2423 * ":let @r = expr": Set register contents. 2424 */ 2425 else if (*arg == '@') 2426 { 2427 ++arg; 2428 if (op != NULL && (*op == '+' || *op == '-')) 2429 EMSG2(_(e_letwrong), op); 2430 else if (endchars != NULL 2431 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2432 EMSG(_(e_letunexp)); 2433 else 2434 { 2435 char_u *ptofree = NULL; 2436 char_u *s; 2437 2438 p = get_tv_string_chk(tv); 2439 if (p != NULL && op != NULL && *op == '.') 2440 { 2441 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2442 if (s != NULL) 2443 { 2444 p = ptofree = concat_str(s, p); 2445 vim_free(s); 2446 } 2447 } 2448 if (p != NULL) 2449 { 2450 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2451 arg_end = arg + 1; 2452 } 2453 vim_free(ptofree); 2454 } 2455 } 2456 2457 /* 2458 * ":let var = expr": Set internal variable. 2459 * ":let {expr} = expr": Idem, name made with curly braces 2460 */ 2461 else if (eval_isnamec1(*arg) || *arg == '{') 2462 { 2463 lval_T lv; 2464 2465 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2466 if (p != NULL && lv.ll_name != NULL) 2467 { 2468 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2469 EMSG(_(e_letunexp)); 2470 else 2471 { 2472 set_var_lval(&lv, p, tv, copy, op); 2473 arg_end = p; 2474 } 2475 } 2476 clear_lval(&lv); 2477 } 2478 2479 else 2480 EMSG2(_(e_invarg2), arg); 2481 2482 return arg_end; 2483} 2484 2485/* 2486 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2487 */ 2488 static int 2489check_changedtick(arg) 2490 char_u *arg; 2491{ 2492 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2493 { 2494 EMSG2(_(e_readonlyvar), arg); 2495 return TRUE; 2496 } 2497 return FALSE; 2498} 2499 2500/* 2501 * Get an lval: variable, Dict item or List item that can be assigned a value 2502 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2503 * "name.key", "name.key[expr]" etc. 2504 * Indexing only works if "name" is an existing List or Dictionary. 2505 * "name" points to the start of the name. 2506 * If "rettv" is not NULL it points to the value to be assigned. 2507 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2508 * wrong; must end in space or cmd separator. 2509 * 2510 * Returns a pointer to just after the name, including indexes. 2511 * When an evaluation error occurs "lp->ll_name" is NULL; 2512 * Returns NULL for a parsing error. Still need to free items in "lp"! 2513 */ 2514 static char_u * 2515get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2516 char_u *name; 2517 typval_T *rettv; 2518 lval_T *lp; 2519 int unlet; 2520 int skip; 2521 int quiet; /* don't give error messages */ 2522 int fne_flags; /* flags for find_name_end() */ 2523{ 2524 char_u *p; 2525 char_u *expr_start, *expr_end; 2526 int cc; 2527 dictitem_T *v; 2528 typval_T var1; 2529 typval_T var2; 2530 int empty1 = FALSE; 2531 listitem_T *ni; 2532 char_u *key = NULL; 2533 int len; 2534 hashtab_T *ht; 2535 2536 /* Clear everything in "lp". */ 2537 vim_memset(lp, 0, sizeof(lval_T)); 2538 2539 if (skip) 2540 { 2541 /* When skipping just find the end of the name. */ 2542 lp->ll_name = name; 2543 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2544 } 2545 2546 /* Find the end of the name. */ 2547 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2548 if (expr_start != NULL) 2549 { 2550 /* Don't expand the name when we already know there is an error. */ 2551 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2552 && *p != '[' && *p != '.') 2553 { 2554 EMSG(_(e_trailing)); 2555 return NULL; 2556 } 2557 2558 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2559 if (lp->ll_exp_name == NULL) 2560 { 2561 /* Report an invalid expression in braces, unless the 2562 * expression evaluation has been cancelled due to an 2563 * aborting error, an interrupt, or an exception. */ 2564 if (!aborting() && !quiet) 2565 { 2566 emsg_severe = TRUE; 2567 EMSG2(_(e_invarg2), name); 2568 return NULL; 2569 } 2570 } 2571 lp->ll_name = lp->ll_exp_name; 2572 } 2573 else 2574 lp->ll_name = name; 2575 2576 /* Without [idx] or .key we are done. */ 2577 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2578 return p; 2579 2580 cc = *p; 2581 *p = NUL; 2582 v = find_var(lp->ll_name, &ht); 2583 if (v == NULL && !quiet) 2584 EMSG2(_(e_undefvar), lp->ll_name); 2585 *p = cc; 2586 if (v == NULL) 2587 return NULL; 2588 2589 /* 2590 * Loop until no more [idx] or .key is following. 2591 */ 2592 lp->ll_tv = &v->di_tv; 2593 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2594 { 2595 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2596 && !(lp->ll_tv->v_type == VAR_DICT 2597 && lp->ll_tv->vval.v_dict != NULL)) 2598 { 2599 if (!quiet) 2600 EMSG(_("E689: Can only index a List or Dictionary")); 2601 return NULL; 2602 } 2603 if (lp->ll_range) 2604 { 2605 if (!quiet) 2606 EMSG(_("E708: [:] must come last")); 2607 return NULL; 2608 } 2609 2610 len = -1; 2611 if (*p == '.') 2612 { 2613 key = p + 1; 2614 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2615 ; 2616 if (len == 0) 2617 { 2618 if (!quiet) 2619 EMSG(_(e_emptykey)); 2620 return NULL; 2621 } 2622 p = key + len; 2623 } 2624 else 2625 { 2626 /* Get the index [expr] or the first index [expr: ]. */ 2627 p = skipwhite(p + 1); 2628 if (*p == ':') 2629 empty1 = TRUE; 2630 else 2631 { 2632 empty1 = FALSE; 2633 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2634 return NULL; 2635 if (get_tv_string_chk(&var1) == NULL) 2636 { 2637 /* not a number or string */ 2638 clear_tv(&var1); 2639 return NULL; 2640 } 2641 } 2642 2643 /* Optionally get the second index [ :expr]. */ 2644 if (*p == ':') 2645 { 2646 if (lp->ll_tv->v_type == VAR_DICT) 2647 { 2648 if (!quiet) 2649 EMSG(_(e_dictrange)); 2650 if (!empty1) 2651 clear_tv(&var1); 2652 return NULL; 2653 } 2654 if (rettv != NULL && (rettv->v_type != VAR_LIST 2655 || rettv->vval.v_list == NULL)) 2656 { 2657 if (!quiet) 2658 EMSG(_("E709: [:] requires a List value")); 2659 if (!empty1) 2660 clear_tv(&var1); 2661 return NULL; 2662 } 2663 p = skipwhite(p + 1); 2664 if (*p == ']') 2665 lp->ll_empty2 = TRUE; 2666 else 2667 { 2668 lp->ll_empty2 = FALSE; 2669 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2670 { 2671 if (!empty1) 2672 clear_tv(&var1); 2673 return NULL; 2674 } 2675 if (get_tv_string_chk(&var2) == NULL) 2676 { 2677 /* not a number or string */ 2678 if (!empty1) 2679 clear_tv(&var1); 2680 clear_tv(&var2); 2681 return NULL; 2682 } 2683 } 2684 lp->ll_range = TRUE; 2685 } 2686 else 2687 lp->ll_range = FALSE; 2688 2689 if (*p != ']') 2690 { 2691 if (!quiet) 2692 EMSG(_(e_missbrac)); 2693 if (!empty1) 2694 clear_tv(&var1); 2695 if (lp->ll_range && !lp->ll_empty2) 2696 clear_tv(&var2); 2697 return NULL; 2698 } 2699 2700 /* Skip to past ']'. */ 2701 ++p; 2702 } 2703 2704 if (lp->ll_tv->v_type == VAR_DICT) 2705 { 2706 if (len == -1) 2707 { 2708 /* "[key]": get key from "var1" */ 2709 key = get_tv_string(&var1); /* is number or string */ 2710 if (*key == NUL) 2711 { 2712 if (!quiet) 2713 EMSG(_(e_emptykey)); 2714 clear_tv(&var1); 2715 return NULL; 2716 } 2717 } 2718 lp->ll_list = NULL; 2719 lp->ll_dict = lp->ll_tv->vval.v_dict; 2720 lp->ll_di = dict_find(lp->ll_dict, key, len); 2721 if (lp->ll_di == NULL) 2722 { 2723 /* Key does not exist in dict: may need to add it. */ 2724 if (*p == '[' || *p == '.' || unlet) 2725 { 2726 if (!quiet) 2727 EMSG2(_(e_dictkey), key); 2728 if (len == -1) 2729 clear_tv(&var1); 2730 return NULL; 2731 } 2732 if (len == -1) 2733 lp->ll_newkey = vim_strsave(key); 2734 else 2735 lp->ll_newkey = vim_strnsave(key, len); 2736 if (len == -1) 2737 clear_tv(&var1); 2738 if (lp->ll_newkey == NULL) 2739 p = NULL; 2740 break; 2741 } 2742 if (len == -1) 2743 clear_tv(&var1); 2744 lp->ll_tv = &lp->ll_di->di_tv; 2745 } 2746 else 2747 { 2748 /* 2749 * Get the number and item for the only or first index of the List. 2750 */ 2751 if (empty1) 2752 lp->ll_n1 = 0; 2753 else 2754 { 2755 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2756 clear_tv(&var1); 2757 } 2758 lp->ll_dict = NULL; 2759 lp->ll_list = lp->ll_tv->vval.v_list; 2760 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2761 if (lp->ll_li == NULL) 2762 { 2763 if (lp->ll_n1 < 0) 2764 { 2765 lp->ll_n1 = 0; 2766 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2767 } 2768 } 2769 if (lp->ll_li == NULL) 2770 { 2771 if (lp->ll_range && !lp->ll_empty2) 2772 clear_tv(&var2); 2773 return NULL; 2774 } 2775 2776 /* 2777 * May need to find the item or absolute index for the second 2778 * index of a range. 2779 * When no index given: "lp->ll_empty2" is TRUE. 2780 * Otherwise "lp->ll_n2" is set to the second index. 2781 */ 2782 if (lp->ll_range && !lp->ll_empty2) 2783 { 2784 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2785 clear_tv(&var2); 2786 if (lp->ll_n2 < 0) 2787 { 2788 ni = list_find(lp->ll_list, lp->ll_n2); 2789 if (ni == NULL) 2790 return NULL; 2791 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2792 } 2793 2794 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2795 if (lp->ll_n1 < 0) 2796 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2797 if (lp->ll_n2 < lp->ll_n1) 2798 return NULL; 2799 } 2800 2801 lp->ll_tv = &lp->ll_li->li_tv; 2802 } 2803 } 2804 2805 return p; 2806} 2807 2808/* 2809 * Clear lval "lp" that was filled by get_lval(). 2810 */ 2811 static void 2812clear_lval(lp) 2813 lval_T *lp; 2814{ 2815 vim_free(lp->ll_exp_name); 2816 vim_free(lp->ll_newkey); 2817} 2818 2819/* 2820 * Set a variable that was parsed by get_lval() to "rettv". 2821 * "endp" points to just after the parsed name. 2822 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2823 */ 2824 static void 2825set_var_lval(lp, endp, rettv, copy, op) 2826 lval_T *lp; 2827 char_u *endp; 2828 typval_T *rettv; 2829 int copy; 2830 char_u *op; 2831{ 2832 int cc; 2833 listitem_T *ri; 2834 dictitem_T *di; 2835 2836 if (lp->ll_tv == NULL) 2837 { 2838 if (!check_changedtick(lp->ll_name)) 2839 { 2840 cc = *endp; 2841 *endp = NUL; 2842 if (op != NULL && *op != '=') 2843 { 2844 typval_T tv; 2845 2846 /* handle +=, -= and .= */ 2847 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2848 &tv, TRUE) == OK) 2849 { 2850 if (tv_op(&tv, rettv, op) == OK) 2851 set_var(lp->ll_name, &tv, FALSE); 2852 clear_tv(&tv); 2853 } 2854 } 2855 else 2856 set_var(lp->ll_name, rettv, copy); 2857 *endp = cc; 2858 } 2859 } 2860 else if (tv_check_lock(lp->ll_newkey == NULL 2861 ? lp->ll_tv->v_lock 2862 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2863 ; 2864 else if (lp->ll_range) 2865 { 2866 /* 2867 * Assign the List values to the list items. 2868 */ 2869 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2870 { 2871 if (op != NULL && *op != '=') 2872 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2873 else 2874 { 2875 clear_tv(&lp->ll_li->li_tv); 2876 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2877 } 2878 ri = ri->li_next; 2879 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2880 break; 2881 if (lp->ll_li->li_next == NULL) 2882 { 2883 /* Need to add an empty item. */ 2884 if (list_append_number(lp->ll_list, 0) == FAIL) 2885 { 2886 ri = NULL; 2887 break; 2888 } 2889 } 2890 lp->ll_li = lp->ll_li->li_next; 2891 ++lp->ll_n1; 2892 } 2893 if (ri != NULL) 2894 EMSG(_("E710: List value has more items than target")); 2895 else if (lp->ll_empty2 2896 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2897 : lp->ll_n1 != lp->ll_n2) 2898 EMSG(_("E711: List value has not enough items")); 2899 } 2900 else 2901 { 2902 /* 2903 * Assign to a List or Dictionary item. 2904 */ 2905 if (lp->ll_newkey != NULL) 2906 { 2907 if (op != NULL && *op != '=') 2908 { 2909 EMSG2(_(e_letwrong), op); 2910 return; 2911 } 2912 2913 /* Need to add an item to the Dictionary. */ 2914 di = dictitem_alloc(lp->ll_newkey); 2915 if (di == NULL) 2916 return; 2917 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2918 { 2919 vim_free(di); 2920 return; 2921 } 2922 lp->ll_tv = &di->di_tv; 2923 } 2924 else if (op != NULL && *op != '=') 2925 { 2926 tv_op(lp->ll_tv, rettv, op); 2927 return; 2928 } 2929 else 2930 clear_tv(lp->ll_tv); 2931 2932 /* 2933 * Assign the value to the variable or list item. 2934 */ 2935 if (copy) 2936 copy_tv(rettv, lp->ll_tv); 2937 else 2938 { 2939 *lp->ll_tv = *rettv; 2940 lp->ll_tv->v_lock = 0; 2941 init_tv(rettv); 2942 } 2943 } 2944} 2945 2946/* 2947 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2948 * Returns OK or FAIL. 2949 */ 2950 static int 2951tv_op(tv1, tv2, op) 2952 typval_T *tv1; 2953 typval_T *tv2; 2954 char_u *op; 2955{ 2956 long n; 2957 char_u numbuf[NUMBUFLEN]; 2958 char_u *s; 2959 2960 /* Can't do anything with a Funcref or a Dict on the right. */ 2961 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2962 { 2963 switch (tv1->v_type) 2964 { 2965 case VAR_DICT: 2966 case VAR_FUNC: 2967 break; 2968 2969 case VAR_LIST: 2970 if (*op != '+' || tv2->v_type != VAR_LIST) 2971 break; 2972 /* List += List */ 2973 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2974 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2975 return OK; 2976 2977 case VAR_NUMBER: 2978 case VAR_STRING: 2979 if (tv2->v_type == VAR_LIST) 2980 break; 2981 if (*op == '+' || *op == '-') 2982 { 2983 /* nr += nr or nr -= nr*/ 2984 n = get_tv_number(tv1); 2985#ifdef FEAT_FLOAT 2986 if (tv2->v_type == VAR_FLOAT) 2987 { 2988 float_T f = n; 2989 2990 if (*op == '+') 2991 f += tv2->vval.v_float; 2992 else 2993 f -= tv2->vval.v_float; 2994 clear_tv(tv1); 2995 tv1->v_type = VAR_FLOAT; 2996 tv1->vval.v_float = f; 2997 } 2998 else 2999#endif 3000 { 3001 if (*op == '+') 3002 n += get_tv_number(tv2); 3003 else 3004 n -= get_tv_number(tv2); 3005 clear_tv(tv1); 3006 tv1->v_type = VAR_NUMBER; 3007 tv1->vval.v_number = n; 3008 } 3009 } 3010 else 3011 { 3012 if (tv2->v_type == VAR_FLOAT) 3013 break; 3014 3015 /* str .= str */ 3016 s = get_tv_string(tv1); 3017 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 3018 clear_tv(tv1); 3019 tv1->v_type = VAR_STRING; 3020 tv1->vval.v_string = s; 3021 } 3022 return OK; 3023 3024#ifdef FEAT_FLOAT 3025 case VAR_FLOAT: 3026 { 3027 float_T f; 3028 3029 if (*op == '.' || (tv2->v_type != VAR_FLOAT 3030 && tv2->v_type != VAR_NUMBER 3031 && tv2->v_type != VAR_STRING)) 3032 break; 3033 if (tv2->v_type == VAR_FLOAT) 3034 f = tv2->vval.v_float; 3035 else 3036 f = get_tv_number(tv2); 3037 if (*op == '+') 3038 tv1->vval.v_float += f; 3039 else 3040 tv1->vval.v_float -= f; 3041 } 3042 return OK; 3043#endif 3044 } 3045 } 3046 3047 EMSG2(_(e_letwrong), op); 3048 return FAIL; 3049} 3050 3051/* 3052 * Add a watcher to a list. 3053 */ 3054 static void 3055list_add_watch(l, lw) 3056 list_T *l; 3057 listwatch_T *lw; 3058{ 3059 lw->lw_next = l->lv_watch; 3060 l->lv_watch = lw; 3061} 3062 3063/* 3064 * Remove a watcher from a list. 3065 * No warning when it isn't found... 3066 */ 3067 static void 3068list_rem_watch(l, lwrem) 3069 list_T *l; 3070 listwatch_T *lwrem; 3071{ 3072 listwatch_T *lw, **lwp; 3073 3074 lwp = &l->lv_watch; 3075 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3076 { 3077 if (lw == lwrem) 3078 { 3079 *lwp = lw->lw_next; 3080 break; 3081 } 3082 lwp = &lw->lw_next; 3083 } 3084} 3085 3086/* 3087 * Just before removing an item from a list: advance watchers to the next 3088 * item. 3089 */ 3090 static void 3091list_fix_watch(l, item) 3092 list_T *l; 3093 listitem_T *item; 3094{ 3095 listwatch_T *lw; 3096 3097 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 3098 if (lw->lw_item == item) 3099 lw->lw_item = item->li_next; 3100} 3101 3102/* 3103 * Evaluate the expression used in a ":for var in expr" command. 3104 * "arg" points to "var". 3105 * Set "*errp" to TRUE for an error, FALSE otherwise; 3106 * Return a pointer that holds the info. Null when there is an error. 3107 */ 3108 void * 3109eval_for_line(arg, errp, nextcmdp, skip) 3110 char_u *arg; 3111 int *errp; 3112 char_u **nextcmdp; 3113 int skip; 3114{ 3115 forinfo_T *fi; 3116 char_u *expr; 3117 typval_T tv; 3118 list_T *l; 3119 3120 *errp = TRUE; /* default: there is an error */ 3121 3122 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 3123 if (fi == NULL) 3124 return NULL; 3125 3126 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 3127 if (expr == NULL) 3128 return fi; 3129 3130 expr = skipwhite(expr); 3131 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 3132 { 3133 EMSG(_("E690: Missing \"in\" after :for")); 3134 return fi; 3135 } 3136 3137 if (skip) 3138 ++emsg_skip; 3139 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 3140 { 3141 *errp = FALSE; 3142 if (!skip) 3143 { 3144 l = tv.vval.v_list; 3145 if (tv.v_type != VAR_LIST || l == NULL) 3146 { 3147 EMSG(_(e_listreq)); 3148 clear_tv(&tv); 3149 } 3150 else 3151 { 3152 /* No need to increment the refcount, it's already set for the 3153 * list being used in "tv". */ 3154 fi->fi_list = l; 3155 list_add_watch(l, &fi->fi_lw); 3156 fi->fi_lw.lw_item = l->lv_first; 3157 } 3158 } 3159 } 3160 if (skip) 3161 --emsg_skip; 3162 3163 return fi; 3164} 3165 3166/* 3167 * Use the first item in a ":for" list. Advance to the next. 3168 * Assign the values to the variable (list). "arg" points to the first one. 3169 * Return TRUE when a valid item was found, FALSE when at end of list or 3170 * something wrong. 3171 */ 3172 int 3173next_for_item(fi_void, arg) 3174 void *fi_void; 3175 char_u *arg; 3176{ 3177 forinfo_T *fi = (forinfo_T *)fi_void; 3178 int result; 3179 listitem_T *item; 3180 3181 item = fi->fi_lw.lw_item; 3182 if (item == NULL) 3183 result = FALSE; 3184 else 3185 { 3186 fi->fi_lw.lw_item = item->li_next; 3187 result = (ex_let_vars(arg, &item->li_tv, TRUE, 3188 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 3189 } 3190 return result; 3191} 3192 3193/* 3194 * Free the structure used to store info used by ":for". 3195 */ 3196 void 3197free_for_info(fi_void) 3198 void *fi_void; 3199{ 3200 forinfo_T *fi = (forinfo_T *)fi_void; 3201 3202 if (fi != NULL && fi->fi_list != NULL) 3203 { 3204 list_rem_watch(fi->fi_list, &fi->fi_lw); 3205 list_unref(fi->fi_list); 3206 } 3207 vim_free(fi); 3208} 3209 3210#if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3211 3212 void 3213set_context_for_expression(xp, arg, cmdidx) 3214 expand_T *xp; 3215 char_u *arg; 3216 cmdidx_T cmdidx; 3217{ 3218 int got_eq = FALSE; 3219 int c; 3220 char_u *p; 3221 3222 if (cmdidx == CMD_let) 3223 { 3224 xp->xp_context = EXPAND_USER_VARS; 3225 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3226 { 3227 /* ":let var1 var2 ...": find last space. */ 3228 for (p = arg + STRLEN(arg); p >= arg; ) 3229 { 3230 xp->xp_pattern = p; 3231 mb_ptr_back(arg, p); 3232 if (vim_iswhite(*p)) 3233 break; 3234 } 3235 return; 3236 } 3237 } 3238 else 3239 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3240 : EXPAND_EXPRESSION; 3241 while ((xp->xp_pattern = vim_strpbrk(arg, 3242 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3243 { 3244 c = *xp->xp_pattern; 3245 if (c == '&') 3246 { 3247 c = xp->xp_pattern[1]; 3248 if (c == '&') 3249 { 3250 ++xp->xp_pattern; 3251 xp->xp_context = cmdidx != CMD_let || got_eq 3252 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3253 } 3254 else if (c != ' ') 3255 { 3256 xp->xp_context = EXPAND_SETTINGS; 3257 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3258 xp->xp_pattern += 2; 3259 3260 } 3261 } 3262 else if (c == '$') 3263 { 3264 /* environment variable */ 3265 xp->xp_context = EXPAND_ENV_VARS; 3266 } 3267 else if (c == '=') 3268 { 3269 got_eq = TRUE; 3270 xp->xp_context = EXPAND_EXPRESSION; 3271 } 3272 else if (c == '<' 3273 && xp->xp_context == EXPAND_FUNCTIONS 3274 && vim_strchr(xp->xp_pattern, '(') == NULL) 3275 { 3276 /* Function name can start with "<SNR>" */ 3277 break; 3278 } 3279 else if (cmdidx != CMD_let || got_eq) 3280 { 3281 if (c == '"') /* string */ 3282 { 3283 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3284 if (c == '\\' && xp->xp_pattern[1] != NUL) 3285 ++xp->xp_pattern; 3286 xp->xp_context = EXPAND_NOTHING; 3287 } 3288 else if (c == '\'') /* literal string */ 3289 { 3290 /* Trick: '' is like stopping and starting a literal string. */ 3291 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3292 /* skip */ ; 3293 xp->xp_context = EXPAND_NOTHING; 3294 } 3295 else if (c == '|') 3296 { 3297 if (xp->xp_pattern[1] == '|') 3298 { 3299 ++xp->xp_pattern; 3300 xp->xp_context = EXPAND_EXPRESSION; 3301 } 3302 else 3303 xp->xp_context = EXPAND_COMMANDS; 3304 } 3305 else 3306 xp->xp_context = EXPAND_EXPRESSION; 3307 } 3308 else 3309 /* Doesn't look like something valid, expand as an expression 3310 * anyway. */ 3311 xp->xp_context = EXPAND_EXPRESSION; 3312 arg = xp->xp_pattern; 3313 if (*arg != NUL) 3314 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3315 /* skip */ ; 3316 } 3317 xp->xp_pattern = arg; 3318} 3319 3320#endif /* FEAT_CMDL_COMPL */ 3321 3322/* 3323 * ":1,25call func(arg1, arg2)" function call. 3324 */ 3325 void 3326ex_call(eap) 3327 exarg_T *eap; 3328{ 3329 char_u *arg = eap->arg; 3330 char_u *startarg; 3331 char_u *name; 3332 char_u *tofree; 3333 int len; 3334 typval_T rettv; 3335 linenr_T lnum; 3336 int doesrange; 3337 int failed = FALSE; 3338 funcdict_T fudi; 3339 3340 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3341 if (fudi.fd_newkey != NULL) 3342 { 3343 /* Still need to give an error message for missing key. */ 3344 EMSG2(_(e_dictkey), fudi.fd_newkey); 3345 vim_free(fudi.fd_newkey); 3346 } 3347 if (tofree == NULL) 3348 return; 3349 3350 /* Increase refcount on dictionary, it could get deleted when evaluating 3351 * the arguments. */ 3352 if (fudi.fd_dict != NULL) 3353 ++fudi.fd_dict->dv_refcount; 3354 3355 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3356 len = (int)STRLEN(tofree); 3357 name = deref_func_name(tofree, &len); 3358 3359 /* Skip white space to allow ":call func ()". Not good, but required for 3360 * backward compatibility. */ 3361 startarg = skipwhite(arg); 3362 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3363 3364 if (*startarg != '(') 3365 { 3366 EMSG2(_("E107: Missing parentheses: %s"), eap->arg); 3367 goto end; 3368 } 3369 3370 /* 3371 * When skipping, evaluate the function once, to find the end of the 3372 * arguments. 3373 * When the function takes a range, this is discovered after the first 3374 * call, and the loop is broken. 3375 */ 3376 if (eap->skip) 3377 { 3378 ++emsg_skip; 3379 lnum = eap->line2; /* do it once, also with an invalid range */ 3380 } 3381 else 3382 lnum = eap->line1; 3383 for ( ; lnum <= eap->line2; ++lnum) 3384 { 3385 if (!eap->skip && eap->addr_count > 0) 3386 { 3387 curwin->w_cursor.lnum = lnum; 3388 curwin->w_cursor.col = 0; 3389 } 3390 arg = startarg; 3391 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3392 eap->line1, eap->line2, &doesrange, 3393 !eap->skip, fudi.fd_dict) == FAIL) 3394 { 3395 failed = TRUE; 3396 break; 3397 } 3398 3399 /* Handle a function returning a Funcref, Dictionary or List. */ 3400 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3401 { 3402 failed = TRUE; 3403 break; 3404 } 3405 3406 clear_tv(&rettv); 3407 if (doesrange || eap->skip) 3408 break; 3409 3410 /* Stop when immediately aborting on error, or when an interrupt 3411 * occurred or an exception was thrown but not caught. 3412 * get_func_tv() returned OK, so that the check for trailing 3413 * characters below is executed. */ 3414 if (aborting()) 3415 break; 3416 } 3417 if (eap->skip) 3418 --emsg_skip; 3419 3420 if (!failed) 3421 { 3422 /* Check for trailing illegal characters and a following command. */ 3423 if (!ends_excmd(*arg)) 3424 { 3425 emsg_severe = TRUE; 3426 EMSG(_(e_trailing)); 3427 } 3428 else 3429 eap->nextcmd = check_nextcmd(arg); 3430 } 3431 3432end: 3433 dict_unref(fudi.fd_dict); 3434 vim_free(tofree); 3435} 3436 3437/* 3438 * ":unlet[!] var1 ... " command. 3439 */ 3440 void 3441ex_unlet(eap) 3442 exarg_T *eap; 3443{ 3444 ex_unletlock(eap, eap->arg, 0); 3445} 3446 3447/* 3448 * ":lockvar" and ":unlockvar" commands 3449 */ 3450 void 3451ex_lockvar(eap) 3452 exarg_T *eap; 3453{ 3454 char_u *arg = eap->arg; 3455 int deep = 2; 3456 3457 if (eap->forceit) 3458 deep = -1; 3459 else if (vim_isdigit(*arg)) 3460 { 3461 deep = getdigits(&arg); 3462 arg = skipwhite(arg); 3463 } 3464 3465 ex_unletlock(eap, arg, deep); 3466} 3467 3468/* 3469 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3470 */ 3471 static void 3472ex_unletlock(eap, argstart, deep) 3473 exarg_T *eap; 3474 char_u *argstart; 3475 int deep; 3476{ 3477 char_u *arg = argstart; 3478 char_u *name_end; 3479 int error = FALSE; 3480 lval_T lv; 3481 3482 do 3483 { 3484 /* Parse the name and find the end. */ 3485 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3486 FNE_CHECK_START); 3487 if (lv.ll_name == NULL) 3488 error = TRUE; /* error but continue parsing */ 3489 if (name_end == NULL || (!vim_iswhite(*name_end) 3490 && !ends_excmd(*name_end))) 3491 { 3492 if (name_end != NULL) 3493 { 3494 emsg_severe = TRUE; 3495 EMSG(_(e_trailing)); 3496 } 3497 if (!(eap->skip || error)) 3498 clear_lval(&lv); 3499 break; 3500 } 3501 3502 if (!error && !eap->skip) 3503 { 3504 if (eap->cmdidx == CMD_unlet) 3505 { 3506 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3507 error = TRUE; 3508 } 3509 else 3510 { 3511 if (do_lock_var(&lv, name_end, deep, 3512 eap->cmdidx == CMD_lockvar) == FAIL) 3513 error = TRUE; 3514 } 3515 } 3516 3517 if (!eap->skip) 3518 clear_lval(&lv); 3519 3520 arg = skipwhite(name_end); 3521 } while (!ends_excmd(*arg)); 3522 3523 eap->nextcmd = check_nextcmd(arg); 3524} 3525 3526 static int 3527do_unlet_var(lp, name_end, forceit) 3528 lval_T *lp; 3529 char_u *name_end; 3530 int forceit; 3531{ 3532 int ret = OK; 3533 int cc; 3534 3535 if (lp->ll_tv == NULL) 3536 { 3537 cc = *name_end; 3538 *name_end = NUL; 3539 3540 /* Normal name or expanded name. */ 3541 if (check_changedtick(lp->ll_name)) 3542 ret = FAIL; 3543 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3544 ret = FAIL; 3545 *name_end = cc; 3546 } 3547 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3548 return FAIL; 3549 else if (lp->ll_range) 3550 { 3551 listitem_T *li; 3552 3553 /* Delete a range of List items. */ 3554 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3555 { 3556 li = lp->ll_li->li_next; 3557 listitem_remove(lp->ll_list, lp->ll_li); 3558 lp->ll_li = li; 3559 ++lp->ll_n1; 3560 } 3561 } 3562 else 3563 { 3564 if (lp->ll_list != NULL) 3565 /* unlet a List item. */ 3566 listitem_remove(lp->ll_list, lp->ll_li); 3567 else 3568 /* unlet a Dictionary item. */ 3569 dictitem_remove(lp->ll_dict, lp->ll_di); 3570 } 3571 3572 return ret; 3573} 3574 3575/* 3576 * "unlet" a variable. Return OK if it existed, FAIL if not. 3577 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3578 */ 3579 int 3580do_unlet(name, forceit) 3581 char_u *name; 3582 int forceit; 3583{ 3584 hashtab_T *ht; 3585 hashitem_T *hi; 3586 char_u *varname; 3587 dictitem_T *di; 3588 3589 ht = find_var_ht(name, &varname); 3590 if (ht != NULL && *varname != NUL) 3591 { 3592 hi = hash_find(ht, varname); 3593 if (!HASHITEM_EMPTY(hi)) 3594 { 3595 di = HI2DI(hi); 3596 if (var_check_fixed(di->di_flags, name) 3597 || var_check_ro(di->di_flags, name)) 3598 return FAIL; 3599 delete_var(ht, hi); 3600 return OK; 3601 } 3602 } 3603 if (forceit) 3604 return OK; 3605 EMSG2(_("E108: No such variable: \"%s\""), name); 3606 return FAIL; 3607} 3608 3609/* 3610 * Lock or unlock variable indicated by "lp". 3611 * "deep" is the levels to go (-1 for unlimited); 3612 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3613 */ 3614 static int 3615do_lock_var(lp, name_end, deep, lock) 3616 lval_T *lp; 3617 char_u *name_end; 3618 int deep; 3619 int lock; 3620{ 3621 int ret = OK; 3622 int cc; 3623 dictitem_T *di; 3624 3625 if (deep == 0) /* nothing to do */ 3626 return OK; 3627 3628 if (lp->ll_tv == NULL) 3629 { 3630 cc = *name_end; 3631 *name_end = NUL; 3632 3633 /* Normal name or expanded name. */ 3634 if (check_changedtick(lp->ll_name)) 3635 ret = FAIL; 3636 else 3637 { 3638 di = find_var(lp->ll_name, NULL); 3639 if (di == NULL) 3640 ret = FAIL; 3641 else 3642 { 3643 if (lock) 3644 di->di_flags |= DI_FLAGS_LOCK; 3645 else 3646 di->di_flags &= ~DI_FLAGS_LOCK; 3647 item_lock(&di->di_tv, deep, lock); 3648 } 3649 } 3650 *name_end = cc; 3651 } 3652 else if (lp->ll_range) 3653 { 3654 listitem_T *li = lp->ll_li; 3655 3656 /* (un)lock a range of List items. */ 3657 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3658 { 3659 item_lock(&li->li_tv, deep, lock); 3660 li = li->li_next; 3661 ++lp->ll_n1; 3662 } 3663 } 3664 else if (lp->ll_list != NULL) 3665 /* (un)lock a List item. */ 3666 item_lock(&lp->ll_li->li_tv, deep, lock); 3667 else 3668 /* un(lock) a Dictionary item. */ 3669 item_lock(&lp->ll_di->di_tv, deep, lock); 3670 3671 return ret; 3672} 3673 3674/* 3675 * Lock or unlock an item. "deep" is nr of levels to go. 3676 */ 3677 static void 3678item_lock(tv, deep, lock) 3679 typval_T *tv; 3680 int deep; 3681 int lock; 3682{ 3683 static int recurse = 0; 3684 list_T *l; 3685 listitem_T *li; 3686 dict_T *d; 3687 hashitem_T *hi; 3688 int todo; 3689 3690 if (recurse >= DICT_MAXNEST) 3691 { 3692 EMSG(_("E743: variable nested too deep for (un)lock")); 3693 return; 3694 } 3695 if (deep == 0) 3696 return; 3697 ++recurse; 3698 3699 /* lock/unlock the item itself */ 3700 if (lock) 3701 tv->v_lock |= VAR_LOCKED; 3702 else 3703 tv->v_lock &= ~VAR_LOCKED; 3704 3705 switch (tv->v_type) 3706 { 3707 case VAR_LIST: 3708 if ((l = tv->vval.v_list) != NULL) 3709 { 3710 if (lock) 3711 l->lv_lock |= VAR_LOCKED; 3712 else 3713 l->lv_lock &= ~VAR_LOCKED; 3714 if (deep < 0 || deep > 1) 3715 /* recursive: lock/unlock the items the List contains */ 3716 for (li = l->lv_first; li != NULL; li = li->li_next) 3717 item_lock(&li->li_tv, deep - 1, lock); 3718 } 3719 break; 3720 case VAR_DICT: 3721 if ((d = tv->vval.v_dict) != NULL) 3722 { 3723 if (lock) 3724 d->dv_lock |= VAR_LOCKED; 3725 else 3726 d->dv_lock &= ~VAR_LOCKED; 3727 if (deep < 0 || deep > 1) 3728 { 3729 /* recursive: lock/unlock the items the List contains */ 3730 todo = (int)d->dv_hashtab.ht_used; 3731 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3732 { 3733 if (!HASHITEM_EMPTY(hi)) 3734 { 3735 --todo; 3736 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3737 } 3738 } 3739 } 3740 } 3741 } 3742 --recurse; 3743} 3744 3745/* 3746 * Return TRUE if typeval "tv" is locked: Either that value is locked itself 3747 * or it refers to a List or Dictionary that is locked. 3748 */ 3749 static int 3750tv_islocked(tv) 3751 typval_T *tv; 3752{ 3753 return (tv->v_lock & VAR_LOCKED) 3754 || (tv->v_type == VAR_LIST 3755 && tv->vval.v_list != NULL 3756 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3757 || (tv->v_type == VAR_DICT 3758 && tv->vval.v_dict != NULL 3759 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3760} 3761 3762#if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3763/* 3764 * Delete all "menutrans_" variables. 3765 */ 3766 void 3767del_menutrans_vars() 3768{ 3769 hashitem_T *hi; 3770 int todo; 3771 3772 hash_lock(&globvarht); 3773 todo = (int)globvarht.ht_used; 3774 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3775 { 3776 if (!HASHITEM_EMPTY(hi)) 3777 { 3778 --todo; 3779 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3780 delete_var(&globvarht, hi); 3781 } 3782 } 3783 hash_unlock(&globvarht); 3784} 3785#endif 3786 3787#if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3788 3789/* 3790 * Local string buffer for the next two functions to store a variable name 3791 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3792 * get_user_var_name(). 3793 */ 3794 3795static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3796 3797static char_u *varnamebuf = NULL; 3798static int varnamebuflen = 0; 3799 3800/* 3801 * Function to concatenate a prefix and a variable name. 3802 */ 3803 static char_u * 3804cat_prefix_varname(prefix, name) 3805 int prefix; 3806 char_u *name; 3807{ 3808 int len; 3809 3810 len = (int)STRLEN(name) + 3; 3811 if (len > varnamebuflen) 3812 { 3813 vim_free(varnamebuf); 3814 len += 10; /* some additional space */ 3815 varnamebuf = alloc(len); 3816 if (varnamebuf == NULL) 3817 { 3818 varnamebuflen = 0; 3819 return NULL; 3820 } 3821 varnamebuflen = len; 3822 } 3823 *varnamebuf = prefix; 3824 varnamebuf[1] = ':'; 3825 STRCPY(varnamebuf + 2, name); 3826 return varnamebuf; 3827} 3828 3829/* 3830 * Function given to ExpandGeneric() to obtain the list of user defined 3831 * (global/buffer/window/built-in) variable names. 3832 */ 3833 char_u * 3834get_user_var_name(xp, idx) 3835 expand_T *xp; 3836 int idx; 3837{ 3838 static long_u gdone; 3839 static long_u bdone; 3840 static long_u wdone; 3841#ifdef FEAT_WINDOWS 3842 static long_u tdone; 3843#endif 3844 static int vidx; 3845 static hashitem_T *hi; 3846 hashtab_T *ht; 3847 3848 if (idx == 0) 3849 { 3850 gdone = bdone = wdone = vidx = 0; 3851#ifdef FEAT_WINDOWS 3852 tdone = 0; 3853#endif 3854 } 3855 3856 /* Global variables */ 3857 if (gdone < globvarht.ht_used) 3858 { 3859 if (gdone++ == 0) 3860 hi = globvarht.ht_array; 3861 else 3862 ++hi; 3863 while (HASHITEM_EMPTY(hi)) 3864 ++hi; 3865 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3866 return cat_prefix_varname('g', hi->hi_key); 3867 return hi->hi_key; 3868 } 3869 3870 /* b: variables */ 3871 ht = &curbuf->b_vars.dv_hashtab; 3872 if (bdone < ht->ht_used) 3873 { 3874 if (bdone++ == 0) 3875 hi = ht->ht_array; 3876 else 3877 ++hi; 3878 while (HASHITEM_EMPTY(hi)) 3879 ++hi; 3880 return cat_prefix_varname('b', hi->hi_key); 3881 } 3882 if (bdone == ht->ht_used) 3883 { 3884 ++bdone; 3885 return (char_u *)"b:changedtick"; 3886 } 3887 3888 /* w: variables */ 3889 ht = &curwin->w_vars.dv_hashtab; 3890 if (wdone < ht->ht_used) 3891 { 3892 if (wdone++ == 0) 3893 hi = ht->ht_array; 3894 else 3895 ++hi; 3896 while (HASHITEM_EMPTY(hi)) 3897 ++hi; 3898 return cat_prefix_varname('w', hi->hi_key); 3899 } 3900 3901#ifdef FEAT_WINDOWS 3902 /* t: variables */ 3903 ht = &curtab->tp_vars.dv_hashtab; 3904 if (tdone < ht->ht_used) 3905 { 3906 if (tdone++ == 0) 3907 hi = ht->ht_array; 3908 else 3909 ++hi; 3910 while (HASHITEM_EMPTY(hi)) 3911 ++hi; 3912 return cat_prefix_varname('t', hi->hi_key); 3913 } 3914#endif 3915 3916 /* v: variables */ 3917 if (vidx < VV_LEN) 3918 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3919 3920 vim_free(varnamebuf); 3921 varnamebuf = NULL; 3922 varnamebuflen = 0; 3923 return NULL; 3924} 3925 3926#endif /* FEAT_CMDL_COMPL */ 3927 3928/* 3929 * types for expressions. 3930 */ 3931typedef enum 3932{ 3933 TYPE_UNKNOWN = 0 3934 , TYPE_EQUAL /* == */ 3935 , TYPE_NEQUAL /* != */ 3936 , TYPE_GREATER /* > */ 3937 , TYPE_GEQUAL /* >= */ 3938 , TYPE_SMALLER /* < */ 3939 , TYPE_SEQUAL /* <= */ 3940 , TYPE_MATCH /* =~ */ 3941 , TYPE_NOMATCH /* !~ */ 3942} exptype_T; 3943 3944/* 3945 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3946 * executed. The function may return OK, but the rettv will be of type 3947 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3948 */ 3949 3950/* 3951 * Handle zero level expression. 3952 * This calls eval1() and handles error message and nextcmd. 3953 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3954 * Note: "rettv.v_lock" is not set. 3955 * Return OK or FAIL. 3956 */ 3957 static int 3958eval0(arg, rettv, nextcmd, evaluate) 3959 char_u *arg; 3960 typval_T *rettv; 3961 char_u **nextcmd; 3962 int evaluate; 3963{ 3964 int ret; 3965 char_u *p; 3966 3967 p = skipwhite(arg); 3968 ret = eval1(&p, rettv, evaluate); 3969 if (ret == FAIL || !ends_excmd(*p)) 3970 { 3971 if (ret != FAIL) 3972 clear_tv(rettv); 3973 /* 3974 * Report the invalid expression unless the expression evaluation has 3975 * been cancelled due to an aborting error, an interrupt, or an 3976 * exception. 3977 */ 3978 if (!aborting()) 3979 EMSG2(_(e_invexpr2), arg); 3980 ret = FAIL; 3981 } 3982 if (nextcmd != NULL) 3983 *nextcmd = check_nextcmd(p); 3984 3985 return ret; 3986} 3987 3988/* 3989 * Handle top level expression: 3990 * expr2 ? expr1 : expr1 3991 * 3992 * "arg" must point to the first non-white of the expression. 3993 * "arg" is advanced to the next non-white after the recognized expression. 3994 * 3995 * Note: "rettv.v_lock" is not set. 3996 * 3997 * Return OK or FAIL. 3998 */ 3999 static int 4000eval1(arg, rettv, evaluate) 4001 char_u **arg; 4002 typval_T *rettv; 4003 int evaluate; 4004{ 4005 int result; 4006 typval_T var2; 4007 4008 /* 4009 * Get the first variable. 4010 */ 4011 if (eval2(arg, rettv, evaluate) == FAIL) 4012 return FAIL; 4013 4014 if ((*arg)[0] == '?') 4015 { 4016 result = FALSE; 4017 if (evaluate) 4018 { 4019 int error = FALSE; 4020 4021 if (get_tv_number_chk(rettv, &error) != 0) 4022 result = TRUE; 4023 clear_tv(rettv); 4024 if (error) 4025 return FAIL; 4026 } 4027 4028 /* 4029 * Get the second variable. 4030 */ 4031 *arg = skipwhite(*arg + 1); 4032 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 4033 return FAIL; 4034 4035 /* 4036 * Check for the ":". 4037 */ 4038 if ((*arg)[0] != ':') 4039 { 4040 EMSG(_("E109: Missing ':' after '?'")); 4041 if (evaluate && result) 4042 clear_tv(rettv); 4043 return FAIL; 4044 } 4045 4046 /* 4047 * Get the third variable. 4048 */ 4049 *arg = skipwhite(*arg + 1); 4050 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 4051 { 4052 if (evaluate && result) 4053 clear_tv(rettv); 4054 return FAIL; 4055 } 4056 if (evaluate && !result) 4057 *rettv = var2; 4058 } 4059 4060 return OK; 4061} 4062 4063/* 4064 * Handle first level expression: 4065 * expr2 || expr2 || expr2 logical OR 4066 * 4067 * "arg" must point to the first non-white of the expression. 4068 * "arg" is advanced to the next non-white after the recognized expression. 4069 * 4070 * Return OK or FAIL. 4071 */ 4072 static int 4073eval2(arg, rettv, evaluate) 4074 char_u **arg; 4075 typval_T *rettv; 4076 int evaluate; 4077{ 4078 typval_T var2; 4079 long result; 4080 int first; 4081 int error = FALSE; 4082 4083 /* 4084 * Get the first variable. 4085 */ 4086 if (eval3(arg, rettv, evaluate) == FAIL) 4087 return FAIL; 4088 4089 /* 4090 * Repeat until there is no following "||". 4091 */ 4092 first = TRUE; 4093 result = FALSE; 4094 while ((*arg)[0] == '|' && (*arg)[1] == '|') 4095 { 4096 if (evaluate && first) 4097 { 4098 if (get_tv_number_chk(rettv, &error) != 0) 4099 result = TRUE; 4100 clear_tv(rettv); 4101 if (error) 4102 return FAIL; 4103 first = FALSE; 4104 } 4105 4106 /* 4107 * Get the second variable. 4108 */ 4109 *arg = skipwhite(*arg + 2); 4110 if (eval3(arg, &var2, evaluate && !result) == FAIL) 4111 return FAIL; 4112 4113 /* 4114 * Compute the result. 4115 */ 4116 if (evaluate && !result) 4117 { 4118 if (get_tv_number_chk(&var2, &error) != 0) 4119 result = TRUE; 4120 clear_tv(&var2); 4121 if (error) 4122 return FAIL; 4123 } 4124 if (evaluate) 4125 { 4126 rettv->v_type = VAR_NUMBER; 4127 rettv->vval.v_number = result; 4128 } 4129 } 4130 4131 return OK; 4132} 4133 4134/* 4135 * Handle second level expression: 4136 * expr3 && expr3 && expr3 logical AND 4137 * 4138 * "arg" must point to the first non-white of the expression. 4139 * "arg" is advanced to the next non-white after the recognized expression. 4140 * 4141 * Return OK or FAIL. 4142 */ 4143 static int 4144eval3(arg, rettv, evaluate) 4145 char_u **arg; 4146 typval_T *rettv; 4147 int evaluate; 4148{ 4149 typval_T var2; 4150 long result; 4151 int first; 4152 int error = FALSE; 4153 4154 /* 4155 * Get the first variable. 4156 */ 4157 if (eval4(arg, rettv, evaluate) == FAIL) 4158 return FAIL; 4159 4160 /* 4161 * Repeat until there is no following "&&". 4162 */ 4163 first = TRUE; 4164 result = TRUE; 4165 while ((*arg)[0] == '&' && (*arg)[1] == '&') 4166 { 4167 if (evaluate && first) 4168 { 4169 if (get_tv_number_chk(rettv, &error) == 0) 4170 result = FALSE; 4171 clear_tv(rettv); 4172 if (error) 4173 return FAIL; 4174 first = FALSE; 4175 } 4176 4177 /* 4178 * Get the second variable. 4179 */ 4180 *arg = skipwhite(*arg + 2); 4181 if (eval4(arg, &var2, evaluate && result) == FAIL) 4182 return FAIL; 4183 4184 /* 4185 * Compute the result. 4186 */ 4187 if (evaluate && result) 4188 { 4189 if (get_tv_number_chk(&var2, &error) == 0) 4190 result = FALSE; 4191 clear_tv(&var2); 4192 if (error) 4193 return FAIL; 4194 } 4195 if (evaluate) 4196 { 4197 rettv->v_type = VAR_NUMBER; 4198 rettv->vval.v_number = result; 4199 } 4200 } 4201 4202 return OK; 4203} 4204 4205/* 4206 * Handle third level expression: 4207 * var1 == var2 4208 * var1 =~ var2 4209 * var1 != var2 4210 * var1 !~ var2 4211 * var1 > var2 4212 * var1 >= var2 4213 * var1 < var2 4214 * var1 <= var2 4215 * var1 is var2 4216 * var1 isnot var2 4217 * 4218 * "arg" must point to the first non-white of the expression. 4219 * "arg" is advanced to the next non-white after the recognized expression. 4220 * 4221 * Return OK or FAIL. 4222 */ 4223 static int 4224eval4(arg, rettv, evaluate) 4225 char_u **arg; 4226 typval_T *rettv; 4227 int evaluate; 4228{ 4229 typval_T var2; 4230 char_u *p; 4231 int i; 4232 exptype_T type = TYPE_UNKNOWN; 4233 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4234 int len = 2; 4235 long n1, n2; 4236 char_u *s1, *s2; 4237 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4238 regmatch_T regmatch; 4239 int ic; 4240 char_u *save_cpo; 4241 4242 /* 4243 * Get the first variable. 4244 */ 4245 if (eval5(arg, rettv, evaluate) == FAIL) 4246 return FAIL; 4247 4248 p = *arg; 4249 switch (p[0]) 4250 { 4251 case '=': if (p[1] == '=') 4252 type = TYPE_EQUAL; 4253 else if (p[1] == '~') 4254 type = TYPE_MATCH; 4255 break; 4256 case '!': if (p[1] == '=') 4257 type = TYPE_NEQUAL; 4258 else if (p[1] == '~') 4259 type = TYPE_NOMATCH; 4260 break; 4261 case '>': if (p[1] != '=') 4262 { 4263 type = TYPE_GREATER; 4264 len = 1; 4265 } 4266 else 4267 type = TYPE_GEQUAL; 4268 break; 4269 case '<': if (p[1] != '=') 4270 { 4271 type = TYPE_SMALLER; 4272 len = 1; 4273 } 4274 else 4275 type = TYPE_SEQUAL; 4276 break; 4277 case 'i': if (p[1] == 's') 4278 { 4279 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4280 len = 5; 4281 if (!vim_isIDc(p[len])) 4282 { 4283 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4284 type_is = TRUE; 4285 } 4286 } 4287 break; 4288 } 4289 4290 /* 4291 * If there is a comparative operator, use it. 4292 */ 4293 if (type != TYPE_UNKNOWN) 4294 { 4295 /* extra question mark appended: ignore case */ 4296 if (p[len] == '?') 4297 { 4298 ic = TRUE; 4299 ++len; 4300 } 4301 /* extra '#' appended: match case */ 4302 else if (p[len] == '#') 4303 { 4304 ic = FALSE; 4305 ++len; 4306 } 4307 /* nothing appended: use 'ignorecase' */ 4308 else 4309 ic = p_ic; 4310 4311 /* 4312 * Get the second variable. 4313 */ 4314 *arg = skipwhite(p + len); 4315 if (eval5(arg, &var2, evaluate) == FAIL) 4316 { 4317 clear_tv(rettv); 4318 return FAIL; 4319 } 4320 4321 if (evaluate) 4322 { 4323 if (type_is && rettv->v_type != var2.v_type) 4324 { 4325 /* For "is" a different type always means FALSE, for "notis" 4326 * it means TRUE. */ 4327 n1 = (type == TYPE_NEQUAL); 4328 } 4329 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4330 { 4331 if (type_is) 4332 { 4333 n1 = (rettv->v_type == var2.v_type 4334 && rettv->vval.v_list == var2.vval.v_list); 4335 if (type == TYPE_NEQUAL) 4336 n1 = !n1; 4337 } 4338 else if (rettv->v_type != var2.v_type 4339 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4340 { 4341 if (rettv->v_type != var2.v_type) 4342 EMSG(_("E691: Can only compare List with List")); 4343 else 4344 EMSG(_("E692: Invalid operation for Lists")); 4345 clear_tv(rettv); 4346 clear_tv(&var2); 4347 return FAIL; 4348 } 4349 else 4350 { 4351 /* Compare two Lists for being equal or unequal. */ 4352 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4353 if (type == TYPE_NEQUAL) 4354 n1 = !n1; 4355 } 4356 } 4357 4358 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4359 { 4360 if (type_is) 4361 { 4362 n1 = (rettv->v_type == var2.v_type 4363 && rettv->vval.v_dict == var2.vval.v_dict); 4364 if (type == TYPE_NEQUAL) 4365 n1 = !n1; 4366 } 4367 else if (rettv->v_type != var2.v_type 4368 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4369 { 4370 if (rettv->v_type != var2.v_type) 4371 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4372 else 4373 EMSG(_("E736: Invalid operation for Dictionary")); 4374 clear_tv(rettv); 4375 clear_tv(&var2); 4376 return FAIL; 4377 } 4378 else 4379 { 4380 /* Compare two Dictionaries for being equal or unequal. */ 4381 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4382 if (type == TYPE_NEQUAL) 4383 n1 = !n1; 4384 } 4385 } 4386 4387 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4388 { 4389 if (rettv->v_type != var2.v_type 4390 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4391 { 4392 if (rettv->v_type != var2.v_type) 4393 EMSG(_("E693: Can only compare Funcref with Funcref")); 4394 else 4395 EMSG(_("E694: Invalid operation for Funcrefs")); 4396 clear_tv(rettv); 4397 clear_tv(&var2); 4398 return FAIL; 4399 } 4400 else 4401 { 4402 /* Compare two Funcrefs for being equal or unequal. */ 4403 if (rettv->vval.v_string == NULL 4404 || var2.vval.v_string == NULL) 4405 n1 = FALSE; 4406 else 4407 n1 = STRCMP(rettv->vval.v_string, 4408 var2.vval.v_string) == 0; 4409 if (type == TYPE_NEQUAL) 4410 n1 = !n1; 4411 } 4412 } 4413 4414#ifdef FEAT_FLOAT 4415 /* 4416 * If one of the two variables is a float, compare as a float. 4417 * When using "=~" or "!~", always compare as string. 4418 */ 4419 else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4420 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4421 { 4422 float_T f1, f2; 4423 4424 if (rettv->v_type == VAR_FLOAT) 4425 f1 = rettv->vval.v_float; 4426 else 4427 f1 = get_tv_number(rettv); 4428 if (var2.v_type == VAR_FLOAT) 4429 f2 = var2.vval.v_float; 4430 else 4431 f2 = get_tv_number(&var2); 4432 n1 = FALSE; 4433 switch (type) 4434 { 4435 case TYPE_EQUAL: n1 = (f1 == f2); break; 4436 case TYPE_NEQUAL: n1 = (f1 != f2); break; 4437 case TYPE_GREATER: n1 = (f1 > f2); break; 4438 case TYPE_GEQUAL: n1 = (f1 >= f2); break; 4439 case TYPE_SMALLER: n1 = (f1 < f2); break; 4440 case TYPE_SEQUAL: n1 = (f1 <= f2); break; 4441 case TYPE_UNKNOWN: 4442 case TYPE_MATCH: 4443 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4444 } 4445 } 4446#endif 4447 4448 /* 4449 * If one of the two variables is a number, compare as a number. 4450 * When using "=~" or "!~", always compare as string. 4451 */ 4452 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4453 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4454 { 4455 n1 = get_tv_number(rettv); 4456 n2 = get_tv_number(&var2); 4457 switch (type) 4458 { 4459 case TYPE_EQUAL: n1 = (n1 == n2); break; 4460 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4461 case TYPE_GREATER: n1 = (n1 > n2); break; 4462 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4463 case TYPE_SMALLER: n1 = (n1 < n2); break; 4464 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4465 case TYPE_UNKNOWN: 4466 case TYPE_MATCH: 4467 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4468 } 4469 } 4470 else 4471 { 4472 s1 = get_tv_string_buf(rettv, buf1); 4473 s2 = get_tv_string_buf(&var2, buf2); 4474 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4475 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4476 else 4477 i = 0; 4478 n1 = FALSE; 4479 switch (type) 4480 { 4481 case TYPE_EQUAL: n1 = (i == 0); break; 4482 case TYPE_NEQUAL: n1 = (i != 0); break; 4483 case TYPE_GREATER: n1 = (i > 0); break; 4484 case TYPE_GEQUAL: n1 = (i >= 0); break; 4485 case TYPE_SMALLER: n1 = (i < 0); break; 4486 case TYPE_SEQUAL: n1 = (i <= 0); break; 4487 4488 case TYPE_MATCH: 4489 case TYPE_NOMATCH: 4490 /* avoid 'l' flag in 'cpoptions' */ 4491 save_cpo = p_cpo; 4492 p_cpo = (char_u *)""; 4493 regmatch.regprog = vim_regcomp(s2, 4494 RE_MAGIC + RE_STRING); 4495 regmatch.rm_ic = ic; 4496 if (regmatch.regprog != NULL) 4497 { 4498 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4499 vim_free(regmatch.regprog); 4500 if (type == TYPE_NOMATCH) 4501 n1 = !n1; 4502 } 4503 p_cpo = save_cpo; 4504 break; 4505 4506 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4507 } 4508 } 4509 clear_tv(rettv); 4510 clear_tv(&var2); 4511 rettv->v_type = VAR_NUMBER; 4512 rettv->vval.v_number = n1; 4513 } 4514 } 4515 4516 return OK; 4517} 4518 4519/* 4520 * Handle fourth level expression: 4521 * + number addition 4522 * - number subtraction 4523 * . string concatenation 4524 * 4525 * "arg" must point to the first non-white of the expression. 4526 * "arg" is advanced to the next non-white after the recognized expression. 4527 * 4528 * Return OK or FAIL. 4529 */ 4530 static int 4531eval5(arg, rettv, evaluate) 4532 char_u **arg; 4533 typval_T *rettv; 4534 int evaluate; 4535{ 4536 typval_T var2; 4537 typval_T var3; 4538 int op; 4539 long n1, n2; 4540#ifdef FEAT_FLOAT 4541 float_T f1 = 0, f2 = 0; 4542#endif 4543 char_u *s1, *s2; 4544 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4545 char_u *p; 4546 4547 /* 4548 * Get the first variable. 4549 */ 4550 if (eval6(arg, rettv, evaluate, FALSE) == FAIL) 4551 return FAIL; 4552 4553 /* 4554 * Repeat computing, until no '+', '-' or '.' is following. 4555 */ 4556 for (;;) 4557 { 4558 op = **arg; 4559 if (op != '+' && op != '-' && op != '.') 4560 break; 4561 4562 if ((op != '+' || rettv->v_type != VAR_LIST) 4563#ifdef FEAT_FLOAT 4564 && (op == '.' || rettv->v_type != VAR_FLOAT) 4565#endif 4566 ) 4567 { 4568 /* For "list + ...", an illegal use of the first operand as 4569 * a number cannot be determined before evaluating the 2nd 4570 * operand: if this is also a list, all is ok. 4571 * For "something . ...", "something - ..." or "non-list + ...", 4572 * we know that the first operand needs to be a string or number 4573 * without evaluating the 2nd operand. So check before to avoid 4574 * side effects after an error. */ 4575 if (evaluate && get_tv_string_chk(rettv) == NULL) 4576 { 4577 clear_tv(rettv); 4578 return FAIL; 4579 } 4580 } 4581 4582 /* 4583 * Get the second variable. 4584 */ 4585 *arg = skipwhite(*arg + 1); 4586 if (eval6(arg, &var2, evaluate, op == '.') == FAIL) 4587 { 4588 clear_tv(rettv); 4589 return FAIL; 4590 } 4591 4592 if (evaluate) 4593 { 4594 /* 4595 * Compute the result. 4596 */ 4597 if (op == '.') 4598 { 4599 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4600 s2 = get_tv_string_buf_chk(&var2, buf2); 4601 if (s2 == NULL) /* type error ? */ 4602 { 4603 clear_tv(rettv); 4604 clear_tv(&var2); 4605 return FAIL; 4606 } 4607 p = concat_str(s1, s2); 4608 clear_tv(rettv); 4609 rettv->v_type = VAR_STRING; 4610 rettv->vval.v_string = p; 4611 } 4612 else if (op == '+' && rettv->v_type == VAR_LIST 4613 && var2.v_type == VAR_LIST) 4614 { 4615 /* concatenate Lists */ 4616 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4617 &var3) == FAIL) 4618 { 4619 clear_tv(rettv); 4620 clear_tv(&var2); 4621 return FAIL; 4622 } 4623 clear_tv(rettv); 4624 *rettv = var3; 4625 } 4626 else 4627 { 4628 int error = FALSE; 4629 4630#ifdef FEAT_FLOAT 4631 if (rettv->v_type == VAR_FLOAT) 4632 { 4633 f1 = rettv->vval.v_float; 4634 n1 = 0; 4635 } 4636 else 4637#endif 4638 { 4639 n1 = get_tv_number_chk(rettv, &error); 4640 if (error) 4641 { 4642 /* This can only happen for "list + non-list". For 4643 * "non-list + ..." or "something - ...", we returned 4644 * before evaluating the 2nd operand. */ 4645 clear_tv(rettv); 4646 return FAIL; 4647 } 4648#ifdef FEAT_FLOAT 4649 if (var2.v_type == VAR_FLOAT) 4650 f1 = n1; 4651#endif 4652 } 4653#ifdef FEAT_FLOAT 4654 if (var2.v_type == VAR_FLOAT) 4655 { 4656 f2 = var2.vval.v_float; 4657 n2 = 0; 4658 } 4659 else 4660#endif 4661 { 4662 n2 = get_tv_number_chk(&var2, &error); 4663 if (error) 4664 { 4665 clear_tv(rettv); 4666 clear_tv(&var2); 4667 return FAIL; 4668 } 4669#ifdef FEAT_FLOAT 4670 if (rettv->v_type == VAR_FLOAT) 4671 f2 = n2; 4672#endif 4673 } 4674 clear_tv(rettv); 4675 4676#ifdef FEAT_FLOAT 4677 /* If there is a float on either side the result is a float. */ 4678 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) 4679 { 4680 if (op == '+') 4681 f1 = f1 + f2; 4682 else 4683 f1 = f1 - f2; 4684 rettv->v_type = VAR_FLOAT; 4685 rettv->vval.v_float = f1; 4686 } 4687 else 4688#endif 4689 { 4690 if (op == '+') 4691 n1 = n1 + n2; 4692 else 4693 n1 = n1 - n2; 4694 rettv->v_type = VAR_NUMBER; 4695 rettv->vval.v_number = n1; 4696 } 4697 } 4698 clear_tv(&var2); 4699 } 4700 } 4701 return OK; 4702} 4703 4704/* 4705 * Handle fifth level expression: 4706 * * number multiplication 4707 * / number division 4708 * % number modulo 4709 * 4710 * "arg" must point to the first non-white of the expression. 4711 * "arg" is advanced to the next non-white after the recognized expression. 4712 * 4713 * Return OK or FAIL. 4714 */ 4715 static int 4716eval6(arg, rettv, evaluate, want_string) 4717 char_u **arg; 4718 typval_T *rettv; 4719 int evaluate; 4720 int want_string; /* after "." operator */ 4721{ 4722 typval_T var2; 4723 int op; 4724 long n1, n2; 4725#ifdef FEAT_FLOAT 4726 int use_float = FALSE; 4727 float_T f1 = 0, f2; 4728#endif 4729 int error = FALSE; 4730 4731 /* 4732 * Get the first variable. 4733 */ 4734 if (eval7(arg, rettv, evaluate, want_string) == FAIL) 4735 return FAIL; 4736 4737 /* 4738 * Repeat computing, until no '*', '/' or '%' is following. 4739 */ 4740 for (;;) 4741 { 4742 op = **arg; 4743 if (op != '*' && op != '/' && op != '%') 4744 break; 4745 4746 if (evaluate) 4747 { 4748#ifdef FEAT_FLOAT 4749 if (rettv->v_type == VAR_FLOAT) 4750 { 4751 f1 = rettv->vval.v_float; 4752 use_float = TRUE; 4753 n1 = 0; 4754 } 4755 else 4756#endif 4757 n1 = get_tv_number_chk(rettv, &error); 4758 clear_tv(rettv); 4759 if (error) 4760 return FAIL; 4761 } 4762 else 4763 n1 = 0; 4764 4765 /* 4766 * Get the second variable. 4767 */ 4768 *arg = skipwhite(*arg + 1); 4769 if (eval7(arg, &var2, evaluate, FALSE) == FAIL) 4770 return FAIL; 4771 4772 if (evaluate) 4773 { 4774#ifdef FEAT_FLOAT 4775 if (var2.v_type == VAR_FLOAT) 4776 { 4777 if (!use_float) 4778 { 4779 f1 = n1; 4780 use_float = TRUE; 4781 } 4782 f2 = var2.vval.v_float; 4783 n2 = 0; 4784 } 4785 else 4786#endif 4787 { 4788 n2 = get_tv_number_chk(&var2, &error); 4789 clear_tv(&var2); 4790 if (error) 4791 return FAIL; 4792#ifdef FEAT_FLOAT 4793 if (use_float) 4794 f2 = n2; 4795#endif 4796 } 4797 4798 /* 4799 * Compute the result. 4800 * When either side is a float the result is a float. 4801 */ 4802#ifdef FEAT_FLOAT 4803 if (use_float) 4804 { 4805 if (op == '*') 4806 f1 = f1 * f2; 4807 else if (op == '/') 4808 { 4809# ifdef VMS 4810 /* VMS crashes on divide by zero, work around it */ 4811 if (f2 == 0.0) 4812 { 4813 if (f1 == 0) 4814 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */ 4815 else if (f1 < 0) 4816 f1 = -1 * __F_FLT_MAX; 4817 else 4818 f1 = __F_FLT_MAX; 4819 } 4820 else 4821 f1 = f1 / f2; 4822# else 4823 /* We rely on the floating point library to handle divide 4824 * by zero to result in "inf" and not a crash. */ 4825 f1 = f1 / f2; 4826# endif 4827 } 4828 else 4829 { 4830 EMSG(_("E804: Cannot use '%' with Float")); 4831 return FAIL; 4832 } 4833 rettv->v_type = VAR_FLOAT; 4834 rettv->vval.v_float = f1; 4835 } 4836 else 4837#endif 4838 { 4839 if (op == '*') 4840 n1 = n1 * n2; 4841 else if (op == '/') 4842 { 4843 if (n2 == 0) /* give an error message? */ 4844 { 4845 if (n1 == 0) 4846 n1 = -0x7fffffffL - 1L; /* similar to NaN */ 4847 else if (n1 < 0) 4848 n1 = -0x7fffffffL; 4849 else 4850 n1 = 0x7fffffffL; 4851 } 4852 else 4853 n1 = n1 / n2; 4854 } 4855 else 4856 { 4857 if (n2 == 0) /* give an error message? */ 4858 n1 = 0; 4859 else 4860 n1 = n1 % n2; 4861 } 4862 rettv->v_type = VAR_NUMBER; 4863 rettv->vval.v_number = n1; 4864 } 4865 } 4866 } 4867 4868 return OK; 4869} 4870 4871/* 4872 * Handle sixth level expression: 4873 * number number constant 4874 * "string" string constant 4875 * 'string' literal string constant 4876 * &option-name option value 4877 * @r register contents 4878 * identifier variable value 4879 * function() function call 4880 * $VAR environment variable 4881 * (expression) nested expression 4882 * [expr, expr] List 4883 * {key: val, key: val} Dictionary 4884 * 4885 * Also handle: 4886 * ! in front logical NOT 4887 * - in front unary minus 4888 * + in front unary plus (ignored) 4889 * trailing [] subscript in String or List 4890 * trailing .name entry in Dictionary 4891 * 4892 * "arg" must point to the first non-white of the expression. 4893 * "arg" is advanced to the next non-white after the recognized expression. 4894 * 4895 * Return OK or FAIL. 4896 */ 4897 static int 4898eval7(arg, rettv, evaluate, want_string) 4899 char_u **arg; 4900 typval_T *rettv; 4901 int evaluate; 4902 int want_string UNUSED; /* after "." operator */ 4903{ 4904 long n; 4905 int len; 4906 char_u *s; 4907 char_u *start_leader, *end_leader; 4908 int ret = OK; 4909 char_u *alias; 4910 4911 /* 4912 * Initialise variable so that clear_tv() can't mistake this for a 4913 * string and free a string that isn't there. 4914 */ 4915 rettv->v_type = VAR_UNKNOWN; 4916 4917 /* 4918 * Skip '!' and '-' characters. They are handled later. 4919 */ 4920 start_leader = *arg; 4921 while (**arg == '!' || **arg == '-' || **arg == '+') 4922 *arg = skipwhite(*arg + 1); 4923 end_leader = *arg; 4924 4925 switch (**arg) 4926 { 4927 /* 4928 * Number constant. 4929 */ 4930 case '0': 4931 case '1': 4932 case '2': 4933 case '3': 4934 case '4': 4935 case '5': 4936 case '6': 4937 case '7': 4938 case '8': 4939 case '9': 4940 { 4941#ifdef FEAT_FLOAT 4942 char_u *p = skipdigits(*arg + 1); 4943 int get_float = FALSE; 4944 4945 /* We accept a float when the format matches 4946 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very 4947 * strict to avoid backwards compatibility problems. 4948 * Don't look for a float after the "." operator, so that 4949 * ":let vers = 1.2.3" doesn't fail. */ 4950 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) 4951 { 4952 get_float = TRUE; 4953 p = skipdigits(p + 2); 4954 if (*p == 'e' || *p == 'E') 4955 { 4956 ++p; 4957 if (*p == '-' || *p == '+') 4958 ++p; 4959 if (!vim_isdigit(*p)) 4960 get_float = FALSE; 4961 else 4962 p = skipdigits(p + 1); 4963 } 4964 if (ASCII_ISALPHA(*p) || *p == '.') 4965 get_float = FALSE; 4966 } 4967 if (get_float) 4968 { 4969 float_T f; 4970 4971 *arg += string2float(*arg, &f); 4972 if (evaluate) 4973 { 4974 rettv->v_type = VAR_FLOAT; 4975 rettv->vval.v_float = f; 4976 } 4977 } 4978 else 4979#endif 4980 { 4981 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4982 *arg += len; 4983 if (evaluate) 4984 { 4985 rettv->v_type = VAR_NUMBER; 4986 rettv->vval.v_number = n; 4987 } 4988 } 4989 break; 4990 } 4991 4992 /* 4993 * String constant: "string". 4994 */ 4995 case '"': ret = get_string_tv(arg, rettv, evaluate); 4996 break; 4997 4998 /* 4999 * Literal string constant: 'str''ing'. 5000 */ 5001 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 5002 break; 5003 5004 /* 5005 * List: [expr, expr] 5006 */ 5007 case '[': ret = get_list_tv(arg, rettv, evaluate); 5008 break; 5009 5010 /* 5011 * Dictionary: {key: val, key: val} 5012 */ 5013 case '{': ret = get_dict_tv(arg, rettv, evaluate); 5014 break; 5015 5016 /* 5017 * Option value: &name 5018 */ 5019 case '&': ret = get_option_tv(arg, rettv, evaluate); 5020 break; 5021 5022 /* 5023 * Environment variable: $VAR. 5024 */ 5025 case '$': ret = get_env_tv(arg, rettv, evaluate); 5026 break; 5027 5028 /* 5029 * Register contents: @r. 5030 */ 5031 case '@': ++*arg; 5032 if (evaluate) 5033 { 5034 rettv->v_type = VAR_STRING; 5035 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 5036 } 5037 if (**arg != NUL) 5038 ++*arg; 5039 break; 5040 5041 /* 5042 * nested expression: (expression). 5043 */ 5044 case '(': *arg = skipwhite(*arg + 1); 5045 ret = eval1(arg, rettv, evaluate); /* recursive! */ 5046 if (**arg == ')') 5047 ++*arg; 5048 else if (ret == OK) 5049 { 5050 EMSG(_("E110: Missing ')'")); 5051 clear_tv(rettv); 5052 ret = FAIL; 5053 } 5054 break; 5055 5056 default: ret = NOTDONE; 5057 break; 5058 } 5059 5060 if (ret == NOTDONE) 5061 { 5062 /* 5063 * Must be a variable or function name. 5064 * Can also be a curly-braces kind of name: {expr}. 5065 */ 5066 s = *arg; 5067 len = get_name_len(arg, &alias, evaluate, TRUE); 5068 if (alias != NULL) 5069 s = alias; 5070 5071 if (len <= 0) 5072 ret = FAIL; 5073 else 5074 { 5075 if (**arg == '(') /* recursive! */ 5076 { 5077 /* If "s" is the name of a variable of type VAR_FUNC 5078 * use its contents. */ 5079 s = deref_func_name(s, &len); 5080 5081 /* Invoke the function. */ 5082 ret = get_func_tv(s, len, rettv, arg, 5083 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 5084 &len, evaluate, NULL); 5085 /* Stop the expression evaluation when immediately 5086 * aborting on error, or when an interrupt occurred or 5087 * an exception was thrown but not caught. */ 5088 if (aborting()) 5089 { 5090 if (ret == OK) 5091 clear_tv(rettv); 5092 ret = FAIL; 5093 } 5094 } 5095 else if (evaluate) 5096 ret = get_var_tv(s, len, rettv, TRUE); 5097 else 5098 ret = OK; 5099 } 5100 5101 if (alias != NULL) 5102 vim_free(alias); 5103 } 5104 5105 *arg = skipwhite(*arg); 5106 5107 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 5108 * expr(expr). */ 5109 if (ret == OK) 5110 ret = handle_subscript(arg, rettv, evaluate, TRUE); 5111 5112 /* 5113 * Apply logical NOT and unary '-', from right to left, ignore '+'. 5114 */ 5115 if (ret == OK && evaluate && end_leader > start_leader) 5116 { 5117 int error = FALSE; 5118 int val = 0; 5119#ifdef FEAT_FLOAT 5120 float_T f = 0.0; 5121 5122 if (rettv->v_type == VAR_FLOAT) 5123 f = rettv->vval.v_float; 5124 else 5125#endif 5126 val = get_tv_number_chk(rettv, &error); 5127 if (error) 5128 { 5129 clear_tv(rettv); 5130 ret = FAIL; 5131 } 5132 else 5133 { 5134 while (end_leader > start_leader) 5135 { 5136 --end_leader; 5137 if (*end_leader == '!') 5138 { 5139#ifdef FEAT_FLOAT 5140 if (rettv->v_type == VAR_FLOAT) 5141 f = !f; 5142 else 5143#endif 5144 val = !val; 5145 } 5146 else if (*end_leader == '-') 5147 { 5148#ifdef FEAT_FLOAT 5149 if (rettv->v_type == VAR_FLOAT) 5150 f = -f; 5151 else 5152#endif 5153 val = -val; 5154 } 5155 } 5156#ifdef FEAT_FLOAT 5157 if (rettv->v_type == VAR_FLOAT) 5158 { 5159 clear_tv(rettv); 5160 rettv->vval.v_float = f; 5161 } 5162 else 5163#endif 5164 { 5165 clear_tv(rettv); 5166 rettv->v_type = VAR_NUMBER; 5167 rettv->vval.v_number = val; 5168 } 5169 } 5170 } 5171 5172 return ret; 5173} 5174 5175/* 5176 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 5177 * "*arg" points to the '[' or '.'. 5178 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 5179 */ 5180 static int 5181eval_index(arg, rettv, evaluate, verbose) 5182 char_u **arg; 5183 typval_T *rettv; 5184 int evaluate; 5185 int verbose; /* give error messages */ 5186{ 5187 int empty1 = FALSE, empty2 = FALSE; 5188 typval_T var1, var2; 5189 long n1, n2 = 0; 5190 long len = -1; 5191 int range = FALSE; 5192 char_u *s; 5193 char_u *key = NULL; 5194 5195 if (rettv->v_type == VAR_FUNC 5196#ifdef FEAT_FLOAT 5197 || rettv->v_type == VAR_FLOAT 5198#endif 5199 ) 5200 { 5201 if (verbose) 5202 EMSG(_("E695: Cannot index a Funcref")); 5203 return FAIL; 5204 } 5205 5206 if (**arg == '.') 5207 { 5208 /* 5209 * dict.name 5210 */ 5211 key = *arg + 1; 5212 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 5213 ; 5214 if (len == 0) 5215 return FAIL; 5216 *arg = skipwhite(key + len); 5217 } 5218 else 5219 { 5220 /* 5221 * something[idx] 5222 * 5223 * Get the (first) variable from inside the []. 5224 */ 5225 *arg = skipwhite(*arg + 1); 5226 if (**arg == ':') 5227 empty1 = TRUE; 5228 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 5229 return FAIL; 5230 else if (evaluate && get_tv_string_chk(&var1) == NULL) 5231 { 5232 /* not a number or string */ 5233 clear_tv(&var1); 5234 return FAIL; 5235 } 5236 5237 /* 5238 * Get the second variable from inside the [:]. 5239 */ 5240 if (**arg == ':') 5241 { 5242 range = TRUE; 5243 *arg = skipwhite(*arg + 1); 5244 if (**arg == ']') 5245 empty2 = TRUE; 5246 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 5247 { 5248 if (!empty1) 5249 clear_tv(&var1); 5250 return FAIL; 5251 } 5252 else if (evaluate && get_tv_string_chk(&var2) == NULL) 5253 { 5254 /* not a number or string */ 5255 if (!empty1) 5256 clear_tv(&var1); 5257 clear_tv(&var2); 5258 return FAIL; 5259 } 5260 } 5261 5262 /* Check for the ']'. */ 5263 if (**arg != ']') 5264 { 5265 if (verbose) 5266 EMSG(_(e_missbrac)); 5267 clear_tv(&var1); 5268 if (range) 5269 clear_tv(&var2); 5270 return FAIL; 5271 } 5272 *arg = skipwhite(*arg + 1); /* skip the ']' */ 5273 } 5274 5275 if (evaluate) 5276 { 5277 n1 = 0; 5278 if (!empty1 && rettv->v_type != VAR_DICT) 5279 { 5280 n1 = get_tv_number(&var1); 5281 clear_tv(&var1); 5282 } 5283 if (range) 5284 { 5285 if (empty2) 5286 n2 = -1; 5287 else 5288 { 5289 n2 = get_tv_number(&var2); 5290 clear_tv(&var2); 5291 } 5292 } 5293 5294 switch (rettv->v_type) 5295 { 5296 case VAR_NUMBER: 5297 case VAR_STRING: 5298 s = get_tv_string(rettv); 5299 len = (long)STRLEN(s); 5300 if (range) 5301 { 5302 /* The resulting variable is a substring. If the indexes 5303 * are out of range the result is empty. */ 5304 if (n1 < 0) 5305 { 5306 n1 = len + n1; 5307 if (n1 < 0) 5308 n1 = 0; 5309 } 5310 if (n2 < 0) 5311 n2 = len + n2; 5312 else if (n2 >= len) 5313 n2 = len; 5314 if (n1 >= len || n2 < 0 || n1 > n2) 5315 s = NULL; 5316 else 5317 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 5318 } 5319 else 5320 { 5321 /* The resulting variable is a string of a single 5322 * character. If the index is too big or negative the 5323 * result is empty. */ 5324 if (n1 >= len || n1 < 0) 5325 s = NULL; 5326 else 5327 s = vim_strnsave(s + n1, 1); 5328 } 5329 clear_tv(rettv); 5330 rettv->v_type = VAR_STRING; 5331 rettv->vval.v_string = s; 5332 break; 5333 5334 case VAR_LIST: 5335 len = list_len(rettv->vval.v_list); 5336 if (n1 < 0) 5337 n1 = len + n1; 5338 if (!empty1 && (n1 < 0 || n1 >= len)) 5339 { 5340 /* For a range we allow invalid values and return an empty 5341 * list. A list index out of range is an error. */ 5342 if (!range) 5343 { 5344 if (verbose) 5345 EMSGN(_(e_listidx), n1); 5346 return FAIL; 5347 } 5348 n1 = len; 5349 } 5350 if (range) 5351 { 5352 list_T *l; 5353 listitem_T *item; 5354 5355 if (n2 < 0) 5356 n2 = len + n2; 5357 else if (n2 >= len) 5358 n2 = len - 1; 5359 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 5360 n2 = -1; 5361 l = list_alloc(); 5362 if (l == NULL) 5363 return FAIL; 5364 for (item = list_find(rettv->vval.v_list, n1); 5365 n1 <= n2; ++n1) 5366 { 5367 if (list_append_tv(l, &item->li_tv) == FAIL) 5368 { 5369 list_free(l, TRUE); 5370 return FAIL; 5371 } 5372 item = item->li_next; 5373 } 5374 clear_tv(rettv); 5375 rettv->v_type = VAR_LIST; 5376 rettv->vval.v_list = l; 5377 ++l->lv_refcount; 5378 } 5379 else 5380 { 5381 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 5382 clear_tv(rettv); 5383 *rettv = var1; 5384 } 5385 break; 5386 5387 case VAR_DICT: 5388 if (range) 5389 { 5390 if (verbose) 5391 EMSG(_(e_dictrange)); 5392 if (len == -1) 5393 clear_tv(&var1); 5394 return FAIL; 5395 } 5396 { 5397 dictitem_T *item; 5398 5399 if (len == -1) 5400 { 5401 key = get_tv_string(&var1); 5402 if (*key == NUL) 5403 { 5404 if (verbose) 5405 EMSG(_(e_emptykey)); 5406 clear_tv(&var1); 5407 return FAIL; 5408 } 5409 } 5410 5411 item = dict_find(rettv->vval.v_dict, key, (int)len); 5412 5413 if (item == NULL && verbose) 5414 EMSG2(_(e_dictkey), key); 5415 if (len == -1) 5416 clear_tv(&var1); 5417 if (item == NULL) 5418 return FAIL; 5419 5420 copy_tv(&item->di_tv, &var1); 5421 clear_tv(rettv); 5422 *rettv = var1; 5423 } 5424 break; 5425 } 5426 } 5427 5428 return OK; 5429} 5430 5431/* 5432 * Get an option value. 5433 * "arg" points to the '&' or '+' before the option name. 5434 * "arg" is advanced to character after the option name. 5435 * Return OK or FAIL. 5436 */ 5437 static int 5438get_option_tv(arg, rettv, evaluate) 5439 char_u **arg; 5440 typval_T *rettv; /* when NULL, only check if option exists */ 5441 int evaluate; 5442{ 5443 char_u *option_end; 5444 long numval; 5445 char_u *stringval; 5446 int opt_type; 5447 int c; 5448 int working = (**arg == '+'); /* has("+option") */ 5449 int ret = OK; 5450 int opt_flags; 5451 5452 /* 5453 * Isolate the option name and find its value. 5454 */ 5455 option_end = find_option_end(arg, &opt_flags); 5456 if (option_end == NULL) 5457 { 5458 if (rettv != NULL) 5459 EMSG2(_("E112: Option name missing: %s"), *arg); 5460 return FAIL; 5461 } 5462 5463 if (!evaluate) 5464 { 5465 *arg = option_end; 5466 return OK; 5467 } 5468 5469 c = *option_end; 5470 *option_end = NUL; 5471 opt_type = get_option_value(*arg, &numval, 5472 rettv == NULL ? NULL : &stringval, opt_flags); 5473 5474 if (opt_type == -3) /* invalid name */ 5475 { 5476 if (rettv != NULL) 5477 EMSG2(_("E113: Unknown option: %s"), *arg); 5478 ret = FAIL; 5479 } 5480 else if (rettv != NULL) 5481 { 5482 if (opt_type == -2) /* hidden string option */ 5483 { 5484 rettv->v_type = VAR_STRING; 5485 rettv->vval.v_string = NULL; 5486 } 5487 else if (opt_type == -1) /* hidden number option */ 5488 { 5489 rettv->v_type = VAR_NUMBER; 5490 rettv->vval.v_number = 0; 5491 } 5492 else if (opt_type == 1) /* number option */ 5493 { 5494 rettv->v_type = VAR_NUMBER; 5495 rettv->vval.v_number = numval; 5496 } 5497 else /* string option */ 5498 { 5499 rettv->v_type = VAR_STRING; 5500 rettv->vval.v_string = stringval; 5501 } 5502 } 5503 else if (working && (opt_type == -2 || opt_type == -1)) 5504 ret = FAIL; 5505 5506 *option_end = c; /* put back for error messages */ 5507 *arg = option_end; 5508 5509 return ret; 5510} 5511 5512/* 5513 * Allocate a variable for a string constant. 5514 * Return OK or FAIL. 5515 */ 5516 static int 5517get_string_tv(arg, rettv, evaluate) 5518 char_u **arg; 5519 typval_T *rettv; 5520 int evaluate; 5521{ 5522 char_u *p; 5523 char_u *name; 5524 int extra = 0; 5525 5526 /* 5527 * Find the end of the string, skipping backslashed characters. 5528 */ 5529 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5530 { 5531 if (*p == '\\' && p[1] != NUL) 5532 { 5533 ++p; 5534 /* A "\<x>" form occupies at least 4 characters, and produces up 5535 * to 6 characters: reserve space for 2 extra */ 5536 if (*p == '<') 5537 extra += 2; 5538 } 5539 } 5540 5541 if (*p != '"') 5542 { 5543 EMSG2(_("E114: Missing quote: %s"), *arg); 5544 return FAIL; 5545 } 5546 5547 /* If only parsing, set *arg and return here */ 5548 if (!evaluate) 5549 { 5550 *arg = p + 1; 5551 return OK; 5552 } 5553 5554 /* 5555 * Copy the string into allocated memory, handling backslashed 5556 * characters. 5557 */ 5558 name = alloc((unsigned)(p - *arg + extra)); 5559 if (name == NULL) 5560 return FAIL; 5561 rettv->v_type = VAR_STRING; 5562 rettv->vval.v_string = name; 5563 5564 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5565 { 5566 if (*p == '\\') 5567 { 5568 switch (*++p) 5569 { 5570 case 'b': *name++ = BS; ++p; break; 5571 case 'e': *name++ = ESC; ++p; break; 5572 case 'f': *name++ = FF; ++p; break; 5573 case 'n': *name++ = NL; ++p; break; 5574 case 'r': *name++ = CAR; ++p; break; 5575 case 't': *name++ = TAB; ++p; break; 5576 5577 case 'X': /* hex: "\x1", "\x12" */ 5578 case 'x': 5579 case 'u': /* Unicode: "\u0023" */ 5580 case 'U': 5581 if (vim_isxdigit(p[1])) 5582 { 5583 int n, nr; 5584 int c = toupper(*p); 5585 5586 if (c == 'X') 5587 n = 2; 5588 else 5589 n = 4; 5590 nr = 0; 5591 while (--n >= 0 && vim_isxdigit(p[1])) 5592 { 5593 ++p; 5594 nr = (nr << 4) + hex2nr(*p); 5595 } 5596 ++p; 5597#ifdef FEAT_MBYTE 5598 /* For "\u" store the number according to 5599 * 'encoding'. */ 5600 if (c != 'X') 5601 name += (*mb_char2bytes)(nr, name); 5602 else 5603#endif 5604 *name++ = nr; 5605 } 5606 break; 5607 5608 /* octal: "\1", "\12", "\123" */ 5609 case '0': 5610 case '1': 5611 case '2': 5612 case '3': 5613 case '4': 5614 case '5': 5615 case '6': 5616 case '7': *name = *p++ - '0'; 5617 if (*p >= '0' && *p <= '7') 5618 { 5619 *name = (*name << 3) + *p++ - '0'; 5620 if (*p >= '0' && *p <= '7') 5621 *name = (*name << 3) + *p++ - '0'; 5622 } 5623 ++name; 5624 break; 5625 5626 /* Special key, e.g.: "\<C-W>" */ 5627 case '<': extra = trans_special(&p, name, TRUE); 5628 if (extra != 0) 5629 { 5630 name += extra; 5631 break; 5632 } 5633 /* FALLTHROUGH */ 5634 5635 default: MB_COPY_CHAR(p, name); 5636 break; 5637 } 5638 } 5639 else 5640 MB_COPY_CHAR(p, name); 5641 5642 } 5643 *name = NUL; 5644 *arg = p + 1; 5645 5646 return OK; 5647} 5648 5649/* 5650 * Allocate a variable for a 'str''ing' constant. 5651 * Return OK or FAIL. 5652 */ 5653 static int 5654get_lit_string_tv(arg, rettv, evaluate) 5655 char_u **arg; 5656 typval_T *rettv; 5657 int evaluate; 5658{ 5659 char_u *p; 5660 char_u *str; 5661 int reduce = 0; 5662 5663 /* 5664 * Find the end of the string, skipping ''. 5665 */ 5666 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5667 { 5668 if (*p == '\'') 5669 { 5670 if (p[1] != '\'') 5671 break; 5672 ++reduce; 5673 ++p; 5674 } 5675 } 5676 5677 if (*p != '\'') 5678 { 5679 EMSG2(_("E115: Missing quote: %s"), *arg); 5680 return FAIL; 5681 } 5682 5683 /* If only parsing return after setting "*arg" */ 5684 if (!evaluate) 5685 { 5686 *arg = p + 1; 5687 return OK; 5688 } 5689 5690 /* 5691 * Copy the string into allocated memory, handling '' to ' reduction. 5692 */ 5693 str = alloc((unsigned)((p - *arg) - reduce)); 5694 if (str == NULL) 5695 return FAIL; 5696 rettv->v_type = VAR_STRING; 5697 rettv->vval.v_string = str; 5698 5699 for (p = *arg + 1; *p != NUL; ) 5700 { 5701 if (*p == '\'') 5702 { 5703 if (p[1] != '\'') 5704 break; 5705 ++p; 5706 } 5707 MB_COPY_CHAR(p, str); 5708 } 5709 *str = NUL; 5710 *arg = p + 1; 5711 5712 return OK; 5713} 5714 5715/* 5716 * Allocate a variable for a List and fill it from "*arg". 5717 * Return OK or FAIL. 5718 */ 5719 static int 5720get_list_tv(arg, rettv, evaluate) 5721 char_u **arg; 5722 typval_T *rettv; 5723 int evaluate; 5724{ 5725 list_T *l = NULL; 5726 typval_T tv; 5727 listitem_T *item; 5728 5729 if (evaluate) 5730 { 5731 l = list_alloc(); 5732 if (l == NULL) 5733 return FAIL; 5734 } 5735 5736 *arg = skipwhite(*arg + 1); 5737 while (**arg != ']' && **arg != NUL) 5738 { 5739 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5740 goto failret; 5741 if (evaluate) 5742 { 5743 item = listitem_alloc(); 5744 if (item != NULL) 5745 { 5746 item->li_tv = tv; 5747 item->li_tv.v_lock = 0; 5748 list_append(l, item); 5749 } 5750 else 5751 clear_tv(&tv); 5752 } 5753 5754 if (**arg == ']') 5755 break; 5756 if (**arg != ',') 5757 { 5758 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5759 goto failret; 5760 } 5761 *arg = skipwhite(*arg + 1); 5762 } 5763 5764 if (**arg != ']') 5765 { 5766 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5767failret: 5768 if (evaluate) 5769 list_free(l, TRUE); 5770 return FAIL; 5771 } 5772 5773 *arg = skipwhite(*arg + 1); 5774 if (evaluate) 5775 { 5776 rettv->v_type = VAR_LIST; 5777 rettv->vval.v_list = l; 5778 ++l->lv_refcount; 5779 } 5780 5781 return OK; 5782} 5783 5784/* 5785 * Allocate an empty header for a list. 5786 * Caller should take care of the reference count. 5787 */ 5788 list_T * 5789list_alloc() 5790{ 5791 list_T *l; 5792 5793 l = (list_T *)alloc_clear(sizeof(list_T)); 5794 if (l != NULL) 5795 { 5796 /* Prepend the list to the list of lists for garbage collection. */ 5797 if (first_list != NULL) 5798 first_list->lv_used_prev = l; 5799 l->lv_used_prev = NULL; 5800 l->lv_used_next = first_list; 5801 first_list = l; 5802 } 5803 return l; 5804} 5805 5806/* 5807 * Allocate an empty list for a return value. 5808 * Returns OK or FAIL. 5809 */ 5810 static int 5811rettv_list_alloc(rettv) 5812 typval_T *rettv; 5813{ 5814 list_T *l = list_alloc(); 5815 5816 if (l == NULL) 5817 return FAIL; 5818 5819 rettv->vval.v_list = l; 5820 rettv->v_type = VAR_LIST; 5821 ++l->lv_refcount; 5822 return OK; 5823} 5824 5825/* 5826 * Unreference a list: decrement the reference count and free it when it 5827 * becomes zero. 5828 */ 5829 void 5830list_unref(l) 5831 list_T *l; 5832{ 5833 if (l != NULL && --l->lv_refcount <= 0) 5834 list_free(l, TRUE); 5835} 5836 5837/* 5838 * Free a list, including all items it points to. 5839 * Ignores the reference count. 5840 */ 5841 void 5842list_free(l, recurse) 5843 list_T *l; 5844 int recurse; /* Free Lists and Dictionaries recursively. */ 5845{ 5846 listitem_T *item; 5847 5848 /* Remove the list from the list of lists for garbage collection. */ 5849 if (l->lv_used_prev == NULL) 5850 first_list = l->lv_used_next; 5851 else 5852 l->lv_used_prev->lv_used_next = l->lv_used_next; 5853 if (l->lv_used_next != NULL) 5854 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5855 5856 for (item = l->lv_first; item != NULL; item = l->lv_first) 5857 { 5858 /* Remove the item before deleting it. */ 5859 l->lv_first = item->li_next; 5860 if (recurse || (item->li_tv.v_type != VAR_LIST 5861 && item->li_tv.v_type != VAR_DICT)) 5862 clear_tv(&item->li_tv); 5863 vim_free(item); 5864 } 5865 vim_free(l); 5866} 5867 5868/* 5869 * Allocate a list item. 5870 */ 5871 static listitem_T * 5872listitem_alloc() 5873{ 5874 return (listitem_T *)alloc(sizeof(listitem_T)); 5875} 5876 5877/* 5878 * Free a list item. Also clears the value. Does not notify watchers. 5879 */ 5880 static void 5881listitem_free(item) 5882 listitem_T *item; 5883{ 5884 clear_tv(&item->li_tv); 5885 vim_free(item); 5886} 5887 5888/* 5889 * Remove a list item from a List and free it. Also clears the value. 5890 */ 5891 static void 5892listitem_remove(l, item) 5893 list_T *l; 5894 listitem_T *item; 5895{ 5896 list_remove(l, item, item); 5897 listitem_free(item); 5898} 5899 5900/* 5901 * Get the number of items in a list. 5902 */ 5903 static long 5904list_len(l) 5905 list_T *l; 5906{ 5907 if (l == NULL) 5908 return 0L; 5909 return l->lv_len; 5910} 5911 5912/* 5913 * Return TRUE when two lists have exactly the same values. 5914 */ 5915 static int 5916list_equal(l1, l2, ic) 5917 list_T *l1; 5918 list_T *l2; 5919 int ic; /* ignore case for strings */ 5920{ 5921 listitem_T *item1, *item2; 5922 5923 if (l1 == NULL || l2 == NULL) 5924 return FALSE; 5925 if (l1 == l2) 5926 return TRUE; 5927 if (list_len(l1) != list_len(l2)) 5928 return FALSE; 5929 5930 for (item1 = l1->lv_first, item2 = l2->lv_first; 5931 item1 != NULL && item2 != NULL; 5932 item1 = item1->li_next, item2 = item2->li_next) 5933 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5934 return FALSE; 5935 return item1 == NULL && item2 == NULL; 5936} 5937 5938#if defined(FEAT_RUBY) || defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) \ 5939 || defined(FEAT_MZSCHEME) || defined(FEAT_LUA) || defined(PROTO) 5940/* 5941 * Return the dictitem that an entry in a hashtable points to. 5942 */ 5943 dictitem_T * 5944dict_lookup(hi) 5945 hashitem_T *hi; 5946{ 5947 return HI2DI(hi); 5948} 5949#endif 5950 5951/* 5952 * Return TRUE when two dictionaries have exactly the same key/values. 5953 */ 5954 static int 5955dict_equal(d1, d2, ic) 5956 dict_T *d1; 5957 dict_T *d2; 5958 int ic; /* ignore case for strings */ 5959{ 5960 hashitem_T *hi; 5961 dictitem_T *item2; 5962 int todo; 5963 5964 if (d1 == NULL || d2 == NULL) 5965 return FALSE; 5966 if (d1 == d2) 5967 return TRUE; 5968 if (dict_len(d1) != dict_len(d2)) 5969 return FALSE; 5970 5971 todo = (int)d1->dv_hashtab.ht_used; 5972 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5973 { 5974 if (!HASHITEM_EMPTY(hi)) 5975 { 5976 item2 = dict_find(d2, hi->hi_key, -1); 5977 if (item2 == NULL) 5978 return FALSE; 5979 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5980 return FALSE; 5981 --todo; 5982 } 5983 } 5984 return TRUE; 5985} 5986 5987/* 5988 * Return TRUE if "tv1" and "tv2" have the same value. 5989 * Compares the items just like "==" would compare them, but strings and 5990 * numbers are different. Floats and numbers are also different. 5991 */ 5992 static int 5993tv_equal(tv1, tv2, ic) 5994 typval_T *tv1; 5995 typval_T *tv2; 5996 int ic; /* ignore case */ 5997{ 5998 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5999 char_u *s1, *s2; 6000 static int recursive = 0; /* cach recursive loops */ 6001 int r; 6002 6003 if (tv1->v_type != tv2->v_type) 6004 return FALSE; 6005 /* Catch lists and dicts that have an endless loop by limiting 6006 * recursiveness to 1000. We guess they are equal then. */ 6007 if (recursive >= 1000) 6008 return TRUE; 6009 6010 switch (tv1->v_type) 6011 { 6012 case VAR_LIST: 6013 ++recursive; 6014 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 6015 --recursive; 6016 return r; 6017 6018 case VAR_DICT: 6019 ++recursive; 6020 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 6021 --recursive; 6022 return r; 6023 6024 case VAR_FUNC: 6025 return (tv1->vval.v_string != NULL 6026 && tv2->vval.v_string != NULL 6027 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 6028 6029 case VAR_NUMBER: 6030 return tv1->vval.v_number == tv2->vval.v_number; 6031 6032#ifdef FEAT_FLOAT 6033 case VAR_FLOAT: 6034 return tv1->vval.v_float == tv2->vval.v_float; 6035#endif 6036 6037 case VAR_STRING: 6038 s1 = get_tv_string_buf(tv1, buf1); 6039 s2 = get_tv_string_buf(tv2, buf2); 6040 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 6041 } 6042 6043 EMSG2(_(e_intern2), "tv_equal()"); 6044 return TRUE; 6045} 6046 6047/* 6048 * Locate item with index "n" in list "l" and return it. 6049 * A negative index is counted from the end; -1 is the last item. 6050 * Returns NULL when "n" is out of range. 6051 */ 6052 static listitem_T * 6053list_find(l, n) 6054 list_T *l; 6055 long n; 6056{ 6057 listitem_T *item; 6058 long idx; 6059 6060 if (l == NULL) 6061 return NULL; 6062 6063 /* Negative index is relative to the end. */ 6064 if (n < 0) 6065 n = l->lv_len + n; 6066 6067 /* Check for index out of range. */ 6068 if (n < 0 || n >= l->lv_len) 6069 return NULL; 6070 6071 /* When there is a cached index may start search from there. */ 6072 if (l->lv_idx_item != NULL) 6073 { 6074 if (n < l->lv_idx / 2) 6075 { 6076 /* closest to the start of the list */ 6077 item = l->lv_first; 6078 idx = 0; 6079 } 6080 else if (n > (l->lv_idx + l->lv_len) / 2) 6081 { 6082 /* closest to the end of the list */ 6083 item = l->lv_last; 6084 idx = l->lv_len - 1; 6085 } 6086 else 6087 { 6088 /* closest to the cached index */ 6089 item = l->lv_idx_item; 6090 idx = l->lv_idx; 6091 } 6092 } 6093 else 6094 { 6095 if (n < l->lv_len / 2) 6096 { 6097 /* closest to the start of the list */ 6098 item = l->lv_first; 6099 idx = 0; 6100 } 6101 else 6102 { 6103 /* closest to the end of the list */ 6104 item = l->lv_last; 6105 idx = l->lv_len - 1; 6106 } 6107 } 6108 6109 while (n > idx) 6110 { 6111 /* search forward */ 6112 item = item->li_next; 6113 ++idx; 6114 } 6115 while (n < idx) 6116 { 6117 /* search backward */ 6118 item = item->li_prev; 6119 --idx; 6120 } 6121 6122 /* cache the used index */ 6123 l->lv_idx = idx; 6124 l->lv_idx_item = item; 6125 6126 return item; 6127} 6128 6129/* 6130 * Get list item "l[idx]" as a number. 6131 */ 6132 static long 6133list_find_nr(l, idx, errorp) 6134 list_T *l; 6135 long idx; 6136 int *errorp; /* set to TRUE when something wrong */ 6137{ 6138 listitem_T *li; 6139 6140 li = list_find(l, idx); 6141 if (li == NULL) 6142 { 6143 if (errorp != NULL) 6144 *errorp = TRUE; 6145 return -1L; 6146 } 6147 return get_tv_number_chk(&li->li_tv, errorp); 6148} 6149 6150/* 6151 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 6152 */ 6153 char_u * 6154list_find_str(l, idx) 6155 list_T *l; 6156 long idx; 6157{ 6158 listitem_T *li; 6159 6160 li = list_find(l, idx - 1); 6161 if (li == NULL) 6162 { 6163 EMSGN(_(e_listidx), idx); 6164 return NULL; 6165 } 6166 return get_tv_string(&li->li_tv); 6167} 6168 6169/* 6170 * Locate "item" list "l" and return its index. 6171 * Returns -1 when "item" is not in the list. 6172 */ 6173 static long 6174list_idx_of_item(l, item) 6175 list_T *l; 6176 listitem_T *item; 6177{ 6178 long idx = 0; 6179 listitem_T *li; 6180 6181 if (l == NULL) 6182 return -1; 6183 idx = 0; 6184 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 6185 ++idx; 6186 if (li == NULL) 6187 return -1; 6188 return idx; 6189} 6190 6191/* 6192 * Append item "item" to the end of list "l". 6193 */ 6194 static void 6195list_append(l, item) 6196 list_T *l; 6197 listitem_T *item; 6198{ 6199 if (l->lv_last == NULL) 6200 { 6201 /* empty list */ 6202 l->lv_first = item; 6203 l->lv_last = item; 6204 item->li_prev = NULL; 6205 } 6206 else 6207 { 6208 l->lv_last->li_next = item; 6209 item->li_prev = l->lv_last; 6210 l->lv_last = item; 6211 } 6212 ++l->lv_len; 6213 item->li_next = NULL; 6214} 6215 6216/* 6217 * Append typval_T "tv" to the end of list "l". 6218 * Return FAIL when out of memory. 6219 */ 6220 int 6221list_append_tv(l, tv) 6222 list_T *l; 6223 typval_T *tv; 6224{ 6225 listitem_T *li = listitem_alloc(); 6226 6227 if (li == NULL) 6228 return FAIL; 6229 copy_tv(tv, &li->li_tv); 6230 list_append(l, li); 6231 return OK; 6232} 6233 6234/* 6235 * Add a dictionary to a list. Used by getqflist(). 6236 * Return FAIL when out of memory. 6237 */ 6238 int 6239list_append_dict(list, dict) 6240 list_T *list; 6241 dict_T *dict; 6242{ 6243 listitem_T *li = listitem_alloc(); 6244 6245 if (li == NULL) 6246 return FAIL; 6247 li->li_tv.v_type = VAR_DICT; 6248 li->li_tv.v_lock = 0; 6249 li->li_tv.vval.v_dict = dict; 6250 list_append(list, li); 6251 ++dict->dv_refcount; 6252 return OK; 6253} 6254 6255/* 6256 * Make a copy of "str" and append it as an item to list "l". 6257 * When "len" >= 0 use "str[len]". 6258 * Returns FAIL when out of memory. 6259 */ 6260 int 6261list_append_string(l, str, len) 6262 list_T *l; 6263 char_u *str; 6264 int len; 6265{ 6266 listitem_T *li = listitem_alloc(); 6267 6268 if (li == NULL) 6269 return FAIL; 6270 list_append(l, li); 6271 li->li_tv.v_type = VAR_STRING; 6272 li->li_tv.v_lock = 0; 6273 if (str == NULL) 6274 li->li_tv.vval.v_string = NULL; 6275 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 6276 : vim_strsave(str))) == NULL) 6277 return FAIL; 6278 return OK; 6279} 6280 6281/* 6282 * Append "n" to list "l". 6283 * Returns FAIL when out of memory. 6284 */ 6285 static int 6286list_append_number(l, n) 6287 list_T *l; 6288 varnumber_T n; 6289{ 6290 listitem_T *li; 6291 6292 li = listitem_alloc(); 6293 if (li == NULL) 6294 return FAIL; 6295 li->li_tv.v_type = VAR_NUMBER; 6296 li->li_tv.v_lock = 0; 6297 li->li_tv.vval.v_number = n; 6298 list_append(l, li); 6299 return OK; 6300} 6301 6302/* 6303 * Insert typval_T "tv" in list "l" before "item". 6304 * If "item" is NULL append at the end. 6305 * Return FAIL when out of memory. 6306 */ 6307 static int 6308list_insert_tv(l, tv, item) 6309 list_T *l; 6310 typval_T *tv; 6311 listitem_T *item; 6312{ 6313 listitem_T *ni = listitem_alloc(); 6314 6315 if (ni == NULL) 6316 return FAIL; 6317 copy_tv(tv, &ni->li_tv); 6318 if (item == NULL) 6319 /* Append new item at end of list. */ 6320 list_append(l, ni); 6321 else 6322 { 6323 /* Insert new item before existing item. */ 6324 ni->li_prev = item->li_prev; 6325 ni->li_next = item; 6326 if (item->li_prev == NULL) 6327 { 6328 l->lv_first = ni; 6329 ++l->lv_idx; 6330 } 6331 else 6332 { 6333 item->li_prev->li_next = ni; 6334 l->lv_idx_item = NULL; 6335 } 6336 item->li_prev = ni; 6337 ++l->lv_len; 6338 } 6339 return OK; 6340} 6341 6342/* 6343 * Extend "l1" with "l2". 6344 * If "bef" is NULL append at the end, otherwise insert before this item. 6345 * Returns FAIL when out of memory. 6346 */ 6347 static int 6348list_extend(l1, l2, bef) 6349 list_T *l1; 6350 list_T *l2; 6351 listitem_T *bef; 6352{ 6353 listitem_T *item; 6354 int todo = l2->lv_len; 6355 6356 /* We also quit the loop when we have inserted the original item count of 6357 * the list, avoid a hang when we extend a list with itself. */ 6358 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 6359 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 6360 return FAIL; 6361 return OK; 6362} 6363 6364/* 6365 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 6366 * Return FAIL when out of memory. 6367 */ 6368 static int 6369list_concat(l1, l2, tv) 6370 list_T *l1; 6371 list_T *l2; 6372 typval_T *tv; 6373{ 6374 list_T *l; 6375 6376 if (l1 == NULL || l2 == NULL) 6377 return FAIL; 6378 6379 /* make a copy of the first list. */ 6380 l = list_copy(l1, FALSE, 0); 6381 if (l == NULL) 6382 return FAIL; 6383 tv->v_type = VAR_LIST; 6384 tv->vval.v_list = l; 6385 6386 /* append all items from the second list */ 6387 return list_extend(l, l2, NULL); 6388} 6389 6390/* 6391 * Make a copy of list "orig". Shallow if "deep" is FALSE. 6392 * The refcount of the new list is set to 1. 6393 * See item_copy() for "copyID". 6394 * Returns NULL when out of memory. 6395 */ 6396 static list_T * 6397list_copy(orig, deep, copyID) 6398 list_T *orig; 6399 int deep; 6400 int copyID; 6401{ 6402 list_T *copy; 6403 listitem_T *item; 6404 listitem_T *ni; 6405 6406 if (orig == NULL) 6407 return NULL; 6408 6409 copy = list_alloc(); 6410 if (copy != NULL) 6411 { 6412 if (copyID != 0) 6413 { 6414 /* Do this before adding the items, because one of the items may 6415 * refer back to this list. */ 6416 orig->lv_copyID = copyID; 6417 orig->lv_copylist = copy; 6418 } 6419 for (item = orig->lv_first; item != NULL && !got_int; 6420 item = item->li_next) 6421 { 6422 ni = listitem_alloc(); 6423 if (ni == NULL) 6424 break; 6425 if (deep) 6426 { 6427 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 6428 { 6429 vim_free(ni); 6430 break; 6431 } 6432 } 6433 else 6434 copy_tv(&item->li_tv, &ni->li_tv); 6435 list_append(copy, ni); 6436 } 6437 ++copy->lv_refcount; 6438 if (item != NULL) 6439 { 6440 list_unref(copy); 6441 copy = NULL; 6442 } 6443 } 6444 6445 return copy; 6446} 6447 6448/* 6449 * Remove items "item" to "item2" from list "l". 6450 * Does not free the listitem or the value! 6451 */ 6452 static void 6453list_remove(l, item, item2) 6454 list_T *l; 6455 listitem_T *item; 6456 listitem_T *item2; 6457{ 6458 listitem_T *ip; 6459 6460 /* notify watchers */ 6461 for (ip = item; ip != NULL; ip = ip->li_next) 6462 { 6463 --l->lv_len; 6464 list_fix_watch(l, ip); 6465 if (ip == item2) 6466 break; 6467 } 6468 6469 if (item2->li_next == NULL) 6470 l->lv_last = item->li_prev; 6471 else 6472 item2->li_next->li_prev = item->li_prev; 6473 if (item->li_prev == NULL) 6474 l->lv_first = item2->li_next; 6475 else 6476 item->li_prev->li_next = item2->li_next; 6477 l->lv_idx_item = NULL; 6478} 6479 6480/* 6481 * Return an allocated string with the string representation of a list. 6482 * May return NULL. 6483 */ 6484 static char_u * 6485list2string(tv, copyID) 6486 typval_T *tv; 6487 int copyID; 6488{ 6489 garray_T ga; 6490 6491 if (tv->vval.v_list == NULL) 6492 return NULL; 6493 ga_init2(&ga, (int)sizeof(char), 80); 6494 ga_append(&ga, '['); 6495 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6496 { 6497 vim_free(ga.ga_data); 6498 return NULL; 6499 } 6500 ga_append(&ga, ']'); 6501 ga_append(&ga, NUL); 6502 return (char_u *)ga.ga_data; 6503} 6504 6505/* 6506 * Join list "l" into a string in "*gap", using separator "sep". 6507 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 6508 * Return FAIL or OK. 6509 */ 6510 static int 6511list_join(gap, l, sep, echo, copyID) 6512 garray_T *gap; 6513 list_T *l; 6514 char_u *sep; 6515 int echo; 6516 int copyID; 6517{ 6518 int first = TRUE; 6519 char_u *tofree; 6520 char_u numbuf[NUMBUFLEN]; 6521 listitem_T *item; 6522 char_u *s; 6523 6524 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6525 { 6526 if (first) 6527 first = FALSE; 6528 else 6529 ga_concat(gap, sep); 6530 6531 if (echo) 6532 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6533 else 6534 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6535 if (s != NULL) 6536 ga_concat(gap, s); 6537 vim_free(tofree); 6538 if (s == NULL) 6539 return FAIL; 6540 line_breakcheck(); 6541 } 6542 return OK; 6543} 6544 6545/* 6546 * Garbage collection for lists and dictionaries. 6547 * 6548 * We use reference counts to be able to free most items right away when they 6549 * are no longer used. But for composite items it's possible that it becomes 6550 * unused while the reference count is > 0: When there is a recursive 6551 * reference. Example: 6552 * :let l = [1, 2, 3] 6553 * :let d = {9: l} 6554 * :let l[1] = d 6555 * 6556 * Since this is quite unusual we handle this with garbage collection: every 6557 * once in a while find out which lists and dicts are not referenced from any 6558 * variable. 6559 * 6560 * Here is a good reference text about garbage collection (refers to Python 6561 * but it applies to all reference-counting mechanisms): 6562 * http://python.ca/nas/python/gc/ 6563 */ 6564 6565/* 6566 * Do garbage collection for lists and dicts. 6567 * Return TRUE if some memory was freed. 6568 */ 6569 int 6570garbage_collect() 6571{ 6572 int copyID; 6573 buf_T *buf; 6574 win_T *wp; 6575 int i; 6576 funccall_T *fc, **pfc; 6577 int did_free; 6578 int did_free_funccal = FALSE; 6579#ifdef FEAT_WINDOWS 6580 tabpage_T *tp; 6581#endif 6582 6583 /* Only do this once. */ 6584 want_garbage_collect = FALSE; 6585 may_garbage_collect = FALSE; 6586 garbage_collect_at_exit = FALSE; 6587 6588 /* We advance by two because we add one for items referenced through 6589 * previous_funccal. */ 6590 current_copyID += COPYID_INC; 6591 copyID = current_copyID; 6592 6593 /* 6594 * 1. Go through all accessible variables and mark all lists and dicts 6595 * with copyID. 6596 */ 6597 6598 /* Don't free variables in the previous_funccal list unless they are only 6599 * referenced through previous_funccal. This must be first, because if 6600 * the item is referenced elsewhere the funccal must not be freed. */ 6601 for (fc = previous_funccal; fc != NULL; fc = fc->caller) 6602 { 6603 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1); 6604 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1); 6605 } 6606 6607 /* script-local variables */ 6608 for (i = 1; i <= ga_scripts.ga_len; ++i) 6609 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6610 6611 /* buffer-local variables */ 6612 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6613 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6614 6615 /* window-local variables */ 6616 FOR_ALL_TAB_WINDOWS(tp, wp) 6617 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6618 6619#ifdef FEAT_WINDOWS 6620 /* tabpage-local variables */ 6621 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6622 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6623#endif 6624 6625 /* global variables */ 6626 set_ref_in_ht(&globvarht, copyID); 6627 6628 /* function-local variables */ 6629 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6630 { 6631 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6632 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6633 } 6634 6635 /* v: vars */ 6636 set_ref_in_ht(&vimvarht, copyID); 6637 6638 /* 6639 * 2. Free lists and dictionaries that are not referenced. 6640 */ 6641 did_free = free_unref_items(copyID); 6642 6643 /* 6644 * 3. Check if any funccal can be freed now. 6645 */ 6646 for (pfc = &previous_funccal; *pfc != NULL; ) 6647 { 6648 if (can_free_funccal(*pfc, copyID)) 6649 { 6650 fc = *pfc; 6651 *pfc = fc->caller; 6652 free_funccal(fc, TRUE); 6653 did_free = TRUE; 6654 did_free_funccal = TRUE; 6655 } 6656 else 6657 pfc = &(*pfc)->caller; 6658 } 6659 if (did_free_funccal) 6660 /* When a funccal was freed some more items might be garbage 6661 * collected, so run again. */ 6662 (void)garbage_collect(); 6663 6664 return did_free; 6665} 6666 6667/* 6668 * Free lists and dictionaries that are no longer referenced. 6669 */ 6670 static int 6671free_unref_items(copyID) 6672 int copyID; 6673{ 6674 dict_T *dd; 6675 list_T *ll; 6676 int did_free = FALSE; 6677 6678 /* 6679 * Go through the list of dicts and free items without the copyID. 6680 */ 6681 for (dd = first_dict; dd != NULL; ) 6682 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6683 { 6684 /* Free the Dictionary and ordinary items it contains, but don't 6685 * recurse into Lists and Dictionaries, they will be in the list 6686 * of dicts or list of lists. */ 6687 dict_free(dd, FALSE); 6688 did_free = TRUE; 6689 6690 /* restart, next dict may also have been freed */ 6691 dd = first_dict; 6692 } 6693 else 6694 dd = dd->dv_used_next; 6695 6696 /* 6697 * Go through the list of lists and free items without the copyID. 6698 * But don't free a list that has a watcher (used in a for loop), these 6699 * are not referenced anywhere. 6700 */ 6701 for (ll = first_list; ll != NULL; ) 6702 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 6703 && ll->lv_watch == NULL) 6704 { 6705 /* Free the List and ordinary items it contains, but don't recurse 6706 * into Lists and Dictionaries, they will be in the list of dicts 6707 * or list of lists. */ 6708 list_free(ll, FALSE); 6709 did_free = TRUE; 6710 6711 /* restart, next list may also have been freed */ 6712 ll = first_list; 6713 } 6714 else 6715 ll = ll->lv_used_next; 6716 6717 return did_free; 6718} 6719 6720/* 6721 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6722 */ 6723 static void 6724set_ref_in_ht(ht, copyID) 6725 hashtab_T *ht; 6726 int copyID; 6727{ 6728 int todo; 6729 hashitem_T *hi; 6730 6731 todo = (int)ht->ht_used; 6732 for (hi = ht->ht_array; todo > 0; ++hi) 6733 if (!HASHITEM_EMPTY(hi)) 6734 { 6735 --todo; 6736 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6737 } 6738} 6739 6740/* 6741 * Mark all lists and dicts referenced through list "l" with "copyID". 6742 */ 6743 static void 6744set_ref_in_list(l, copyID) 6745 list_T *l; 6746 int copyID; 6747{ 6748 listitem_T *li; 6749 6750 for (li = l->lv_first; li != NULL; li = li->li_next) 6751 set_ref_in_item(&li->li_tv, copyID); 6752} 6753 6754/* 6755 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6756 */ 6757 static void 6758set_ref_in_item(tv, copyID) 6759 typval_T *tv; 6760 int copyID; 6761{ 6762 dict_T *dd; 6763 list_T *ll; 6764 6765 switch (tv->v_type) 6766 { 6767 case VAR_DICT: 6768 dd = tv->vval.v_dict; 6769 if (dd != NULL && dd->dv_copyID != copyID) 6770 { 6771 /* Didn't see this dict yet. */ 6772 dd->dv_copyID = copyID; 6773 set_ref_in_ht(&dd->dv_hashtab, copyID); 6774 } 6775 break; 6776 6777 case VAR_LIST: 6778 ll = tv->vval.v_list; 6779 if (ll != NULL && ll->lv_copyID != copyID) 6780 { 6781 /* Didn't see this list yet. */ 6782 ll->lv_copyID = copyID; 6783 set_ref_in_list(ll, copyID); 6784 } 6785 break; 6786 } 6787 return; 6788} 6789 6790/* 6791 * Allocate an empty header for a dictionary. 6792 */ 6793 dict_T * 6794dict_alloc() 6795{ 6796 dict_T *d; 6797 6798 d = (dict_T *)alloc(sizeof(dict_T)); 6799 if (d != NULL) 6800 { 6801 /* Add the list to the list of dicts for garbage collection. */ 6802 if (first_dict != NULL) 6803 first_dict->dv_used_prev = d; 6804 d->dv_used_next = first_dict; 6805 d->dv_used_prev = NULL; 6806 first_dict = d; 6807 6808 hash_init(&d->dv_hashtab); 6809 d->dv_lock = 0; 6810 d->dv_refcount = 0; 6811 d->dv_copyID = 0; 6812 } 6813 return d; 6814} 6815 6816/* 6817 * Allocate an empty dict for a return value. 6818 * Returns OK or FAIL. 6819 */ 6820 static int 6821rettv_dict_alloc(rettv) 6822 typval_T *rettv; 6823{ 6824 dict_T *d = dict_alloc(); 6825 6826 if (d == NULL) 6827 return FAIL; 6828 6829 rettv->vval.v_dict = d; 6830 rettv->v_type = VAR_DICT; 6831 ++d->dv_refcount; 6832 return OK; 6833} 6834 6835 6836/* 6837 * Unreference a Dictionary: decrement the reference count and free it when it 6838 * becomes zero. 6839 */ 6840 static void 6841dict_unref(d) 6842 dict_T *d; 6843{ 6844 if (d != NULL && --d->dv_refcount <= 0) 6845 dict_free(d, TRUE); 6846} 6847 6848/* 6849 * Free a Dictionary, including all items it contains. 6850 * Ignores the reference count. 6851 */ 6852 static void 6853dict_free(d, recurse) 6854 dict_T *d; 6855 int recurse; /* Free Lists and Dictionaries recursively. */ 6856{ 6857 int todo; 6858 hashitem_T *hi; 6859 dictitem_T *di; 6860 6861 /* Remove the dict from the list of dicts for garbage collection. */ 6862 if (d->dv_used_prev == NULL) 6863 first_dict = d->dv_used_next; 6864 else 6865 d->dv_used_prev->dv_used_next = d->dv_used_next; 6866 if (d->dv_used_next != NULL) 6867 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6868 6869 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6870 hash_lock(&d->dv_hashtab); 6871 todo = (int)d->dv_hashtab.ht_used; 6872 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6873 { 6874 if (!HASHITEM_EMPTY(hi)) 6875 { 6876 /* Remove the item before deleting it, just in case there is 6877 * something recursive causing trouble. */ 6878 di = HI2DI(hi); 6879 hash_remove(&d->dv_hashtab, hi); 6880 if (recurse || (di->di_tv.v_type != VAR_LIST 6881 && di->di_tv.v_type != VAR_DICT)) 6882 clear_tv(&di->di_tv); 6883 vim_free(di); 6884 --todo; 6885 } 6886 } 6887 hash_clear(&d->dv_hashtab); 6888 vim_free(d); 6889} 6890 6891/* 6892 * Allocate a Dictionary item. 6893 * The "key" is copied to the new item. 6894 * Note that the value of the item "di_tv" still needs to be initialized! 6895 * Returns NULL when out of memory. 6896 */ 6897 dictitem_T * 6898dictitem_alloc(key) 6899 char_u *key; 6900{ 6901 dictitem_T *di; 6902 6903 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6904 if (di != NULL) 6905 { 6906 STRCPY(di->di_key, key); 6907 di->di_flags = 0; 6908 } 6909 return di; 6910} 6911 6912/* 6913 * Make a copy of a Dictionary item. 6914 */ 6915 static dictitem_T * 6916dictitem_copy(org) 6917 dictitem_T *org; 6918{ 6919 dictitem_T *di; 6920 6921 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6922 + STRLEN(org->di_key))); 6923 if (di != NULL) 6924 { 6925 STRCPY(di->di_key, org->di_key); 6926 di->di_flags = 0; 6927 copy_tv(&org->di_tv, &di->di_tv); 6928 } 6929 return di; 6930} 6931 6932/* 6933 * Remove item "item" from Dictionary "dict" and free it. 6934 */ 6935 static void 6936dictitem_remove(dict, item) 6937 dict_T *dict; 6938 dictitem_T *item; 6939{ 6940 hashitem_T *hi; 6941 6942 hi = hash_find(&dict->dv_hashtab, item->di_key); 6943 if (HASHITEM_EMPTY(hi)) 6944 EMSG2(_(e_intern2), "dictitem_remove()"); 6945 else 6946 hash_remove(&dict->dv_hashtab, hi); 6947 dictitem_free(item); 6948} 6949 6950/* 6951 * Free a dict item. Also clears the value. 6952 */ 6953 void 6954dictitem_free(item) 6955 dictitem_T *item; 6956{ 6957 clear_tv(&item->di_tv); 6958 vim_free(item); 6959} 6960 6961/* 6962 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6963 * The refcount of the new dict is set to 1. 6964 * See item_copy() for "copyID". 6965 * Returns NULL when out of memory. 6966 */ 6967 static dict_T * 6968dict_copy(orig, deep, copyID) 6969 dict_T *orig; 6970 int deep; 6971 int copyID; 6972{ 6973 dict_T *copy; 6974 dictitem_T *di; 6975 int todo; 6976 hashitem_T *hi; 6977 6978 if (orig == NULL) 6979 return NULL; 6980 6981 copy = dict_alloc(); 6982 if (copy != NULL) 6983 { 6984 if (copyID != 0) 6985 { 6986 orig->dv_copyID = copyID; 6987 orig->dv_copydict = copy; 6988 } 6989 todo = (int)orig->dv_hashtab.ht_used; 6990 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6991 { 6992 if (!HASHITEM_EMPTY(hi)) 6993 { 6994 --todo; 6995 6996 di = dictitem_alloc(hi->hi_key); 6997 if (di == NULL) 6998 break; 6999 if (deep) 7000 { 7001 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 7002 copyID) == FAIL) 7003 { 7004 vim_free(di); 7005 break; 7006 } 7007 } 7008 else 7009 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 7010 if (dict_add(copy, di) == FAIL) 7011 { 7012 dictitem_free(di); 7013 break; 7014 } 7015 } 7016 } 7017 7018 ++copy->dv_refcount; 7019 if (todo > 0) 7020 { 7021 dict_unref(copy); 7022 copy = NULL; 7023 } 7024 } 7025 7026 return copy; 7027} 7028 7029/* 7030 * Add item "item" to Dictionary "d". 7031 * Returns FAIL when out of memory and when key already exists. 7032 */ 7033 int 7034dict_add(d, item) 7035 dict_T *d; 7036 dictitem_T *item; 7037{ 7038 return hash_add(&d->dv_hashtab, item->di_key); 7039} 7040 7041/* 7042 * Add a number or string entry to dictionary "d". 7043 * When "str" is NULL use number "nr", otherwise use "str". 7044 * Returns FAIL when out of memory and when key already exists. 7045 */ 7046 int 7047dict_add_nr_str(d, key, nr, str) 7048 dict_T *d; 7049 char *key; 7050 long nr; 7051 char_u *str; 7052{ 7053 dictitem_T *item; 7054 7055 item = dictitem_alloc((char_u *)key); 7056 if (item == NULL) 7057 return FAIL; 7058 item->di_tv.v_lock = 0; 7059 if (str == NULL) 7060 { 7061 item->di_tv.v_type = VAR_NUMBER; 7062 item->di_tv.vval.v_number = nr; 7063 } 7064 else 7065 { 7066 item->di_tv.v_type = VAR_STRING; 7067 item->di_tv.vval.v_string = vim_strsave(str); 7068 } 7069 if (dict_add(d, item) == FAIL) 7070 { 7071 dictitem_free(item); 7072 return FAIL; 7073 } 7074 return OK; 7075} 7076 7077/* 7078 * Add a list entry to dictionary "d". 7079 * Returns FAIL when out of memory and when key already exists. 7080 */ 7081 int 7082dict_add_list(d, key, list) 7083 dict_T *d; 7084 char *key; 7085 list_T *list; 7086{ 7087 dictitem_T *item; 7088 7089 item = dictitem_alloc((char_u *)key); 7090 if (item == NULL) 7091 return FAIL; 7092 item->di_tv.v_lock = 0; 7093 item->di_tv.v_type = VAR_LIST; 7094 item->di_tv.vval.v_list = list; 7095 if (dict_add(d, item) == FAIL) 7096 { 7097 dictitem_free(item); 7098 return FAIL; 7099 } 7100 return OK; 7101} 7102 7103/* 7104 * Get the number of items in a Dictionary. 7105 */ 7106 static long 7107dict_len(d) 7108 dict_T *d; 7109{ 7110 if (d == NULL) 7111 return 0L; 7112 return (long)d->dv_hashtab.ht_used; 7113} 7114 7115/* 7116 * Find item "key[len]" in Dictionary "d". 7117 * If "len" is negative use strlen(key). 7118 * Returns NULL when not found. 7119 */ 7120 dictitem_T * 7121dict_find(d, key, len) 7122 dict_T *d; 7123 char_u *key; 7124 int len; 7125{ 7126#define AKEYLEN 200 7127 char_u buf[AKEYLEN]; 7128 char_u *akey; 7129 char_u *tofree = NULL; 7130 hashitem_T *hi; 7131 7132 if (len < 0) 7133 akey = key; 7134 else if (len >= AKEYLEN) 7135 { 7136 tofree = akey = vim_strnsave(key, len); 7137 if (akey == NULL) 7138 return NULL; 7139 } 7140 else 7141 { 7142 /* Avoid a malloc/free by using buf[]. */ 7143 vim_strncpy(buf, key, len); 7144 akey = buf; 7145 } 7146 7147 hi = hash_find(&d->dv_hashtab, akey); 7148 vim_free(tofree); 7149 if (HASHITEM_EMPTY(hi)) 7150 return NULL; 7151 return HI2DI(hi); 7152} 7153 7154/* 7155 * Get a string item from a dictionary. 7156 * When "save" is TRUE allocate memory for it. 7157 * Returns NULL if the entry doesn't exist or out of memory. 7158 */ 7159 char_u * 7160get_dict_string(d, key, save) 7161 dict_T *d; 7162 char_u *key; 7163 int save; 7164{ 7165 dictitem_T *di; 7166 char_u *s; 7167 7168 di = dict_find(d, key, -1); 7169 if (di == NULL) 7170 return NULL; 7171 s = get_tv_string(&di->di_tv); 7172 if (save && s != NULL) 7173 s = vim_strsave(s); 7174 return s; 7175} 7176 7177/* 7178 * Get a number item from a dictionary. 7179 * Returns 0 if the entry doesn't exist or out of memory. 7180 */ 7181 long 7182get_dict_number(d, key) 7183 dict_T *d; 7184 char_u *key; 7185{ 7186 dictitem_T *di; 7187 7188 di = dict_find(d, key, -1); 7189 if (di == NULL) 7190 return 0; 7191 return get_tv_number(&di->di_tv); 7192} 7193 7194/* 7195 * Return an allocated string with the string representation of a Dictionary. 7196 * May return NULL. 7197 */ 7198 static char_u * 7199dict2string(tv, copyID) 7200 typval_T *tv; 7201 int copyID; 7202{ 7203 garray_T ga; 7204 int first = TRUE; 7205 char_u *tofree; 7206 char_u numbuf[NUMBUFLEN]; 7207 hashitem_T *hi; 7208 char_u *s; 7209 dict_T *d; 7210 int todo; 7211 7212 if ((d = tv->vval.v_dict) == NULL) 7213 return NULL; 7214 ga_init2(&ga, (int)sizeof(char), 80); 7215 ga_append(&ga, '{'); 7216 7217 todo = (int)d->dv_hashtab.ht_used; 7218 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 7219 { 7220 if (!HASHITEM_EMPTY(hi)) 7221 { 7222 --todo; 7223 7224 if (first) 7225 first = FALSE; 7226 else 7227 ga_concat(&ga, (char_u *)", "); 7228 7229 tofree = string_quote(hi->hi_key, FALSE); 7230 if (tofree != NULL) 7231 { 7232 ga_concat(&ga, tofree); 7233 vim_free(tofree); 7234 } 7235 ga_concat(&ga, (char_u *)": "); 7236 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 7237 if (s != NULL) 7238 ga_concat(&ga, s); 7239 vim_free(tofree); 7240 if (s == NULL) 7241 break; 7242 } 7243 } 7244 if (todo > 0) 7245 { 7246 vim_free(ga.ga_data); 7247 return NULL; 7248 } 7249 7250 ga_append(&ga, '}'); 7251 ga_append(&ga, NUL); 7252 return (char_u *)ga.ga_data; 7253} 7254 7255/* 7256 * Allocate a variable for a Dictionary and fill it from "*arg". 7257 * Return OK or FAIL. Returns NOTDONE for {expr}. 7258 */ 7259 static int 7260get_dict_tv(arg, rettv, evaluate) 7261 char_u **arg; 7262 typval_T *rettv; 7263 int evaluate; 7264{ 7265 dict_T *d = NULL; 7266 typval_T tvkey; 7267 typval_T tv; 7268 char_u *key = NULL; 7269 dictitem_T *item; 7270 char_u *start = skipwhite(*arg + 1); 7271 char_u buf[NUMBUFLEN]; 7272 7273 /* 7274 * First check if it's not a curly-braces thing: {expr}. 7275 * Must do this without evaluating, otherwise a function may be called 7276 * twice. Unfortunately this means we need to call eval1() twice for the 7277 * first item. 7278 * But {} is an empty Dictionary. 7279 */ 7280 if (*start != '}') 7281 { 7282 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 7283 return FAIL; 7284 if (*start == '}') 7285 return NOTDONE; 7286 } 7287 7288 if (evaluate) 7289 { 7290 d = dict_alloc(); 7291 if (d == NULL) 7292 return FAIL; 7293 } 7294 tvkey.v_type = VAR_UNKNOWN; 7295 tv.v_type = VAR_UNKNOWN; 7296 7297 *arg = skipwhite(*arg + 1); 7298 while (**arg != '}' && **arg != NUL) 7299 { 7300 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 7301 goto failret; 7302 if (**arg != ':') 7303 { 7304 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 7305 clear_tv(&tvkey); 7306 goto failret; 7307 } 7308 if (evaluate) 7309 { 7310 key = get_tv_string_buf_chk(&tvkey, buf); 7311 if (key == NULL || *key == NUL) 7312 { 7313 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 7314 if (key != NULL) 7315 EMSG(_(e_emptykey)); 7316 clear_tv(&tvkey); 7317 goto failret; 7318 } 7319 } 7320 7321 *arg = skipwhite(*arg + 1); 7322 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 7323 { 7324 if (evaluate) 7325 clear_tv(&tvkey); 7326 goto failret; 7327 } 7328 if (evaluate) 7329 { 7330 item = dict_find(d, key, -1); 7331 if (item != NULL) 7332 { 7333 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 7334 clear_tv(&tvkey); 7335 clear_tv(&tv); 7336 goto failret; 7337 } 7338 item = dictitem_alloc(key); 7339 clear_tv(&tvkey); 7340 if (item != NULL) 7341 { 7342 item->di_tv = tv; 7343 item->di_tv.v_lock = 0; 7344 if (dict_add(d, item) == FAIL) 7345 dictitem_free(item); 7346 } 7347 } 7348 7349 if (**arg == '}') 7350 break; 7351 if (**arg != ',') 7352 { 7353 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 7354 goto failret; 7355 } 7356 *arg = skipwhite(*arg + 1); 7357 } 7358 7359 if (**arg != '}') 7360 { 7361 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 7362failret: 7363 if (evaluate) 7364 dict_free(d, TRUE); 7365 return FAIL; 7366 } 7367 7368 *arg = skipwhite(*arg + 1); 7369 if (evaluate) 7370 { 7371 rettv->v_type = VAR_DICT; 7372 rettv->vval.v_dict = d; 7373 ++d->dv_refcount; 7374 } 7375 7376 return OK; 7377} 7378 7379/* 7380 * Return a string with the string representation of a variable. 7381 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7382 * "numbuf" is used for a number. 7383 * Does not put quotes around strings, as ":echo" displays values. 7384 * When "copyID" is not NULL replace recursive lists and dicts with "...". 7385 * May return NULL. 7386 */ 7387 static char_u * 7388echo_string(tv, tofree, numbuf, copyID) 7389 typval_T *tv; 7390 char_u **tofree; 7391 char_u *numbuf; 7392 int copyID; 7393{ 7394 static int recurse = 0; 7395 char_u *r = NULL; 7396 7397 if (recurse >= DICT_MAXNEST) 7398 { 7399 EMSG(_("E724: variable nested too deep for displaying")); 7400 *tofree = NULL; 7401 return NULL; 7402 } 7403 ++recurse; 7404 7405 switch (tv->v_type) 7406 { 7407 case VAR_FUNC: 7408 *tofree = NULL; 7409 r = tv->vval.v_string; 7410 break; 7411 7412 case VAR_LIST: 7413 if (tv->vval.v_list == NULL) 7414 { 7415 *tofree = NULL; 7416 r = NULL; 7417 } 7418 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 7419 { 7420 *tofree = NULL; 7421 r = (char_u *)"[...]"; 7422 } 7423 else 7424 { 7425 tv->vval.v_list->lv_copyID = copyID; 7426 *tofree = list2string(tv, copyID); 7427 r = *tofree; 7428 } 7429 break; 7430 7431 case VAR_DICT: 7432 if (tv->vval.v_dict == NULL) 7433 { 7434 *tofree = NULL; 7435 r = NULL; 7436 } 7437 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 7438 { 7439 *tofree = NULL; 7440 r = (char_u *)"{...}"; 7441 } 7442 else 7443 { 7444 tv->vval.v_dict->dv_copyID = copyID; 7445 *tofree = dict2string(tv, copyID); 7446 r = *tofree; 7447 } 7448 break; 7449 7450 case VAR_STRING: 7451 case VAR_NUMBER: 7452 *tofree = NULL; 7453 r = get_tv_string_buf(tv, numbuf); 7454 break; 7455 7456#ifdef FEAT_FLOAT 7457 case VAR_FLOAT: 7458 *tofree = NULL; 7459 vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float); 7460 r = numbuf; 7461 break; 7462#endif 7463 7464 default: 7465 EMSG2(_(e_intern2), "echo_string()"); 7466 *tofree = NULL; 7467 } 7468 7469 --recurse; 7470 return r; 7471} 7472 7473/* 7474 * Return a string with the string representation of a variable. 7475 * If the memory is allocated "tofree" is set to it, otherwise NULL. 7476 * "numbuf" is used for a number. 7477 * Puts quotes around strings, so that they can be parsed back by eval(). 7478 * May return NULL. 7479 */ 7480 static char_u * 7481tv2string(tv, tofree, numbuf, copyID) 7482 typval_T *tv; 7483 char_u **tofree; 7484 char_u *numbuf; 7485 int copyID; 7486{ 7487 switch (tv->v_type) 7488 { 7489 case VAR_FUNC: 7490 *tofree = string_quote(tv->vval.v_string, TRUE); 7491 return *tofree; 7492 case VAR_STRING: 7493 *tofree = string_quote(tv->vval.v_string, FALSE); 7494 return *tofree; 7495#ifdef FEAT_FLOAT 7496 case VAR_FLOAT: 7497 *tofree = NULL; 7498 vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float); 7499 return numbuf; 7500#endif 7501 case VAR_NUMBER: 7502 case VAR_LIST: 7503 case VAR_DICT: 7504 break; 7505 default: 7506 EMSG2(_(e_intern2), "tv2string()"); 7507 } 7508 return echo_string(tv, tofree, numbuf, copyID); 7509} 7510 7511/* 7512 * Return string "str" in ' quotes, doubling ' characters. 7513 * If "str" is NULL an empty string is assumed. 7514 * If "function" is TRUE make it function('string'). 7515 */ 7516 static char_u * 7517string_quote(str, function) 7518 char_u *str; 7519 int function; 7520{ 7521 unsigned len; 7522 char_u *p, *r, *s; 7523 7524 len = (function ? 13 : 3); 7525 if (str != NULL) 7526 { 7527 len += (unsigned)STRLEN(str); 7528 for (p = str; *p != NUL; mb_ptr_adv(p)) 7529 if (*p == '\'') 7530 ++len; 7531 } 7532 s = r = alloc(len); 7533 if (r != NULL) 7534 { 7535 if (function) 7536 { 7537 STRCPY(r, "function('"); 7538 r += 10; 7539 } 7540 else 7541 *r++ = '\''; 7542 if (str != NULL) 7543 for (p = str; *p != NUL; ) 7544 { 7545 if (*p == '\'') 7546 *r++ = '\''; 7547 MB_COPY_CHAR(p, r); 7548 } 7549 *r++ = '\''; 7550 if (function) 7551 *r++ = ')'; 7552 *r++ = NUL; 7553 } 7554 return s; 7555} 7556 7557#ifdef FEAT_FLOAT 7558/* 7559 * Convert the string "text" to a floating point number. 7560 * This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure 7561 * this always uses a decimal point. 7562 * Returns the length of the text that was consumed. 7563 */ 7564 static int 7565string2float(text, value) 7566 char_u *text; 7567 float_T *value; /* result stored here */ 7568{ 7569 char *s = (char *)text; 7570 float_T f; 7571 7572 f = strtod(s, &s); 7573 *value = f; 7574 return (int)((char_u *)s - text); 7575} 7576#endif 7577 7578/* 7579 * Get the value of an environment variable. 7580 * "arg" is pointing to the '$'. It is advanced to after the name. 7581 * If the environment variable was not set, silently assume it is empty. 7582 * Always return OK. 7583 */ 7584 static int 7585get_env_tv(arg, rettv, evaluate) 7586 char_u **arg; 7587 typval_T *rettv; 7588 int evaluate; 7589{ 7590 char_u *string = NULL; 7591 int len; 7592 int cc; 7593 char_u *name; 7594 int mustfree = FALSE; 7595 7596 ++*arg; 7597 name = *arg; 7598 len = get_env_len(arg); 7599 if (evaluate) 7600 { 7601 if (len != 0) 7602 { 7603 cc = name[len]; 7604 name[len] = NUL; 7605 /* first try vim_getenv(), fast for normal environment vars */ 7606 string = vim_getenv(name, &mustfree); 7607 if (string != NULL && *string != NUL) 7608 { 7609 if (!mustfree) 7610 string = vim_strsave(string); 7611 } 7612 else 7613 { 7614 if (mustfree) 7615 vim_free(string); 7616 7617 /* next try expanding things like $VIM and ${HOME} */ 7618 string = expand_env_save(name - 1); 7619 if (string != NULL && *string == '$') 7620 { 7621 vim_free(string); 7622 string = NULL; 7623 } 7624 } 7625 name[len] = cc; 7626 } 7627 rettv->v_type = VAR_STRING; 7628 rettv->vval.v_string = string; 7629 } 7630 7631 return OK; 7632} 7633 7634/* 7635 * Array with names and number of arguments of all internal functions 7636 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 7637 */ 7638static struct fst 7639{ 7640 char *f_name; /* function name */ 7641 char f_min_argc; /* minimal number of arguments */ 7642 char f_max_argc; /* maximal number of arguments */ 7643 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 7644 /* implementation of function */ 7645} functions[] = 7646{ 7647#ifdef FEAT_FLOAT 7648 {"abs", 1, 1, f_abs}, 7649 {"acos", 1, 1, f_acos}, /* WJMc */ 7650#endif 7651 {"add", 2, 2, f_add}, 7652 {"append", 2, 2, f_append}, 7653 {"argc", 0, 0, f_argc}, 7654 {"argidx", 0, 0, f_argidx}, 7655 {"argv", 0, 1, f_argv}, 7656#ifdef FEAT_FLOAT 7657 {"asin", 1, 1, f_asin}, /* WJMc */ 7658 {"atan", 1, 1, f_atan}, 7659 {"atan2", 2, 2, f_atan2}, 7660#endif 7661 {"browse", 4, 4, f_browse}, 7662 {"browsedir", 2, 2, f_browsedir}, 7663 {"bufexists", 1, 1, f_bufexists}, 7664 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 7665 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 7666 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 7667 {"buflisted", 1, 1, f_buflisted}, 7668 {"bufloaded", 1, 1, f_bufloaded}, 7669 {"bufname", 1, 1, f_bufname}, 7670 {"bufnr", 1, 2, f_bufnr}, 7671 {"bufwinnr", 1, 1, f_bufwinnr}, 7672 {"byte2line", 1, 1, f_byte2line}, 7673 {"byteidx", 2, 2, f_byteidx}, 7674 {"call", 2, 3, f_call}, 7675#ifdef FEAT_FLOAT 7676 {"ceil", 1, 1, f_ceil}, 7677#endif 7678 {"changenr", 0, 0, f_changenr}, 7679 {"char2nr", 1, 1, f_char2nr}, 7680 {"cindent", 1, 1, f_cindent}, 7681 {"clearmatches", 0, 0, f_clearmatches}, 7682 {"col", 1, 1, f_col}, 7683#if defined(FEAT_INS_EXPAND) 7684 {"complete", 2, 2, f_complete}, 7685 {"complete_add", 1, 1, f_complete_add}, 7686 {"complete_check", 0, 0, f_complete_check}, 7687#endif 7688 {"confirm", 1, 4, f_confirm}, 7689 {"copy", 1, 1, f_copy}, 7690#ifdef FEAT_FLOAT 7691 {"cos", 1, 1, f_cos}, 7692 {"cosh", 1, 1, f_cosh}, 7693#endif 7694 {"count", 2, 4, f_count}, 7695 {"cscope_connection",0,3, f_cscope_connection}, 7696 {"cursor", 1, 3, f_cursor}, 7697 {"deepcopy", 1, 2, f_deepcopy}, 7698 {"delete", 1, 1, f_delete}, 7699 {"did_filetype", 0, 0, f_did_filetype}, 7700 {"diff_filler", 1, 1, f_diff_filler}, 7701 {"diff_hlID", 2, 2, f_diff_hlID}, 7702 {"empty", 1, 1, f_empty}, 7703 {"escape", 2, 2, f_escape}, 7704 {"eval", 1, 1, f_eval}, 7705 {"eventhandler", 0, 0, f_eventhandler}, 7706 {"executable", 1, 1, f_executable}, 7707 {"exists", 1, 1, f_exists}, 7708#ifdef FEAT_FLOAT 7709 {"exp", 1, 1, f_exp}, 7710#endif 7711 {"expand", 1, 2, f_expand}, 7712 {"extend", 2, 3, f_extend}, 7713 {"feedkeys", 1, 2, f_feedkeys}, 7714 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7715 {"filereadable", 1, 1, f_filereadable}, 7716 {"filewritable", 1, 1, f_filewritable}, 7717 {"filter", 2, 2, f_filter}, 7718 {"finddir", 1, 3, f_finddir}, 7719 {"findfile", 1, 3, f_findfile}, 7720#ifdef FEAT_FLOAT 7721 {"float2nr", 1, 1, f_float2nr}, 7722 {"floor", 1, 1, f_floor}, 7723 {"fmod", 2, 2, f_fmod}, 7724#endif 7725 {"fnameescape", 1, 1, f_fnameescape}, 7726 {"fnamemodify", 2, 2, f_fnamemodify}, 7727 {"foldclosed", 1, 1, f_foldclosed}, 7728 {"foldclosedend", 1, 1, f_foldclosedend}, 7729 {"foldlevel", 1, 1, f_foldlevel}, 7730 {"foldtext", 0, 0, f_foldtext}, 7731 {"foldtextresult", 1, 1, f_foldtextresult}, 7732 {"foreground", 0, 0, f_foreground}, 7733 {"function", 1, 1, f_function}, 7734 {"garbagecollect", 0, 1, f_garbagecollect}, 7735 {"get", 2, 3, f_get}, 7736 {"getbufline", 2, 3, f_getbufline}, 7737 {"getbufvar", 2, 2, f_getbufvar}, 7738 {"getchar", 0, 1, f_getchar}, 7739 {"getcharmod", 0, 0, f_getcharmod}, 7740 {"getcmdline", 0, 0, f_getcmdline}, 7741 {"getcmdpos", 0, 0, f_getcmdpos}, 7742 {"getcmdtype", 0, 0, f_getcmdtype}, 7743 {"getcwd", 0, 0, f_getcwd}, 7744 {"getfontname", 0, 1, f_getfontname}, 7745 {"getfperm", 1, 1, f_getfperm}, 7746 {"getfsize", 1, 1, f_getfsize}, 7747 {"getftime", 1, 1, f_getftime}, 7748 {"getftype", 1, 1, f_getftype}, 7749 {"getline", 1, 2, f_getline}, 7750 {"getloclist", 1, 1, f_getqflist}, 7751 {"getmatches", 0, 0, f_getmatches}, 7752 {"getpid", 0, 0, f_getpid}, 7753 {"getpos", 1, 1, f_getpos}, 7754 {"getqflist", 0, 0, f_getqflist}, 7755 {"getreg", 0, 2, f_getreg}, 7756 {"getregtype", 0, 1, f_getregtype}, 7757 {"gettabvar", 2, 2, f_gettabvar}, 7758 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7759 {"getwinposx", 0, 0, f_getwinposx}, 7760 {"getwinposy", 0, 0, f_getwinposy}, 7761 {"getwinvar", 2, 2, f_getwinvar}, 7762 {"glob", 1, 2, f_glob}, 7763 {"globpath", 2, 3, f_globpath}, 7764 {"has", 1, 1, f_has}, 7765 {"has_key", 2, 2, f_has_key}, 7766 {"haslocaldir", 0, 0, f_haslocaldir}, 7767 {"hasmapto", 1, 3, f_hasmapto}, 7768 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7769 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7770 {"histadd", 2, 2, f_histadd}, 7771 {"histdel", 1, 2, f_histdel}, 7772 {"histget", 1, 2, f_histget}, 7773 {"histnr", 1, 1, f_histnr}, 7774 {"hlID", 1, 1, f_hlID}, 7775 {"hlexists", 1, 1, f_hlexists}, 7776 {"hostname", 0, 0, f_hostname}, 7777 {"iconv", 3, 3, f_iconv}, 7778 {"indent", 1, 1, f_indent}, 7779 {"index", 2, 4, f_index}, 7780 {"input", 1, 3, f_input}, 7781 {"inputdialog", 1, 3, f_inputdialog}, 7782 {"inputlist", 1, 1, f_inputlist}, 7783 {"inputrestore", 0, 0, f_inputrestore}, 7784 {"inputsave", 0, 0, f_inputsave}, 7785 {"inputsecret", 1, 2, f_inputsecret}, 7786 {"insert", 2, 3, f_insert}, 7787 {"isdirectory", 1, 1, f_isdirectory}, 7788 {"islocked", 1, 1, f_islocked}, 7789 {"items", 1, 1, f_items}, 7790 {"join", 1, 2, f_join}, 7791 {"keys", 1, 1, f_keys}, 7792 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7793 {"len", 1, 1, f_len}, 7794 {"libcall", 3, 3, f_libcall}, 7795 {"libcallnr", 3, 3, f_libcallnr}, 7796 {"line", 1, 1, f_line}, 7797 {"line2byte", 1, 1, f_line2byte}, 7798 {"lispindent", 1, 1, f_lispindent}, 7799 {"localtime", 0, 0, f_localtime}, 7800#ifdef FEAT_FLOAT 7801 {"log", 1, 1, f_log}, 7802 {"log10", 1, 1, f_log10}, 7803#endif 7804 {"map", 2, 2, f_map}, 7805 {"maparg", 1, 3, f_maparg}, 7806 {"mapcheck", 1, 3, f_mapcheck}, 7807 {"match", 2, 4, f_match}, 7808 {"matchadd", 2, 4, f_matchadd}, 7809 {"matcharg", 1, 1, f_matcharg}, 7810 {"matchdelete", 1, 1, f_matchdelete}, 7811 {"matchend", 2, 4, f_matchend}, 7812 {"matchlist", 2, 4, f_matchlist}, 7813 {"matchstr", 2, 4, f_matchstr}, 7814 {"max", 1, 1, f_max}, 7815 {"min", 1, 1, f_min}, 7816#ifdef vim_mkdir 7817 {"mkdir", 1, 3, f_mkdir}, 7818#endif 7819 {"mode", 0, 1, f_mode}, 7820#ifdef FEAT_MZSCHEME 7821 {"mzeval", 1, 1, f_mzeval}, 7822#endif 7823 {"nextnonblank", 1, 1, f_nextnonblank}, 7824 {"nr2char", 1, 1, f_nr2char}, 7825 {"pathshorten", 1, 1, f_pathshorten}, 7826#ifdef FEAT_FLOAT 7827 {"pow", 2, 2, f_pow}, 7828#endif 7829 {"prevnonblank", 1, 1, f_prevnonblank}, 7830 {"printf", 2, 19, f_printf}, 7831 {"pumvisible", 0, 0, f_pumvisible}, 7832 {"range", 1, 3, f_range}, 7833 {"readfile", 1, 3, f_readfile}, 7834 {"reltime", 0, 2, f_reltime}, 7835 {"reltimestr", 1, 1, f_reltimestr}, 7836 {"remote_expr", 2, 3, f_remote_expr}, 7837 {"remote_foreground", 1, 1, f_remote_foreground}, 7838 {"remote_peek", 1, 2, f_remote_peek}, 7839 {"remote_read", 1, 1, f_remote_read}, 7840 {"remote_send", 2, 3, f_remote_send}, 7841 {"remove", 2, 3, f_remove}, 7842 {"rename", 2, 2, f_rename}, 7843 {"repeat", 2, 2, f_repeat}, 7844 {"resolve", 1, 1, f_resolve}, 7845 {"reverse", 1, 1, f_reverse}, 7846#ifdef FEAT_FLOAT 7847 {"round", 1, 1, f_round}, 7848#endif 7849 {"search", 1, 4, f_search}, 7850 {"searchdecl", 1, 3, f_searchdecl}, 7851 {"searchpair", 3, 7, f_searchpair}, 7852 {"searchpairpos", 3, 7, f_searchpairpos}, 7853 {"searchpos", 1, 4, f_searchpos}, 7854 {"server2client", 2, 2, f_server2client}, 7855 {"serverlist", 0, 0, f_serverlist}, 7856 {"setbufvar", 3, 3, f_setbufvar}, 7857 {"setcmdpos", 1, 1, f_setcmdpos}, 7858 {"setline", 2, 2, f_setline}, 7859 {"setloclist", 2, 3, f_setloclist}, 7860 {"setmatches", 1, 1, f_setmatches}, 7861 {"setpos", 2, 2, f_setpos}, 7862 {"setqflist", 1, 2, f_setqflist}, 7863 {"setreg", 2, 3, f_setreg}, 7864 {"settabvar", 3, 3, f_settabvar}, 7865 {"settabwinvar", 4, 4, f_settabwinvar}, 7866 {"setwinvar", 3, 3, f_setwinvar}, 7867 {"shellescape", 1, 2, f_shellescape}, 7868 {"simplify", 1, 1, f_simplify}, 7869#ifdef FEAT_FLOAT 7870 {"sin", 1, 1, f_sin}, 7871 {"sinh", 1, 1, f_sinh}, 7872#endif 7873 {"sort", 1, 2, f_sort}, 7874 {"soundfold", 1, 1, f_soundfold}, 7875 {"spellbadword", 0, 1, f_spellbadword}, 7876 {"spellsuggest", 1, 3, f_spellsuggest}, 7877 {"split", 1, 3, f_split}, 7878#ifdef FEAT_FLOAT 7879 {"sqrt", 1, 1, f_sqrt}, 7880 {"str2float", 1, 1, f_str2float}, 7881#endif 7882 {"str2nr", 1, 2, f_str2nr}, 7883 {"strchars", 1, 1, f_strchars}, 7884 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 7885#ifdef HAVE_STRFTIME 7886 {"strftime", 1, 2, f_strftime}, 7887#endif 7888 {"stridx", 2, 3, f_stridx}, 7889 {"string", 1, 1, f_string}, 7890 {"strlen", 1, 1, f_strlen}, 7891 {"strpart", 2, 3, f_strpart}, 7892 {"strridx", 2, 3, f_strridx}, 7893 {"strtrans", 1, 1, f_strtrans}, 7894 {"strwidth", 1, 1, f_strwidth}, 7895 {"submatch", 1, 1, f_submatch}, 7896 {"substitute", 4, 4, f_substitute}, 7897 {"synID", 3, 3, f_synID}, 7898 {"synIDattr", 2, 3, f_synIDattr}, 7899 {"synIDtrans", 1, 1, f_synIDtrans}, 7900 {"synconcealed", 2, 2, f_synconcealed}, 7901 {"synstack", 2, 2, f_synstack}, 7902 {"system", 1, 2, f_system}, 7903 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7904 {"tabpagenr", 0, 1, f_tabpagenr}, 7905 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7906 {"tagfiles", 0, 0, f_tagfiles}, 7907 {"taglist", 1, 1, f_taglist}, 7908#ifdef FEAT_FLOAT 7909 {"tan", 1, 1, f_tan}, 7910 {"tanh", 1, 1, f_tanh}, 7911#endif 7912 {"tempname", 0, 0, f_tempname}, 7913 {"test", 1, 1, f_test}, 7914 {"tolower", 1, 1, f_tolower}, 7915 {"toupper", 1, 1, f_toupper}, 7916 {"tr", 3, 3, f_tr}, 7917#ifdef FEAT_FLOAT 7918 {"trunc", 1, 1, f_trunc}, 7919#endif 7920 {"type", 1, 1, f_type}, 7921 {"undofile", 1, 1, f_undofile}, 7922 {"undotree", 0, 0, f_undotree}, 7923 {"values", 1, 1, f_values}, 7924 {"virtcol", 1, 1, f_virtcol}, 7925 {"visualmode", 0, 1, f_visualmode}, 7926 {"winbufnr", 1, 1, f_winbufnr}, 7927 {"wincol", 0, 0, f_wincol}, 7928 {"winheight", 1, 1, f_winheight}, 7929 {"winline", 0, 0, f_winline}, 7930 {"winnr", 0, 1, f_winnr}, 7931 {"winrestcmd", 0, 0, f_winrestcmd}, 7932 {"winrestview", 1, 1, f_winrestview}, 7933 {"winsaveview", 0, 0, f_winsaveview}, 7934 {"winwidth", 1, 1, f_winwidth}, 7935 {"writefile", 2, 3, f_writefile}, 7936}; 7937 7938#if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7939 7940/* 7941 * Function given to ExpandGeneric() to obtain the list of internal 7942 * or user defined function names. 7943 */ 7944 char_u * 7945get_function_name(xp, idx) 7946 expand_T *xp; 7947 int idx; 7948{ 7949 static int intidx = -1; 7950 char_u *name; 7951 7952 if (idx == 0) 7953 intidx = -1; 7954 if (intidx < 0) 7955 { 7956 name = get_user_func_name(xp, idx); 7957 if (name != NULL) 7958 return name; 7959 } 7960 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7961 { 7962 STRCPY(IObuff, functions[intidx].f_name); 7963 STRCAT(IObuff, "("); 7964 if (functions[intidx].f_max_argc == 0) 7965 STRCAT(IObuff, ")"); 7966 return IObuff; 7967 } 7968 7969 return NULL; 7970} 7971 7972/* 7973 * Function given to ExpandGeneric() to obtain the list of internal or 7974 * user defined variable or function names. 7975 */ 7976 char_u * 7977get_expr_name(xp, idx) 7978 expand_T *xp; 7979 int idx; 7980{ 7981 static int intidx = -1; 7982 char_u *name; 7983 7984 if (idx == 0) 7985 intidx = -1; 7986 if (intidx < 0) 7987 { 7988 name = get_function_name(xp, idx); 7989 if (name != NULL) 7990 return name; 7991 } 7992 return get_user_var_name(xp, ++intidx); 7993} 7994 7995#endif /* FEAT_CMDL_COMPL */ 7996 7997#if defined(EBCDIC) || defined(PROTO) 7998/* 7999 * Compare struct fst by function name. 8000 */ 8001 static int 8002compare_func_name(s1, s2) 8003 const void *s1; 8004 const void *s2; 8005{ 8006 struct fst *p1 = (struct fst *)s1; 8007 struct fst *p2 = (struct fst *)s2; 8008 8009 return STRCMP(p1->f_name, p2->f_name); 8010} 8011 8012/* 8013 * Sort the function table by function name. 8014 * The sorting of the table above is ASCII dependant. 8015 * On machines using EBCDIC we have to sort it. 8016 */ 8017 static void 8018sortFunctions() 8019{ 8020 int funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8021 8022 qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name); 8023} 8024#endif 8025 8026 8027/* 8028 * Find internal function in table above. 8029 * Return index, or -1 if not found 8030 */ 8031 static int 8032find_internal_func(name) 8033 char_u *name; /* name of the function */ 8034{ 8035 int first = 0; 8036 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 8037 int cmp; 8038 int x; 8039 8040 /* 8041 * Find the function name in the table. Binary search. 8042 */ 8043 while (first <= last) 8044 { 8045 x = first + ((unsigned)(last - first) >> 1); 8046 cmp = STRCMP(name, functions[x].f_name); 8047 if (cmp < 0) 8048 last = x - 1; 8049 else if (cmp > 0) 8050 first = x + 1; 8051 else 8052 return x; 8053 } 8054 return -1; 8055} 8056 8057/* 8058 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 8059 * name it contains, otherwise return "name". 8060 */ 8061 static char_u * 8062deref_func_name(name, lenp) 8063 char_u *name; 8064 int *lenp; 8065{ 8066 dictitem_T *v; 8067 int cc; 8068 8069 cc = name[*lenp]; 8070 name[*lenp] = NUL; 8071 v = find_var(name, NULL); 8072 name[*lenp] = cc; 8073 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 8074 { 8075 if (v->di_tv.vval.v_string == NULL) 8076 { 8077 *lenp = 0; 8078 return (char_u *)""; /* just in case */ 8079 } 8080 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 8081 return v->di_tv.vval.v_string; 8082 } 8083 8084 return name; 8085} 8086 8087/* 8088 * Allocate a variable for the result of a function. 8089 * Return OK or FAIL. 8090 */ 8091 static int 8092get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 8093 evaluate, selfdict) 8094 char_u *name; /* name of the function */ 8095 int len; /* length of "name" */ 8096 typval_T *rettv; 8097 char_u **arg; /* argument, pointing to the '(' */ 8098 linenr_T firstline; /* first line of range */ 8099 linenr_T lastline; /* last line of range */ 8100 int *doesrange; /* return: function handled range */ 8101 int evaluate; 8102 dict_T *selfdict; /* Dictionary for "self" */ 8103{ 8104 char_u *argp; 8105 int ret = OK; 8106 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 8107 int argcount = 0; /* number of arguments found */ 8108 8109 /* 8110 * Get the arguments. 8111 */ 8112 argp = *arg; 8113 while (argcount < MAX_FUNC_ARGS) 8114 { 8115 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 8116 if (*argp == ')' || *argp == ',' || *argp == NUL) 8117 break; 8118 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 8119 { 8120 ret = FAIL; 8121 break; 8122 } 8123 ++argcount; 8124 if (*argp != ',') 8125 break; 8126 } 8127 if (*argp == ')') 8128 ++argp; 8129 else 8130 ret = FAIL; 8131 8132 if (ret == OK) 8133 ret = call_func(name, len, rettv, argcount, argvars, 8134 firstline, lastline, doesrange, evaluate, selfdict); 8135 else if (!aborting()) 8136 { 8137 if (argcount == MAX_FUNC_ARGS) 8138 emsg_funcname(N_("E740: Too many arguments for function %s"), name); 8139 else 8140 emsg_funcname(N_("E116: Invalid arguments for function %s"), name); 8141 } 8142 8143 while (--argcount >= 0) 8144 clear_tv(&argvars[argcount]); 8145 8146 *arg = skipwhite(argp); 8147 return ret; 8148} 8149 8150 8151/* 8152 * Call a function with its resolved parameters 8153 * Return OK when the function can't be called, FAIL otherwise. 8154 * Also returns OK when an error was encountered while executing the function. 8155 */ 8156 static int 8157call_func(funcname, len, rettv, argcount, argvars, firstline, lastline, 8158 doesrange, evaluate, selfdict) 8159 char_u *funcname; /* name of the function */ 8160 int len; /* length of "name" */ 8161 typval_T *rettv; /* return value goes here */ 8162 int argcount; /* number of "argvars" */ 8163 typval_T *argvars; /* vars for arguments, must have "argcount" 8164 PLUS ONE elements! */ 8165 linenr_T firstline; /* first line of range */ 8166 linenr_T lastline; /* last line of range */ 8167 int *doesrange; /* return: function handled range */ 8168 int evaluate; 8169 dict_T *selfdict; /* Dictionary for "self" */ 8170{ 8171 int ret = FAIL; 8172#define ERROR_UNKNOWN 0 8173#define ERROR_TOOMANY 1 8174#define ERROR_TOOFEW 2 8175#define ERROR_SCRIPT 3 8176#define ERROR_DICT 4 8177#define ERROR_NONE 5 8178#define ERROR_OTHER 6 8179 int error = ERROR_NONE; 8180 int i; 8181 int llen; 8182 ufunc_T *fp; 8183#define FLEN_FIXED 40 8184 char_u fname_buf[FLEN_FIXED + 1]; 8185 char_u *fname; 8186 char_u *name; 8187 8188 /* Make a copy of the name, if it comes from a funcref variable it could 8189 * be changed or deleted in the called function. */ 8190 name = vim_strnsave(funcname, len); 8191 if (name == NULL) 8192 return ret; 8193 8194 /* 8195 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 8196 * Change <SNR>123_name() to K_SNR 123_name(). 8197 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 8198 */ 8199 llen = eval_fname_script(name); 8200 if (llen > 0) 8201 { 8202 fname_buf[0] = K_SPECIAL; 8203 fname_buf[1] = KS_EXTRA; 8204 fname_buf[2] = (int)KE_SNR; 8205 i = 3; 8206 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 8207 { 8208 if (current_SID <= 0) 8209 error = ERROR_SCRIPT; 8210 else 8211 { 8212 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 8213 i = (int)STRLEN(fname_buf); 8214 } 8215 } 8216 if (i + STRLEN(name + llen) < FLEN_FIXED) 8217 { 8218 STRCPY(fname_buf + i, name + llen); 8219 fname = fname_buf; 8220 } 8221 else 8222 { 8223 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 8224 if (fname == NULL) 8225 error = ERROR_OTHER; 8226 else 8227 { 8228 mch_memmove(fname, fname_buf, (size_t)i); 8229 STRCPY(fname + i, name + llen); 8230 } 8231 } 8232 } 8233 else 8234 fname = name; 8235 8236 *doesrange = FALSE; 8237 8238 8239 /* execute the function if no errors detected and executing */ 8240 if (evaluate && error == ERROR_NONE) 8241 { 8242 rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ 8243 rettv->vval.v_number = 0; 8244 error = ERROR_UNKNOWN; 8245 8246 if (!builtin_function(fname)) 8247 { 8248 /* 8249 * User defined function. 8250 */ 8251 fp = find_func(fname); 8252 8253#ifdef FEAT_AUTOCMD 8254 /* Trigger FuncUndefined event, may load the function. */ 8255 if (fp == NULL 8256 && apply_autocmds(EVENT_FUNCUNDEFINED, 8257 fname, fname, TRUE, NULL) 8258 && !aborting()) 8259 { 8260 /* executed an autocommand, search for the function again */ 8261 fp = find_func(fname); 8262 } 8263#endif 8264 /* Try loading a package. */ 8265 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 8266 { 8267 /* loaded a package, search for the function again */ 8268 fp = find_func(fname); 8269 } 8270 8271 if (fp != NULL) 8272 { 8273 if (fp->uf_flags & FC_RANGE) 8274 *doesrange = TRUE; 8275 if (argcount < fp->uf_args.ga_len) 8276 error = ERROR_TOOFEW; 8277 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 8278 error = ERROR_TOOMANY; 8279 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 8280 error = ERROR_DICT; 8281 else 8282 { 8283 /* 8284 * Call the user function. 8285 * Save and restore search patterns, script variables and 8286 * redo buffer. 8287 */ 8288 save_search_patterns(); 8289 saveRedobuff(); 8290 ++fp->uf_calls; 8291 call_user_func(fp, argcount, argvars, rettv, 8292 firstline, lastline, 8293 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 8294 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 8295 && fp->uf_refcount <= 0) 8296 /* Function was unreferenced while being used, free it 8297 * now. */ 8298 func_free(fp); 8299 restoreRedobuff(); 8300 restore_search_patterns(); 8301 error = ERROR_NONE; 8302 } 8303 } 8304 } 8305 else 8306 { 8307 /* 8308 * Find the function name in the table, call its implementation. 8309 */ 8310 i = find_internal_func(fname); 8311 if (i >= 0) 8312 { 8313 if (argcount < functions[i].f_min_argc) 8314 error = ERROR_TOOFEW; 8315 else if (argcount > functions[i].f_max_argc) 8316 error = ERROR_TOOMANY; 8317 else 8318 { 8319 argvars[argcount].v_type = VAR_UNKNOWN; 8320 functions[i].f_func(argvars, rettv); 8321 error = ERROR_NONE; 8322 } 8323 } 8324 } 8325 /* 8326 * The function call (or "FuncUndefined" autocommand sequence) might 8327 * have been aborted by an error, an interrupt, or an explicitly thrown 8328 * exception that has not been caught so far. This situation can be 8329 * tested for by calling aborting(). For an error in an internal 8330 * function or for the "E132" error in call_user_func(), however, the 8331 * throw point at which the "force_abort" flag (temporarily reset by 8332 * emsg()) is normally updated has not been reached yet. We need to 8333 * update that flag first to make aborting() reliable. 8334 */ 8335 update_force_abort(); 8336 } 8337 if (error == ERROR_NONE) 8338 ret = OK; 8339 8340 /* 8341 * Report an error unless the argument evaluation or function call has been 8342 * cancelled due to an aborting error, an interrupt, or an exception. 8343 */ 8344 if (!aborting()) 8345 { 8346 switch (error) 8347 { 8348 case ERROR_UNKNOWN: 8349 emsg_funcname(N_("E117: Unknown function: %s"), name); 8350 break; 8351 case ERROR_TOOMANY: 8352 emsg_funcname(e_toomanyarg, name); 8353 break; 8354 case ERROR_TOOFEW: 8355 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 8356 name); 8357 break; 8358 case ERROR_SCRIPT: 8359 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 8360 name); 8361 break; 8362 case ERROR_DICT: 8363 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 8364 name); 8365 break; 8366 } 8367 } 8368 8369 if (fname != name && fname != fname_buf) 8370 vim_free(fname); 8371 vim_free(name); 8372 8373 return ret; 8374} 8375 8376/* 8377 * Give an error message with a function name. Handle <SNR> things. 8378 * "ermsg" is to be passed without translation, use N_() instead of _(). 8379 */ 8380 static void 8381emsg_funcname(ermsg, name) 8382 char *ermsg; 8383 char_u *name; 8384{ 8385 char_u *p; 8386 8387 if (*name == K_SPECIAL) 8388 p = concat_str((char_u *)"<SNR>", name + 3); 8389 else 8390 p = name; 8391 EMSG2(_(ermsg), p); 8392 if (p != name) 8393 vim_free(p); 8394} 8395 8396/* 8397 * Return TRUE for a non-zero Number and a non-empty String. 8398 */ 8399 static int 8400non_zero_arg(argvars) 8401 typval_T *argvars; 8402{ 8403 return ((argvars[0].v_type == VAR_NUMBER 8404 && argvars[0].vval.v_number != 0) 8405 || (argvars[0].v_type == VAR_STRING 8406 && argvars[0].vval.v_string != NULL 8407 && *argvars[0].vval.v_string != NUL)); 8408} 8409 8410/********************************************* 8411 * Implementation of the built-in functions 8412 */ 8413 8414#ifdef FEAT_FLOAT 8415static int get_float_arg __ARGS((typval_T *argvars, float_T *f)); 8416 8417/* 8418 * Get the float value of "argvars[0]" into "f". 8419 * Returns FAIL when the argument is not a Number or Float. 8420 */ 8421 static int 8422get_float_arg(argvars, f) 8423 typval_T *argvars; 8424 float_T *f; 8425{ 8426 if (argvars[0].v_type == VAR_FLOAT) 8427 { 8428 *f = argvars[0].vval.v_float; 8429 return OK; 8430 } 8431 if (argvars[0].v_type == VAR_NUMBER) 8432 { 8433 *f = (float_T)argvars[0].vval.v_number; 8434 return OK; 8435 } 8436 EMSG(_("E808: Number or Float required")); 8437 return FAIL; 8438} 8439 8440/* 8441 * "abs(expr)" function 8442 */ 8443 static void 8444f_abs(argvars, rettv) 8445 typval_T *argvars; 8446 typval_T *rettv; 8447{ 8448 if (argvars[0].v_type == VAR_FLOAT) 8449 { 8450 rettv->v_type = VAR_FLOAT; 8451 rettv->vval.v_float = fabs(argvars[0].vval.v_float); 8452 } 8453 else 8454 { 8455 varnumber_T n; 8456 int error = FALSE; 8457 8458 n = get_tv_number_chk(&argvars[0], &error); 8459 if (error) 8460 rettv->vval.v_number = -1; 8461 else if (n > 0) 8462 rettv->vval.v_number = n; 8463 else 8464 rettv->vval.v_number = -n; 8465 } 8466} 8467 8468/* 8469 * "acos()" function 8470 */ 8471 static void 8472f_acos(argvars, rettv) 8473 typval_T *argvars; 8474 typval_T *rettv; 8475{ 8476 float_T f; 8477 8478 rettv->v_type = VAR_FLOAT; 8479 if (get_float_arg(argvars, &f) == OK) 8480 rettv->vval.v_float = acos(f); 8481 else 8482 rettv->vval.v_float = 0.0; 8483} 8484#endif 8485 8486/* 8487 * "add(list, item)" function 8488 */ 8489 static void 8490f_add(argvars, rettv) 8491 typval_T *argvars; 8492 typval_T *rettv; 8493{ 8494 list_T *l; 8495 8496 rettv->vval.v_number = 1; /* Default: Failed */ 8497 if (argvars[0].v_type == VAR_LIST) 8498 { 8499 if ((l = argvars[0].vval.v_list) != NULL 8500 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 8501 && list_append_tv(l, &argvars[1]) == OK) 8502 copy_tv(&argvars[0], rettv); 8503 } 8504 else 8505 EMSG(_(e_listreq)); 8506} 8507 8508/* 8509 * "append(lnum, string/list)" function 8510 */ 8511 static void 8512f_append(argvars, rettv) 8513 typval_T *argvars; 8514 typval_T *rettv; 8515{ 8516 long lnum; 8517 char_u *line; 8518 list_T *l = NULL; 8519 listitem_T *li = NULL; 8520 typval_T *tv; 8521 long added = 0; 8522 8523 lnum = get_tv_lnum(argvars); 8524 if (lnum >= 0 8525 && lnum <= curbuf->b_ml.ml_line_count 8526 && u_save(lnum, lnum + 1) == OK) 8527 { 8528 if (argvars[1].v_type == VAR_LIST) 8529 { 8530 l = argvars[1].vval.v_list; 8531 if (l == NULL) 8532 return; 8533 li = l->lv_first; 8534 } 8535 for (;;) 8536 { 8537 if (l == NULL) 8538 tv = &argvars[1]; /* append a string */ 8539 else if (li == NULL) 8540 break; /* end of list */ 8541 else 8542 tv = &li->li_tv; /* append item from list */ 8543 line = get_tv_string_chk(tv); 8544 if (line == NULL) /* type error */ 8545 { 8546 rettv->vval.v_number = 1; /* Failed */ 8547 break; 8548 } 8549 ml_append(lnum + added, line, (colnr_T)0, FALSE); 8550 ++added; 8551 if (l == NULL) 8552 break; 8553 li = li->li_next; 8554 } 8555 8556 appended_lines_mark(lnum, added); 8557 if (curwin->w_cursor.lnum > lnum) 8558 curwin->w_cursor.lnum += added; 8559 } 8560 else 8561 rettv->vval.v_number = 1; /* Failed */ 8562} 8563 8564/* 8565 * "argc()" function 8566 */ 8567 static void 8568f_argc(argvars, rettv) 8569 typval_T *argvars UNUSED; 8570 typval_T *rettv; 8571{ 8572 rettv->vval.v_number = ARGCOUNT; 8573} 8574 8575/* 8576 * "argidx()" function 8577 */ 8578 static void 8579f_argidx(argvars, rettv) 8580 typval_T *argvars UNUSED; 8581 typval_T *rettv; 8582{ 8583 rettv->vval.v_number = curwin->w_arg_idx; 8584} 8585 8586/* 8587 * "argv(nr)" function 8588 */ 8589 static void 8590f_argv(argvars, rettv) 8591 typval_T *argvars; 8592 typval_T *rettv; 8593{ 8594 int idx; 8595 8596 if (argvars[0].v_type != VAR_UNKNOWN) 8597 { 8598 idx = get_tv_number_chk(&argvars[0], NULL); 8599 if (idx >= 0 && idx < ARGCOUNT) 8600 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 8601 else 8602 rettv->vval.v_string = NULL; 8603 rettv->v_type = VAR_STRING; 8604 } 8605 else if (rettv_list_alloc(rettv) == OK) 8606 for (idx = 0; idx < ARGCOUNT; ++idx) 8607 list_append_string(rettv->vval.v_list, 8608 alist_name(&ARGLIST[idx]), -1); 8609} 8610 8611#ifdef FEAT_FLOAT 8612/* 8613 * "asin()" function 8614 */ 8615 static void 8616f_asin(argvars, rettv) 8617 typval_T *argvars; 8618 typval_T *rettv; 8619{ 8620 float_T f; 8621 8622 rettv->v_type = VAR_FLOAT; 8623 if (get_float_arg(argvars, &f) == OK) 8624 rettv->vval.v_float = asin(f); 8625 else 8626 rettv->vval.v_float = 0.0; 8627} 8628 8629/* 8630 * "atan()" function 8631 */ 8632 static void 8633f_atan(argvars, rettv) 8634 typval_T *argvars; 8635 typval_T *rettv; 8636{ 8637 float_T f; 8638 8639 rettv->v_type = VAR_FLOAT; 8640 if (get_float_arg(argvars, &f) == OK) 8641 rettv->vval.v_float = atan(f); 8642 else 8643 rettv->vval.v_float = 0.0; 8644} 8645 8646/* 8647 * "atan2()" function 8648 */ 8649 static void 8650f_atan2(argvars, rettv) 8651 typval_T *argvars; 8652 typval_T *rettv; 8653{ 8654 float_T fx, fy; 8655 8656 rettv->v_type = VAR_FLOAT; 8657 if (get_float_arg(argvars, &fx) == OK 8658 && get_float_arg(&argvars[1], &fy) == OK) 8659 rettv->vval.v_float = atan2(fx, fy); 8660 else 8661 rettv->vval.v_float = 0.0; 8662} 8663#endif 8664 8665/* 8666 * "browse(save, title, initdir, default)" function 8667 */ 8668 static void 8669f_browse(argvars, rettv) 8670 typval_T *argvars UNUSED; 8671 typval_T *rettv; 8672{ 8673#ifdef FEAT_BROWSE 8674 int save; 8675 char_u *title; 8676 char_u *initdir; 8677 char_u *defname; 8678 char_u buf[NUMBUFLEN]; 8679 char_u buf2[NUMBUFLEN]; 8680 int error = FALSE; 8681 8682 save = get_tv_number_chk(&argvars[0], &error); 8683 title = get_tv_string_chk(&argvars[1]); 8684 initdir = get_tv_string_buf_chk(&argvars[2], buf); 8685 defname = get_tv_string_buf_chk(&argvars[3], buf2); 8686 8687 if (error || title == NULL || initdir == NULL || defname == NULL) 8688 rettv->vval.v_string = NULL; 8689 else 8690 rettv->vval.v_string = 8691 do_browse(save ? BROWSE_SAVE : 0, 8692 title, defname, NULL, initdir, NULL, curbuf); 8693#else 8694 rettv->vval.v_string = NULL; 8695#endif 8696 rettv->v_type = VAR_STRING; 8697} 8698 8699/* 8700 * "browsedir(title, initdir)" function 8701 */ 8702 static void 8703f_browsedir(argvars, rettv) 8704 typval_T *argvars UNUSED; 8705 typval_T *rettv; 8706{ 8707#ifdef FEAT_BROWSE 8708 char_u *title; 8709 char_u *initdir; 8710 char_u buf[NUMBUFLEN]; 8711 8712 title = get_tv_string_chk(&argvars[0]); 8713 initdir = get_tv_string_buf_chk(&argvars[1], buf); 8714 8715 if (title == NULL || initdir == NULL) 8716 rettv->vval.v_string = NULL; 8717 else 8718 rettv->vval.v_string = do_browse(BROWSE_DIR, 8719 title, NULL, NULL, initdir, NULL, curbuf); 8720#else 8721 rettv->vval.v_string = NULL; 8722#endif 8723 rettv->v_type = VAR_STRING; 8724} 8725 8726static buf_T *find_buffer __ARGS((typval_T *avar)); 8727 8728/* 8729 * Find a buffer by number or exact name. 8730 */ 8731 static buf_T * 8732find_buffer(avar) 8733 typval_T *avar; 8734{ 8735 buf_T *buf = NULL; 8736 8737 if (avar->v_type == VAR_NUMBER) 8738 buf = buflist_findnr((int)avar->vval.v_number); 8739 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 8740 { 8741 buf = buflist_findname_exp(avar->vval.v_string); 8742 if (buf == NULL) 8743 { 8744 /* No full path name match, try a match with a URL or a "nofile" 8745 * buffer, these don't use the full path. */ 8746 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 8747 if (buf->b_fname != NULL 8748 && (path_with_url(buf->b_fname) 8749#ifdef FEAT_QUICKFIX 8750 || bt_nofile(buf) 8751#endif 8752 ) 8753 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 8754 break; 8755 } 8756 } 8757 return buf; 8758} 8759 8760/* 8761 * "bufexists(expr)" function 8762 */ 8763 static void 8764f_bufexists(argvars, rettv) 8765 typval_T *argvars; 8766 typval_T *rettv; 8767{ 8768 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 8769} 8770 8771/* 8772 * "buflisted(expr)" function 8773 */ 8774 static void 8775f_buflisted(argvars, rettv) 8776 typval_T *argvars; 8777 typval_T *rettv; 8778{ 8779 buf_T *buf; 8780 8781 buf = find_buffer(&argvars[0]); 8782 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 8783} 8784 8785/* 8786 * "bufloaded(expr)" function 8787 */ 8788 static void 8789f_bufloaded(argvars, rettv) 8790 typval_T *argvars; 8791 typval_T *rettv; 8792{ 8793 buf_T *buf; 8794 8795 buf = find_buffer(&argvars[0]); 8796 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 8797} 8798 8799static buf_T *get_buf_tv __ARGS((typval_T *tv)); 8800 8801/* 8802 * Get buffer by number or pattern. 8803 */ 8804 static buf_T * 8805get_buf_tv(tv) 8806 typval_T *tv; 8807{ 8808 char_u *name = tv->vval.v_string; 8809 int save_magic; 8810 char_u *save_cpo; 8811 buf_T *buf; 8812 8813 if (tv->v_type == VAR_NUMBER) 8814 return buflist_findnr((int)tv->vval.v_number); 8815 if (tv->v_type != VAR_STRING) 8816 return NULL; 8817 if (name == NULL || *name == NUL) 8818 return curbuf; 8819 if (name[0] == '$' && name[1] == NUL) 8820 return lastbuf; 8821 8822 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 8823 save_magic = p_magic; 8824 p_magic = TRUE; 8825 save_cpo = p_cpo; 8826 p_cpo = (char_u *)""; 8827 8828 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 8829 TRUE, FALSE)); 8830 8831 p_magic = save_magic; 8832 p_cpo = save_cpo; 8833 8834 /* If not found, try expanding the name, like done for bufexists(). */ 8835 if (buf == NULL) 8836 buf = find_buffer(tv); 8837 8838 return buf; 8839} 8840 8841/* 8842 * "bufname(expr)" function 8843 */ 8844 static void 8845f_bufname(argvars, rettv) 8846 typval_T *argvars; 8847 typval_T *rettv; 8848{ 8849 buf_T *buf; 8850 8851 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8852 ++emsg_off; 8853 buf = get_buf_tv(&argvars[0]); 8854 rettv->v_type = VAR_STRING; 8855 if (buf != NULL && buf->b_fname != NULL) 8856 rettv->vval.v_string = vim_strsave(buf->b_fname); 8857 else 8858 rettv->vval.v_string = NULL; 8859 --emsg_off; 8860} 8861 8862/* 8863 * "bufnr(expr)" function 8864 */ 8865 static void 8866f_bufnr(argvars, rettv) 8867 typval_T *argvars; 8868 typval_T *rettv; 8869{ 8870 buf_T *buf; 8871 int error = FALSE; 8872 char_u *name; 8873 8874 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8875 ++emsg_off; 8876 buf = get_buf_tv(&argvars[0]); 8877 --emsg_off; 8878 8879 /* If the buffer isn't found and the second argument is not zero create a 8880 * new buffer. */ 8881 if (buf == NULL 8882 && argvars[1].v_type != VAR_UNKNOWN 8883 && get_tv_number_chk(&argvars[1], &error) != 0 8884 && !error 8885 && (name = get_tv_string_chk(&argvars[0])) != NULL 8886 && !error) 8887 buf = buflist_new(name, NULL, (linenr_T)1, 0); 8888 8889 if (buf != NULL) 8890 rettv->vval.v_number = buf->b_fnum; 8891 else 8892 rettv->vval.v_number = -1; 8893} 8894 8895/* 8896 * "bufwinnr(nr)" function 8897 */ 8898 static void 8899f_bufwinnr(argvars, rettv) 8900 typval_T *argvars; 8901 typval_T *rettv; 8902{ 8903#ifdef FEAT_WINDOWS 8904 win_T *wp; 8905 int winnr = 0; 8906#endif 8907 buf_T *buf; 8908 8909 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8910 ++emsg_off; 8911 buf = get_buf_tv(&argvars[0]); 8912#ifdef FEAT_WINDOWS 8913 for (wp = firstwin; wp; wp = wp->w_next) 8914 { 8915 ++winnr; 8916 if (wp->w_buffer == buf) 8917 break; 8918 } 8919 rettv->vval.v_number = (wp != NULL ? winnr : -1); 8920#else 8921 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 8922#endif 8923 --emsg_off; 8924} 8925 8926/* 8927 * "byte2line(byte)" function 8928 */ 8929 static void 8930f_byte2line(argvars, rettv) 8931 typval_T *argvars UNUSED; 8932 typval_T *rettv; 8933{ 8934#ifndef FEAT_BYTEOFF 8935 rettv->vval.v_number = -1; 8936#else 8937 long boff = 0; 8938 8939 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8940 if (boff < 0) 8941 rettv->vval.v_number = -1; 8942 else 8943 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8944 (linenr_T)0, &boff); 8945#endif 8946} 8947 8948/* 8949 * "byteidx()" function 8950 */ 8951 static void 8952f_byteidx(argvars, rettv) 8953 typval_T *argvars; 8954 typval_T *rettv; 8955{ 8956#ifdef FEAT_MBYTE 8957 char_u *t; 8958#endif 8959 char_u *str; 8960 long idx; 8961 8962 str = get_tv_string_chk(&argvars[0]); 8963 idx = get_tv_number_chk(&argvars[1], NULL); 8964 rettv->vval.v_number = -1; 8965 if (str == NULL || idx < 0) 8966 return; 8967 8968#ifdef FEAT_MBYTE 8969 t = str; 8970 for ( ; idx > 0; idx--) 8971 { 8972 if (*t == NUL) /* EOL reached */ 8973 return; 8974 t += (*mb_ptr2len)(t); 8975 } 8976 rettv->vval.v_number = (varnumber_T)(t - str); 8977#else 8978 if ((size_t)idx <= STRLEN(str)) 8979 rettv->vval.v_number = idx; 8980#endif 8981} 8982 8983/* 8984 * "call(func, arglist)" function 8985 */ 8986 static void 8987f_call(argvars, rettv) 8988 typval_T *argvars; 8989 typval_T *rettv; 8990{ 8991 char_u *func; 8992 typval_T argv[MAX_FUNC_ARGS + 1]; 8993 int argc = 0; 8994 listitem_T *item; 8995 int dummy; 8996 dict_T *selfdict = NULL; 8997 8998 if (argvars[1].v_type != VAR_LIST) 8999 { 9000 EMSG(_(e_listreq)); 9001 return; 9002 } 9003 if (argvars[1].vval.v_list == NULL) 9004 return; 9005 9006 if (argvars[0].v_type == VAR_FUNC) 9007 func = argvars[0].vval.v_string; 9008 else 9009 func = get_tv_string(&argvars[0]); 9010 if (*func == NUL) 9011 return; /* type error or empty name */ 9012 9013 if (argvars[2].v_type != VAR_UNKNOWN) 9014 { 9015 if (argvars[2].v_type != VAR_DICT) 9016 { 9017 EMSG(_(e_dictreq)); 9018 return; 9019 } 9020 selfdict = argvars[2].vval.v_dict; 9021 } 9022 9023 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 9024 item = item->li_next) 9025 { 9026 if (argc == MAX_FUNC_ARGS) 9027 { 9028 EMSG(_("E699: Too many arguments")); 9029 break; 9030 } 9031 /* Make a copy of each argument. This is needed to be able to set 9032 * v_lock to VAR_FIXED in the copy without changing the original list. 9033 */ 9034 copy_tv(&item->li_tv, &argv[argc++]); 9035 } 9036 9037 if (item == NULL) 9038 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 9039 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 9040 &dummy, TRUE, selfdict); 9041 9042 /* Free the arguments. */ 9043 while (argc > 0) 9044 clear_tv(&argv[--argc]); 9045} 9046 9047#ifdef FEAT_FLOAT 9048/* 9049 * "ceil({float})" function 9050 */ 9051 static void 9052f_ceil(argvars, rettv) 9053 typval_T *argvars; 9054 typval_T *rettv; 9055{ 9056 float_T f; 9057 9058 rettv->v_type = VAR_FLOAT; 9059 if (get_float_arg(argvars, &f) == OK) 9060 rettv->vval.v_float = ceil(f); 9061 else 9062 rettv->vval.v_float = 0.0; 9063} 9064#endif 9065 9066/* 9067 * "changenr()" function 9068 */ 9069 static void 9070f_changenr(argvars, rettv) 9071 typval_T *argvars UNUSED; 9072 typval_T *rettv; 9073{ 9074 rettv->vval.v_number = curbuf->b_u_seq_cur; 9075} 9076 9077/* 9078 * "char2nr(string)" function 9079 */ 9080 static void 9081f_char2nr(argvars, rettv) 9082 typval_T *argvars; 9083 typval_T *rettv; 9084{ 9085#ifdef FEAT_MBYTE 9086 if (has_mbyte) 9087 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 9088 else 9089#endif 9090 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 9091} 9092 9093/* 9094 * "cindent(lnum)" function 9095 */ 9096 static void 9097f_cindent(argvars, rettv) 9098 typval_T *argvars; 9099 typval_T *rettv; 9100{ 9101#ifdef FEAT_CINDENT 9102 pos_T pos; 9103 linenr_T lnum; 9104 9105 pos = curwin->w_cursor; 9106 lnum = get_tv_lnum(argvars); 9107 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9108 { 9109 curwin->w_cursor.lnum = lnum; 9110 rettv->vval.v_number = get_c_indent(); 9111 curwin->w_cursor = pos; 9112 } 9113 else 9114#endif 9115 rettv->vval.v_number = -1; 9116} 9117 9118/* 9119 * "clearmatches()" function 9120 */ 9121 static void 9122f_clearmatches(argvars, rettv) 9123 typval_T *argvars UNUSED; 9124 typval_T *rettv UNUSED; 9125{ 9126#ifdef FEAT_SEARCH_EXTRA 9127 clear_matches(curwin); 9128#endif 9129} 9130 9131/* 9132 * "col(string)" function 9133 */ 9134 static void 9135f_col(argvars, rettv) 9136 typval_T *argvars; 9137 typval_T *rettv; 9138{ 9139 colnr_T col = 0; 9140 pos_T *fp; 9141 int fnum = curbuf->b_fnum; 9142 9143 fp = var2fpos(&argvars[0], FALSE, &fnum); 9144 if (fp != NULL && fnum == curbuf->b_fnum) 9145 { 9146 if (fp->col == MAXCOL) 9147 { 9148 /* '> can be MAXCOL, get the length of the line then */ 9149 if (fp->lnum <= curbuf->b_ml.ml_line_count) 9150 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 9151 else 9152 col = MAXCOL; 9153 } 9154 else 9155 { 9156 col = fp->col + 1; 9157#ifdef FEAT_VIRTUALEDIT 9158 /* col(".") when the cursor is on the NUL at the end of the line 9159 * because of "coladd" can be seen as an extra column. */ 9160 if (virtual_active() && fp == &curwin->w_cursor) 9161 { 9162 char_u *p = ml_get_cursor(); 9163 9164 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 9165 curwin->w_virtcol - curwin->w_cursor.coladd)) 9166 { 9167# ifdef FEAT_MBYTE 9168 int l; 9169 9170 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 9171 col += l; 9172# else 9173 if (*p != NUL && p[1] == NUL) 9174 ++col; 9175# endif 9176 } 9177 } 9178#endif 9179 } 9180 } 9181 rettv->vval.v_number = col; 9182} 9183 9184#if defined(FEAT_INS_EXPAND) 9185/* 9186 * "complete()" function 9187 */ 9188 static void 9189f_complete(argvars, rettv) 9190 typval_T *argvars; 9191 typval_T *rettv UNUSED; 9192{ 9193 int startcol; 9194 9195 if ((State & INSERT) == 0) 9196 { 9197 EMSG(_("E785: complete() can only be used in Insert mode")); 9198 return; 9199 } 9200 9201 /* Check for undo allowed here, because if something was already inserted 9202 * the line was already saved for undo and this check isn't done. */ 9203 if (!undo_allowed()) 9204 return; 9205 9206 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 9207 { 9208 EMSG(_(e_invarg)); 9209 return; 9210 } 9211 9212 startcol = get_tv_number_chk(&argvars[0], NULL); 9213 if (startcol <= 0) 9214 return; 9215 9216 set_completion(startcol - 1, argvars[1].vval.v_list); 9217} 9218 9219/* 9220 * "complete_add()" function 9221 */ 9222 static void 9223f_complete_add(argvars, rettv) 9224 typval_T *argvars; 9225 typval_T *rettv; 9226{ 9227 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 9228} 9229 9230/* 9231 * "complete_check()" function 9232 */ 9233 static void 9234f_complete_check(argvars, rettv) 9235 typval_T *argvars UNUSED; 9236 typval_T *rettv; 9237{ 9238 int saved = RedrawingDisabled; 9239 9240 RedrawingDisabled = 0; 9241 ins_compl_check_keys(0); 9242 rettv->vval.v_number = compl_interrupted; 9243 RedrawingDisabled = saved; 9244} 9245#endif 9246 9247/* 9248 * "confirm(message, buttons[, default [, type]])" function 9249 */ 9250 static void 9251f_confirm(argvars, rettv) 9252 typval_T *argvars UNUSED; 9253 typval_T *rettv UNUSED; 9254{ 9255#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 9256 char_u *message; 9257 char_u *buttons = NULL; 9258 char_u buf[NUMBUFLEN]; 9259 char_u buf2[NUMBUFLEN]; 9260 int def = 1; 9261 int type = VIM_GENERIC; 9262 char_u *typestr; 9263 int error = FALSE; 9264 9265 message = get_tv_string_chk(&argvars[0]); 9266 if (message == NULL) 9267 error = TRUE; 9268 if (argvars[1].v_type != VAR_UNKNOWN) 9269 { 9270 buttons = get_tv_string_buf_chk(&argvars[1], buf); 9271 if (buttons == NULL) 9272 error = TRUE; 9273 if (argvars[2].v_type != VAR_UNKNOWN) 9274 { 9275 def = get_tv_number_chk(&argvars[2], &error); 9276 if (argvars[3].v_type != VAR_UNKNOWN) 9277 { 9278 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 9279 if (typestr == NULL) 9280 error = TRUE; 9281 else 9282 { 9283 switch (TOUPPER_ASC(*typestr)) 9284 { 9285 case 'E': type = VIM_ERROR; break; 9286 case 'Q': type = VIM_QUESTION; break; 9287 case 'I': type = VIM_INFO; break; 9288 case 'W': type = VIM_WARNING; break; 9289 case 'G': type = VIM_GENERIC; break; 9290 } 9291 } 9292 } 9293 } 9294 } 9295 9296 if (buttons == NULL || *buttons == NUL) 9297 buttons = (char_u *)_("&Ok"); 9298 9299 if (!error) 9300 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 9301 def, NULL); 9302#endif 9303} 9304 9305/* 9306 * "copy()" function 9307 */ 9308 static void 9309f_copy(argvars, rettv) 9310 typval_T *argvars; 9311 typval_T *rettv; 9312{ 9313 item_copy(&argvars[0], rettv, FALSE, 0); 9314} 9315 9316#ifdef FEAT_FLOAT 9317/* 9318 * "cos()" function 9319 */ 9320 static void 9321f_cos(argvars, rettv) 9322 typval_T *argvars; 9323 typval_T *rettv; 9324{ 9325 float_T f; 9326 9327 rettv->v_type = VAR_FLOAT; 9328 if (get_float_arg(argvars, &f) == OK) 9329 rettv->vval.v_float = cos(f); 9330 else 9331 rettv->vval.v_float = 0.0; 9332} 9333 9334/* 9335 * "cosh()" function 9336 */ 9337 static void 9338f_cosh(argvars, rettv) 9339 typval_T *argvars; 9340 typval_T *rettv; 9341{ 9342 float_T f; 9343 9344 rettv->v_type = VAR_FLOAT; 9345 if (get_float_arg(argvars, &f) == OK) 9346 rettv->vval.v_float = cosh(f); 9347 else 9348 rettv->vval.v_float = 0.0; 9349} 9350#endif 9351 9352/* 9353 * "count()" function 9354 */ 9355 static void 9356f_count(argvars, rettv) 9357 typval_T *argvars; 9358 typval_T *rettv; 9359{ 9360 long n = 0; 9361 int ic = FALSE; 9362 9363 if (argvars[0].v_type == VAR_LIST) 9364 { 9365 listitem_T *li; 9366 list_T *l; 9367 long idx; 9368 9369 if ((l = argvars[0].vval.v_list) != NULL) 9370 { 9371 li = l->lv_first; 9372 if (argvars[2].v_type != VAR_UNKNOWN) 9373 { 9374 int error = FALSE; 9375 9376 ic = get_tv_number_chk(&argvars[2], &error); 9377 if (argvars[3].v_type != VAR_UNKNOWN) 9378 { 9379 idx = get_tv_number_chk(&argvars[3], &error); 9380 if (!error) 9381 { 9382 li = list_find(l, idx); 9383 if (li == NULL) 9384 EMSGN(_(e_listidx), idx); 9385 } 9386 } 9387 if (error) 9388 li = NULL; 9389 } 9390 9391 for ( ; li != NULL; li = li->li_next) 9392 if (tv_equal(&li->li_tv, &argvars[1], ic)) 9393 ++n; 9394 } 9395 } 9396 else if (argvars[0].v_type == VAR_DICT) 9397 { 9398 int todo; 9399 dict_T *d; 9400 hashitem_T *hi; 9401 9402 if ((d = argvars[0].vval.v_dict) != NULL) 9403 { 9404 int error = FALSE; 9405 9406 if (argvars[2].v_type != VAR_UNKNOWN) 9407 { 9408 ic = get_tv_number_chk(&argvars[2], &error); 9409 if (argvars[3].v_type != VAR_UNKNOWN) 9410 EMSG(_(e_invarg)); 9411 } 9412 9413 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 9414 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 9415 { 9416 if (!HASHITEM_EMPTY(hi)) 9417 { 9418 --todo; 9419 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 9420 ++n; 9421 } 9422 } 9423 } 9424 } 9425 else 9426 EMSG2(_(e_listdictarg), "count()"); 9427 rettv->vval.v_number = n; 9428} 9429 9430/* 9431 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 9432 * 9433 * Checks the existence of a cscope connection. 9434 */ 9435 static void 9436f_cscope_connection(argvars, rettv) 9437 typval_T *argvars UNUSED; 9438 typval_T *rettv UNUSED; 9439{ 9440#ifdef FEAT_CSCOPE 9441 int num = 0; 9442 char_u *dbpath = NULL; 9443 char_u *prepend = NULL; 9444 char_u buf[NUMBUFLEN]; 9445 9446 if (argvars[0].v_type != VAR_UNKNOWN 9447 && argvars[1].v_type != VAR_UNKNOWN) 9448 { 9449 num = (int)get_tv_number(&argvars[0]); 9450 dbpath = get_tv_string(&argvars[1]); 9451 if (argvars[2].v_type != VAR_UNKNOWN) 9452 prepend = get_tv_string_buf(&argvars[2], buf); 9453 } 9454 9455 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 9456#endif 9457} 9458 9459/* 9460 * "cursor(lnum, col)" function 9461 * 9462 * Moves the cursor to the specified line and column. 9463 * Returns 0 when the position could be set, -1 otherwise. 9464 */ 9465 static void 9466f_cursor(argvars, rettv) 9467 typval_T *argvars; 9468 typval_T *rettv; 9469{ 9470 long line, col; 9471#ifdef FEAT_VIRTUALEDIT 9472 long coladd = 0; 9473#endif 9474 9475 rettv->vval.v_number = -1; 9476 if (argvars[1].v_type == VAR_UNKNOWN) 9477 { 9478 pos_T pos; 9479 9480 if (list2fpos(argvars, &pos, NULL) == FAIL) 9481 return; 9482 line = pos.lnum; 9483 col = pos.col; 9484#ifdef FEAT_VIRTUALEDIT 9485 coladd = pos.coladd; 9486#endif 9487 } 9488 else 9489 { 9490 line = get_tv_lnum(argvars); 9491 col = get_tv_number_chk(&argvars[1], NULL); 9492#ifdef FEAT_VIRTUALEDIT 9493 if (argvars[2].v_type != VAR_UNKNOWN) 9494 coladd = get_tv_number_chk(&argvars[2], NULL); 9495#endif 9496 } 9497 if (line < 0 || col < 0 9498#ifdef FEAT_VIRTUALEDIT 9499 || coladd < 0 9500#endif 9501 ) 9502 return; /* type error; errmsg already given */ 9503 if (line > 0) 9504 curwin->w_cursor.lnum = line; 9505 if (col > 0) 9506 curwin->w_cursor.col = col - 1; 9507#ifdef FEAT_VIRTUALEDIT 9508 curwin->w_cursor.coladd = coladd; 9509#endif 9510 9511 /* Make sure the cursor is in a valid position. */ 9512 check_cursor(); 9513#ifdef FEAT_MBYTE 9514 /* Correct cursor for multi-byte character. */ 9515 if (has_mbyte) 9516 mb_adjust_cursor(); 9517#endif 9518 9519 curwin->w_set_curswant = TRUE; 9520 rettv->vval.v_number = 0; 9521} 9522 9523/* 9524 * "deepcopy()" function 9525 */ 9526 static void 9527f_deepcopy(argvars, rettv) 9528 typval_T *argvars; 9529 typval_T *rettv; 9530{ 9531 int noref = 0; 9532 9533 if (argvars[1].v_type != VAR_UNKNOWN) 9534 noref = get_tv_number_chk(&argvars[1], NULL); 9535 if (noref < 0 || noref > 1) 9536 EMSG(_(e_invarg)); 9537 else 9538 { 9539 current_copyID += COPYID_INC; 9540 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); 9541 } 9542} 9543 9544/* 9545 * "delete()" function 9546 */ 9547 static void 9548f_delete(argvars, rettv) 9549 typval_T *argvars; 9550 typval_T *rettv; 9551{ 9552 if (check_restricted() || check_secure()) 9553 rettv->vval.v_number = -1; 9554 else 9555 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 9556} 9557 9558/* 9559 * "did_filetype()" function 9560 */ 9561 static void 9562f_did_filetype(argvars, rettv) 9563 typval_T *argvars UNUSED; 9564 typval_T *rettv UNUSED; 9565{ 9566#ifdef FEAT_AUTOCMD 9567 rettv->vval.v_number = did_filetype; 9568#endif 9569} 9570 9571/* 9572 * "diff_filler()" function 9573 */ 9574 static void 9575f_diff_filler(argvars, rettv) 9576 typval_T *argvars UNUSED; 9577 typval_T *rettv UNUSED; 9578{ 9579#ifdef FEAT_DIFF 9580 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 9581#endif 9582} 9583 9584/* 9585 * "diff_hlID()" function 9586 */ 9587 static void 9588f_diff_hlID(argvars, rettv) 9589 typval_T *argvars UNUSED; 9590 typval_T *rettv UNUSED; 9591{ 9592#ifdef FEAT_DIFF 9593 linenr_T lnum = get_tv_lnum(argvars); 9594 static linenr_T prev_lnum = 0; 9595 static int changedtick = 0; 9596 static int fnum = 0; 9597 static int change_start = 0; 9598 static int change_end = 0; 9599 static hlf_T hlID = (hlf_T)0; 9600 int filler_lines; 9601 int col; 9602 9603 if (lnum < 0) /* ignore type error in {lnum} arg */ 9604 lnum = 0; 9605 if (lnum != prev_lnum 9606 || changedtick != curbuf->b_changedtick 9607 || fnum != curbuf->b_fnum) 9608 { 9609 /* New line, buffer, change: need to get the values. */ 9610 filler_lines = diff_check(curwin, lnum); 9611 if (filler_lines < 0) 9612 { 9613 if (filler_lines == -1) 9614 { 9615 change_start = MAXCOL; 9616 change_end = -1; 9617 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 9618 hlID = HLF_ADD; /* added line */ 9619 else 9620 hlID = HLF_CHD; /* changed line */ 9621 } 9622 else 9623 hlID = HLF_ADD; /* added line */ 9624 } 9625 else 9626 hlID = (hlf_T)0; 9627 prev_lnum = lnum; 9628 changedtick = curbuf->b_changedtick; 9629 fnum = curbuf->b_fnum; 9630 } 9631 9632 if (hlID == HLF_CHD || hlID == HLF_TXD) 9633 { 9634 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 9635 if (col >= change_start && col <= change_end) 9636 hlID = HLF_TXD; /* changed text */ 9637 else 9638 hlID = HLF_CHD; /* changed line */ 9639 } 9640 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 9641#endif 9642} 9643 9644/* 9645 * "empty({expr})" function 9646 */ 9647 static void 9648f_empty(argvars, rettv) 9649 typval_T *argvars; 9650 typval_T *rettv; 9651{ 9652 int n; 9653 9654 switch (argvars[0].v_type) 9655 { 9656 case VAR_STRING: 9657 case VAR_FUNC: 9658 n = argvars[0].vval.v_string == NULL 9659 || *argvars[0].vval.v_string == NUL; 9660 break; 9661 case VAR_NUMBER: 9662 n = argvars[0].vval.v_number == 0; 9663 break; 9664#ifdef FEAT_FLOAT 9665 case VAR_FLOAT: 9666 n = argvars[0].vval.v_float == 0.0; 9667 break; 9668#endif 9669 case VAR_LIST: 9670 n = argvars[0].vval.v_list == NULL 9671 || argvars[0].vval.v_list->lv_first == NULL; 9672 break; 9673 case VAR_DICT: 9674 n = argvars[0].vval.v_dict == NULL 9675 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 9676 break; 9677 default: 9678 EMSG2(_(e_intern2), "f_empty()"); 9679 n = 0; 9680 } 9681 9682 rettv->vval.v_number = n; 9683} 9684 9685/* 9686 * "escape({string}, {chars})" function 9687 */ 9688 static void 9689f_escape(argvars, rettv) 9690 typval_T *argvars; 9691 typval_T *rettv; 9692{ 9693 char_u buf[NUMBUFLEN]; 9694 9695 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 9696 get_tv_string_buf(&argvars[1], buf)); 9697 rettv->v_type = VAR_STRING; 9698} 9699 9700/* 9701 * "eval()" function 9702 */ 9703 static void 9704f_eval(argvars, rettv) 9705 typval_T *argvars; 9706 typval_T *rettv; 9707{ 9708 char_u *s; 9709 9710 s = get_tv_string_chk(&argvars[0]); 9711 if (s != NULL) 9712 s = skipwhite(s); 9713 9714 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 9715 { 9716 rettv->v_type = VAR_NUMBER; 9717 rettv->vval.v_number = 0; 9718 } 9719 else if (*s != NUL) 9720 EMSG(_(e_trailing)); 9721} 9722 9723/* 9724 * "eventhandler()" function 9725 */ 9726 static void 9727f_eventhandler(argvars, rettv) 9728 typval_T *argvars UNUSED; 9729 typval_T *rettv; 9730{ 9731 rettv->vval.v_number = vgetc_busy; 9732} 9733 9734/* 9735 * "executable()" function 9736 */ 9737 static void 9738f_executable(argvars, rettv) 9739 typval_T *argvars; 9740 typval_T *rettv; 9741{ 9742 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 9743} 9744 9745/* 9746 * "exists()" function 9747 */ 9748 static void 9749f_exists(argvars, rettv) 9750 typval_T *argvars; 9751 typval_T *rettv; 9752{ 9753 char_u *p; 9754 char_u *name; 9755 int n = FALSE; 9756 int len = 0; 9757 9758 no_autoload = TRUE; 9759 9760 p = get_tv_string(&argvars[0]); 9761 if (*p == '$') /* environment variable */ 9762 { 9763 /* first try "normal" environment variables (fast) */ 9764 if (mch_getenv(p + 1) != NULL) 9765 n = TRUE; 9766 else 9767 { 9768 /* try expanding things like $VIM and ${HOME} */ 9769 p = expand_env_save(p); 9770 if (p != NULL && *p != '$') 9771 n = TRUE; 9772 vim_free(p); 9773 } 9774 } 9775 else if (*p == '&' || *p == '+') /* option */ 9776 { 9777 n = (get_option_tv(&p, NULL, TRUE) == OK); 9778 if (*skipwhite(p) != NUL) 9779 n = FALSE; /* trailing garbage */ 9780 } 9781 else if (*p == '*') /* internal or user defined function */ 9782 { 9783 n = function_exists(p + 1); 9784 } 9785 else if (*p == ':') 9786 { 9787 n = cmd_exists(p + 1); 9788 } 9789 else if (*p == '#') 9790 { 9791#ifdef FEAT_AUTOCMD 9792 if (p[1] == '#') 9793 n = autocmd_supported(p + 2); 9794 else 9795 n = au_exists(p + 1); 9796#endif 9797 } 9798 else /* internal variable */ 9799 { 9800 char_u *tofree; 9801 typval_T tv; 9802 9803 /* get_name_len() takes care of expanding curly braces */ 9804 name = p; 9805 len = get_name_len(&p, &tofree, TRUE, FALSE); 9806 if (len > 0) 9807 { 9808 if (tofree != NULL) 9809 name = tofree; 9810 n = (get_var_tv(name, len, &tv, FALSE) == OK); 9811 if (n) 9812 { 9813 /* handle d.key, l[idx], f(expr) */ 9814 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 9815 if (n) 9816 clear_tv(&tv); 9817 } 9818 } 9819 if (*p != NUL) 9820 n = FALSE; 9821 9822 vim_free(tofree); 9823 } 9824 9825 rettv->vval.v_number = n; 9826 9827 no_autoload = FALSE; 9828} 9829 9830#ifdef FEAT_FLOAT 9831/* 9832 * "exp()" function 9833 */ 9834 static void 9835f_exp(argvars, rettv) 9836 typval_T *argvars; 9837 typval_T *rettv; 9838{ 9839 float_T f; 9840 9841 rettv->v_type = VAR_FLOAT; 9842 if (get_float_arg(argvars, &f) == OK) 9843 rettv->vval.v_float = exp(f); 9844 else 9845 rettv->vval.v_float = 0.0; 9846} 9847#endif 9848 9849/* 9850 * "expand()" function 9851 */ 9852 static void 9853f_expand(argvars, rettv) 9854 typval_T *argvars; 9855 typval_T *rettv; 9856{ 9857 char_u *s; 9858 int len; 9859 char_u *errormsg; 9860 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 9861 expand_T xpc; 9862 int error = FALSE; 9863 9864 rettv->v_type = VAR_STRING; 9865 s = get_tv_string(&argvars[0]); 9866 if (*s == '%' || *s == '#' || *s == '<') 9867 { 9868 ++emsg_off; 9869 rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL); 9870 --emsg_off; 9871 } 9872 else 9873 { 9874 /* When the optional second argument is non-zero, don't remove matches 9875 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 9876 if (argvars[1].v_type != VAR_UNKNOWN 9877 && get_tv_number_chk(&argvars[1], &error)) 9878 flags |= WILD_KEEP_ALL; 9879 if (!error) 9880 { 9881 ExpandInit(&xpc); 9882 xpc.xp_context = EXPAND_FILES; 9883 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 9884 } 9885 else 9886 rettv->vval.v_string = NULL; 9887 } 9888} 9889 9890/* 9891 * "extend(list, list [, idx])" function 9892 * "extend(dict, dict [, action])" function 9893 */ 9894 static void 9895f_extend(argvars, rettv) 9896 typval_T *argvars; 9897 typval_T *rettv; 9898{ 9899 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 9900 { 9901 list_T *l1, *l2; 9902 listitem_T *item; 9903 long before; 9904 int error = FALSE; 9905 9906 l1 = argvars[0].vval.v_list; 9907 l2 = argvars[1].vval.v_list; 9908 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 9909 && l2 != NULL) 9910 { 9911 if (argvars[2].v_type != VAR_UNKNOWN) 9912 { 9913 before = get_tv_number_chk(&argvars[2], &error); 9914 if (error) 9915 return; /* type error; errmsg already given */ 9916 9917 if (before == l1->lv_len) 9918 item = NULL; 9919 else 9920 { 9921 item = list_find(l1, before); 9922 if (item == NULL) 9923 { 9924 EMSGN(_(e_listidx), before); 9925 return; 9926 } 9927 } 9928 } 9929 else 9930 item = NULL; 9931 list_extend(l1, l2, item); 9932 9933 copy_tv(&argvars[0], rettv); 9934 } 9935 } 9936 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 9937 { 9938 dict_T *d1, *d2; 9939 dictitem_T *di1; 9940 char_u *action; 9941 int i; 9942 hashitem_T *hi2; 9943 int todo; 9944 9945 d1 = argvars[0].vval.v_dict; 9946 d2 = argvars[1].vval.v_dict; 9947 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 9948 && d2 != NULL) 9949 { 9950 /* Check the third argument. */ 9951 if (argvars[2].v_type != VAR_UNKNOWN) 9952 { 9953 static char *(av[]) = {"keep", "force", "error"}; 9954 9955 action = get_tv_string_chk(&argvars[2]); 9956 if (action == NULL) 9957 return; /* type error; errmsg already given */ 9958 for (i = 0; i < 3; ++i) 9959 if (STRCMP(action, av[i]) == 0) 9960 break; 9961 if (i == 3) 9962 { 9963 EMSG2(_(e_invarg2), action); 9964 return; 9965 } 9966 } 9967 else 9968 action = (char_u *)"force"; 9969 9970 /* Go over all entries in the second dict and add them to the 9971 * first dict. */ 9972 todo = (int)d2->dv_hashtab.ht_used; 9973 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 9974 { 9975 if (!HASHITEM_EMPTY(hi2)) 9976 { 9977 --todo; 9978 di1 = dict_find(d1, hi2->hi_key, -1); 9979 if (di1 == NULL) 9980 { 9981 di1 = dictitem_copy(HI2DI(hi2)); 9982 if (di1 != NULL && dict_add(d1, di1) == FAIL) 9983 dictitem_free(di1); 9984 } 9985 else if (*action == 'e') 9986 { 9987 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 9988 break; 9989 } 9990 else if (*action == 'f') 9991 { 9992 clear_tv(&di1->di_tv); 9993 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 9994 } 9995 } 9996 } 9997 9998 copy_tv(&argvars[0], rettv); 9999 } 10000 } 10001 else 10002 EMSG2(_(e_listdictarg), "extend()"); 10003} 10004 10005/* 10006 * "feedkeys()" function 10007 */ 10008 static void 10009f_feedkeys(argvars, rettv) 10010 typval_T *argvars; 10011 typval_T *rettv UNUSED; 10012{ 10013 int remap = TRUE; 10014 char_u *keys, *flags; 10015 char_u nbuf[NUMBUFLEN]; 10016 int typed = FALSE; 10017 char_u *keys_esc; 10018 10019 /* This is not allowed in the sandbox. If the commands would still be 10020 * executed in the sandbox it would be OK, but it probably happens later, 10021 * when "sandbox" is no longer set. */ 10022 if (check_secure()) 10023 return; 10024 10025 keys = get_tv_string(&argvars[0]); 10026 if (*keys != NUL) 10027 { 10028 if (argvars[1].v_type != VAR_UNKNOWN) 10029 { 10030 flags = get_tv_string_buf(&argvars[1], nbuf); 10031 for ( ; *flags != NUL; ++flags) 10032 { 10033 switch (*flags) 10034 { 10035 case 'n': remap = FALSE; break; 10036 case 'm': remap = TRUE; break; 10037 case 't': typed = TRUE; break; 10038 } 10039 } 10040 } 10041 10042 /* Need to escape K_SPECIAL and CSI before putting the string in the 10043 * typeahead buffer. */ 10044 keys_esc = vim_strsave_escape_csi(keys); 10045 if (keys_esc != NULL) 10046 { 10047 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 10048 typebuf.tb_len, !typed, FALSE); 10049 vim_free(keys_esc); 10050 if (vgetc_busy) 10051 typebuf_was_filled = TRUE; 10052 } 10053 } 10054} 10055 10056/* 10057 * "filereadable()" function 10058 */ 10059 static void 10060f_filereadable(argvars, rettv) 10061 typval_T *argvars; 10062 typval_T *rettv; 10063{ 10064 int fd; 10065 char_u *p; 10066 int n; 10067 10068#ifndef O_NONBLOCK 10069# define O_NONBLOCK 0 10070#endif 10071 p = get_tv_string(&argvars[0]); 10072 if (*p && !mch_isdir(p) && (fd = mch_open((char *)p, 10073 O_RDONLY | O_NONBLOCK, 0)) >= 0) 10074 { 10075 n = TRUE; 10076 close(fd); 10077 } 10078 else 10079 n = FALSE; 10080 10081 rettv->vval.v_number = n; 10082} 10083 10084/* 10085 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 10086 * rights to write into. 10087 */ 10088 static void 10089f_filewritable(argvars, rettv) 10090 typval_T *argvars; 10091 typval_T *rettv; 10092{ 10093 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 10094} 10095 10096static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what)); 10097 10098 static void 10099findfilendir(argvars, rettv, find_what) 10100 typval_T *argvars; 10101 typval_T *rettv; 10102 int find_what; 10103{ 10104#ifdef FEAT_SEARCHPATH 10105 char_u *fname; 10106 char_u *fresult = NULL; 10107 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 10108 char_u *p; 10109 char_u pathbuf[NUMBUFLEN]; 10110 int count = 1; 10111 int first = TRUE; 10112 int error = FALSE; 10113#endif 10114 10115 rettv->vval.v_string = NULL; 10116 rettv->v_type = VAR_STRING; 10117 10118#ifdef FEAT_SEARCHPATH 10119 fname = get_tv_string(&argvars[0]); 10120 10121 if (argvars[1].v_type != VAR_UNKNOWN) 10122 { 10123 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 10124 if (p == NULL) 10125 error = TRUE; 10126 else 10127 { 10128 if (*p != NUL) 10129 path = p; 10130 10131 if (argvars[2].v_type != VAR_UNKNOWN) 10132 count = get_tv_number_chk(&argvars[2], &error); 10133 } 10134 } 10135 10136 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 10137 error = TRUE; 10138 10139 if (*fname != NUL && !error) 10140 { 10141 do 10142 { 10143 if (rettv->v_type == VAR_STRING) 10144 vim_free(fresult); 10145 fresult = find_file_in_path_option(first ? fname : NULL, 10146 first ? (int)STRLEN(fname) : 0, 10147 0, first, path, 10148 find_what, 10149 curbuf->b_ffname, 10150 find_what == FINDFILE_DIR 10151 ? (char_u *)"" : curbuf->b_p_sua); 10152 first = FALSE; 10153 10154 if (fresult != NULL && rettv->v_type == VAR_LIST) 10155 list_append_string(rettv->vval.v_list, fresult, -1); 10156 10157 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 10158 } 10159 10160 if (rettv->v_type == VAR_STRING) 10161 rettv->vval.v_string = fresult; 10162#endif 10163} 10164 10165static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 10166static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 10167 10168/* 10169 * Implementation of map() and filter(). 10170 */ 10171 static void 10172filter_map(argvars, rettv, map) 10173 typval_T *argvars; 10174 typval_T *rettv; 10175 int map; 10176{ 10177 char_u buf[NUMBUFLEN]; 10178 char_u *expr; 10179 listitem_T *li, *nli; 10180 list_T *l = NULL; 10181 dictitem_T *di; 10182 hashtab_T *ht; 10183 hashitem_T *hi; 10184 dict_T *d = NULL; 10185 typval_T save_val; 10186 typval_T save_key; 10187 int rem; 10188 int todo; 10189 char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; 10190 int save_did_emsg; 10191 int idx = 0; 10192 10193 if (argvars[0].v_type == VAR_LIST) 10194 { 10195 if ((l = argvars[0].vval.v_list) == NULL 10196 || (map && tv_check_lock(l->lv_lock, ermsg))) 10197 return; 10198 } 10199 else if (argvars[0].v_type == VAR_DICT) 10200 { 10201 if ((d = argvars[0].vval.v_dict) == NULL 10202 || (map && tv_check_lock(d->dv_lock, ermsg))) 10203 return; 10204 } 10205 else 10206 { 10207 EMSG2(_(e_listdictarg), ermsg); 10208 return; 10209 } 10210 10211 expr = get_tv_string_buf_chk(&argvars[1], buf); 10212 /* On type errors, the preceding call has already displayed an error 10213 * message. Avoid a misleading error message for an empty string that 10214 * was not passed as argument. */ 10215 if (expr != NULL) 10216 { 10217 prepare_vimvar(VV_VAL, &save_val); 10218 expr = skipwhite(expr); 10219 10220 /* We reset "did_emsg" to be able to detect whether an error 10221 * occurred during evaluation of the expression. */ 10222 save_did_emsg = did_emsg; 10223 did_emsg = FALSE; 10224 10225 prepare_vimvar(VV_KEY, &save_key); 10226 if (argvars[0].v_type == VAR_DICT) 10227 { 10228 vimvars[VV_KEY].vv_type = VAR_STRING; 10229 10230 ht = &d->dv_hashtab; 10231 hash_lock(ht); 10232 todo = (int)ht->ht_used; 10233 for (hi = ht->ht_array; todo > 0; ++hi) 10234 { 10235 if (!HASHITEM_EMPTY(hi)) 10236 { 10237 --todo; 10238 di = HI2DI(hi); 10239 if (tv_check_lock(di->di_tv.v_lock, ermsg)) 10240 break; 10241 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 10242 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 10243 || did_emsg) 10244 break; 10245 if (!map && rem) 10246 dictitem_remove(d, di); 10247 clear_tv(&vimvars[VV_KEY].vv_tv); 10248 } 10249 } 10250 hash_unlock(ht); 10251 } 10252 else 10253 { 10254 vimvars[VV_KEY].vv_type = VAR_NUMBER; 10255 10256 for (li = l->lv_first; li != NULL; li = nli) 10257 { 10258 if (tv_check_lock(li->li_tv.v_lock, ermsg)) 10259 break; 10260 nli = li->li_next; 10261 vimvars[VV_KEY].vv_nr = idx; 10262 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 10263 || did_emsg) 10264 break; 10265 if (!map && rem) 10266 listitem_remove(l, li); 10267 ++idx; 10268 } 10269 } 10270 10271 restore_vimvar(VV_KEY, &save_key); 10272 restore_vimvar(VV_VAL, &save_val); 10273 10274 did_emsg |= save_did_emsg; 10275 } 10276 10277 copy_tv(&argvars[0], rettv); 10278} 10279 10280 static int 10281filter_map_one(tv, expr, map, remp) 10282 typval_T *tv; 10283 char_u *expr; 10284 int map; 10285 int *remp; 10286{ 10287 typval_T rettv; 10288 char_u *s; 10289 int retval = FAIL; 10290 10291 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 10292 s = expr; 10293 if (eval1(&s, &rettv, TRUE) == FAIL) 10294 goto theend; 10295 if (*s != NUL) /* check for trailing chars after expr */ 10296 { 10297 EMSG2(_(e_invexpr2), s); 10298 goto theend; 10299 } 10300 if (map) 10301 { 10302 /* map(): replace the list item value */ 10303 clear_tv(tv); 10304 rettv.v_lock = 0; 10305 *tv = rettv; 10306 } 10307 else 10308 { 10309 int error = FALSE; 10310 10311 /* filter(): when expr is zero remove the item */ 10312 *remp = (get_tv_number_chk(&rettv, &error) == 0); 10313 clear_tv(&rettv); 10314 /* On type error, nothing has been removed; return FAIL to stop the 10315 * loop. The error message was given by get_tv_number_chk(). */ 10316 if (error) 10317 goto theend; 10318 } 10319 retval = OK; 10320theend: 10321 clear_tv(&vimvars[VV_VAL].vv_tv); 10322 return retval; 10323} 10324 10325/* 10326 * "filter()" function 10327 */ 10328 static void 10329f_filter(argvars, rettv) 10330 typval_T *argvars; 10331 typval_T *rettv; 10332{ 10333 filter_map(argvars, rettv, FALSE); 10334} 10335 10336/* 10337 * "finddir({fname}[, {path}[, {count}]])" function 10338 */ 10339 static void 10340f_finddir(argvars, rettv) 10341 typval_T *argvars; 10342 typval_T *rettv; 10343{ 10344 findfilendir(argvars, rettv, FINDFILE_DIR); 10345} 10346 10347/* 10348 * "findfile({fname}[, {path}[, {count}]])" function 10349 */ 10350 static void 10351f_findfile(argvars, rettv) 10352 typval_T *argvars; 10353 typval_T *rettv; 10354{ 10355 findfilendir(argvars, rettv, FINDFILE_FILE); 10356} 10357 10358#ifdef FEAT_FLOAT 10359/* 10360 * "float2nr({float})" function 10361 */ 10362 static void 10363f_float2nr(argvars, rettv) 10364 typval_T *argvars; 10365 typval_T *rettv; 10366{ 10367 float_T f; 10368 10369 if (get_float_arg(argvars, &f) == OK) 10370 { 10371 if (f < -0x7fffffff) 10372 rettv->vval.v_number = -0x7fffffff; 10373 else if (f > 0x7fffffff) 10374 rettv->vval.v_number = 0x7fffffff; 10375 else 10376 rettv->vval.v_number = (varnumber_T)f; 10377 } 10378} 10379 10380/* 10381 * "floor({float})" function 10382 */ 10383 static void 10384f_floor(argvars, rettv) 10385 typval_T *argvars; 10386 typval_T *rettv; 10387{ 10388 float_T f; 10389 10390 rettv->v_type = VAR_FLOAT; 10391 if (get_float_arg(argvars, &f) == OK) 10392 rettv->vval.v_float = floor(f); 10393 else 10394 rettv->vval.v_float = 0.0; 10395} 10396 10397/* 10398 * "fmod()" function 10399 */ 10400 static void 10401f_fmod(argvars, rettv) 10402 typval_T *argvars; 10403 typval_T *rettv; 10404{ 10405 float_T fx, fy; 10406 10407 rettv->v_type = VAR_FLOAT; 10408 if (get_float_arg(argvars, &fx) == OK 10409 && get_float_arg(&argvars[1], &fy) == OK) 10410 rettv->vval.v_float = fmod(fx, fy); 10411 else 10412 rettv->vval.v_float = 0.0; 10413} 10414#endif 10415 10416/* 10417 * "fnameescape({string})" function 10418 */ 10419 static void 10420f_fnameescape(argvars, rettv) 10421 typval_T *argvars; 10422 typval_T *rettv; 10423{ 10424 rettv->vval.v_string = vim_strsave_fnameescape( 10425 get_tv_string(&argvars[0]), FALSE); 10426 rettv->v_type = VAR_STRING; 10427} 10428 10429/* 10430 * "fnamemodify({fname}, {mods})" function 10431 */ 10432 static void 10433f_fnamemodify(argvars, rettv) 10434 typval_T *argvars; 10435 typval_T *rettv; 10436{ 10437 char_u *fname; 10438 char_u *mods; 10439 int usedlen = 0; 10440 int len; 10441 char_u *fbuf = NULL; 10442 char_u buf[NUMBUFLEN]; 10443 10444 fname = get_tv_string_chk(&argvars[0]); 10445 mods = get_tv_string_buf_chk(&argvars[1], buf); 10446 if (fname == NULL || mods == NULL) 10447 fname = NULL; 10448 else 10449 { 10450 len = (int)STRLEN(fname); 10451 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 10452 } 10453 10454 rettv->v_type = VAR_STRING; 10455 if (fname == NULL) 10456 rettv->vval.v_string = NULL; 10457 else 10458 rettv->vval.v_string = vim_strnsave(fname, len); 10459 vim_free(fbuf); 10460} 10461 10462static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 10463 10464/* 10465 * "foldclosed()" function 10466 */ 10467 static void 10468foldclosed_both(argvars, rettv, end) 10469 typval_T *argvars; 10470 typval_T *rettv; 10471 int end; 10472{ 10473#ifdef FEAT_FOLDING 10474 linenr_T lnum; 10475 linenr_T first, last; 10476 10477 lnum = get_tv_lnum(argvars); 10478 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10479 { 10480 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 10481 { 10482 if (end) 10483 rettv->vval.v_number = (varnumber_T)last; 10484 else 10485 rettv->vval.v_number = (varnumber_T)first; 10486 return; 10487 } 10488 } 10489#endif 10490 rettv->vval.v_number = -1; 10491} 10492 10493/* 10494 * "foldclosed()" function 10495 */ 10496 static void 10497f_foldclosed(argvars, rettv) 10498 typval_T *argvars; 10499 typval_T *rettv; 10500{ 10501 foldclosed_both(argvars, rettv, FALSE); 10502} 10503 10504/* 10505 * "foldclosedend()" function 10506 */ 10507 static void 10508f_foldclosedend(argvars, rettv) 10509 typval_T *argvars; 10510 typval_T *rettv; 10511{ 10512 foldclosed_both(argvars, rettv, TRUE); 10513} 10514 10515/* 10516 * "foldlevel()" function 10517 */ 10518 static void 10519f_foldlevel(argvars, rettv) 10520 typval_T *argvars; 10521 typval_T *rettv; 10522{ 10523#ifdef FEAT_FOLDING 10524 linenr_T lnum; 10525 10526 lnum = get_tv_lnum(argvars); 10527 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10528 rettv->vval.v_number = foldLevel(lnum); 10529#endif 10530} 10531 10532/* 10533 * "foldtext()" function 10534 */ 10535 static void 10536f_foldtext(argvars, rettv) 10537 typval_T *argvars UNUSED; 10538 typval_T *rettv; 10539{ 10540#ifdef FEAT_FOLDING 10541 linenr_T lnum; 10542 char_u *s; 10543 char_u *r; 10544 int len; 10545 char *txt; 10546#endif 10547 10548 rettv->v_type = VAR_STRING; 10549 rettv->vval.v_string = NULL; 10550#ifdef FEAT_FOLDING 10551 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 10552 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 10553 <= curbuf->b_ml.ml_line_count 10554 && vimvars[VV_FOLDDASHES].vv_str != NULL) 10555 { 10556 /* Find first non-empty line in the fold. */ 10557 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 10558 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10559 { 10560 if (!linewhite(lnum)) 10561 break; 10562 ++lnum; 10563 } 10564 10565 /* Find interesting text in this line. */ 10566 s = skipwhite(ml_get(lnum)); 10567 /* skip C comment-start */ 10568 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 10569 { 10570 s = skipwhite(s + 2); 10571 if (*skipwhite(s) == NUL 10572 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 10573 { 10574 s = skipwhite(ml_get(lnum + 1)); 10575 if (*s == '*') 10576 s = skipwhite(s + 1); 10577 } 10578 } 10579 txt = _("+-%s%3ld lines: "); 10580 r = alloc((unsigned)(STRLEN(txt) 10581 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 10582 + 20 /* for %3ld */ 10583 + STRLEN(s))); /* concatenated */ 10584 if (r != NULL) 10585 { 10586 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 10587 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 10588 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 10589 len = (int)STRLEN(r); 10590 STRCAT(r, s); 10591 /* remove 'foldmarker' and 'commentstring' */ 10592 foldtext_cleanup(r + len); 10593 rettv->vval.v_string = r; 10594 } 10595 } 10596#endif 10597} 10598 10599/* 10600 * "foldtextresult(lnum)" function 10601 */ 10602 static void 10603f_foldtextresult(argvars, rettv) 10604 typval_T *argvars UNUSED; 10605 typval_T *rettv; 10606{ 10607#ifdef FEAT_FOLDING 10608 linenr_T lnum; 10609 char_u *text; 10610 char_u buf[51]; 10611 foldinfo_T foldinfo; 10612 int fold_count; 10613#endif 10614 10615 rettv->v_type = VAR_STRING; 10616 rettv->vval.v_string = NULL; 10617#ifdef FEAT_FOLDING 10618 lnum = get_tv_lnum(argvars); 10619 /* treat illegal types and illegal string values for {lnum} the same */ 10620 if (lnum < 0) 10621 lnum = 0; 10622 fold_count = foldedCount(curwin, lnum, &foldinfo); 10623 if (fold_count > 0) 10624 { 10625 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 10626 &foldinfo, buf); 10627 if (text == buf) 10628 text = vim_strsave(text); 10629 rettv->vval.v_string = text; 10630 } 10631#endif 10632} 10633 10634/* 10635 * "foreground()" function 10636 */ 10637 static void 10638f_foreground(argvars, rettv) 10639 typval_T *argvars UNUSED; 10640 typval_T *rettv UNUSED; 10641{ 10642#ifdef FEAT_GUI 10643 if (gui.in_use) 10644 gui_mch_set_foreground(); 10645#else 10646# ifdef WIN32 10647 win32_set_foreground(); 10648# endif 10649#endif 10650} 10651 10652/* 10653 * "function()" function 10654 */ 10655 static void 10656f_function(argvars, rettv) 10657 typval_T *argvars; 10658 typval_T *rettv; 10659{ 10660 char_u *s; 10661 10662 s = get_tv_string(&argvars[0]); 10663 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 10664 EMSG2(_(e_invarg2), s); 10665 /* Don't check an autoload name for existence here. */ 10666 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) 10667 EMSG2(_("E700: Unknown function: %s"), s); 10668 else 10669 { 10670 rettv->vval.v_string = vim_strsave(s); 10671 rettv->v_type = VAR_FUNC; 10672 } 10673} 10674 10675/* 10676 * "garbagecollect()" function 10677 */ 10678 static void 10679f_garbagecollect(argvars, rettv) 10680 typval_T *argvars; 10681 typval_T *rettv UNUSED; 10682{ 10683 /* This is postponed until we are back at the toplevel, because we may be 10684 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 10685 want_garbage_collect = TRUE; 10686 10687 if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1) 10688 garbage_collect_at_exit = TRUE; 10689} 10690 10691/* 10692 * "get()" function 10693 */ 10694 static void 10695f_get(argvars, rettv) 10696 typval_T *argvars; 10697 typval_T *rettv; 10698{ 10699 listitem_T *li; 10700 list_T *l; 10701 dictitem_T *di; 10702 dict_T *d; 10703 typval_T *tv = NULL; 10704 10705 if (argvars[0].v_type == VAR_LIST) 10706 { 10707 if ((l = argvars[0].vval.v_list) != NULL) 10708 { 10709 int error = FALSE; 10710 10711 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 10712 if (!error && li != NULL) 10713 tv = &li->li_tv; 10714 } 10715 } 10716 else if (argvars[0].v_type == VAR_DICT) 10717 { 10718 if ((d = argvars[0].vval.v_dict) != NULL) 10719 { 10720 di = dict_find(d, get_tv_string(&argvars[1]), -1); 10721 if (di != NULL) 10722 tv = &di->di_tv; 10723 } 10724 } 10725 else 10726 EMSG2(_(e_listdictarg), "get()"); 10727 10728 if (tv == NULL) 10729 { 10730 if (argvars[2].v_type != VAR_UNKNOWN) 10731 copy_tv(&argvars[2], rettv); 10732 } 10733 else 10734 copy_tv(tv, rettv); 10735} 10736 10737static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 10738 10739/* 10740 * Get line or list of lines from buffer "buf" into "rettv". 10741 * Return a range (from start to end) of lines in rettv from the specified 10742 * buffer. 10743 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 10744 */ 10745 static void 10746get_buffer_lines(buf, start, end, retlist, rettv) 10747 buf_T *buf; 10748 linenr_T start; 10749 linenr_T end; 10750 int retlist; 10751 typval_T *rettv; 10752{ 10753 char_u *p; 10754 10755 if (retlist && rettv_list_alloc(rettv) == FAIL) 10756 return; 10757 10758 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 10759 return; 10760 10761 if (!retlist) 10762 { 10763 if (start >= 1 && start <= buf->b_ml.ml_line_count) 10764 p = ml_get_buf(buf, start, FALSE); 10765 else 10766 p = (char_u *)""; 10767 10768 rettv->v_type = VAR_STRING; 10769 rettv->vval.v_string = vim_strsave(p); 10770 } 10771 else 10772 { 10773 if (end < start) 10774 return; 10775 10776 if (start < 1) 10777 start = 1; 10778 if (end > buf->b_ml.ml_line_count) 10779 end = buf->b_ml.ml_line_count; 10780 while (start <= end) 10781 if (list_append_string(rettv->vval.v_list, 10782 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 10783 break; 10784 } 10785} 10786 10787/* 10788 * "getbufline()" function 10789 */ 10790 static void 10791f_getbufline(argvars, rettv) 10792 typval_T *argvars; 10793 typval_T *rettv; 10794{ 10795 linenr_T lnum; 10796 linenr_T end; 10797 buf_T *buf; 10798 10799 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10800 ++emsg_off; 10801 buf = get_buf_tv(&argvars[0]); 10802 --emsg_off; 10803 10804 lnum = get_tv_lnum_buf(&argvars[1], buf); 10805 if (argvars[2].v_type == VAR_UNKNOWN) 10806 end = lnum; 10807 else 10808 end = get_tv_lnum_buf(&argvars[2], buf); 10809 10810 get_buffer_lines(buf, lnum, end, TRUE, rettv); 10811} 10812 10813/* 10814 * "getbufvar()" function 10815 */ 10816 static void 10817f_getbufvar(argvars, rettv) 10818 typval_T *argvars; 10819 typval_T *rettv; 10820{ 10821 buf_T *buf; 10822 buf_T *save_curbuf; 10823 char_u *varname; 10824 dictitem_T *v; 10825 10826 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 10827 varname = get_tv_string_chk(&argvars[1]); 10828 ++emsg_off; 10829 buf = get_buf_tv(&argvars[0]); 10830 10831 rettv->v_type = VAR_STRING; 10832 rettv->vval.v_string = NULL; 10833 10834 if (buf != NULL && varname != NULL) 10835 { 10836 /* set curbuf to be our buf, temporarily */ 10837 save_curbuf = curbuf; 10838 curbuf = buf; 10839 10840 if (*varname == '&') /* buffer-local-option */ 10841 get_option_tv(&varname, rettv, TRUE); 10842 else 10843 { 10844 if (*varname == NUL) 10845 /* let getbufvar({nr}, "") return the "b:" dictionary. The 10846 * scope prefix before the NUL byte is required by 10847 * find_var_in_ht(). */ 10848 varname = (char_u *)"b:" + 2; 10849 /* look up the variable */ 10850 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); 10851 if (v != NULL) 10852 copy_tv(&v->di_tv, rettv); 10853 } 10854 10855 /* restore previous notion of curbuf */ 10856 curbuf = save_curbuf; 10857 } 10858 10859 --emsg_off; 10860} 10861 10862/* 10863 * "getchar()" function 10864 */ 10865 static void 10866f_getchar(argvars, rettv) 10867 typval_T *argvars; 10868 typval_T *rettv; 10869{ 10870 varnumber_T n; 10871 int error = FALSE; 10872 10873 /* Position the cursor. Needed after a message that ends in a space. */ 10874 windgoto(msg_row, msg_col); 10875 10876 ++no_mapping; 10877 ++allow_keys; 10878 for (;;) 10879 { 10880 if (argvars[0].v_type == VAR_UNKNOWN) 10881 /* getchar(): blocking wait. */ 10882 n = safe_vgetc(); 10883 else if (get_tv_number_chk(&argvars[0], &error) == 1) 10884 /* getchar(1): only check if char avail */ 10885 n = vpeekc(); 10886 else if (error || vpeekc() == NUL) 10887 /* illegal argument or getchar(0) and no char avail: return zero */ 10888 n = 0; 10889 else 10890 /* getchar(0) and char avail: return char */ 10891 n = safe_vgetc(); 10892 if (n == K_IGNORE) 10893 continue; 10894 break; 10895 } 10896 --no_mapping; 10897 --allow_keys; 10898 10899 vimvars[VV_MOUSE_WIN].vv_nr = 0; 10900 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 10901 vimvars[VV_MOUSE_COL].vv_nr = 0; 10902 10903 rettv->vval.v_number = n; 10904 if (IS_SPECIAL(n) || mod_mask != 0) 10905 { 10906 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 10907 int i = 0; 10908 10909 /* Turn a special key into three bytes, plus modifier. */ 10910 if (mod_mask != 0) 10911 { 10912 temp[i++] = K_SPECIAL; 10913 temp[i++] = KS_MODIFIER; 10914 temp[i++] = mod_mask; 10915 } 10916 if (IS_SPECIAL(n)) 10917 { 10918 temp[i++] = K_SPECIAL; 10919 temp[i++] = K_SECOND(n); 10920 temp[i++] = K_THIRD(n); 10921 } 10922#ifdef FEAT_MBYTE 10923 else if (has_mbyte) 10924 i += (*mb_char2bytes)(n, temp + i); 10925#endif 10926 else 10927 temp[i++] = n; 10928 temp[i++] = NUL; 10929 rettv->v_type = VAR_STRING; 10930 rettv->vval.v_string = vim_strsave(temp); 10931 10932#ifdef FEAT_MOUSE 10933 if (n == K_LEFTMOUSE 10934 || n == K_LEFTMOUSE_NM 10935 || n == K_LEFTDRAG 10936 || n == K_LEFTRELEASE 10937 || n == K_LEFTRELEASE_NM 10938 || n == K_MIDDLEMOUSE 10939 || n == K_MIDDLEDRAG 10940 || n == K_MIDDLERELEASE 10941 || n == K_RIGHTMOUSE 10942 || n == K_RIGHTDRAG 10943 || n == K_RIGHTRELEASE 10944 || n == K_X1MOUSE 10945 || n == K_X1DRAG 10946 || n == K_X1RELEASE 10947 || n == K_X2MOUSE 10948 || n == K_X2DRAG 10949 || n == K_X2RELEASE 10950 || n == K_MOUSELEFT 10951 || n == K_MOUSERIGHT 10952 || n == K_MOUSEDOWN 10953 || n == K_MOUSEUP) 10954 { 10955 int row = mouse_row; 10956 int col = mouse_col; 10957 win_T *win; 10958 linenr_T lnum; 10959# ifdef FEAT_WINDOWS 10960 win_T *wp; 10961# endif 10962 int winnr = 1; 10963 10964 if (row >= 0 && col >= 0) 10965 { 10966 /* Find the window at the mouse coordinates and compute the 10967 * text position. */ 10968 win = mouse_find_win(&row, &col); 10969 (void)mouse_comp_pos(win, &row, &col, &lnum); 10970# ifdef FEAT_WINDOWS 10971 for (wp = firstwin; wp != win; wp = wp->w_next) 10972 ++winnr; 10973# endif 10974 vimvars[VV_MOUSE_WIN].vv_nr = winnr; 10975 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 10976 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 10977 } 10978 } 10979#endif 10980 } 10981} 10982 10983/* 10984 * "getcharmod()" function 10985 */ 10986 static void 10987f_getcharmod(argvars, rettv) 10988 typval_T *argvars UNUSED; 10989 typval_T *rettv; 10990{ 10991 rettv->vval.v_number = mod_mask; 10992} 10993 10994/* 10995 * "getcmdline()" function 10996 */ 10997 static void 10998f_getcmdline(argvars, rettv) 10999 typval_T *argvars UNUSED; 11000 typval_T *rettv; 11001{ 11002 rettv->v_type = VAR_STRING; 11003 rettv->vval.v_string = get_cmdline_str(); 11004} 11005 11006/* 11007 * "getcmdpos()" function 11008 */ 11009 static void 11010f_getcmdpos(argvars, rettv) 11011 typval_T *argvars UNUSED; 11012 typval_T *rettv; 11013{ 11014 rettv->vval.v_number = get_cmdline_pos() + 1; 11015} 11016 11017/* 11018 * "getcmdtype()" function 11019 */ 11020 static void 11021f_getcmdtype(argvars, rettv) 11022 typval_T *argvars UNUSED; 11023 typval_T *rettv; 11024{ 11025 rettv->v_type = VAR_STRING; 11026 rettv->vval.v_string = alloc(2); 11027 if (rettv->vval.v_string != NULL) 11028 { 11029 rettv->vval.v_string[0] = get_cmdline_type(); 11030 rettv->vval.v_string[1] = NUL; 11031 } 11032} 11033 11034/* 11035 * "getcwd()" function 11036 */ 11037 static void 11038f_getcwd(argvars, rettv) 11039 typval_T *argvars UNUSED; 11040 typval_T *rettv; 11041{ 11042 char_u cwd[MAXPATHL]; 11043 11044 rettv->v_type = VAR_STRING; 11045 if (mch_dirname(cwd, MAXPATHL) == FAIL) 11046 rettv->vval.v_string = NULL; 11047 else 11048 { 11049 rettv->vval.v_string = vim_strsave(cwd); 11050#ifdef BACKSLASH_IN_FILENAME 11051 if (rettv->vval.v_string != NULL) 11052 slash_adjust(rettv->vval.v_string); 11053#endif 11054 } 11055} 11056 11057/* 11058 * "getfontname()" function 11059 */ 11060 static void 11061f_getfontname(argvars, rettv) 11062 typval_T *argvars UNUSED; 11063 typval_T *rettv; 11064{ 11065 rettv->v_type = VAR_STRING; 11066 rettv->vval.v_string = NULL; 11067#ifdef FEAT_GUI 11068 if (gui.in_use) 11069 { 11070 GuiFont font; 11071 char_u *name = NULL; 11072 11073 if (argvars[0].v_type == VAR_UNKNOWN) 11074 { 11075 /* Get the "Normal" font. Either the name saved by 11076 * hl_set_font_name() or from the font ID. */ 11077 font = gui.norm_font; 11078 name = hl_get_font_name(); 11079 } 11080 else 11081 { 11082 name = get_tv_string(&argvars[0]); 11083 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 11084 return; 11085 font = gui_mch_get_font(name, FALSE); 11086 if (font == NOFONT) 11087 return; /* Invalid font name, return empty string. */ 11088 } 11089 rettv->vval.v_string = gui_mch_get_fontname(font, name); 11090 if (argvars[0].v_type != VAR_UNKNOWN) 11091 gui_mch_free_font(font); 11092 } 11093#endif 11094} 11095 11096/* 11097 * "getfperm({fname})" function 11098 */ 11099 static void 11100f_getfperm(argvars, rettv) 11101 typval_T *argvars; 11102 typval_T *rettv; 11103{ 11104 char_u *fname; 11105 struct stat st; 11106 char_u *perm = NULL; 11107 char_u flags[] = "rwx"; 11108 int i; 11109 11110 fname = get_tv_string(&argvars[0]); 11111 11112 rettv->v_type = VAR_STRING; 11113 if (mch_stat((char *)fname, &st) >= 0) 11114 { 11115 perm = vim_strsave((char_u *)"---------"); 11116 if (perm != NULL) 11117 { 11118 for (i = 0; i < 9; i++) 11119 { 11120 if (st.st_mode & (1 << (8 - i))) 11121 perm[i] = flags[i % 3]; 11122 } 11123 } 11124 } 11125 rettv->vval.v_string = perm; 11126} 11127 11128/* 11129 * "getfsize({fname})" function 11130 */ 11131 static void 11132f_getfsize(argvars, rettv) 11133 typval_T *argvars; 11134 typval_T *rettv; 11135{ 11136 char_u *fname; 11137 struct stat st; 11138 11139 fname = get_tv_string(&argvars[0]); 11140 11141 rettv->v_type = VAR_NUMBER; 11142 11143 if (mch_stat((char *)fname, &st) >= 0) 11144 { 11145 if (mch_isdir(fname)) 11146 rettv->vval.v_number = 0; 11147 else 11148 { 11149 rettv->vval.v_number = (varnumber_T)st.st_size; 11150 11151 /* non-perfect check for overflow */ 11152 if ((off_t)rettv->vval.v_number != (off_t)st.st_size) 11153 rettv->vval.v_number = -2; 11154 } 11155 } 11156 else 11157 rettv->vval.v_number = -1; 11158} 11159 11160/* 11161 * "getftime({fname})" function 11162 */ 11163 static void 11164f_getftime(argvars, rettv) 11165 typval_T *argvars; 11166 typval_T *rettv; 11167{ 11168 char_u *fname; 11169 struct stat st; 11170 11171 fname = get_tv_string(&argvars[0]); 11172 11173 if (mch_stat((char *)fname, &st) >= 0) 11174 rettv->vval.v_number = (varnumber_T)st.st_mtime; 11175 else 11176 rettv->vval.v_number = -1; 11177} 11178 11179/* 11180 * "getftype({fname})" function 11181 */ 11182 static void 11183f_getftype(argvars, rettv) 11184 typval_T *argvars; 11185 typval_T *rettv; 11186{ 11187 char_u *fname; 11188 struct stat st; 11189 char_u *type = NULL; 11190 char *t; 11191 11192 fname = get_tv_string(&argvars[0]); 11193 11194 rettv->v_type = VAR_STRING; 11195 if (mch_lstat((char *)fname, &st) >= 0) 11196 { 11197#ifdef S_ISREG 11198 if (S_ISREG(st.st_mode)) 11199 t = "file"; 11200 else if (S_ISDIR(st.st_mode)) 11201 t = "dir"; 11202# ifdef S_ISLNK 11203 else if (S_ISLNK(st.st_mode)) 11204 t = "link"; 11205# endif 11206# ifdef S_ISBLK 11207 else if (S_ISBLK(st.st_mode)) 11208 t = "bdev"; 11209# endif 11210# ifdef S_ISCHR 11211 else if (S_ISCHR(st.st_mode)) 11212 t = "cdev"; 11213# endif 11214# ifdef S_ISFIFO 11215 else if (S_ISFIFO(st.st_mode)) 11216 t = "fifo"; 11217# endif 11218# ifdef S_ISSOCK 11219 else if (S_ISSOCK(st.st_mode)) 11220 t = "fifo"; 11221# endif 11222 else 11223 t = "other"; 11224#else 11225# ifdef S_IFMT 11226 switch (st.st_mode & S_IFMT) 11227 { 11228 case S_IFREG: t = "file"; break; 11229 case S_IFDIR: t = "dir"; break; 11230# ifdef S_IFLNK 11231 case S_IFLNK: t = "link"; break; 11232# endif 11233# ifdef S_IFBLK 11234 case S_IFBLK: t = "bdev"; break; 11235# endif 11236# ifdef S_IFCHR 11237 case S_IFCHR: t = "cdev"; break; 11238# endif 11239# ifdef S_IFIFO 11240 case S_IFIFO: t = "fifo"; break; 11241# endif 11242# ifdef S_IFSOCK 11243 case S_IFSOCK: t = "socket"; break; 11244# endif 11245 default: t = "other"; 11246 } 11247# else 11248 if (mch_isdir(fname)) 11249 t = "dir"; 11250 else 11251 t = "file"; 11252# endif 11253#endif 11254 type = vim_strsave((char_u *)t); 11255 } 11256 rettv->vval.v_string = type; 11257} 11258 11259/* 11260 * "getline(lnum, [end])" function 11261 */ 11262 static void 11263f_getline(argvars, rettv) 11264 typval_T *argvars; 11265 typval_T *rettv; 11266{ 11267 linenr_T lnum; 11268 linenr_T end; 11269 int retlist; 11270 11271 lnum = get_tv_lnum(argvars); 11272 if (argvars[1].v_type == VAR_UNKNOWN) 11273 { 11274 end = 0; 11275 retlist = FALSE; 11276 } 11277 else 11278 { 11279 end = get_tv_lnum(&argvars[1]); 11280 retlist = TRUE; 11281 } 11282 11283 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 11284} 11285 11286/* 11287 * "getmatches()" function 11288 */ 11289 static void 11290f_getmatches(argvars, rettv) 11291 typval_T *argvars UNUSED; 11292 typval_T *rettv; 11293{ 11294#ifdef FEAT_SEARCH_EXTRA 11295 dict_T *dict; 11296 matchitem_T *cur = curwin->w_match_head; 11297 11298 if (rettv_list_alloc(rettv) == OK) 11299 { 11300 while (cur != NULL) 11301 { 11302 dict = dict_alloc(); 11303 if (dict == NULL) 11304 return; 11305 dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id)); 11306 dict_add_nr_str(dict, "pattern", 0L, cur->pattern); 11307 dict_add_nr_str(dict, "priority", (long)cur->priority, NULL); 11308 dict_add_nr_str(dict, "id", (long)cur->id, NULL); 11309 list_append_dict(rettv->vval.v_list, dict); 11310 cur = cur->next; 11311 } 11312 } 11313#endif 11314} 11315 11316/* 11317 * "getpid()" function 11318 */ 11319 static void 11320f_getpid(argvars, rettv) 11321 typval_T *argvars UNUSED; 11322 typval_T *rettv; 11323{ 11324 rettv->vval.v_number = mch_get_pid(); 11325} 11326 11327/* 11328 * "getpos(string)" function 11329 */ 11330 static void 11331f_getpos(argvars, rettv) 11332 typval_T *argvars; 11333 typval_T *rettv; 11334{ 11335 pos_T *fp; 11336 list_T *l; 11337 int fnum = -1; 11338 11339 if (rettv_list_alloc(rettv) == OK) 11340 { 11341 l = rettv->vval.v_list; 11342 fp = var2fpos(&argvars[0], TRUE, &fnum); 11343 if (fnum != -1) 11344 list_append_number(l, (varnumber_T)fnum); 11345 else 11346 list_append_number(l, (varnumber_T)0); 11347 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 11348 : (varnumber_T)0); 11349 list_append_number(l, (fp != NULL) 11350 ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1) 11351 : (varnumber_T)0); 11352 list_append_number(l, 11353#ifdef FEAT_VIRTUALEDIT 11354 (fp != NULL) ? (varnumber_T)fp->coladd : 11355#endif 11356 (varnumber_T)0); 11357 } 11358 else 11359 rettv->vval.v_number = FALSE; 11360} 11361 11362/* 11363 * "getqflist()" and "getloclist()" functions 11364 */ 11365 static void 11366f_getqflist(argvars, rettv) 11367 typval_T *argvars UNUSED; 11368 typval_T *rettv UNUSED; 11369{ 11370#ifdef FEAT_QUICKFIX 11371 win_T *wp; 11372#endif 11373 11374#ifdef FEAT_QUICKFIX 11375 if (rettv_list_alloc(rettv) == OK) 11376 { 11377 wp = NULL; 11378 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 11379 { 11380 wp = find_win_by_nr(&argvars[0], NULL); 11381 if (wp == NULL) 11382 return; 11383 } 11384 11385 (void)get_errorlist(wp, rettv->vval.v_list); 11386 } 11387#endif 11388} 11389 11390/* 11391 * "getreg()" function 11392 */ 11393 static void 11394f_getreg(argvars, rettv) 11395 typval_T *argvars; 11396 typval_T *rettv; 11397{ 11398 char_u *strregname; 11399 int regname; 11400 int arg2 = FALSE; 11401 int error = FALSE; 11402 11403 if (argvars[0].v_type != VAR_UNKNOWN) 11404 { 11405 strregname = get_tv_string_chk(&argvars[0]); 11406 error = strregname == NULL; 11407 if (argvars[1].v_type != VAR_UNKNOWN) 11408 arg2 = get_tv_number_chk(&argvars[1], &error); 11409 } 11410 else 11411 strregname = vimvars[VV_REG].vv_str; 11412 regname = (strregname == NULL ? '"' : *strregname); 11413 if (regname == 0) 11414 regname = '"'; 11415 11416 rettv->v_type = VAR_STRING; 11417 rettv->vval.v_string = error ? NULL : 11418 get_reg_contents(regname, TRUE, arg2); 11419} 11420 11421/* 11422 * "getregtype()" function 11423 */ 11424 static void 11425f_getregtype(argvars, rettv) 11426 typval_T *argvars; 11427 typval_T *rettv; 11428{ 11429 char_u *strregname; 11430 int regname; 11431 char_u buf[NUMBUFLEN + 2]; 11432 long reglen = 0; 11433 11434 if (argvars[0].v_type != VAR_UNKNOWN) 11435 { 11436 strregname = get_tv_string_chk(&argvars[0]); 11437 if (strregname == NULL) /* type error; errmsg already given */ 11438 { 11439 rettv->v_type = VAR_STRING; 11440 rettv->vval.v_string = NULL; 11441 return; 11442 } 11443 } 11444 else 11445 /* Default to v:register */ 11446 strregname = vimvars[VV_REG].vv_str; 11447 11448 regname = (strregname == NULL ? '"' : *strregname); 11449 if (regname == 0) 11450 regname = '"'; 11451 11452 buf[0] = NUL; 11453 buf[1] = NUL; 11454 switch (get_reg_type(regname, ®len)) 11455 { 11456 case MLINE: buf[0] = 'V'; break; 11457 case MCHAR: buf[0] = 'v'; break; 11458#ifdef FEAT_VISUAL 11459 case MBLOCK: 11460 buf[0] = Ctrl_V; 11461 sprintf((char *)buf + 1, "%ld", reglen + 1); 11462 break; 11463#endif 11464 } 11465 rettv->v_type = VAR_STRING; 11466 rettv->vval.v_string = vim_strsave(buf); 11467} 11468 11469/* 11470 * "gettabvar()" function 11471 */ 11472 static void 11473f_gettabvar(argvars, rettv) 11474 typval_T *argvars; 11475 typval_T *rettv; 11476{ 11477 tabpage_T *tp; 11478 dictitem_T *v; 11479 char_u *varname; 11480 11481 rettv->v_type = VAR_STRING; 11482 rettv->vval.v_string = NULL; 11483 11484 varname = get_tv_string_chk(&argvars[1]); 11485 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11486 if (tp != NULL && varname != NULL) 11487 { 11488 /* look up the variable */ 11489 v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE); 11490 if (v != NULL) 11491 copy_tv(&v->di_tv, rettv); 11492 } 11493} 11494 11495/* 11496 * "gettabwinvar()" function 11497 */ 11498 static void 11499f_gettabwinvar(argvars, rettv) 11500 typval_T *argvars; 11501 typval_T *rettv; 11502{ 11503 getwinvar(argvars, rettv, 1); 11504} 11505 11506/* 11507 * "getwinposx()" function 11508 */ 11509 static void 11510f_getwinposx(argvars, rettv) 11511 typval_T *argvars UNUSED; 11512 typval_T *rettv; 11513{ 11514 rettv->vval.v_number = -1; 11515#ifdef FEAT_GUI 11516 if (gui.in_use) 11517 { 11518 int x, y; 11519 11520 if (gui_mch_get_winpos(&x, &y) == OK) 11521 rettv->vval.v_number = x; 11522 } 11523#endif 11524} 11525 11526/* 11527 * "getwinposy()" function 11528 */ 11529 static void 11530f_getwinposy(argvars, rettv) 11531 typval_T *argvars UNUSED; 11532 typval_T *rettv; 11533{ 11534 rettv->vval.v_number = -1; 11535#ifdef FEAT_GUI 11536 if (gui.in_use) 11537 { 11538 int x, y; 11539 11540 if (gui_mch_get_winpos(&x, &y) == OK) 11541 rettv->vval.v_number = y; 11542 } 11543#endif 11544} 11545 11546/* 11547 * Find window specified by "vp" in tabpage "tp". 11548 */ 11549 static win_T * 11550find_win_by_nr(vp, tp) 11551 typval_T *vp; 11552 tabpage_T *tp; /* NULL for current tab page */ 11553{ 11554#ifdef FEAT_WINDOWS 11555 win_T *wp; 11556#endif 11557 int nr; 11558 11559 nr = get_tv_number_chk(vp, NULL); 11560 11561#ifdef FEAT_WINDOWS 11562 if (nr < 0) 11563 return NULL; 11564 if (nr == 0) 11565 return curwin; 11566 11567 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 11568 wp != NULL; wp = wp->w_next) 11569 if (--nr <= 0) 11570 break; 11571 return wp; 11572#else 11573 if (nr == 0 || nr == 1) 11574 return curwin; 11575 return NULL; 11576#endif 11577} 11578 11579/* 11580 * "getwinvar()" function 11581 */ 11582 static void 11583f_getwinvar(argvars, rettv) 11584 typval_T *argvars; 11585 typval_T *rettv; 11586{ 11587 getwinvar(argvars, rettv, 0); 11588} 11589 11590/* 11591 * getwinvar() and gettabwinvar() 11592 */ 11593 static void 11594getwinvar(argvars, rettv, off) 11595 typval_T *argvars; 11596 typval_T *rettv; 11597 int off; /* 1 for gettabwinvar() */ 11598{ 11599 win_T *win, *oldcurwin; 11600 char_u *varname; 11601 dictitem_T *v; 11602 tabpage_T *tp; 11603 11604#ifdef FEAT_WINDOWS 11605 if (off == 1) 11606 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 11607 else 11608 tp = curtab; 11609#endif 11610 win = find_win_by_nr(&argvars[off], tp); 11611 varname = get_tv_string_chk(&argvars[off + 1]); 11612 ++emsg_off; 11613 11614 rettv->v_type = VAR_STRING; 11615 rettv->vval.v_string = NULL; 11616 11617 if (win != NULL && varname != NULL) 11618 { 11619 /* Set curwin to be our win, temporarily. Also set curbuf, so 11620 * that we can get buffer-local options. */ 11621 oldcurwin = curwin; 11622 curwin = win; 11623 curbuf = win->w_buffer; 11624 11625 if (*varname == '&') /* window-local-option */ 11626 get_option_tv(&varname, rettv, 1); 11627 else 11628 { 11629 if (*varname == NUL) 11630 /* let getwinvar({nr}, "") return the "w:" dictionary. The 11631 * scope prefix before the NUL byte is required by 11632 * find_var_in_ht(). */ 11633 varname = (char_u *)"w:" + 2; 11634 /* look up the variable */ 11635 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 11636 if (v != NULL) 11637 copy_tv(&v->di_tv, rettv); 11638 } 11639 11640 /* restore previous notion of curwin */ 11641 curwin = oldcurwin; 11642 curbuf = curwin->w_buffer; 11643 } 11644 11645 --emsg_off; 11646} 11647 11648/* 11649 * "glob()" function 11650 */ 11651 static void 11652f_glob(argvars, rettv) 11653 typval_T *argvars; 11654 typval_T *rettv; 11655{ 11656 int flags = WILD_SILENT|WILD_USE_NL; 11657 expand_T xpc; 11658 int error = FALSE; 11659 11660 /* When the optional second argument is non-zero, don't remove matches 11661 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11662 if (argvars[1].v_type != VAR_UNKNOWN 11663 && get_tv_number_chk(&argvars[1], &error)) 11664 flags |= WILD_KEEP_ALL; 11665 rettv->v_type = VAR_STRING; 11666 if (!error) 11667 { 11668 ExpandInit(&xpc); 11669 xpc.xp_context = EXPAND_FILES; 11670 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 11671 NULL, flags, WILD_ALL); 11672 } 11673 else 11674 rettv->vval.v_string = NULL; 11675} 11676 11677/* 11678 * "globpath()" function 11679 */ 11680 static void 11681f_globpath(argvars, rettv) 11682 typval_T *argvars; 11683 typval_T *rettv; 11684{ 11685 int flags = 0; 11686 char_u buf1[NUMBUFLEN]; 11687 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 11688 int error = FALSE; 11689 11690 /* When the optional second argument is non-zero, don't remove matches 11691 * for 'wildignore' and don't put matches for 'suffixes' at the end. */ 11692 if (argvars[2].v_type != VAR_UNKNOWN 11693 && get_tv_number_chk(&argvars[2], &error)) 11694 flags |= WILD_KEEP_ALL; 11695 rettv->v_type = VAR_STRING; 11696 if (file == NULL || error) 11697 rettv->vval.v_string = NULL; 11698 else 11699 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file, 11700 flags); 11701} 11702 11703/* 11704 * "has()" function 11705 */ 11706 static void 11707f_has(argvars, rettv) 11708 typval_T *argvars; 11709 typval_T *rettv; 11710{ 11711 int i; 11712 char_u *name; 11713 int n = FALSE; 11714 static char *(has_list[]) = 11715 { 11716#ifdef AMIGA 11717 "amiga", 11718# ifdef FEAT_ARP 11719 "arp", 11720# endif 11721#endif 11722#ifdef __BEOS__ 11723 "beos", 11724#endif 11725#ifdef MSDOS 11726# ifdef DJGPP 11727 "dos32", 11728# else 11729 "dos16", 11730# endif 11731#endif 11732#ifdef MACOS 11733 "mac", 11734#endif 11735#if defined(MACOS_X_UNIX) 11736 "macunix", 11737#endif 11738#ifdef OS2 11739 "os2", 11740#endif 11741#ifdef __QNX__ 11742 "qnx", 11743#endif 11744#ifdef RISCOS 11745 "riscos", 11746#endif 11747#ifdef UNIX 11748 "unix", 11749#endif 11750#ifdef VMS 11751 "vms", 11752#endif 11753#ifdef WIN16 11754 "win16", 11755#endif 11756#ifdef WIN32 11757 "win32", 11758#endif 11759#if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 11760 "win32unix", 11761#endif 11762#if defined(WIN64) || defined(_WIN64) 11763 "win64", 11764#endif 11765#ifdef EBCDIC 11766 "ebcdic", 11767#endif 11768#ifndef CASE_INSENSITIVE_FILENAME 11769 "fname_case", 11770#endif 11771#ifdef FEAT_ARABIC 11772 "arabic", 11773#endif 11774#ifdef FEAT_AUTOCMD 11775 "autocmd", 11776#endif 11777#ifdef FEAT_BEVAL 11778 "balloon_eval", 11779# ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 11780 "balloon_multiline", 11781# endif 11782#endif 11783#if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 11784 "builtin_terms", 11785# ifdef ALL_BUILTIN_TCAPS 11786 "all_builtin_terms", 11787# endif 11788#endif 11789#ifdef FEAT_BYTEOFF 11790 "byte_offset", 11791#endif 11792#ifdef FEAT_CINDENT 11793 "cindent", 11794#endif 11795#ifdef FEAT_CLIENTSERVER 11796 "clientserver", 11797#endif 11798#ifdef FEAT_CLIPBOARD 11799 "clipboard", 11800#endif 11801#ifdef FEAT_CMDL_COMPL 11802 "cmdline_compl", 11803#endif 11804#ifdef FEAT_CMDHIST 11805 "cmdline_hist", 11806#endif 11807#ifdef FEAT_COMMENTS 11808 "comments", 11809#endif 11810#ifdef FEAT_CONCEAL 11811 "conceal", 11812#endif 11813#ifdef FEAT_CRYPT 11814 "cryptv", 11815#endif 11816#ifdef FEAT_CSCOPE 11817 "cscope", 11818#endif 11819#ifdef FEAT_CURSORBIND 11820 "cursorbind", 11821#endif 11822#ifdef CURSOR_SHAPE 11823 "cursorshape", 11824#endif 11825#ifdef DEBUG 11826 "debug", 11827#endif 11828#ifdef FEAT_CON_DIALOG 11829 "dialog_con", 11830#endif 11831#ifdef FEAT_GUI_DIALOG 11832 "dialog_gui", 11833#endif 11834#ifdef FEAT_DIFF 11835 "diff", 11836#endif 11837#ifdef FEAT_DIGRAPHS 11838 "digraphs", 11839#endif 11840#ifdef FEAT_DND 11841 "dnd", 11842#endif 11843#ifdef FEAT_EMACS_TAGS 11844 "emacs_tags", 11845#endif 11846 "eval", /* always present, of course! */ 11847#ifdef FEAT_EX_EXTRA 11848 "ex_extra", 11849#endif 11850#ifdef FEAT_SEARCH_EXTRA 11851 "extra_search", 11852#endif 11853#ifdef FEAT_FKMAP 11854 "farsi", 11855#endif 11856#ifdef FEAT_SEARCHPATH 11857 "file_in_path", 11858#endif 11859#if defined(UNIX) && !defined(USE_SYSTEM) 11860 "filterpipe", 11861#endif 11862#ifdef FEAT_FIND_ID 11863 "find_in_path", 11864#endif 11865#ifdef FEAT_FLOAT 11866 "float", 11867#endif 11868#ifdef FEAT_FOLDING 11869 "folding", 11870#endif 11871#ifdef FEAT_FOOTER 11872 "footer", 11873#endif 11874#if !defined(USE_SYSTEM) && defined(UNIX) 11875 "fork", 11876#endif 11877#ifdef FEAT_GETTEXT 11878 "gettext", 11879#endif 11880#ifdef FEAT_GUI 11881 "gui", 11882#endif 11883#ifdef FEAT_GUI_ATHENA 11884# ifdef FEAT_GUI_NEXTAW 11885 "gui_neXtaw", 11886# else 11887 "gui_athena", 11888# endif 11889#endif 11890#ifdef FEAT_GUI_GTK 11891 "gui_gtk", 11892 "gui_gtk2", 11893#endif 11894#ifdef FEAT_GUI_GNOME 11895 "gui_gnome", 11896#endif 11897#ifdef FEAT_GUI_MAC 11898 "gui_mac", 11899#endif 11900#ifdef FEAT_GUI_MOTIF 11901 "gui_motif", 11902#endif 11903#ifdef FEAT_GUI_PHOTON 11904 "gui_photon", 11905#endif 11906#ifdef FEAT_GUI_W16 11907 "gui_win16", 11908#endif 11909#ifdef FEAT_GUI_W32 11910 "gui_win32", 11911#endif 11912#ifdef FEAT_HANGULIN 11913 "hangul_input", 11914#endif 11915#if defined(HAVE_ICONV_H) && defined(USE_ICONV) 11916 "iconv", 11917#endif 11918#ifdef FEAT_INS_EXPAND 11919 "insert_expand", 11920#endif 11921#ifdef FEAT_JUMPLIST 11922 "jumplist", 11923#endif 11924#ifdef FEAT_KEYMAP 11925 "keymap", 11926#endif 11927#ifdef FEAT_LANGMAP 11928 "langmap", 11929#endif 11930#ifdef FEAT_LIBCALL 11931 "libcall", 11932#endif 11933#ifdef FEAT_LINEBREAK 11934 "linebreak", 11935#endif 11936#ifdef FEAT_LISP 11937 "lispindent", 11938#endif 11939#ifdef FEAT_LISTCMDS 11940 "listcmds", 11941#endif 11942#ifdef FEAT_LOCALMAP 11943 "localmap", 11944#endif 11945#ifdef FEAT_LUA 11946# ifndef DYNAMIC_LUA 11947 "lua", 11948# endif 11949#endif 11950#ifdef FEAT_MENU 11951 "menu", 11952#endif 11953#ifdef FEAT_SESSION 11954 "mksession", 11955#endif 11956#ifdef FEAT_MODIFY_FNAME 11957 "modify_fname", 11958#endif 11959#ifdef FEAT_MOUSE 11960 "mouse", 11961#endif 11962#ifdef FEAT_MOUSESHAPE 11963 "mouseshape", 11964#endif 11965#if defined(UNIX) || defined(VMS) 11966# ifdef FEAT_MOUSE_DEC 11967 "mouse_dec", 11968# endif 11969# ifdef FEAT_MOUSE_GPM 11970 "mouse_gpm", 11971# endif 11972# ifdef FEAT_MOUSE_JSB 11973 "mouse_jsbterm", 11974# endif 11975# ifdef FEAT_MOUSE_NET 11976 "mouse_netterm", 11977# endif 11978# ifdef FEAT_MOUSE_PTERM 11979 "mouse_pterm", 11980# endif 11981# ifdef FEAT_SYSMOUSE 11982 "mouse_sysmouse", 11983# endif 11984# ifdef FEAT_MOUSE_XTERM 11985 "mouse_xterm", 11986# endif 11987#endif 11988#ifdef FEAT_MBYTE 11989 "multi_byte", 11990#endif 11991#ifdef FEAT_MBYTE_IME 11992 "multi_byte_ime", 11993#endif 11994#ifdef FEAT_MULTI_LANG 11995 "multi_lang", 11996#endif 11997#ifdef FEAT_MZSCHEME 11998#ifndef DYNAMIC_MZSCHEME 11999 "mzscheme", 12000#endif 12001#endif 12002#ifdef FEAT_OLE 12003 "ole", 12004#endif 12005#ifdef FEAT_OSFILETYPE 12006 "osfiletype", 12007#endif 12008#ifdef FEAT_PATH_EXTRA 12009 "path_extra", 12010#endif 12011#ifdef FEAT_PERL 12012#ifndef DYNAMIC_PERL 12013 "perl", 12014#endif 12015#endif 12016#ifdef FEAT_PERSISTENT_UNDO 12017 "persistent_undo", 12018#endif 12019#ifdef FEAT_PYTHON 12020#ifndef DYNAMIC_PYTHON 12021 "python", 12022#endif 12023#endif 12024#ifdef FEAT_PYTHON3 12025#ifndef DYNAMIC_PYTHON3 12026 "python3", 12027#endif 12028#endif 12029#ifdef FEAT_POSTSCRIPT 12030 "postscript", 12031#endif 12032#ifdef FEAT_PRINTER 12033 "printer", 12034#endif 12035#ifdef FEAT_PROFILE 12036 "profile", 12037#endif 12038#ifdef FEAT_RELTIME 12039 "reltime", 12040#endif 12041#ifdef FEAT_QUICKFIX 12042 "quickfix", 12043#endif 12044#ifdef FEAT_RIGHTLEFT 12045 "rightleft", 12046#endif 12047#if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 12048 "ruby", 12049#endif 12050#ifdef FEAT_SCROLLBIND 12051 "scrollbind", 12052#endif 12053#ifdef FEAT_CMDL_INFO 12054 "showcmd", 12055 "cmdline_info", 12056#endif 12057#ifdef FEAT_SIGNS 12058 "signs", 12059#endif 12060#ifdef FEAT_SMARTINDENT 12061 "smartindent", 12062#endif 12063#ifdef FEAT_SNIFF 12064 "sniff", 12065#endif 12066#ifdef STARTUPTIME 12067 "startuptime", 12068#endif 12069#ifdef FEAT_STL_OPT 12070 "statusline", 12071#endif 12072#ifdef FEAT_SUN_WORKSHOP 12073 "sun_workshop", 12074#endif 12075#ifdef FEAT_NETBEANS_INTG 12076 "netbeans_intg", 12077#endif 12078#ifdef FEAT_SPELL 12079 "spell", 12080#endif 12081#ifdef FEAT_SYN_HL 12082 "syntax", 12083#endif 12084#if defined(USE_SYSTEM) || !defined(UNIX) 12085 "system", 12086#endif 12087#ifdef FEAT_TAG_BINS 12088 "tag_binary", 12089#endif 12090#ifdef FEAT_TAG_OLDSTATIC 12091 "tag_old_static", 12092#endif 12093#ifdef FEAT_TAG_ANYWHITE 12094 "tag_any_white", 12095#endif 12096#ifdef FEAT_TCL 12097# ifndef DYNAMIC_TCL 12098 "tcl", 12099# endif 12100#endif 12101#ifdef TERMINFO 12102 "terminfo", 12103#endif 12104#ifdef FEAT_TERMRESPONSE 12105 "termresponse", 12106#endif 12107#ifdef FEAT_TEXTOBJ 12108 "textobjects", 12109#endif 12110#ifdef HAVE_TGETENT 12111 "tgetent", 12112#endif 12113#ifdef FEAT_TITLE 12114 "title", 12115#endif 12116#ifdef FEAT_TOOLBAR 12117 "toolbar", 12118#endif 12119#ifdef FEAT_USR_CMDS 12120 "user-commands", /* was accidentally included in 5.4 */ 12121 "user_commands", 12122#endif 12123#ifdef FEAT_VIMINFO 12124 "viminfo", 12125#endif 12126#ifdef FEAT_VERTSPLIT 12127 "vertsplit", 12128#endif 12129#ifdef FEAT_VIRTUALEDIT 12130 "virtualedit", 12131#endif 12132#ifdef FEAT_VISUAL 12133 "visual", 12134#endif 12135#ifdef FEAT_VISUALEXTRA 12136 "visualextra", 12137#endif 12138#ifdef FEAT_VREPLACE 12139 "vreplace", 12140#endif 12141#ifdef FEAT_WILDIGN 12142 "wildignore", 12143#endif 12144#ifdef FEAT_WILDMENU 12145 "wildmenu", 12146#endif 12147#ifdef FEAT_WINDOWS 12148 "windows", 12149#endif 12150#ifdef FEAT_WAK 12151 "winaltkeys", 12152#endif 12153#ifdef FEAT_WRITEBACKUP 12154 "writebackup", 12155#endif 12156#ifdef FEAT_XIM 12157 "xim", 12158#endif 12159#ifdef FEAT_XFONTSET 12160 "xfontset", 12161#endif 12162#ifdef USE_XSMP 12163 "xsmp", 12164#endif 12165#ifdef USE_XSMP_INTERACT 12166 "xsmp_interact", 12167#endif 12168#ifdef FEAT_XCLIPBOARD 12169 "xterm_clipboard", 12170#endif 12171#ifdef FEAT_XTERM_SAVE 12172 "xterm_save", 12173#endif 12174#if defined(UNIX) && defined(FEAT_X11) 12175 "X11", 12176#endif 12177 NULL 12178 }; 12179 12180 name = get_tv_string(&argvars[0]); 12181 for (i = 0; has_list[i] != NULL; ++i) 12182 if (STRICMP(name, has_list[i]) == 0) 12183 { 12184 n = TRUE; 12185 break; 12186 } 12187 12188 if (n == FALSE) 12189 { 12190 if (STRNICMP(name, "patch", 5) == 0) 12191 n = has_patch(atoi((char *)name + 5)); 12192 else if (STRICMP(name, "vim_starting") == 0) 12193 n = (starting != 0); 12194#ifdef FEAT_MBYTE 12195 else if (STRICMP(name, "multi_byte_encoding") == 0) 12196 n = has_mbyte; 12197#endif 12198#if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 12199 else if (STRICMP(name, "balloon_multiline") == 0) 12200 n = multiline_balloon_available(); 12201#endif 12202#ifdef DYNAMIC_TCL 12203 else if (STRICMP(name, "tcl") == 0) 12204 n = tcl_enabled(FALSE); 12205#endif 12206#if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 12207 else if (STRICMP(name, "iconv") == 0) 12208 n = iconv_enabled(FALSE); 12209#endif 12210#ifdef DYNAMIC_LUA 12211 else if (STRICMP(name, "lua") == 0) 12212 n = lua_enabled(FALSE); 12213#endif 12214#ifdef DYNAMIC_MZSCHEME 12215 else if (STRICMP(name, "mzscheme") == 0) 12216 n = mzscheme_enabled(FALSE); 12217#endif 12218#ifdef DYNAMIC_RUBY 12219 else if (STRICMP(name, "ruby") == 0) 12220 n = ruby_enabled(FALSE); 12221#endif 12222#ifdef FEAT_PYTHON 12223#ifdef DYNAMIC_PYTHON 12224 else if (STRICMP(name, "python") == 0) 12225 n = python_enabled(FALSE); 12226#endif 12227#endif 12228#ifdef FEAT_PYTHON3 12229#ifdef DYNAMIC_PYTHON3 12230 else if (STRICMP(name, "python3") == 0) 12231 n = python3_enabled(FALSE); 12232#endif 12233#endif 12234#ifdef DYNAMIC_PERL 12235 else if (STRICMP(name, "perl") == 0) 12236 n = perl_enabled(FALSE); 12237#endif 12238#ifdef FEAT_GUI 12239 else if (STRICMP(name, "gui_running") == 0) 12240 n = (gui.in_use || gui.starting); 12241# ifdef FEAT_GUI_W32 12242 else if (STRICMP(name, "gui_win32s") == 0) 12243 n = gui_is_win32s(); 12244# endif 12245# ifdef FEAT_BROWSE 12246 else if (STRICMP(name, "browse") == 0) 12247 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 12248# endif 12249#endif 12250#ifdef FEAT_SYN_HL 12251 else if (STRICMP(name, "syntax_items") == 0) 12252 n = syntax_present(curwin); 12253#endif 12254#if defined(WIN3264) 12255 else if (STRICMP(name, "win95") == 0) 12256 n = mch_windows95(); 12257#endif 12258#ifdef FEAT_NETBEANS_INTG 12259 else if (STRICMP(name, "netbeans_enabled") == 0) 12260 n = netbeans_active(); 12261#endif 12262 } 12263 12264 rettv->vval.v_number = n; 12265} 12266 12267/* 12268 * "has_key()" function 12269 */ 12270 static void 12271f_has_key(argvars, rettv) 12272 typval_T *argvars; 12273 typval_T *rettv; 12274{ 12275 if (argvars[0].v_type != VAR_DICT) 12276 { 12277 EMSG(_(e_dictreq)); 12278 return; 12279 } 12280 if (argvars[0].vval.v_dict == NULL) 12281 return; 12282 12283 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 12284 get_tv_string(&argvars[1]), -1) != NULL; 12285} 12286 12287/* 12288 * "haslocaldir()" function 12289 */ 12290 static void 12291f_haslocaldir(argvars, rettv) 12292 typval_T *argvars UNUSED; 12293 typval_T *rettv; 12294{ 12295 rettv->vval.v_number = (curwin->w_localdir != NULL); 12296} 12297 12298/* 12299 * "hasmapto()" function 12300 */ 12301 static void 12302f_hasmapto(argvars, rettv) 12303 typval_T *argvars; 12304 typval_T *rettv; 12305{ 12306 char_u *name; 12307 char_u *mode; 12308 char_u buf[NUMBUFLEN]; 12309 int abbr = FALSE; 12310 12311 name = get_tv_string(&argvars[0]); 12312 if (argvars[1].v_type == VAR_UNKNOWN) 12313 mode = (char_u *)"nvo"; 12314 else 12315 { 12316 mode = get_tv_string_buf(&argvars[1], buf); 12317 if (argvars[2].v_type != VAR_UNKNOWN) 12318 abbr = get_tv_number(&argvars[2]); 12319 } 12320 12321 if (map_to_exists(name, mode, abbr)) 12322 rettv->vval.v_number = TRUE; 12323 else 12324 rettv->vval.v_number = FALSE; 12325} 12326 12327/* 12328 * "histadd()" function 12329 */ 12330 static void 12331f_histadd(argvars, rettv) 12332 typval_T *argvars UNUSED; 12333 typval_T *rettv; 12334{ 12335#ifdef FEAT_CMDHIST 12336 int histype; 12337 char_u *str; 12338 char_u buf[NUMBUFLEN]; 12339#endif 12340 12341 rettv->vval.v_number = FALSE; 12342 if (check_restricted() || check_secure()) 12343 return; 12344#ifdef FEAT_CMDHIST 12345 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12346 histype = str != NULL ? get_histtype(str) : -1; 12347 if (histype >= 0) 12348 { 12349 str = get_tv_string_buf(&argvars[1], buf); 12350 if (*str != NUL) 12351 { 12352 init_history(); 12353 add_to_history(histype, str, FALSE, NUL); 12354 rettv->vval.v_number = TRUE; 12355 return; 12356 } 12357 } 12358#endif 12359} 12360 12361/* 12362 * "histdel()" function 12363 */ 12364 static void 12365f_histdel(argvars, rettv) 12366 typval_T *argvars UNUSED; 12367 typval_T *rettv UNUSED; 12368{ 12369#ifdef FEAT_CMDHIST 12370 int n; 12371 char_u buf[NUMBUFLEN]; 12372 char_u *str; 12373 12374 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12375 if (str == NULL) 12376 n = 0; 12377 else if (argvars[1].v_type == VAR_UNKNOWN) 12378 /* only one argument: clear entire history */ 12379 n = clr_history(get_histtype(str)); 12380 else if (argvars[1].v_type == VAR_NUMBER) 12381 /* index given: remove that entry */ 12382 n = del_history_idx(get_histtype(str), 12383 (int)get_tv_number(&argvars[1])); 12384 else 12385 /* string given: remove all matching entries */ 12386 n = del_history_entry(get_histtype(str), 12387 get_tv_string_buf(&argvars[1], buf)); 12388 rettv->vval.v_number = n; 12389#endif 12390} 12391 12392/* 12393 * "histget()" function 12394 */ 12395 static void 12396f_histget(argvars, rettv) 12397 typval_T *argvars UNUSED; 12398 typval_T *rettv; 12399{ 12400#ifdef FEAT_CMDHIST 12401 int type; 12402 int idx; 12403 char_u *str; 12404 12405 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 12406 if (str == NULL) 12407 rettv->vval.v_string = NULL; 12408 else 12409 { 12410 type = get_histtype(str); 12411 if (argvars[1].v_type == VAR_UNKNOWN) 12412 idx = get_history_idx(type); 12413 else 12414 idx = (int)get_tv_number_chk(&argvars[1], NULL); 12415 /* -1 on type error */ 12416 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 12417 } 12418#else 12419 rettv->vval.v_string = NULL; 12420#endif 12421 rettv->v_type = VAR_STRING; 12422} 12423 12424/* 12425 * "histnr()" function 12426 */ 12427 static void 12428f_histnr(argvars, rettv) 12429 typval_T *argvars UNUSED; 12430 typval_T *rettv; 12431{ 12432 int i; 12433 12434#ifdef FEAT_CMDHIST 12435 char_u *history = get_tv_string_chk(&argvars[0]); 12436 12437 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 12438 if (i >= HIST_CMD && i < HIST_COUNT) 12439 i = get_history_idx(i); 12440 else 12441#endif 12442 i = -1; 12443 rettv->vval.v_number = i; 12444} 12445 12446/* 12447 * "highlightID(name)" function 12448 */ 12449 static void 12450f_hlID(argvars, rettv) 12451 typval_T *argvars; 12452 typval_T *rettv; 12453{ 12454 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 12455} 12456 12457/* 12458 * "highlight_exists()" function 12459 */ 12460 static void 12461f_hlexists(argvars, rettv) 12462 typval_T *argvars; 12463 typval_T *rettv; 12464{ 12465 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 12466} 12467 12468/* 12469 * "hostname()" function 12470 */ 12471 static void 12472f_hostname(argvars, rettv) 12473 typval_T *argvars UNUSED; 12474 typval_T *rettv; 12475{ 12476 char_u hostname[256]; 12477 12478 mch_get_host_name(hostname, 256); 12479 rettv->v_type = VAR_STRING; 12480 rettv->vval.v_string = vim_strsave(hostname); 12481} 12482 12483/* 12484 * iconv() function 12485 */ 12486 static void 12487f_iconv(argvars, rettv) 12488 typval_T *argvars UNUSED; 12489 typval_T *rettv; 12490{ 12491#ifdef FEAT_MBYTE 12492 char_u buf1[NUMBUFLEN]; 12493 char_u buf2[NUMBUFLEN]; 12494 char_u *from, *to, *str; 12495 vimconv_T vimconv; 12496#endif 12497 12498 rettv->v_type = VAR_STRING; 12499 rettv->vval.v_string = NULL; 12500 12501#ifdef FEAT_MBYTE 12502 str = get_tv_string(&argvars[0]); 12503 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 12504 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 12505 vimconv.vc_type = CONV_NONE; 12506 convert_setup(&vimconv, from, to); 12507 12508 /* If the encodings are equal, no conversion needed. */ 12509 if (vimconv.vc_type == CONV_NONE) 12510 rettv->vval.v_string = vim_strsave(str); 12511 else 12512 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 12513 12514 convert_setup(&vimconv, NULL, NULL); 12515 vim_free(from); 12516 vim_free(to); 12517#endif 12518} 12519 12520/* 12521 * "indent()" function 12522 */ 12523 static void 12524f_indent(argvars, rettv) 12525 typval_T *argvars; 12526 typval_T *rettv; 12527{ 12528 linenr_T lnum; 12529 12530 lnum = get_tv_lnum(argvars); 12531 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12532 rettv->vval.v_number = get_indent_lnum(lnum); 12533 else 12534 rettv->vval.v_number = -1; 12535} 12536 12537/* 12538 * "index()" function 12539 */ 12540 static void 12541f_index(argvars, rettv) 12542 typval_T *argvars; 12543 typval_T *rettv; 12544{ 12545 list_T *l; 12546 listitem_T *item; 12547 long idx = 0; 12548 int ic = FALSE; 12549 12550 rettv->vval.v_number = -1; 12551 if (argvars[0].v_type != VAR_LIST) 12552 { 12553 EMSG(_(e_listreq)); 12554 return; 12555 } 12556 l = argvars[0].vval.v_list; 12557 if (l != NULL) 12558 { 12559 item = l->lv_first; 12560 if (argvars[2].v_type != VAR_UNKNOWN) 12561 { 12562 int error = FALSE; 12563 12564 /* Start at specified item. Use the cached index that list_find() 12565 * sets, so that a negative number also works. */ 12566 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 12567 idx = l->lv_idx; 12568 if (argvars[3].v_type != VAR_UNKNOWN) 12569 ic = get_tv_number_chk(&argvars[3], &error); 12570 if (error) 12571 item = NULL; 12572 } 12573 12574 for ( ; item != NULL; item = item->li_next, ++idx) 12575 if (tv_equal(&item->li_tv, &argvars[1], ic)) 12576 { 12577 rettv->vval.v_number = idx; 12578 break; 12579 } 12580 } 12581} 12582 12583static int inputsecret_flag = 0; 12584 12585static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 12586 12587/* 12588 * This function is used by f_input() and f_inputdialog() functions. The third 12589 * argument to f_input() specifies the type of completion to use at the 12590 * prompt. The third argument to f_inputdialog() specifies the value to return 12591 * when the user cancels the prompt. 12592 */ 12593 static void 12594get_user_input(argvars, rettv, inputdialog) 12595 typval_T *argvars; 12596 typval_T *rettv; 12597 int inputdialog; 12598{ 12599 char_u *prompt = get_tv_string_chk(&argvars[0]); 12600 char_u *p = NULL; 12601 int c; 12602 char_u buf[NUMBUFLEN]; 12603 int cmd_silent_save = cmd_silent; 12604 char_u *defstr = (char_u *)""; 12605 int xp_type = EXPAND_NOTHING; 12606 char_u *xp_arg = NULL; 12607 12608 rettv->v_type = VAR_STRING; 12609 rettv->vval.v_string = NULL; 12610 12611#ifdef NO_CONSOLE_INPUT 12612 /* While starting up, there is no place to enter text. */ 12613 if (no_console_input()) 12614 return; 12615#endif 12616 12617 cmd_silent = FALSE; /* Want to see the prompt. */ 12618 if (prompt != NULL) 12619 { 12620 /* Only the part of the message after the last NL is considered as 12621 * prompt for the command line */ 12622 p = vim_strrchr(prompt, '\n'); 12623 if (p == NULL) 12624 p = prompt; 12625 else 12626 { 12627 ++p; 12628 c = *p; 12629 *p = NUL; 12630 msg_start(); 12631 msg_clr_eos(); 12632 msg_puts_attr(prompt, echo_attr); 12633 msg_didout = FALSE; 12634 msg_starthere(); 12635 *p = c; 12636 } 12637 cmdline_row = msg_row; 12638 12639 if (argvars[1].v_type != VAR_UNKNOWN) 12640 { 12641 defstr = get_tv_string_buf_chk(&argvars[1], buf); 12642 if (defstr != NULL) 12643 stuffReadbuffSpec(defstr); 12644 12645 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 12646 { 12647 char_u *xp_name; 12648 int xp_namelen; 12649 long argt; 12650 12651 rettv->vval.v_string = NULL; 12652 12653 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 12654 if (xp_name == NULL) 12655 return; 12656 12657 xp_namelen = (int)STRLEN(xp_name); 12658 12659 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 12660 &xp_arg) == FAIL) 12661 return; 12662 } 12663 } 12664 12665 if (defstr != NULL) 12666 rettv->vval.v_string = 12667 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 12668 xp_type, xp_arg); 12669 12670 vim_free(xp_arg); 12671 12672 /* since the user typed this, no need to wait for return */ 12673 need_wait_return = FALSE; 12674 msg_didout = FALSE; 12675 } 12676 cmd_silent = cmd_silent_save; 12677} 12678 12679/* 12680 * "input()" function 12681 * Also handles inputsecret() when inputsecret is set. 12682 */ 12683 static void 12684f_input(argvars, rettv) 12685 typval_T *argvars; 12686 typval_T *rettv; 12687{ 12688 get_user_input(argvars, rettv, FALSE); 12689} 12690 12691/* 12692 * "inputdialog()" function 12693 */ 12694 static void 12695f_inputdialog(argvars, rettv) 12696 typval_T *argvars; 12697 typval_T *rettv; 12698{ 12699#if defined(FEAT_GUI_TEXTDIALOG) 12700 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 12701 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 12702 { 12703 char_u *message; 12704 char_u buf[NUMBUFLEN]; 12705 char_u *defstr = (char_u *)""; 12706 12707 message = get_tv_string_chk(&argvars[0]); 12708 if (argvars[1].v_type != VAR_UNKNOWN 12709 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 12710 vim_strncpy(IObuff, defstr, IOSIZE - 1); 12711 else 12712 IObuff[0] = NUL; 12713 if (message != NULL && defstr != NULL 12714 && do_dialog(VIM_QUESTION, NULL, message, 12715 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 12716 rettv->vval.v_string = vim_strsave(IObuff); 12717 else 12718 { 12719 if (message != NULL && defstr != NULL 12720 && argvars[1].v_type != VAR_UNKNOWN 12721 && argvars[2].v_type != VAR_UNKNOWN) 12722 rettv->vval.v_string = vim_strsave( 12723 get_tv_string_buf(&argvars[2], buf)); 12724 else 12725 rettv->vval.v_string = NULL; 12726 } 12727 rettv->v_type = VAR_STRING; 12728 } 12729 else 12730#endif 12731 get_user_input(argvars, rettv, TRUE); 12732} 12733 12734/* 12735 * "inputlist()" function 12736 */ 12737 static void 12738f_inputlist(argvars, rettv) 12739 typval_T *argvars; 12740 typval_T *rettv; 12741{ 12742 listitem_T *li; 12743 int selected; 12744 int mouse_used; 12745 12746#ifdef NO_CONSOLE_INPUT 12747 /* While starting up, there is no place to enter text. */ 12748 if (no_console_input()) 12749 return; 12750#endif 12751 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 12752 { 12753 EMSG2(_(e_listarg), "inputlist()"); 12754 return; 12755 } 12756 12757 msg_start(); 12758 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 12759 lines_left = Rows; /* avoid more prompt */ 12760 msg_scroll = TRUE; 12761 msg_clr_eos(); 12762 12763 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 12764 { 12765 msg_puts(get_tv_string(&li->li_tv)); 12766 msg_putchar('\n'); 12767 } 12768 12769 /* Ask for choice. */ 12770 selected = prompt_for_number(&mouse_used); 12771 if (mouse_used) 12772 selected -= lines_left; 12773 12774 rettv->vval.v_number = selected; 12775} 12776 12777 12778static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 12779 12780/* 12781 * "inputrestore()" function 12782 */ 12783 static void 12784f_inputrestore(argvars, rettv) 12785 typval_T *argvars UNUSED; 12786 typval_T *rettv; 12787{ 12788 if (ga_userinput.ga_len > 0) 12789 { 12790 --ga_userinput.ga_len; 12791 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 12792 + ga_userinput.ga_len); 12793 /* default return is zero == OK */ 12794 } 12795 else if (p_verbose > 1) 12796 { 12797 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 12798 rettv->vval.v_number = 1; /* Failed */ 12799 } 12800} 12801 12802/* 12803 * "inputsave()" function 12804 */ 12805 static void 12806f_inputsave(argvars, rettv) 12807 typval_T *argvars UNUSED; 12808 typval_T *rettv; 12809{ 12810 /* Add an entry to the stack of typeahead storage. */ 12811 if (ga_grow(&ga_userinput, 1) == OK) 12812 { 12813 save_typeahead((tasave_T *)(ga_userinput.ga_data) 12814 + ga_userinput.ga_len); 12815 ++ga_userinput.ga_len; 12816 /* default return is zero == OK */ 12817 } 12818 else 12819 rettv->vval.v_number = 1; /* Failed */ 12820} 12821 12822/* 12823 * "inputsecret()" function 12824 */ 12825 static void 12826f_inputsecret(argvars, rettv) 12827 typval_T *argvars; 12828 typval_T *rettv; 12829{ 12830 ++cmdline_star; 12831 ++inputsecret_flag; 12832 f_input(argvars, rettv); 12833 --cmdline_star; 12834 --inputsecret_flag; 12835} 12836 12837/* 12838 * "insert()" function 12839 */ 12840 static void 12841f_insert(argvars, rettv) 12842 typval_T *argvars; 12843 typval_T *rettv; 12844{ 12845 long before = 0; 12846 listitem_T *item; 12847 list_T *l; 12848 int error = FALSE; 12849 12850 if (argvars[0].v_type != VAR_LIST) 12851 EMSG2(_(e_listarg), "insert()"); 12852 else if ((l = argvars[0].vval.v_list) != NULL 12853 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 12854 { 12855 if (argvars[2].v_type != VAR_UNKNOWN) 12856 before = get_tv_number_chk(&argvars[2], &error); 12857 if (error) 12858 return; /* type error; errmsg already given */ 12859 12860 if (before == l->lv_len) 12861 item = NULL; 12862 else 12863 { 12864 item = list_find(l, before); 12865 if (item == NULL) 12866 { 12867 EMSGN(_(e_listidx), before); 12868 l = NULL; 12869 } 12870 } 12871 if (l != NULL) 12872 { 12873 list_insert_tv(l, &argvars[1], item); 12874 copy_tv(&argvars[0], rettv); 12875 } 12876 } 12877} 12878 12879/* 12880 * "isdirectory()" function 12881 */ 12882 static void 12883f_isdirectory(argvars, rettv) 12884 typval_T *argvars; 12885 typval_T *rettv; 12886{ 12887 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 12888} 12889 12890/* 12891 * "islocked()" function 12892 */ 12893 static void 12894f_islocked(argvars, rettv) 12895 typval_T *argvars; 12896 typval_T *rettv; 12897{ 12898 lval_T lv; 12899 char_u *end; 12900 dictitem_T *di; 12901 12902 rettv->vval.v_number = -1; 12903 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 12904 FNE_CHECK_START); 12905 if (end != NULL && lv.ll_name != NULL) 12906 { 12907 if (*end != NUL) 12908 EMSG(_(e_trailing)); 12909 else 12910 { 12911 if (lv.ll_tv == NULL) 12912 { 12913 if (check_changedtick(lv.ll_name)) 12914 rettv->vval.v_number = 1; /* always locked */ 12915 else 12916 { 12917 di = find_var(lv.ll_name, NULL); 12918 if (di != NULL) 12919 { 12920 /* Consider a variable locked when: 12921 * 1. the variable itself is locked 12922 * 2. the value of the variable is locked. 12923 * 3. the List or Dict value is locked. 12924 */ 12925 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 12926 || tv_islocked(&di->di_tv)); 12927 } 12928 } 12929 } 12930 else if (lv.ll_range) 12931 EMSG(_("E786: Range not allowed")); 12932 else if (lv.ll_newkey != NULL) 12933 EMSG2(_(e_dictkey), lv.ll_newkey); 12934 else if (lv.ll_list != NULL) 12935 /* List item. */ 12936 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 12937 else 12938 /* Dictionary item. */ 12939 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 12940 } 12941 } 12942 12943 clear_lval(&lv); 12944} 12945 12946static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 12947 12948/* 12949 * Turn a dict into a list: 12950 * "what" == 0: list of keys 12951 * "what" == 1: list of values 12952 * "what" == 2: list of items 12953 */ 12954 static void 12955dict_list(argvars, rettv, what) 12956 typval_T *argvars; 12957 typval_T *rettv; 12958 int what; 12959{ 12960 list_T *l2; 12961 dictitem_T *di; 12962 hashitem_T *hi; 12963 listitem_T *li; 12964 listitem_T *li2; 12965 dict_T *d; 12966 int todo; 12967 12968 if (argvars[0].v_type != VAR_DICT) 12969 { 12970 EMSG(_(e_dictreq)); 12971 return; 12972 } 12973 if ((d = argvars[0].vval.v_dict) == NULL) 12974 return; 12975 12976 if (rettv_list_alloc(rettv) == FAIL) 12977 return; 12978 12979 todo = (int)d->dv_hashtab.ht_used; 12980 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12981 { 12982 if (!HASHITEM_EMPTY(hi)) 12983 { 12984 --todo; 12985 di = HI2DI(hi); 12986 12987 li = listitem_alloc(); 12988 if (li == NULL) 12989 break; 12990 list_append(rettv->vval.v_list, li); 12991 12992 if (what == 0) 12993 { 12994 /* keys() */ 12995 li->li_tv.v_type = VAR_STRING; 12996 li->li_tv.v_lock = 0; 12997 li->li_tv.vval.v_string = vim_strsave(di->di_key); 12998 } 12999 else if (what == 1) 13000 { 13001 /* values() */ 13002 copy_tv(&di->di_tv, &li->li_tv); 13003 } 13004 else 13005 { 13006 /* items() */ 13007 l2 = list_alloc(); 13008 li->li_tv.v_type = VAR_LIST; 13009 li->li_tv.v_lock = 0; 13010 li->li_tv.vval.v_list = l2; 13011 if (l2 == NULL) 13012 break; 13013 ++l2->lv_refcount; 13014 13015 li2 = listitem_alloc(); 13016 if (li2 == NULL) 13017 break; 13018 list_append(l2, li2); 13019 li2->li_tv.v_type = VAR_STRING; 13020 li2->li_tv.v_lock = 0; 13021 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 13022 13023 li2 = listitem_alloc(); 13024 if (li2 == NULL) 13025 break; 13026 list_append(l2, li2); 13027 copy_tv(&di->di_tv, &li2->li_tv); 13028 } 13029 } 13030 } 13031} 13032 13033/* 13034 * "items(dict)" function 13035 */ 13036 static void 13037f_items(argvars, rettv) 13038 typval_T *argvars; 13039 typval_T *rettv; 13040{ 13041 dict_list(argvars, rettv, 2); 13042} 13043 13044/* 13045 * "join()" function 13046 */ 13047 static void 13048f_join(argvars, rettv) 13049 typval_T *argvars; 13050 typval_T *rettv; 13051{ 13052 garray_T ga; 13053 char_u *sep; 13054 13055 if (argvars[0].v_type != VAR_LIST) 13056 { 13057 EMSG(_(e_listreq)); 13058 return; 13059 } 13060 if (argvars[0].vval.v_list == NULL) 13061 return; 13062 if (argvars[1].v_type == VAR_UNKNOWN) 13063 sep = (char_u *)" "; 13064 else 13065 sep = get_tv_string_chk(&argvars[1]); 13066 13067 rettv->v_type = VAR_STRING; 13068 13069 if (sep != NULL) 13070 { 13071 ga_init2(&ga, (int)sizeof(char), 80); 13072 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 13073 ga_append(&ga, NUL); 13074 rettv->vval.v_string = (char_u *)ga.ga_data; 13075 } 13076 else 13077 rettv->vval.v_string = NULL; 13078} 13079 13080/* 13081 * "keys()" function 13082 */ 13083 static void 13084f_keys(argvars, rettv) 13085 typval_T *argvars; 13086 typval_T *rettv; 13087{ 13088 dict_list(argvars, rettv, 0); 13089} 13090 13091/* 13092 * "last_buffer_nr()" function. 13093 */ 13094 static void 13095f_last_buffer_nr(argvars, rettv) 13096 typval_T *argvars UNUSED; 13097 typval_T *rettv; 13098{ 13099 int n = 0; 13100 buf_T *buf; 13101 13102 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 13103 if (n < buf->b_fnum) 13104 n = buf->b_fnum; 13105 13106 rettv->vval.v_number = n; 13107} 13108 13109/* 13110 * "len()" function 13111 */ 13112 static void 13113f_len(argvars, rettv) 13114 typval_T *argvars; 13115 typval_T *rettv; 13116{ 13117 switch (argvars[0].v_type) 13118 { 13119 case VAR_STRING: 13120 case VAR_NUMBER: 13121 rettv->vval.v_number = (varnumber_T)STRLEN( 13122 get_tv_string(&argvars[0])); 13123 break; 13124 case VAR_LIST: 13125 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 13126 break; 13127 case VAR_DICT: 13128 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 13129 break; 13130 default: 13131 EMSG(_("E701: Invalid type for len()")); 13132 break; 13133 } 13134} 13135 13136static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 13137 13138 static void 13139libcall_common(argvars, rettv, type) 13140 typval_T *argvars; 13141 typval_T *rettv; 13142 int type; 13143{ 13144#ifdef FEAT_LIBCALL 13145 char_u *string_in; 13146 char_u **string_result; 13147 int nr_result; 13148#endif 13149 13150 rettv->v_type = type; 13151 if (type != VAR_NUMBER) 13152 rettv->vval.v_string = NULL; 13153 13154 if (check_restricted() || check_secure()) 13155 return; 13156 13157#ifdef FEAT_LIBCALL 13158 /* The first two args must be strings, otherwise its meaningless */ 13159 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 13160 { 13161 string_in = NULL; 13162 if (argvars[2].v_type == VAR_STRING) 13163 string_in = argvars[2].vval.v_string; 13164 if (type == VAR_NUMBER) 13165 string_result = NULL; 13166 else 13167 string_result = &rettv->vval.v_string; 13168 if (mch_libcall(argvars[0].vval.v_string, 13169 argvars[1].vval.v_string, 13170 string_in, 13171 argvars[2].vval.v_number, 13172 string_result, 13173 &nr_result) == OK 13174 && type == VAR_NUMBER) 13175 rettv->vval.v_number = nr_result; 13176 } 13177#endif 13178} 13179 13180/* 13181 * "libcall()" function 13182 */ 13183 static void 13184f_libcall(argvars, rettv) 13185 typval_T *argvars; 13186 typval_T *rettv; 13187{ 13188 libcall_common(argvars, rettv, VAR_STRING); 13189} 13190 13191/* 13192 * "libcallnr()" function 13193 */ 13194 static void 13195f_libcallnr(argvars, rettv) 13196 typval_T *argvars; 13197 typval_T *rettv; 13198{ 13199 libcall_common(argvars, rettv, VAR_NUMBER); 13200} 13201 13202/* 13203 * "line(string)" function 13204 */ 13205 static void 13206f_line(argvars, rettv) 13207 typval_T *argvars; 13208 typval_T *rettv; 13209{ 13210 linenr_T lnum = 0; 13211 pos_T *fp; 13212 int fnum; 13213 13214 fp = var2fpos(&argvars[0], TRUE, &fnum); 13215 if (fp != NULL) 13216 lnum = fp->lnum; 13217 rettv->vval.v_number = lnum; 13218} 13219 13220/* 13221 * "line2byte(lnum)" function 13222 */ 13223 static void 13224f_line2byte(argvars, rettv) 13225 typval_T *argvars UNUSED; 13226 typval_T *rettv; 13227{ 13228#ifndef FEAT_BYTEOFF 13229 rettv->vval.v_number = -1; 13230#else 13231 linenr_T lnum; 13232 13233 lnum = get_tv_lnum(argvars); 13234 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13235 rettv->vval.v_number = -1; 13236 else 13237 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 13238 if (rettv->vval.v_number >= 0) 13239 ++rettv->vval.v_number; 13240#endif 13241} 13242 13243/* 13244 * "lispindent(lnum)" function 13245 */ 13246 static void 13247f_lispindent(argvars, rettv) 13248 typval_T *argvars; 13249 typval_T *rettv; 13250{ 13251#ifdef FEAT_LISP 13252 pos_T pos; 13253 linenr_T lnum; 13254 13255 pos = curwin->w_cursor; 13256 lnum = get_tv_lnum(argvars); 13257 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 13258 { 13259 curwin->w_cursor.lnum = lnum; 13260 rettv->vval.v_number = get_lisp_indent(); 13261 curwin->w_cursor = pos; 13262 } 13263 else 13264#endif 13265 rettv->vval.v_number = -1; 13266} 13267 13268/* 13269 * "localtime()" function 13270 */ 13271 static void 13272f_localtime(argvars, rettv) 13273 typval_T *argvars UNUSED; 13274 typval_T *rettv; 13275{ 13276 rettv->vval.v_number = (varnumber_T)time(NULL); 13277} 13278 13279static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 13280 13281 static void 13282get_maparg(argvars, rettv, exact) 13283 typval_T *argvars; 13284 typval_T *rettv; 13285 int exact; 13286{ 13287 char_u *keys; 13288 char_u *which; 13289 char_u buf[NUMBUFLEN]; 13290 char_u *keys_buf = NULL; 13291 char_u *rhs; 13292 int mode; 13293 garray_T ga; 13294 int abbr = FALSE; 13295 13296 /* return empty string for failure */ 13297 rettv->v_type = VAR_STRING; 13298 rettv->vval.v_string = NULL; 13299 13300 keys = get_tv_string(&argvars[0]); 13301 if (*keys == NUL) 13302 return; 13303 13304 if (argvars[1].v_type != VAR_UNKNOWN) 13305 { 13306 which = get_tv_string_buf_chk(&argvars[1], buf); 13307 if (argvars[2].v_type != VAR_UNKNOWN) 13308 abbr = get_tv_number(&argvars[2]); 13309 } 13310 else 13311 which = (char_u *)""; 13312 if (which == NULL) 13313 return; 13314 13315 mode = get_map_mode(&which, 0); 13316 13317 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 13318 rhs = check_map(keys, mode, exact, FALSE, abbr); 13319 vim_free(keys_buf); 13320 if (rhs != NULL) 13321 { 13322 ga_init(&ga); 13323 ga.ga_itemsize = 1; 13324 ga.ga_growsize = 40; 13325 13326 while (*rhs != NUL) 13327 ga_concat(&ga, str2special(&rhs, FALSE)); 13328 13329 ga_append(&ga, NUL); 13330 rettv->vval.v_string = (char_u *)ga.ga_data; 13331 } 13332} 13333 13334#ifdef FEAT_FLOAT 13335/* 13336 * "log()" function 13337 */ 13338 static void 13339f_log(argvars, rettv) 13340 typval_T *argvars; 13341 typval_T *rettv; 13342{ 13343 float_T f; 13344 13345 rettv->v_type = VAR_FLOAT; 13346 if (get_float_arg(argvars, &f) == OK) 13347 rettv->vval.v_float = log(f); 13348 else 13349 rettv->vval.v_float = 0.0; 13350} 13351 13352/* 13353 * "log10()" function 13354 */ 13355 static void 13356f_log10(argvars, rettv) 13357 typval_T *argvars; 13358 typval_T *rettv; 13359{ 13360 float_T f; 13361 13362 rettv->v_type = VAR_FLOAT; 13363 if (get_float_arg(argvars, &f) == OK) 13364 rettv->vval.v_float = log10(f); 13365 else 13366 rettv->vval.v_float = 0.0; 13367} 13368#endif 13369 13370/* 13371 * "map()" function 13372 */ 13373 static void 13374f_map(argvars, rettv) 13375 typval_T *argvars; 13376 typval_T *rettv; 13377{ 13378 filter_map(argvars, rettv, TRUE); 13379} 13380 13381/* 13382 * "maparg()" function 13383 */ 13384 static void 13385f_maparg(argvars, rettv) 13386 typval_T *argvars; 13387 typval_T *rettv; 13388{ 13389 get_maparg(argvars, rettv, TRUE); 13390} 13391 13392/* 13393 * "mapcheck()" function 13394 */ 13395 static void 13396f_mapcheck(argvars, rettv) 13397 typval_T *argvars; 13398 typval_T *rettv; 13399{ 13400 get_maparg(argvars, rettv, FALSE); 13401} 13402 13403static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 13404 13405 static void 13406find_some_match(argvars, rettv, type) 13407 typval_T *argvars; 13408 typval_T *rettv; 13409 int type; 13410{ 13411 char_u *str = NULL; 13412 char_u *expr = NULL; 13413 char_u *pat; 13414 regmatch_T regmatch; 13415 char_u patbuf[NUMBUFLEN]; 13416 char_u strbuf[NUMBUFLEN]; 13417 char_u *save_cpo; 13418 long start = 0; 13419 long nth = 1; 13420 colnr_T startcol = 0; 13421 int match = 0; 13422 list_T *l = NULL; 13423 listitem_T *li = NULL; 13424 long idx = 0; 13425 char_u *tofree = NULL; 13426 13427 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13428 save_cpo = p_cpo; 13429 p_cpo = (char_u *)""; 13430 13431 rettv->vval.v_number = -1; 13432 if (type == 3) 13433 { 13434 /* return empty list when there are no matches */ 13435 if (rettv_list_alloc(rettv) == FAIL) 13436 goto theend; 13437 } 13438 else if (type == 2) 13439 { 13440 rettv->v_type = VAR_STRING; 13441 rettv->vval.v_string = NULL; 13442 } 13443 13444 if (argvars[0].v_type == VAR_LIST) 13445 { 13446 if ((l = argvars[0].vval.v_list) == NULL) 13447 goto theend; 13448 li = l->lv_first; 13449 } 13450 else 13451 expr = str = get_tv_string(&argvars[0]); 13452 13453 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13454 if (pat == NULL) 13455 goto theend; 13456 13457 if (argvars[2].v_type != VAR_UNKNOWN) 13458 { 13459 int error = FALSE; 13460 13461 start = get_tv_number_chk(&argvars[2], &error); 13462 if (error) 13463 goto theend; 13464 if (l != NULL) 13465 { 13466 li = list_find(l, start); 13467 if (li == NULL) 13468 goto theend; 13469 idx = l->lv_idx; /* use the cached index */ 13470 } 13471 else 13472 { 13473 if (start < 0) 13474 start = 0; 13475 if (start > (long)STRLEN(str)) 13476 goto theend; 13477 /* When "count" argument is there ignore matches before "start", 13478 * otherwise skip part of the string. Differs when pattern is "^" 13479 * or "\<". */ 13480 if (argvars[3].v_type != VAR_UNKNOWN) 13481 startcol = start; 13482 else 13483 str += start; 13484 } 13485 13486 if (argvars[3].v_type != VAR_UNKNOWN) 13487 nth = get_tv_number_chk(&argvars[3], &error); 13488 if (error) 13489 goto theend; 13490 } 13491 13492 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13493 if (regmatch.regprog != NULL) 13494 { 13495 regmatch.rm_ic = p_ic; 13496 13497 for (;;) 13498 { 13499 if (l != NULL) 13500 { 13501 if (li == NULL) 13502 { 13503 match = FALSE; 13504 break; 13505 } 13506 vim_free(tofree); 13507 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 13508 if (str == NULL) 13509 break; 13510 } 13511 13512 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 13513 13514 if (match && --nth <= 0) 13515 break; 13516 if (l == NULL && !match) 13517 break; 13518 13519 /* Advance to just after the match. */ 13520 if (l != NULL) 13521 { 13522 li = li->li_next; 13523 ++idx; 13524 } 13525 else 13526 { 13527#ifdef FEAT_MBYTE 13528 startcol = (colnr_T)(regmatch.startp[0] 13529 + (*mb_ptr2len)(regmatch.startp[0]) - str); 13530#else 13531 startcol = (colnr_T)(regmatch.startp[0] + 1 - str); 13532#endif 13533 } 13534 } 13535 13536 if (match) 13537 { 13538 if (type == 3) 13539 { 13540 int i; 13541 13542 /* return list with matched string and submatches */ 13543 for (i = 0; i < NSUBEXP; ++i) 13544 { 13545 if (regmatch.endp[i] == NULL) 13546 { 13547 if (list_append_string(rettv->vval.v_list, 13548 (char_u *)"", 0) == FAIL) 13549 break; 13550 } 13551 else if (list_append_string(rettv->vval.v_list, 13552 regmatch.startp[i], 13553 (int)(regmatch.endp[i] - regmatch.startp[i])) 13554 == FAIL) 13555 break; 13556 } 13557 } 13558 else if (type == 2) 13559 { 13560 /* return matched string */ 13561 if (l != NULL) 13562 copy_tv(&li->li_tv, rettv); 13563 else 13564 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 13565 (int)(regmatch.endp[0] - regmatch.startp[0])); 13566 } 13567 else if (l != NULL) 13568 rettv->vval.v_number = idx; 13569 else 13570 { 13571 if (type != 0) 13572 rettv->vval.v_number = 13573 (varnumber_T)(regmatch.startp[0] - str); 13574 else 13575 rettv->vval.v_number = 13576 (varnumber_T)(regmatch.endp[0] - str); 13577 rettv->vval.v_number += (varnumber_T)(str - expr); 13578 } 13579 } 13580 vim_free(regmatch.regprog); 13581 } 13582 13583theend: 13584 vim_free(tofree); 13585 p_cpo = save_cpo; 13586} 13587 13588/* 13589 * "match()" function 13590 */ 13591 static void 13592f_match(argvars, rettv) 13593 typval_T *argvars; 13594 typval_T *rettv; 13595{ 13596 find_some_match(argvars, rettv, 1); 13597} 13598 13599/* 13600 * "matchadd()" function 13601 */ 13602 static void 13603f_matchadd(argvars, rettv) 13604 typval_T *argvars; 13605 typval_T *rettv; 13606{ 13607#ifdef FEAT_SEARCH_EXTRA 13608 char_u buf[NUMBUFLEN]; 13609 char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */ 13610 char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */ 13611 int prio = 10; /* default priority */ 13612 int id = -1; 13613 int error = FALSE; 13614 13615 rettv->vval.v_number = -1; 13616 13617 if (grp == NULL || pat == NULL) 13618 return; 13619 if (argvars[2].v_type != VAR_UNKNOWN) 13620 { 13621 prio = get_tv_number_chk(&argvars[2], &error); 13622 if (argvars[3].v_type != VAR_UNKNOWN) 13623 id = get_tv_number_chk(&argvars[3], &error); 13624 } 13625 if (error == TRUE) 13626 return; 13627 if (id >= 1 && id <= 3) 13628 { 13629 EMSGN("E798: ID is reserved for \":match\": %ld", id); 13630 return; 13631 } 13632 13633 rettv->vval.v_number = match_add(curwin, grp, pat, prio, id); 13634#endif 13635} 13636 13637/* 13638 * "matcharg()" function 13639 */ 13640 static void 13641f_matcharg(argvars, rettv) 13642 typval_T *argvars; 13643 typval_T *rettv; 13644{ 13645 if (rettv_list_alloc(rettv) == OK) 13646 { 13647#ifdef FEAT_SEARCH_EXTRA 13648 int id = get_tv_number(&argvars[0]); 13649 matchitem_T *m; 13650 13651 if (id >= 1 && id <= 3) 13652 { 13653 if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 13654 { 13655 list_append_string(rettv->vval.v_list, 13656 syn_id2name(m->hlg_id), -1); 13657 list_append_string(rettv->vval.v_list, m->pattern, -1); 13658 } 13659 else 13660 { 13661 list_append_string(rettv->vval.v_list, NUL, -1); 13662 list_append_string(rettv->vval.v_list, NUL, -1); 13663 } 13664 } 13665#endif 13666 } 13667} 13668 13669/* 13670 * "matchdelete()" function 13671 */ 13672 static void 13673f_matchdelete(argvars, rettv) 13674 typval_T *argvars; 13675 typval_T *rettv; 13676{ 13677#ifdef FEAT_SEARCH_EXTRA 13678 rettv->vval.v_number = match_delete(curwin, 13679 (int)get_tv_number(&argvars[0]), TRUE); 13680#endif 13681} 13682 13683/* 13684 * "matchend()" function 13685 */ 13686 static void 13687f_matchend(argvars, rettv) 13688 typval_T *argvars; 13689 typval_T *rettv; 13690{ 13691 find_some_match(argvars, rettv, 0); 13692} 13693 13694/* 13695 * "matchlist()" function 13696 */ 13697 static void 13698f_matchlist(argvars, rettv) 13699 typval_T *argvars; 13700 typval_T *rettv; 13701{ 13702 find_some_match(argvars, rettv, 3); 13703} 13704 13705/* 13706 * "matchstr()" function 13707 */ 13708 static void 13709f_matchstr(argvars, rettv) 13710 typval_T *argvars; 13711 typval_T *rettv; 13712{ 13713 find_some_match(argvars, rettv, 2); 13714} 13715 13716static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 13717 13718 static void 13719max_min(argvars, rettv, domax) 13720 typval_T *argvars; 13721 typval_T *rettv; 13722 int domax; 13723{ 13724 long n = 0; 13725 long i; 13726 int error = FALSE; 13727 13728 if (argvars[0].v_type == VAR_LIST) 13729 { 13730 list_T *l; 13731 listitem_T *li; 13732 13733 l = argvars[0].vval.v_list; 13734 if (l != NULL) 13735 { 13736 li = l->lv_first; 13737 if (li != NULL) 13738 { 13739 n = get_tv_number_chk(&li->li_tv, &error); 13740 for (;;) 13741 { 13742 li = li->li_next; 13743 if (li == NULL) 13744 break; 13745 i = get_tv_number_chk(&li->li_tv, &error); 13746 if (domax ? i > n : i < n) 13747 n = i; 13748 } 13749 } 13750 } 13751 } 13752 else if (argvars[0].v_type == VAR_DICT) 13753 { 13754 dict_T *d; 13755 int first = TRUE; 13756 hashitem_T *hi; 13757 int todo; 13758 13759 d = argvars[0].vval.v_dict; 13760 if (d != NULL) 13761 { 13762 todo = (int)d->dv_hashtab.ht_used; 13763 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 13764 { 13765 if (!HASHITEM_EMPTY(hi)) 13766 { 13767 --todo; 13768 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 13769 if (first) 13770 { 13771 n = i; 13772 first = FALSE; 13773 } 13774 else if (domax ? i > n : i < n) 13775 n = i; 13776 } 13777 } 13778 } 13779 } 13780 else 13781 EMSG(_(e_listdictarg)); 13782 rettv->vval.v_number = error ? 0 : n; 13783} 13784 13785/* 13786 * "max()" function 13787 */ 13788 static void 13789f_max(argvars, rettv) 13790 typval_T *argvars; 13791 typval_T *rettv; 13792{ 13793 max_min(argvars, rettv, TRUE); 13794} 13795 13796/* 13797 * "min()" function 13798 */ 13799 static void 13800f_min(argvars, rettv) 13801 typval_T *argvars; 13802 typval_T *rettv; 13803{ 13804 max_min(argvars, rettv, FALSE); 13805} 13806 13807static int mkdir_recurse __ARGS((char_u *dir, int prot)); 13808 13809/* 13810 * Create the directory in which "dir" is located, and higher levels when 13811 * needed. 13812 */ 13813 static int 13814mkdir_recurse(dir, prot) 13815 char_u *dir; 13816 int prot; 13817{ 13818 char_u *p; 13819 char_u *updir; 13820 int r = FAIL; 13821 13822 /* Get end of directory name in "dir". 13823 * We're done when it's "/" or "c:/". */ 13824 p = gettail_sep(dir); 13825 if (p <= get_past_head(dir)) 13826 return OK; 13827 13828 /* If the directory exists we're done. Otherwise: create it.*/ 13829 updir = vim_strnsave(dir, (int)(p - dir)); 13830 if (updir == NULL) 13831 return FAIL; 13832 if (mch_isdir(updir)) 13833 r = OK; 13834 else if (mkdir_recurse(updir, prot) == OK) 13835 r = vim_mkdir_emsg(updir, prot); 13836 vim_free(updir); 13837 return r; 13838} 13839 13840#ifdef vim_mkdir 13841/* 13842 * "mkdir()" function 13843 */ 13844 static void 13845f_mkdir(argvars, rettv) 13846 typval_T *argvars; 13847 typval_T *rettv; 13848{ 13849 char_u *dir; 13850 char_u buf[NUMBUFLEN]; 13851 int prot = 0755; 13852 13853 rettv->vval.v_number = FAIL; 13854 if (check_restricted() || check_secure()) 13855 return; 13856 13857 dir = get_tv_string_buf(&argvars[0], buf); 13858 if (argvars[1].v_type != VAR_UNKNOWN) 13859 { 13860 if (argvars[2].v_type != VAR_UNKNOWN) 13861 prot = get_tv_number_chk(&argvars[2], NULL); 13862 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 13863 mkdir_recurse(dir, prot); 13864 } 13865 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 13866} 13867#endif 13868 13869/* 13870 * "mode()" function 13871 */ 13872 static void 13873f_mode(argvars, rettv) 13874 typval_T *argvars; 13875 typval_T *rettv; 13876{ 13877 char_u buf[3]; 13878 13879 buf[1] = NUL; 13880 buf[2] = NUL; 13881 13882#ifdef FEAT_VISUAL 13883 if (VIsual_active) 13884 { 13885 if (VIsual_select) 13886 buf[0] = VIsual_mode + 's' - 'v'; 13887 else 13888 buf[0] = VIsual_mode; 13889 } 13890 else 13891#endif 13892 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE 13893 || State == CONFIRM) 13894 { 13895 buf[0] = 'r'; 13896 if (State == ASKMORE) 13897 buf[1] = 'm'; 13898 else if (State == CONFIRM) 13899 buf[1] = '?'; 13900 } 13901 else if (State == EXTERNCMD) 13902 buf[0] = '!'; 13903 else if (State & INSERT) 13904 { 13905#ifdef FEAT_VREPLACE 13906 if (State & VREPLACE_FLAG) 13907 { 13908 buf[0] = 'R'; 13909 buf[1] = 'v'; 13910 } 13911 else 13912#endif 13913 if (State & REPLACE_FLAG) 13914 buf[0] = 'R'; 13915 else 13916 buf[0] = 'i'; 13917 } 13918 else if (State & CMDLINE) 13919 { 13920 buf[0] = 'c'; 13921 if (exmode_active) 13922 buf[1] = 'v'; 13923 } 13924 else if (exmode_active) 13925 { 13926 buf[0] = 'c'; 13927 buf[1] = 'e'; 13928 } 13929 else 13930 { 13931 buf[0] = 'n'; 13932 if (finish_op) 13933 buf[1] = 'o'; 13934 } 13935 13936 /* Clear out the minor mode when the argument is not a non-zero number or 13937 * non-empty string. */ 13938 if (!non_zero_arg(&argvars[0])) 13939 buf[1] = NUL; 13940 13941 rettv->vval.v_string = vim_strsave(buf); 13942 rettv->v_type = VAR_STRING; 13943} 13944 13945#ifdef FEAT_MZSCHEME 13946/* 13947 * "mzeval()" function 13948 */ 13949 static void 13950f_mzeval(argvars, rettv) 13951 typval_T *argvars; 13952 typval_T *rettv; 13953{ 13954 char_u *str; 13955 char_u buf[NUMBUFLEN]; 13956 13957 str = get_tv_string_buf(&argvars[0], buf); 13958 do_mzeval(str, rettv); 13959} 13960#endif 13961 13962/* 13963 * "nextnonblank()" function 13964 */ 13965 static void 13966f_nextnonblank(argvars, rettv) 13967 typval_T *argvars; 13968 typval_T *rettv; 13969{ 13970 linenr_T lnum; 13971 13972 for (lnum = get_tv_lnum(argvars); ; ++lnum) 13973 { 13974 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 13975 { 13976 lnum = 0; 13977 break; 13978 } 13979 if (*skipwhite(ml_get(lnum)) != NUL) 13980 break; 13981 } 13982 rettv->vval.v_number = lnum; 13983} 13984 13985/* 13986 * "nr2char()" function 13987 */ 13988 static void 13989f_nr2char(argvars, rettv) 13990 typval_T *argvars; 13991 typval_T *rettv; 13992{ 13993 char_u buf[NUMBUFLEN]; 13994 13995#ifdef FEAT_MBYTE 13996 if (has_mbyte) 13997 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 13998 else 13999#endif 14000 { 14001 buf[0] = (char_u)get_tv_number(&argvars[0]); 14002 buf[1] = NUL; 14003 } 14004 rettv->v_type = VAR_STRING; 14005 rettv->vval.v_string = vim_strsave(buf); 14006} 14007 14008/* 14009 * "pathshorten()" function 14010 */ 14011 static void 14012f_pathshorten(argvars, rettv) 14013 typval_T *argvars; 14014 typval_T *rettv; 14015{ 14016 char_u *p; 14017 14018 rettv->v_type = VAR_STRING; 14019 p = get_tv_string_chk(&argvars[0]); 14020 if (p == NULL) 14021 rettv->vval.v_string = NULL; 14022 else 14023 { 14024 p = vim_strsave(p); 14025 rettv->vval.v_string = p; 14026 if (p != NULL) 14027 shorten_dir(p); 14028 } 14029} 14030 14031#ifdef FEAT_FLOAT 14032/* 14033 * "pow()" function 14034 */ 14035 static void 14036f_pow(argvars, rettv) 14037 typval_T *argvars; 14038 typval_T *rettv; 14039{ 14040 float_T fx, fy; 14041 14042 rettv->v_type = VAR_FLOAT; 14043 if (get_float_arg(argvars, &fx) == OK 14044 && get_float_arg(&argvars[1], &fy) == OK) 14045 rettv->vval.v_float = pow(fx, fy); 14046 else 14047 rettv->vval.v_float = 0.0; 14048} 14049#endif 14050 14051/* 14052 * "prevnonblank()" function 14053 */ 14054 static void 14055f_prevnonblank(argvars, rettv) 14056 typval_T *argvars; 14057 typval_T *rettv; 14058{ 14059 linenr_T lnum; 14060 14061 lnum = get_tv_lnum(argvars); 14062 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 14063 lnum = 0; 14064 else 14065 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 14066 --lnum; 14067 rettv->vval.v_number = lnum; 14068} 14069 14070#ifdef HAVE_STDARG_H 14071/* This dummy va_list is here because: 14072 * - passing a NULL pointer doesn't work when va_list isn't a pointer 14073 * - locally in the function results in a "used before set" warning 14074 * - using va_start() to initialize it gives "function with fixed args" error */ 14075static va_list ap; 14076#endif 14077 14078/* 14079 * "printf()" function 14080 */ 14081 static void 14082f_printf(argvars, rettv) 14083 typval_T *argvars; 14084 typval_T *rettv; 14085{ 14086 rettv->v_type = VAR_STRING; 14087 rettv->vval.v_string = NULL; 14088#ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 14089 { 14090 char_u buf[NUMBUFLEN]; 14091 int len; 14092 char_u *s; 14093 int saved_did_emsg = did_emsg; 14094 char *fmt; 14095 14096 /* Get the required length, allocate the buffer and do it for real. */ 14097 did_emsg = FALSE; 14098 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 14099 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 14100 if (!did_emsg) 14101 { 14102 s = alloc(len + 1); 14103 if (s != NULL) 14104 { 14105 rettv->vval.v_string = s; 14106 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 14107 } 14108 } 14109 did_emsg |= saved_did_emsg; 14110 } 14111#endif 14112} 14113 14114/* 14115 * "pumvisible()" function 14116 */ 14117 static void 14118f_pumvisible(argvars, rettv) 14119 typval_T *argvars UNUSED; 14120 typval_T *rettv UNUSED; 14121{ 14122#ifdef FEAT_INS_EXPAND 14123 if (pum_visible()) 14124 rettv->vval.v_number = 1; 14125#endif 14126} 14127 14128/* 14129 * "range()" function 14130 */ 14131 static void 14132f_range(argvars, rettv) 14133 typval_T *argvars; 14134 typval_T *rettv; 14135{ 14136 long start; 14137 long end; 14138 long stride = 1; 14139 long i; 14140 int error = FALSE; 14141 14142 start = get_tv_number_chk(&argvars[0], &error); 14143 if (argvars[1].v_type == VAR_UNKNOWN) 14144 { 14145 end = start - 1; 14146 start = 0; 14147 } 14148 else 14149 { 14150 end = get_tv_number_chk(&argvars[1], &error); 14151 if (argvars[2].v_type != VAR_UNKNOWN) 14152 stride = get_tv_number_chk(&argvars[2], &error); 14153 } 14154 14155 if (error) 14156 return; /* type error; errmsg already given */ 14157 if (stride == 0) 14158 EMSG(_("E726: Stride is zero")); 14159 else if (stride > 0 ? end + 1 < start : end - 1 > start) 14160 EMSG(_("E727: Start past end")); 14161 else 14162 { 14163 if (rettv_list_alloc(rettv) == OK) 14164 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 14165 if (list_append_number(rettv->vval.v_list, 14166 (varnumber_T)i) == FAIL) 14167 break; 14168 } 14169} 14170 14171/* 14172 * "readfile()" function 14173 */ 14174 static void 14175f_readfile(argvars, rettv) 14176 typval_T *argvars; 14177 typval_T *rettv; 14178{ 14179 int binary = FALSE; 14180 char_u *fname; 14181 FILE *fd; 14182 listitem_T *li; 14183#define FREAD_SIZE 200 /* optimized for text lines */ 14184 char_u buf[FREAD_SIZE]; 14185 int readlen; /* size of last fread() */ 14186 int buflen; /* nr of valid chars in buf[] */ 14187 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 14188 int tolist; /* first byte in buf[] still to be put in list */ 14189 int chop; /* how many CR to chop off */ 14190 char_u *prev = NULL; /* previously read bytes, if any */ 14191 int prevlen = 0; /* length of "prev" if not NULL */ 14192 char_u *s; 14193 int len; 14194 long maxline = MAXLNUM; 14195 long cnt = 0; 14196 14197 if (argvars[1].v_type != VAR_UNKNOWN) 14198 { 14199 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 14200 binary = TRUE; 14201 if (argvars[2].v_type != VAR_UNKNOWN) 14202 maxline = get_tv_number(&argvars[2]); 14203 } 14204 14205 if (rettv_list_alloc(rettv) == FAIL) 14206 return; 14207 14208 /* Always open the file in binary mode, library functions have a mind of 14209 * their own about CR-LF conversion. */ 14210 fname = get_tv_string(&argvars[0]); 14211 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 14212 { 14213 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 14214 return; 14215 } 14216 14217 filtd = 0; 14218 while (cnt < maxline || maxline < 0) 14219 { 14220 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 14221 buflen = filtd + readlen; 14222 tolist = 0; 14223 for ( ; filtd < buflen || readlen <= 0; ++filtd) 14224 { 14225 if (buf[filtd] == '\n' || readlen <= 0) 14226 { 14227 /* Only when in binary mode add an empty list item when the 14228 * last line ends in a '\n'. */ 14229 if (!binary && readlen == 0 && filtd == 0) 14230 break; 14231 14232 /* Found end-of-line or end-of-file: add a text line to the 14233 * list. */ 14234 chop = 0; 14235 if (!binary) 14236 while (filtd - chop - 1 >= tolist 14237 && buf[filtd - chop - 1] == '\r') 14238 ++chop; 14239 len = filtd - tolist - chop; 14240 if (prev == NULL) 14241 s = vim_strnsave(buf + tolist, len); 14242 else 14243 { 14244 s = alloc((unsigned)(prevlen + len + 1)); 14245 if (s != NULL) 14246 { 14247 mch_memmove(s, prev, prevlen); 14248 vim_free(prev); 14249 prev = NULL; 14250 mch_memmove(s + prevlen, buf + tolist, len); 14251 s[prevlen + len] = NUL; 14252 } 14253 } 14254 tolist = filtd + 1; 14255 14256 li = listitem_alloc(); 14257 if (li == NULL) 14258 { 14259 vim_free(s); 14260 break; 14261 } 14262 li->li_tv.v_type = VAR_STRING; 14263 li->li_tv.v_lock = 0; 14264 li->li_tv.vval.v_string = s; 14265 list_append(rettv->vval.v_list, li); 14266 14267 if (++cnt >= maxline && maxline >= 0) 14268 break; 14269 if (readlen <= 0) 14270 break; 14271 } 14272 else if (buf[filtd] == NUL) 14273 buf[filtd] = '\n'; 14274#ifdef FEAT_MBYTE 14275 else if (buf[filtd] == 0xef 14276 && enc_utf8 14277 && filtd + 2 < buflen 14278 && !binary 14279 && buf[filtd + 1] == 0xbb 14280 && buf[filtd + 2] == 0xbf) 14281 { 14282 /* remove utf-8 byte order mark */ 14283 mch_memmove(buf + filtd, buf + filtd + 3, buflen - filtd - 3); 14284 --filtd; 14285 buflen -= 3; 14286 } 14287#endif 14288 } 14289 if (readlen <= 0) 14290 break; 14291 14292 if (tolist == 0) 14293 { 14294 /* "buf" is full, need to move text to an allocated buffer */ 14295 if (prev == NULL) 14296 { 14297 prev = vim_strnsave(buf, buflen); 14298 prevlen = buflen; 14299 } 14300 else 14301 { 14302 s = alloc((unsigned)(prevlen + buflen)); 14303 if (s != NULL) 14304 { 14305 mch_memmove(s, prev, prevlen); 14306 mch_memmove(s + prevlen, buf, buflen); 14307 vim_free(prev); 14308 prev = s; 14309 prevlen += buflen; 14310 } 14311 } 14312 filtd = 0; 14313 } 14314 else 14315 { 14316 mch_memmove(buf, buf + tolist, buflen - tolist); 14317 filtd -= tolist; 14318 } 14319 } 14320 14321 /* 14322 * For a negative line count use only the lines at the end of the file, 14323 * free the rest. 14324 */ 14325 if (maxline < 0) 14326 while (cnt > -maxline) 14327 { 14328 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 14329 --cnt; 14330 } 14331 14332 vim_free(prev); 14333 fclose(fd); 14334} 14335 14336#if defined(FEAT_RELTIME) 14337static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 14338 14339/* 14340 * Convert a List to proftime_T. 14341 * Return FAIL when there is something wrong. 14342 */ 14343 static int 14344list2proftime(arg, tm) 14345 typval_T *arg; 14346 proftime_T *tm; 14347{ 14348 long n1, n2; 14349 int error = FALSE; 14350 14351 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 14352 || arg->vval.v_list->lv_len != 2) 14353 return FAIL; 14354 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 14355 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 14356# ifdef WIN3264 14357 tm->HighPart = n1; 14358 tm->LowPart = n2; 14359# else 14360 tm->tv_sec = n1; 14361 tm->tv_usec = n2; 14362# endif 14363 return error ? FAIL : OK; 14364} 14365#endif /* FEAT_RELTIME */ 14366 14367/* 14368 * "reltime()" function 14369 */ 14370 static void 14371f_reltime(argvars, rettv) 14372 typval_T *argvars; 14373 typval_T *rettv; 14374{ 14375#ifdef FEAT_RELTIME 14376 proftime_T res; 14377 proftime_T start; 14378 14379 if (argvars[0].v_type == VAR_UNKNOWN) 14380 { 14381 /* No arguments: get current time. */ 14382 profile_start(&res); 14383 } 14384 else if (argvars[1].v_type == VAR_UNKNOWN) 14385 { 14386 if (list2proftime(&argvars[0], &res) == FAIL) 14387 return; 14388 profile_end(&res); 14389 } 14390 else 14391 { 14392 /* Two arguments: compute the difference. */ 14393 if (list2proftime(&argvars[0], &start) == FAIL 14394 || list2proftime(&argvars[1], &res) == FAIL) 14395 return; 14396 profile_sub(&res, &start); 14397 } 14398 14399 if (rettv_list_alloc(rettv) == OK) 14400 { 14401 long n1, n2; 14402 14403# ifdef WIN3264 14404 n1 = res.HighPart; 14405 n2 = res.LowPart; 14406# else 14407 n1 = res.tv_sec; 14408 n2 = res.tv_usec; 14409# endif 14410 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 14411 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 14412 } 14413#endif 14414} 14415 14416/* 14417 * "reltimestr()" function 14418 */ 14419 static void 14420f_reltimestr(argvars, rettv) 14421 typval_T *argvars; 14422 typval_T *rettv; 14423{ 14424#ifdef FEAT_RELTIME 14425 proftime_T tm; 14426#endif 14427 14428 rettv->v_type = VAR_STRING; 14429 rettv->vval.v_string = NULL; 14430#ifdef FEAT_RELTIME 14431 if (list2proftime(&argvars[0], &tm) == OK) 14432 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 14433#endif 14434} 14435 14436#if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 14437static void make_connection __ARGS((void)); 14438static int check_connection __ARGS((void)); 14439 14440 static void 14441make_connection() 14442{ 14443 if (X_DISPLAY == NULL 14444# ifdef FEAT_GUI 14445 && !gui.in_use 14446# endif 14447 ) 14448 { 14449 x_force_connect = TRUE; 14450 setup_term_clip(); 14451 x_force_connect = FALSE; 14452 } 14453} 14454 14455 static int 14456check_connection() 14457{ 14458 make_connection(); 14459 if (X_DISPLAY == NULL) 14460 { 14461 EMSG(_("E240: No connection to Vim server")); 14462 return FAIL; 14463 } 14464 return OK; 14465} 14466#endif 14467 14468#ifdef FEAT_CLIENTSERVER 14469static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 14470 14471 static void 14472remote_common(argvars, rettv, expr) 14473 typval_T *argvars; 14474 typval_T *rettv; 14475 int expr; 14476{ 14477 char_u *server_name; 14478 char_u *keys; 14479 char_u *r = NULL; 14480 char_u buf[NUMBUFLEN]; 14481# ifdef WIN32 14482 HWND w; 14483# else 14484 Window w; 14485# endif 14486 14487 if (check_restricted() || check_secure()) 14488 return; 14489 14490# ifdef FEAT_X11 14491 if (check_connection() == FAIL) 14492 return; 14493# endif 14494 14495 server_name = get_tv_string_chk(&argvars[0]); 14496 if (server_name == NULL) 14497 return; /* type error; errmsg already given */ 14498 keys = get_tv_string_buf(&argvars[1], buf); 14499# ifdef WIN32 14500 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 14501# else 14502 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 14503 < 0) 14504# endif 14505 { 14506 if (r != NULL) 14507 EMSG(r); /* sending worked but evaluation failed */ 14508 else 14509 EMSG2(_("E241: Unable to send to %s"), server_name); 14510 return; 14511 } 14512 14513 rettv->vval.v_string = r; 14514 14515 if (argvars[2].v_type != VAR_UNKNOWN) 14516 { 14517 dictitem_T v; 14518 char_u str[30]; 14519 char_u *idvar; 14520 14521 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 14522 v.di_tv.v_type = VAR_STRING; 14523 v.di_tv.vval.v_string = vim_strsave(str); 14524 idvar = get_tv_string_chk(&argvars[2]); 14525 if (idvar != NULL) 14526 set_var(idvar, &v.di_tv, FALSE); 14527 vim_free(v.di_tv.vval.v_string); 14528 } 14529} 14530#endif 14531 14532/* 14533 * "remote_expr()" function 14534 */ 14535 static void 14536f_remote_expr(argvars, rettv) 14537 typval_T *argvars UNUSED; 14538 typval_T *rettv; 14539{ 14540 rettv->v_type = VAR_STRING; 14541 rettv->vval.v_string = NULL; 14542#ifdef FEAT_CLIENTSERVER 14543 remote_common(argvars, rettv, TRUE); 14544#endif 14545} 14546 14547/* 14548 * "remote_foreground()" function 14549 */ 14550 static void 14551f_remote_foreground(argvars, rettv) 14552 typval_T *argvars UNUSED; 14553 typval_T *rettv UNUSED; 14554{ 14555#ifdef FEAT_CLIENTSERVER 14556# ifdef WIN32 14557 /* On Win32 it's done in this application. */ 14558 { 14559 char_u *server_name = get_tv_string_chk(&argvars[0]); 14560 14561 if (server_name != NULL) 14562 serverForeground(server_name); 14563 } 14564# else 14565 /* Send a foreground() expression to the server. */ 14566 argvars[1].v_type = VAR_STRING; 14567 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 14568 argvars[2].v_type = VAR_UNKNOWN; 14569 remote_common(argvars, rettv, TRUE); 14570 vim_free(argvars[1].vval.v_string); 14571# endif 14572#endif 14573} 14574 14575 static void 14576f_remote_peek(argvars, rettv) 14577 typval_T *argvars UNUSED; 14578 typval_T *rettv; 14579{ 14580#ifdef FEAT_CLIENTSERVER 14581 dictitem_T v; 14582 char_u *s = NULL; 14583# ifdef WIN32 14584 long_u n = 0; 14585# endif 14586 char_u *serverid; 14587 14588 if (check_restricted() || check_secure()) 14589 { 14590 rettv->vval.v_number = -1; 14591 return; 14592 } 14593 serverid = get_tv_string_chk(&argvars[0]); 14594 if (serverid == NULL) 14595 { 14596 rettv->vval.v_number = -1; 14597 return; /* type error; errmsg already given */ 14598 } 14599# ifdef WIN32 14600 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14601 if (n == 0) 14602 rettv->vval.v_number = -1; 14603 else 14604 { 14605 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 14606 rettv->vval.v_number = (s != NULL); 14607 } 14608# else 14609 if (check_connection() == FAIL) 14610 return; 14611 14612 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 14613 serverStrToWin(serverid), &s); 14614# endif 14615 14616 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 14617 { 14618 char_u *retvar; 14619 14620 v.di_tv.v_type = VAR_STRING; 14621 v.di_tv.vval.v_string = vim_strsave(s); 14622 retvar = get_tv_string_chk(&argvars[1]); 14623 if (retvar != NULL) 14624 set_var(retvar, &v.di_tv, FALSE); 14625 vim_free(v.di_tv.vval.v_string); 14626 } 14627#else 14628 rettv->vval.v_number = -1; 14629#endif 14630} 14631 14632 static void 14633f_remote_read(argvars, rettv) 14634 typval_T *argvars UNUSED; 14635 typval_T *rettv; 14636{ 14637 char_u *r = NULL; 14638 14639#ifdef FEAT_CLIENTSERVER 14640 char_u *serverid = get_tv_string_chk(&argvars[0]); 14641 14642 if (serverid != NULL && !check_restricted() && !check_secure()) 14643 { 14644# ifdef WIN32 14645 /* The server's HWND is encoded in the 'id' parameter */ 14646 long_u n = 0; 14647 14648 sscanf(serverid, SCANF_HEX_LONG_U, &n); 14649 if (n != 0) 14650 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 14651 if (r == NULL) 14652# else 14653 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 14654 serverStrToWin(serverid), &r, FALSE) < 0) 14655# endif 14656 EMSG(_("E277: Unable to read a server reply")); 14657 } 14658#endif 14659 rettv->v_type = VAR_STRING; 14660 rettv->vval.v_string = r; 14661} 14662 14663/* 14664 * "remote_send()" function 14665 */ 14666 static void 14667f_remote_send(argvars, rettv) 14668 typval_T *argvars UNUSED; 14669 typval_T *rettv; 14670{ 14671 rettv->v_type = VAR_STRING; 14672 rettv->vval.v_string = NULL; 14673#ifdef FEAT_CLIENTSERVER 14674 remote_common(argvars, rettv, FALSE); 14675#endif 14676} 14677 14678/* 14679 * "remove()" function 14680 */ 14681 static void 14682f_remove(argvars, rettv) 14683 typval_T *argvars; 14684 typval_T *rettv; 14685{ 14686 list_T *l; 14687 listitem_T *item, *item2; 14688 listitem_T *li; 14689 long idx; 14690 long end; 14691 char_u *key; 14692 dict_T *d; 14693 dictitem_T *di; 14694 14695 if (argvars[0].v_type == VAR_DICT) 14696 { 14697 if (argvars[2].v_type != VAR_UNKNOWN) 14698 EMSG2(_(e_toomanyarg), "remove()"); 14699 else if ((d = argvars[0].vval.v_dict) != NULL 14700 && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) 14701 { 14702 key = get_tv_string_chk(&argvars[1]); 14703 if (key != NULL) 14704 { 14705 di = dict_find(d, key, -1); 14706 if (di == NULL) 14707 EMSG2(_(e_dictkey), key); 14708 else 14709 { 14710 *rettv = di->di_tv; 14711 init_tv(&di->di_tv); 14712 dictitem_remove(d, di); 14713 } 14714 } 14715 } 14716 } 14717 else if (argvars[0].v_type != VAR_LIST) 14718 EMSG2(_(e_listdictarg), "remove()"); 14719 else if ((l = argvars[0].vval.v_list) != NULL 14720 && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) 14721 { 14722 int error = FALSE; 14723 14724 idx = get_tv_number_chk(&argvars[1], &error); 14725 if (error) 14726 ; /* type error: do nothing, errmsg already given */ 14727 else if ((item = list_find(l, idx)) == NULL) 14728 EMSGN(_(e_listidx), idx); 14729 else 14730 { 14731 if (argvars[2].v_type == VAR_UNKNOWN) 14732 { 14733 /* Remove one item, return its value. */ 14734 list_remove(l, item, item); 14735 *rettv = item->li_tv; 14736 vim_free(item); 14737 } 14738 else 14739 { 14740 /* Remove range of items, return list with values. */ 14741 end = get_tv_number_chk(&argvars[2], &error); 14742 if (error) 14743 ; /* type error: do nothing */ 14744 else if ((item2 = list_find(l, end)) == NULL) 14745 EMSGN(_(e_listidx), end); 14746 else 14747 { 14748 int cnt = 0; 14749 14750 for (li = item; li != NULL; li = li->li_next) 14751 { 14752 ++cnt; 14753 if (li == item2) 14754 break; 14755 } 14756 if (li == NULL) /* didn't find "item2" after "item" */ 14757 EMSG(_(e_invrange)); 14758 else 14759 { 14760 list_remove(l, item, item2); 14761 if (rettv_list_alloc(rettv) == OK) 14762 { 14763 l = rettv->vval.v_list; 14764 l->lv_first = item; 14765 l->lv_last = item2; 14766 item->li_prev = NULL; 14767 item2->li_next = NULL; 14768 l->lv_len = cnt; 14769 } 14770 } 14771 } 14772 } 14773 } 14774 } 14775} 14776 14777/* 14778 * "rename({from}, {to})" function 14779 */ 14780 static void 14781f_rename(argvars, rettv) 14782 typval_T *argvars; 14783 typval_T *rettv; 14784{ 14785 char_u buf[NUMBUFLEN]; 14786 14787 if (check_restricted() || check_secure()) 14788 rettv->vval.v_number = -1; 14789 else 14790 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 14791 get_tv_string_buf(&argvars[1], buf)); 14792} 14793 14794/* 14795 * "repeat()" function 14796 */ 14797 static void 14798f_repeat(argvars, rettv) 14799 typval_T *argvars; 14800 typval_T *rettv; 14801{ 14802 char_u *p; 14803 int n; 14804 int slen; 14805 int len; 14806 char_u *r; 14807 int i; 14808 14809 n = get_tv_number(&argvars[1]); 14810 if (argvars[0].v_type == VAR_LIST) 14811 { 14812 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 14813 while (n-- > 0) 14814 if (list_extend(rettv->vval.v_list, 14815 argvars[0].vval.v_list, NULL) == FAIL) 14816 break; 14817 } 14818 else 14819 { 14820 p = get_tv_string(&argvars[0]); 14821 rettv->v_type = VAR_STRING; 14822 rettv->vval.v_string = NULL; 14823 14824 slen = (int)STRLEN(p); 14825 len = slen * n; 14826 if (len <= 0) 14827 return; 14828 14829 r = alloc(len + 1); 14830 if (r != NULL) 14831 { 14832 for (i = 0; i < n; i++) 14833 mch_memmove(r + i * slen, p, (size_t)slen); 14834 r[len] = NUL; 14835 } 14836 14837 rettv->vval.v_string = r; 14838 } 14839} 14840 14841/* 14842 * "resolve()" function 14843 */ 14844 static void 14845f_resolve(argvars, rettv) 14846 typval_T *argvars; 14847 typval_T *rettv; 14848{ 14849 char_u *p; 14850 14851 p = get_tv_string(&argvars[0]); 14852#ifdef FEAT_SHORTCUT 14853 { 14854 char_u *v = NULL; 14855 14856 v = mch_resolve_shortcut(p); 14857 if (v != NULL) 14858 rettv->vval.v_string = v; 14859 else 14860 rettv->vval.v_string = vim_strsave(p); 14861 } 14862#else 14863# ifdef HAVE_READLINK 14864 { 14865 char_u buf[MAXPATHL + 1]; 14866 char_u *cpy; 14867 int len; 14868 char_u *remain = NULL; 14869 char_u *q; 14870 int is_relative_to_current = FALSE; 14871 int has_trailing_pathsep = FALSE; 14872 int limit = 100; 14873 14874 p = vim_strsave(p); 14875 14876 if (p[0] == '.' && (vim_ispathsep(p[1]) 14877 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 14878 is_relative_to_current = TRUE; 14879 14880 len = STRLEN(p); 14881 if (len > 0 && after_pathsep(p, p + len)) 14882 has_trailing_pathsep = TRUE; 14883 14884 q = getnextcomp(p); 14885 if (*q != NUL) 14886 { 14887 /* Separate the first path component in "p", and keep the 14888 * remainder (beginning with the path separator). */ 14889 remain = vim_strsave(q - 1); 14890 q[-1] = NUL; 14891 } 14892 14893 for (;;) 14894 { 14895 for (;;) 14896 { 14897 len = readlink((char *)p, (char *)buf, MAXPATHL); 14898 if (len <= 0) 14899 break; 14900 buf[len] = NUL; 14901 14902 if (limit-- == 0) 14903 { 14904 vim_free(p); 14905 vim_free(remain); 14906 EMSG(_("E655: Too many symbolic links (cycle?)")); 14907 rettv->vval.v_string = NULL; 14908 goto fail; 14909 } 14910 14911 /* Ensure that the result will have a trailing path separator 14912 * if the argument has one. */ 14913 if (remain == NULL && has_trailing_pathsep) 14914 add_pathsep(buf); 14915 14916 /* Separate the first path component in the link value and 14917 * concatenate the remainders. */ 14918 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 14919 if (*q != NUL) 14920 { 14921 if (remain == NULL) 14922 remain = vim_strsave(q - 1); 14923 else 14924 { 14925 cpy = concat_str(q - 1, remain); 14926 if (cpy != NULL) 14927 { 14928 vim_free(remain); 14929 remain = cpy; 14930 } 14931 } 14932 q[-1] = NUL; 14933 } 14934 14935 q = gettail(p); 14936 if (q > p && *q == NUL) 14937 { 14938 /* Ignore trailing path separator. */ 14939 q[-1] = NUL; 14940 q = gettail(p); 14941 } 14942 if (q > p && !mch_isFullName(buf)) 14943 { 14944 /* symlink is relative to directory of argument */ 14945 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 14946 if (cpy != NULL) 14947 { 14948 STRCPY(cpy, p); 14949 STRCPY(gettail(cpy), buf); 14950 vim_free(p); 14951 p = cpy; 14952 } 14953 } 14954 else 14955 { 14956 vim_free(p); 14957 p = vim_strsave(buf); 14958 } 14959 } 14960 14961 if (remain == NULL) 14962 break; 14963 14964 /* Append the first path component of "remain" to "p". */ 14965 q = getnextcomp(remain + 1); 14966 len = q - remain - (*q != NUL); 14967 cpy = vim_strnsave(p, STRLEN(p) + len); 14968 if (cpy != NULL) 14969 { 14970 STRNCAT(cpy, remain, len); 14971 vim_free(p); 14972 p = cpy; 14973 } 14974 /* Shorten "remain". */ 14975 if (*q != NUL) 14976 STRMOVE(remain, q - 1); 14977 else 14978 { 14979 vim_free(remain); 14980 remain = NULL; 14981 } 14982 } 14983 14984 /* If the result is a relative path name, make it explicitly relative to 14985 * the current directory if and only if the argument had this form. */ 14986 if (!vim_ispathsep(*p)) 14987 { 14988 if (is_relative_to_current 14989 && *p != NUL 14990 && !(p[0] == '.' 14991 && (p[1] == NUL 14992 || vim_ispathsep(p[1]) 14993 || (p[1] == '.' 14994 && (p[2] == NUL 14995 || vim_ispathsep(p[2])))))) 14996 { 14997 /* Prepend "./". */ 14998 cpy = concat_str((char_u *)"./", p); 14999 if (cpy != NULL) 15000 { 15001 vim_free(p); 15002 p = cpy; 15003 } 15004 } 15005 else if (!is_relative_to_current) 15006 { 15007 /* Strip leading "./". */ 15008 q = p; 15009 while (q[0] == '.' && vim_ispathsep(q[1])) 15010 q += 2; 15011 if (q > p) 15012 STRMOVE(p, p + 2); 15013 } 15014 } 15015 15016 /* Ensure that the result will have no trailing path separator 15017 * if the argument had none. But keep "/" or "//". */ 15018 if (!has_trailing_pathsep) 15019 { 15020 q = p + STRLEN(p); 15021 if (after_pathsep(p, q)) 15022 *gettail_sep(p) = NUL; 15023 } 15024 15025 rettv->vval.v_string = p; 15026 } 15027# else 15028 rettv->vval.v_string = vim_strsave(p); 15029# endif 15030#endif 15031 15032 simplify_filename(rettv->vval.v_string); 15033 15034#ifdef HAVE_READLINK 15035fail: 15036#endif 15037 rettv->v_type = VAR_STRING; 15038} 15039 15040/* 15041 * "reverse({list})" function 15042 */ 15043 static void 15044f_reverse(argvars, rettv) 15045 typval_T *argvars; 15046 typval_T *rettv; 15047{ 15048 list_T *l; 15049 listitem_T *li, *ni; 15050 15051 if (argvars[0].v_type != VAR_LIST) 15052 EMSG2(_(e_listarg), "reverse()"); 15053 else if ((l = argvars[0].vval.v_list) != NULL 15054 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 15055 { 15056 li = l->lv_last; 15057 l->lv_first = l->lv_last = NULL; 15058 l->lv_len = 0; 15059 while (li != NULL) 15060 { 15061 ni = li->li_prev; 15062 list_append(l, li); 15063 li = ni; 15064 } 15065 rettv->vval.v_list = l; 15066 rettv->v_type = VAR_LIST; 15067 ++l->lv_refcount; 15068 l->lv_idx = l->lv_len - l->lv_idx - 1; 15069 } 15070} 15071 15072#define SP_NOMOVE 0x01 /* don't move cursor */ 15073#define SP_REPEAT 0x02 /* repeat to find outer pair */ 15074#define SP_RETCOUNT 0x04 /* return matchcount */ 15075#define SP_SETPCMARK 0x08 /* set previous context mark */ 15076#define SP_START 0x10 /* accept match at start position */ 15077#define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 15078#define SP_END 0x40 /* leave cursor at end of match */ 15079 15080static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 15081 15082/* 15083 * Get flags for a search function. 15084 * Possibly sets "p_ws". 15085 * Returns BACKWARD, FORWARD or zero (for an error). 15086 */ 15087 static int 15088get_search_arg(varp, flagsp) 15089 typval_T *varp; 15090 int *flagsp; 15091{ 15092 int dir = FORWARD; 15093 char_u *flags; 15094 char_u nbuf[NUMBUFLEN]; 15095 int mask; 15096 15097 if (varp->v_type != VAR_UNKNOWN) 15098 { 15099 flags = get_tv_string_buf_chk(varp, nbuf); 15100 if (flags == NULL) 15101 return 0; /* type error; errmsg already given */ 15102 while (*flags != NUL) 15103 { 15104 switch (*flags) 15105 { 15106 case 'b': dir = BACKWARD; break; 15107 case 'w': p_ws = TRUE; break; 15108 case 'W': p_ws = FALSE; break; 15109 default: mask = 0; 15110 if (flagsp != NULL) 15111 switch (*flags) 15112 { 15113 case 'c': mask = SP_START; break; 15114 case 'e': mask = SP_END; break; 15115 case 'm': mask = SP_RETCOUNT; break; 15116 case 'n': mask = SP_NOMOVE; break; 15117 case 'p': mask = SP_SUBPAT; break; 15118 case 'r': mask = SP_REPEAT; break; 15119 case 's': mask = SP_SETPCMARK; break; 15120 } 15121 if (mask == 0) 15122 { 15123 EMSG2(_(e_invarg2), flags); 15124 dir = 0; 15125 } 15126 else 15127 *flagsp |= mask; 15128 } 15129 if (dir == 0) 15130 break; 15131 ++flags; 15132 } 15133 } 15134 return dir; 15135} 15136 15137/* 15138 * Shared by search() and searchpos() functions 15139 */ 15140 static int 15141search_cmn(argvars, match_pos, flagsp) 15142 typval_T *argvars; 15143 pos_T *match_pos; 15144 int *flagsp; 15145{ 15146 int flags; 15147 char_u *pat; 15148 pos_T pos; 15149 pos_T save_cursor; 15150 int save_p_ws = p_ws; 15151 int dir; 15152 int retval = 0; /* default: FAIL */ 15153 long lnum_stop = 0; 15154 proftime_T tm; 15155#ifdef FEAT_RELTIME 15156 long time_limit = 0; 15157#endif 15158 int options = SEARCH_KEEP; 15159 int subpatnum; 15160 15161 pat = get_tv_string(&argvars[0]); 15162 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 15163 if (dir == 0) 15164 goto theend; 15165 flags = *flagsp; 15166 if (flags & SP_START) 15167 options |= SEARCH_START; 15168 if (flags & SP_END) 15169 options |= SEARCH_END; 15170 15171 /* Optional arguments: line number to stop searching and timeout. */ 15172 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) 15173 { 15174 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 15175 if (lnum_stop < 0) 15176 goto theend; 15177#ifdef FEAT_RELTIME 15178 if (argvars[3].v_type != VAR_UNKNOWN) 15179 { 15180 time_limit = get_tv_number_chk(&argvars[3], NULL); 15181 if (time_limit < 0) 15182 goto theend; 15183 } 15184#endif 15185 } 15186 15187#ifdef FEAT_RELTIME 15188 /* Set the time limit, if there is one. */ 15189 profile_setlimit(time_limit, &tm); 15190#endif 15191 15192 /* 15193 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 15194 * Check to make sure only those flags are set. 15195 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 15196 * flags cannot be set. Check for that condition also. 15197 */ 15198 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 15199 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 15200 { 15201 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 15202 goto theend; 15203 } 15204 15205 pos = save_cursor = curwin->w_cursor; 15206 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15207 options, RE_SEARCH, (linenr_T)lnum_stop, &tm); 15208 if (subpatnum != FAIL) 15209 { 15210 if (flags & SP_SUBPAT) 15211 retval = subpatnum; 15212 else 15213 retval = pos.lnum; 15214 if (flags & SP_SETPCMARK) 15215 setpcmark(); 15216 curwin->w_cursor = pos; 15217 if (match_pos != NULL) 15218 { 15219 /* Store the match cursor position */ 15220 match_pos->lnum = pos.lnum; 15221 match_pos->col = pos.col + 1; 15222 } 15223 /* "/$" will put the cursor after the end of the line, may need to 15224 * correct that here */ 15225 check_cursor(); 15226 } 15227 15228 /* If 'n' flag is used: restore cursor position. */ 15229 if (flags & SP_NOMOVE) 15230 curwin->w_cursor = save_cursor; 15231 else 15232 curwin->w_set_curswant = TRUE; 15233theend: 15234 p_ws = save_p_ws; 15235 15236 return retval; 15237} 15238 15239#ifdef FEAT_FLOAT 15240/* 15241 * "round({float})" function 15242 */ 15243 static void 15244f_round(argvars, rettv) 15245 typval_T *argvars; 15246 typval_T *rettv; 15247{ 15248 float_T f; 15249 15250 rettv->v_type = VAR_FLOAT; 15251 if (get_float_arg(argvars, &f) == OK) 15252 /* round() is not in C90, use ceil() or floor() instead. */ 15253 rettv->vval.v_float = f > 0 ? floor(f + 0.5) : ceil(f - 0.5); 15254 else 15255 rettv->vval.v_float = 0.0; 15256} 15257#endif 15258 15259/* 15260 * "search()" function 15261 */ 15262 static void 15263f_search(argvars, rettv) 15264 typval_T *argvars; 15265 typval_T *rettv; 15266{ 15267 int flags = 0; 15268 15269 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 15270} 15271 15272/* 15273 * "searchdecl()" function 15274 */ 15275 static void 15276f_searchdecl(argvars, rettv) 15277 typval_T *argvars; 15278 typval_T *rettv; 15279{ 15280 int locally = 1; 15281 int thisblock = 0; 15282 int error = FALSE; 15283 char_u *name; 15284 15285 rettv->vval.v_number = 1; /* default: FAIL */ 15286 15287 name = get_tv_string_chk(&argvars[0]); 15288 if (argvars[1].v_type != VAR_UNKNOWN) 15289 { 15290 locally = get_tv_number_chk(&argvars[1], &error) == 0; 15291 if (!error && argvars[2].v_type != VAR_UNKNOWN) 15292 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 15293 } 15294 if (!error && name != NULL) 15295 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 15296 locally, thisblock, SEARCH_KEEP) == FAIL; 15297} 15298 15299/* 15300 * Used by searchpair() and searchpairpos() 15301 */ 15302 static int 15303searchpair_cmn(argvars, match_pos) 15304 typval_T *argvars; 15305 pos_T *match_pos; 15306{ 15307 char_u *spat, *mpat, *epat; 15308 char_u *skip; 15309 int save_p_ws = p_ws; 15310 int dir; 15311 int flags = 0; 15312 char_u nbuf1[NUMBUFLEN]; 15313 char_u nbuf2[NUMBUFLEN]; 15314 char_u nbuf3[NUMBUFLEN]; 15315 int retval = 0; /* default: FAIL */ 15316 long lnum_stop = 0; 15317 long time_limit = 0; 15318 15319 /* Get the three pattern arguments: start, middle, end. */ 15320 spat = get_tv_string_chk(&argvars[0]); 15321 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 15322 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 15323 if (spat == NULL || mpat == NULL || epat == NULL) 15324 goto theend; /* type error */ 15325 15326 /* Handle the optional fourth argument: flags */ 15327 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 15328 if (dir == 0) 15329 goto theend; 15330 15331 /* Don't accept SP_END or SP_SUBPAT. 15332 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 15333 */ 15334 if ((flags & (SP_END | SP_SUBPAT)) != 0 15335 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 15336 { 15337 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 15338 goto theend; 15339 } 15340 15341 /* Using 'r' implies 'W', otherwise it doesn't work. */ 15342 if (flags & SP_REPEAT) 15343 p_ws = FALSE; 15344 15345 /* Optional fifth argument: skip expression */ 15346 if (argvars[3].v_type == VAR_UNKNOWN 15347 || argvars[4].v_type == VAR_UNKNOWN) 15348 skip = (char_u *)""; 15349 else 15350 { 15351 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 15352 if (argvars[5].v_type != VAR_UNKNOWN) 15353 { 15354 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 15355 if (lnum_stop < 0) 15356 goto theend; 15357#ifdef FEAT_RELTIME 15358 if (argvars[6].v_type != VAR_UNKNOWN) 15359 { 15360 time_limit = get_tv_number_chk(&argvars[6], NULL); 15361 if (time_limit < 0) 15362 goto theend; 15363 } 15364#endif 15365 } 15366 } 15367 if (skip == NULL) 15368 goto theend; /* type error */ 15369 15370 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 15371 match_pos, lnum_stop, time_limit); 15372 15373theend: 15374 p_ws = save_p_ws; 15375 15376 return retval; 15377} 15378 15379/* 15380 * "searchpair()" function 15381 */ 15382 static void 15383f_searchpair(argvars, rettv) 15384 typval_T *argvars; 15385 typval_T *rettv; 15386{ 15387 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 15388} 15389 15390/* 15391 * "searchpairpos()" function 15392 */ 15393 static void 15394f_searchpairpos(argvars, rettv) 15395 typval_T *argvars; 15396 typval_T *rettv; 15397{ 15398 pos_T match_pos; 15399 int lnum = 0; 15400 int col = 0; 15401 15402 if (rettv_list_alloc(rettv) == FAIL) 15403 return; 15404 15405 if (searchpair_cmn(argvars, &match_pos) > 0) 15406 { 15407 lnum = match_pos.lnum; 15408 col = match_pos.col; 15409 } 15410 15411 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15412 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15413} 15414 15415/* 15416 * Search for a start/middle/end thing. 15417 * Used by searchpair(), see its documentation for the details. 15418 * Returns 0 or -1 for no match, 15419 */ 15420 long 15421do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, 15422 lnum_stop, time_limit) 15423 char_u *spat; /* start pattern */ 15424 char_u *mpat; /* middle pattern */ 15425 char_u *epat; /* end pattern */ 15426 int dir; /* BACKWARD or FORWARD */ 15427 char_u *skip; /* skip expression */ 15428 int flags; /* SP_SETPCMARK and other SP_ values */ 15429 pos_T *match_pos; 15430 linenr_T lnum_stop; /* stop at this line if not zero */ 15431 long time_limit; /* stop after this many msec */ 15432{ 15433 char_u *save_cpo; 15434 char_u *pat, *pat2 = NULL, *pat3 = NULL; 15435 long retval = 0; 15436 pos_T pos; 15437 pos_T firstpos; 15438 pos_T foundpos; 15439 pos_T save_cursor; 15440 pos_T save_pos; 15441 int n; 15442 int r; 15443 int nest = 1; 15444 int err; 15445 int options = SEARCH_KEEP; 15446 proftime_T tm; 15447 15448 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15449 save_cpo = p_cpo; 15450 p_cpo = empty_option; 15451 15452#ifdef FEAT_RELTIME 15453 /* Set the time limit, if there is one. */ 15454 profile_setlimit(time_limit, &tm); 15455#endif 15456 15457 /* Make two search patterns: start/end (pat2, for in nested pairs) and 15458 * start/middle/end (pat3, for the top pair). */ 15459 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 15460 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 15461 if (pat2 == NULL || pat3 == NULL) 15462 goto theend; 15463 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 15464 if (*mpat == NUL) 15465 STRCPY(pat3, pat2); 15466 else 15467 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 15468 spat, epat, mpat); 15469 if (flags & SP_START) 15470 options |= SEARCH_START; 15471 15472 save_cursor = curwin->w_cursor; 15473 pos = curwin->w_cursor; 15474 clearpos(&firstpos); 15475 clearpos(&foundpos); 15476 pat = pat3; 15477 for (;;) 15478 { 15479 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 15480 options, RE_SEARCH, lnum_stop, &tm); 15481 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 15482 /* didn't find it or found the first match again: FAIL */ 15483 break; 15484 15485 if (firstpos.lnum == 0) 15486 firstpos = pos; 15487 if (equalpos(pos, foundpos)) 15488 { 15489 /* Found the same position again. Can happen with a pattern that 15490 * has "\zs" at the end and searching backwards. Advance one 15491 * character and try again. */ 15492 if (dir == BACKWARD) 15493 decl(&pos); 15494 else 15495 incl(&pos); 15496 } 15497 foundpos = pos; 15498 15499 /* clear the start flag to avoid getting stuck here */ 15500 options &= ~SEARCH_START; 15501 15502 /* If the skip pattern matches, ignore this match. */ 15503 if (*skip != NUL) 15504 { 15505 save_pos = curwin->w_cursor; 15506 curwin->w_cursor = pos; 15507 r = eval_to_bool(skip, &err, NULL, FALSE); 15508 curwin->w_cursor = save_pos; 15509 if (err) 15510 { 15511 /* Evaluating {skip} caused an error, break here. */ 15512 curwin->w_cursor = save_cursor; 15513 retval = -1; 15514 break; 15515 } 15516 if (r) 15517 continue; 15518 } 15519 15520 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 15521 { 15522 /* Found end when searching backwards or start when searching 15523 * forward: nested pair. */ 15524 ++nest; 15525 pat = pat2; /* nested, don't search for middle */ 15526 } 15527 else 15528 { 15529 /* Found end when searching forward or start when searching 15530 * backward: end of (nested) pair; or found middle in outer pair. */ 15531 if (--nest == 1) 15532 pat = pat3; /* outer level, search for middle */ 15533 } 15534 15535 if (nest == 0) 15536 { 15537 /* Found the match: return matchcount or line number. */ 15538 if (flags & SP_RETCOUNT) 15539 ++retval; 15540 else 15541 retval = pos.lnum; 15542 if (flags & SP_SETPCMARK) 15543 setpcmark(); 15544 curwin->w_cursor = pos; 15545 if (!(flags & SP_REPEAT)) 15546 break; 15547 nest = 1; /* search for next unmatched */ 15548 } 15549 } 15550 15551 if (match_pos != NULL) 15552 { 15553 /* Store the match cursor position */ 15554 match_pos->lnum = curwin->w_cursor.lnum; 15555 match_pos->col = curwin->w_cursor.col + 1; 15556 } 15557 15558 /* If 'n' flag is used or search failed: restore cursor position. */ 15559 if ((flags & SP_NOMOVE) || retval == 0) 15560 curwin->w_cursor = save_cursor; 15561 15562theend: 15563 vim_free(pat2); 15564 vim_free(pat3); 15565 if (p_cpo == empty_option) 15566 p_cpo = save_cpo; 15567 else 15568 /* Darn, evaluating the {skip} expression changed the value. */ 15569 free_string_option(save_cpo); 15570 15571 return retval; 15572} 15573 15574/* 15575 * "searchpos()" function 15576 */ 15577 static void 15578f_searchpos(argvars, rettv) 15579 typval_T *argvars; 15580 typval_T *rettv; 15581{ 15582 pos_T match_pos; 15583 int lnum = 0; 15584 int col = 0; 15585 int n; 15586 int flags = 0; 15587 15588 if (rettv_list_alloc(rettv) == FAIL) 15589 return; 15590 15591 n = search_cmn(argvars, &match_pos, &flags); 15592 if (n > 0) 15593 { 15594 lnum = match_pos.lnum; 15595 col = match_pos.col; 15596 } 15597 15598 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 15599 list_append_number(rettv->vval.v_list, (varnumber_T)col); 15600 if (flags & SP_SUBPAT) 15601 list_append_number(rettv->vval.v_list, (varnumber_T)n); 15602} 15603 15604 15605 static void 15606f_server2client(argvars, rettv) 15607 typval_T *argvars UNUSED; 15608 typval_T *rettv; 15609{ 15610#ifdef FEAT_CLIENTSERVER 15611 char_u buf[NUMBUFLEN]; 15612 char_u *server = get_tv_string_chk(&argvars[0]); 15613 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 15614 15615 rettv->vval.v_number = -1; 15616 if (server == NULL || reply == NULL) 15617 return; 15618 if (check_restricted() || check_secure()) 15619 return; 15620# ifdef FEAT_X11 15621 if (check_connection() == FAIL) 15622 return; 15623# endif 15624 15625 if (serverSendReply(server, reply) < 0) 15626 { 15627 EMSG(_("E258: Unable to send to client")); 15628 return; 15629 } 15630 rettv->vval.v_number = 0; 15631#else 15632 rettv->vval.v_number = -1; 15633#endif 15634} 15635 15636 static void 15637f_serverlist(argvars, rettv) 15638 typval_T *argvars UNUSED; 15639 typval_T *rettv; 15640{ 15641 char_u *r = NULL; 15642 15643#ifdef FEAT_CLIENTSERVER 15644# ifdef WIN32 15645 r = serverGetVimNames(); 15646# else 15647 make_connection(); 15648 if (X_DISPLAY != NULL) 15649 r = serverGetVimNames(X_DISPLAY); 15650# endif 15651#endif 15652 rettv->v_type = VAR_STRING; 15653 rettv->vval.v_string = r; 15654} 15655 15656/* 15657 * "setbufvar()" function 15658 */ 15659 static void 15660f_setbufvar(argvars, rettv) 15661 typval_T *argvars; 15662 typval_T *rettv UNUSED; 15663{ 15664 buf_T *buf; 15665 aco_save_T aco; 15666 char_u *varname, *bufvarname; 15667 typval_T *varp; 15668 char_u nbuf[NUMBUFLEN]; 15669 15670 if (check_restricted() || check_secure()) 15671 return; 15672 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 15673 varname = get_tv_string_chk(&argvars[1]); 15674 buf = get_buf_tv(&argvars[0]); 15675 varp = &argvars[2]; 15676 15677 if (buf != NULL && varname != NULL && varp != NULL) 15678 { 15679 /* set curbuf to be our buf, temporarily */ 15680 aucmd_prepbuf(&aco, buf); 15681 15682 if (*varname == '&') 15683 { 15684 long numval; 15685 char_u *strval; 15686 int error = FALSE; 15687 15688 ++varname; 15689 numval = get_tv_number_chk(varp, &error); 15690 strval = get_tv_string_buf_chk(varp, nbuf); 15691 if (!error && strval != NULL) 15692 set_option_value(varname, numval, strval, OPT_LOCAL); 15693 } 15694 else 15695 { 15696 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 15697 if (bufvarname != NULL) 15698 { 15699 STRCPY(bufvarname, "b:"); 15700 STRCPY(bufvarname + 2, varname); 15701 set_var(bufvarname, varp, TRUE); 15702 vim_free(bufvarname); 15703 } 15704 } 15705 15706 /* reset notion of buffer */ 15707 aucmd_restbuf(&aco); 15708 } 15709} 15710 15711/* 15712 * "setcmdpos()" function 15713 */ 15714 static void 15715f_setcmdpos(argvars, rettv) 15716 typval_T *argvars; 15717 typval_T *rettv; 15718{ 15719 int pos = (int)get_tv_number(&argvars[0]) - 1; 15720 15721 if (pos >= 0) 15722 rettv->vval.v_number = set_cmdline_pos(pos); 15723} 15724 15725/* 15726 * "setline()" function 15727 */ 15728 static void 15729f_setline(argvars, rettv) 15730 typval_T *argvars; 15731 typval_T *rettv; 15732{ 15733 linenr_T lnum; 15734 char_u *line = NULL; 15735 list_T *l = NULL; 15736 listitem_T *li = NULL; 15737 long added = 0; 15738 linenr_T lcount = curbuf->b_ml.ml_line_count; 15739 15740 lnum = get_tv_lnum(&argvars[0]); 15741 if (argvars[1].v_type == VAR_LIST) 15742 { 15743 l = argvars[1].vval.v_list; 15744 li = l->lv_first; 15745 } 15746 else 15747 line = get_tv_string_chk(&argvars[1]); 15748 15749 /* default result is zero == OK */ 15750 for (;;) 15751 { 15752 if (l != NULL) 15753 { 15754 /* list argument, get next string */ 15755 if (li == NULL) 15756 break; 15757 line = get_tv_string_chk(&li->li_tv); 15758 li = li->li_next; 15759 } 15760 15761 rettv->vval.v_number = 1; /* FAIL */ 15762 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 15763 break; 15764 if (lnum <= curbuf->b_ml.ml_line_count) 15765 { 15766 /* existing line, replace it */ 15767 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 15768 { 15769 changed_bytes(lnum, 0); 15770 if (lnum == curwin->w_cursor.lnum) 15771 check_cursor_col(); 15772 rettv->vval.v_number = 0; /* OK */ 15773 } 15774 } 15775 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 15776 { 15777 /* lnum is one past the last line, append the line */ 15778 ++added; 15779 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 15780 rettv->vval.v_number = 0; /* OK */ 15781 } 15782 15783 if (l == NULL) /* only one string argument */ 15784 break; 15785 ++lnum; 15786 } 15787 15788 if (added > 0) 15789 appended_lines_mark(lcount, added); 15790} 15791 15792static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)); 15793 15794/* 15795 * Used by "setqflist()" and "setloclist()" functions 15796 */ 15797 static void 15798set_qf_ll_list(wp, list_arg, action_arg, rettv) 15799 win_T *wp UNUSED; 15800 typval_T *list_arg UNUSED; 15801 typval_T *action_arg UNUSED; 15802 typval_T *rettv; 15803{ 15804#ifdef FEAT_QUICKFIX 15805 char_u *act; 15806 int action = ' '; 15807#endif 15808 15809 rettv->vval.v_number = -1; 15810 15811#ifdef FEAT_QUICKFIX 15812 if (list_arg->v_type != VAR_LIST) 15813 EMSG(_(e_listreq)); 15814 else 15815 { 15816 list_T *l = list_arg->vval.v_list; 15817 15818 if (action_arg->v_type == VAR_STRING) 15819 { 15820 act = get_tv_string_chk(action_arg); 15821 if (act == NULL) 15822 return; /* type error; errmsg already given */ 15823 if (*act == 'a' || *act == 'r') 15824 action = *act; 15825 } 15826 15827 if (l != NULL && set_errorlist(wp, l, action, NULL) == OK) 15828 rettv->vval.v_number = 0; 15829 } 15830#endif 15831} 15832 15833/* 15834 * "setloclist()" function 15835 */ 15836 static void 15837f_setloclist(argvars, rettv) 15838 typval_T *argvars; 15839 typval_T *rettv; 15840{ 15841 win_T *win; 15842 15843 rettv->vval.v_number = -1; 15844 15845 win = find_win_by_nr(&argvars[0], NULL); 15846 if (win != NULL) 15847 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 15848} 15849 15850/* 15851 * "setmatches()" function 15852 */ 15853 static void 15854f_setmatches(argvars, rettv) 15855 typval_T *argvars; 15856 typval_T *rettv; 15857{ 15858#ifdef FEAT_SEARCH_EXTRA 15859 list_T *l; 15860 listitem_T *li; 15861 dict_T *d; 15862 15863 rettv->vval.v_number = -1; 15864 if (argvars[0].v_type != VAR_LIST) 15865 { 15866 EMSG(_(e_listreq)); 15867 return; 15868 } 15869 if ((l = argvars[0].vval.v_list) != NULL) 15870 { 15871 15872 /* To some extent make sure that we are dealing with a list from 15873 * "getmatches()". */ 15874 li = l->lv_first; 15875 while (li != NULL) 15876 { 15877 if (li->li_tv.v_type != VAR_DICT 15878 || (d = li->li_tv.vval.v_dict) == NULL) 15879 { 15880 EMSG(_(e_invarg)); 15881 return; 15882 } 15883 if (!(dict_find(d, (char_u *)"group", -1) != NULL 15884 && dict_find(d, (char_u *)"pattern", -1) != NULL 15885 && dict_find(d, (char_u *)"priority", -1) != NULL 15886 && dict_find(d, (char_u *)"id", -1) != NULL)) 15887 { 15888 EMSG(_(e_invarg)); 15889 return; 15890 } 15891 li = li->li_next; 15892 } 15893 15894 clear_matches(curwin); 15895 li = l->lv_first; 15896 while (li != NULL) 15897 { 15898 d = li->li_tv.vval.v_dict; 15899 match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE), 15900 get_dict_string(d, (char_u *)"pattern", FALSE), 15901 (int)get_dict_number(d, (char_u *)"priority"), 15902 (int)get_dict_number(d, (char_u *)"id")); 15903 li = li->li_next; 15904 } 15905 rettv->vval.v_number = 0; 15906 } 15907#endif 15908} 15909 15910/* 15911 * "setpos()" function 15912 */ 15913 static void 15914f_setpos(argvars, rettv) 15915 typval_T *argvars; 15916 typval_T *rettv; 15917{ 15918 pos_T pos; 15919 int fnum; 15920 char_u *name; 15921 15922 rettv->vval.v_number = -1; 15923 name = get_tv_string_chk(argvars); 15924 if (name != NULL) 15925 { 15926 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 15927 { 15928 if (--pos.col < 0) 15929 pos.col = 0; 15930 if (name[0] == '.' && name[1] == NUL) 15931 { 15932 /* set cursor */ 15933 if (fnum == curbuf->b_fnum) 15934 { 15935 curwin->w_cursor = pos; 15936 check_cursor(); 15937 rettv->vval.v_number = 0; 15938 } 15939 else 15940 EMSG(_(e_invarg)); 15941 } 15942 else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) 15943 { 15944 /* set mark */ 15945 if (setmark_pos(name[1], &pos, fnum) == OK) 15946 rettv->vval.v_number = 0; 15947 } 15948 else 15949 EMSG(_(e_invarg)); 15950 } 15951 } 15952} 15953 15954/* 15955 * "setqflist()" function 15956 */ 15957 static void 15958f_setqflist(argvars, rettv) 15959 typval_T *argvars; 15960 typval_T *rettv; 15961{ 15962 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 15963} 15964 15965/* 15966 * "setreg()" function 15967 */ 15968 static void 15969f_setreg(argvars, rettv) 15970 typval_T *argvars; 15971 typval_T *rettv; 15972{ 15973 int regname; 15974 char_u *strregname; 15975 char_u *stropt; 15976 char_u *strval; 15977 int append; 15978 char_u yank_type; 15979 long block_len; 15980 15981 block_len = -1; 15982 yank_type = MAUTO; 15983 append = FALSE; 15984 15985 strregname = get_tv_string_chk(argvars); 15986 rettv->vval.v_number = 1; /* FAIL is default */ 15987 15988 if (strregname == NULL) 15989 return; /* type error; errmsg already given */ 15990 regname = *strregname; 15991 if (regname == 0 || regname == '@') 15992 regname = '"'; 15993 else if (regname == '=') 15994 return; 15995 15996 if (argvars[2].v_type != VAR_UNKNOWN) 15997 { 15998 stropt = get_tv_string_chk(&argvars[2]); 15999 if (stropt == NULL) 16000 return; /* type error */ 16001 for (; *stropt != NUL; ++stropt) 16002 switch (*stropt) 16003 { 16004 case 'a': case 'A': /* append */ 16005 append = TRUE; 16006 break; 16007 case 'v': case 'c': /* character-wise selection */ 16008 yank_type = MCHAR; 16009 break; 16010 case 'V': case 'l': /* line-wise selection */ 16011 yank_type = MLINE; 16012 break; 16013#ifdef FEAT_VISUAL 16014 case 'b': case Ctrl_V: /* block-wise selection */ 16015 yank_type = MBLOCK; 16016 if (VIM_ISDIGIT(stropt[1])) 16017 { 16018 ++stropt; 16019 block_len = getdigits(&stropt) - 1; 16020 --stropt; 16021 } 16022 break; 16023#endif 16024 } 16025 } 16026 16027 strval = get_tv_string_chk(&argvars[1]); 16028 if (strval != NULL) 16029 write_reg_contents_ex(regname, strval, -1, 16030 append, yank_type, block_len); 16031 rettv->vval.v_number = 0; 16032} 16033 16034/* 16035 * "settabvar()" function 16036 */ 16037 static void 16038f_settabvar(argvars, rettv) 16039 typval_T *argvars; 16040 typval_T *rettv; 16041{ 16042 tabpage_T *save_curtab; 16043 char_u *varname, *tabvarname; 16044 typval_T *varp; 16045 tabpage_T *tp; 16046 16047 rettv->vval.v_number = 0; 16048 16049 if (check_restricted() || check_secure()) 16050 return; 16051 16052 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 16053 varname = get_tv_string_chk(&argvars[1]); 16054 varp = &argvars[2]; 16055 16056 if (tp != NULL && varname != NULL && varp != NULL) 16057 { 16058 save_curtab = curtab; 16059 goto_tabpage_tp(tp); 16060 16061 tabvarname = alloc((unsigned)STRLEN(varname) + 3); 16062 if (tabvarname != NULL) 16063 { 16064 STRCPY(tabvarname, "t:"); 16065 STRCPY(tabvarname + 2, varname); 16066 set_var(tabvarname, varp, TRUE); 16067 vim_free(tabvarname); 16068 } 16069 16070 /* Restore current tabpage */ 16071 if (valid_tabpage(save_curtab)) 16072 goto_tabpage_tp(save_curtab); 16073 } 16074} 16075 16076/* 16077 * "settabwinvar()" function 16078 */ 16079 static void 16080f_settabwinvar(argvars, rettv) 16081 typval_T *argvars; 16082 typval_T *rettv; 16083{ 16084 setwinvar(argvars, rettv, 1); 16085} 16086 16087/* 16088 * "setwinvar()" function 16089 */ 16090 static void 16091f_setwinvar(argvars, rettv) 16092 typval_T *argvars; 16093 typval_T *rettv; 16094{ 16095 setwinvar(argvars, rettv, 0); 16096} 16097 16098/* 16099 * "setwinvar()" and "settabwinvar()" functions 16100 */ 16101 static void 16102setwinvar(argvars, rettv, off) 16103 typval_T *argvars; 16104 typval_T *rettv UNUSED; 16105 int off; 16106{ 16107 win_T *win; 16108#ifdef FEAT_WINDOWS 16109 win_T *save_curwin; 16110 tabpage_T *save_curtab; 16111#endif 16112 char_u *varname, *winvarname; 16113 typval_T *varp; 16114 char_u nbuf[NUMBUFLEN]; 16115 tabpage_T *tp; 16116 16117 if (check_restricted() || check_secure()) 16118 return; 16119 16120#ifdef FEAT_WINDOWS 16121 if (off == 1) 16122 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 16123 else 16124 tp = curtab; 16125#endif 16126 win = find_win_by_nr(&argvars[off], tp); 16127 varname = get_tv_string_chk(&argvars[off + 1]); 16128 varp = &argvars[off + 2]; 16129 16130 if (win != NULL && varname != NULL && varp != NULL) 16131 { 16132#ifdef FEAT_WINDOWS 16133 /* set curwin to be our win, temporarily */ 16134 save_curwin = curwin; 16135 save_curtab = curtab; 16136 goto_tabpage_tp(tp); 16137 if (!win_valid(win)) 16138 return; 16139 curwin = win; 16140 curbuf = curwin->w_buffer; 16141#endif 16142 16143 if (*varname == '&') 16144 { 16145 long numval; 16146 char_u *strval; 16147 int error = FALSE; 16148 16149 ++varname; 16150 numval = get_tv_number_chk(varp, &error); 16151 strval = get_tv_string_buf_chk(varp, nbuf); 16152 if (!error && strval != NULL) 16153 set_option_value(varname, numval, strval, OPT_LOCAL); 16154 } 16155 else 16156 { 16157 winvarname = alloc((unsigned)STRLEN(varname) + 3); 16158 if (winvarname != NULL) 16159 { 16160 STRCPY(winvarname, "w:"); 16161 STRCPY(winvarname + 2, varname); 16162 set_var(winvarname, varp, TRUE); 16163 vim_free(winvarname); 16164 } 16165 } 16166 16167#ifdef FEAT_WINDOWS 16168 /* Restore current tabpage and window, if still valid (autocomands can 16169 * make them invalid). */ 16170 if (valid_tabpage(save_curtab)) 16171 goto_tabpage_tp(save_curtab); 16172 if (win_valid(save_curwin)) 16173 { 16174 curwin = save_curwin; 16175 curbuf = curwin->w_buffer; 16176 } 16177#endif 16178 } 16179} 16180 16181/* 16182 * "shellescape({string})" function 16183 */ 16184 static void 16185f_shellescape(argvars, rettv) 16186 typval_T *argvars; 16187 typval_T *rettv; 16188{ 16189 rettv->vval.v_string = vim_strsave_shellescape( 16190 get_tv_string(&argvars[0]), non_zero_arg(&argvars[1])); 16191 rettv->v_type = VAR_STRING; 16192} 16193 16194/* 16195 * "simplify()" function 16196 */ 16197 static void 16198f_simplify(argvars, rettv) 16199 typval_T *argvars; 16200 typval_T *rettv; 16201{ 16202 char_u *p; 16203 16204 p = get_tv_string(&argvars[0]); 16205 rettv->vval.v_string = vim_strsave(p); 16206 simplify_filename(rettv->vval.v_string); /* simplify in place */ 16207 rettv->v_type = VAR_STRING; 16208} 16209 16210#ifdef FEAT_FLOAT 16211/* 16212 * "sin()" function 16213 */ 16214 static void 16215f_sin(argvars, rettv) 16216 typval_T *argvars; 16217 typval_T *rettv; 16218{ 16219 float_T f; 16220 16221 rettv->v_type = VAR_FLOAT; 16222 if (get_float_arg(argvars, &f) == OK) 16223 rettv->vval.v_float = sin(f); 16224 else 16225 rettv->vval.v_float = 0.0; 16226} 16227 16228/* 16229 * "sinh()" function 16230 */ 16231 static void 16232f_sinh(argvars, rettv) 16233 typval_T *argvars; 16234 typval_T *rettv; 16235{ 16236 float_T f; 16237 16238 rettv->v_type = VAR_FLOAT; 16239 if (get_float_arg(argvars, &f) == OK) 16240 rettv->vval.v_float = sinh(f); 16241 else 16242 rettv->vval.v_float = 0.0; 16243} 16244#endif 16245 16246static int 16247#ifdef __BORLANDC__ 16248 _RTLENTRYF 16249#endif 16250 item_compare __ARGS((const void *s1, const void *s2)); 16251static int 16252#ifdef __BORLANDC__ 16253 _RTLENTRYF 16254#endif 16255 item_compare2 __ARGS((const void *s1, const void *s2)); 16256 16257static int item_compare_ic; 16258static char_u *item_compare_func; 16259static int item_compare_func_err; 16260#define ITEM_COMPARE_FAIL 999 16261 16262/* 16263 * Compare functions for f_sort() below. 16264 */ 16265 static int 16266#ifdef __BORLANDC__ 16267_RTLENTRYF 16268#endif 16269item_compare(s1, s2) 16270 const void *s1; 16271 const void *s2; 16272{ 16273 char_u *p1, *p2; 16274 char_u *tofree1, *tofree2; 16275 int res; 16276 char_u numbuf1[NUMBUFLEN]; 16277 char_u numbuf2[NUMBUFLEN]; 16278 16279 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 16280 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 16281 if (p1 == NULL) 16282 p1 = (char_u *)""; 16283 if (p2 == NULL) 16284 p2 = (char_u *)""; 16285 if (item_compare_ic) 16286 res = STRICMP(p1, p2); 16287 else 16288 res = STRCMP(p1, p2); 16289 vim_free(tofree1); 16290 vim_free(tofree2); 16291 return res; 16292} 16293 16294 static int 16295#ifdef __BORLANDC__ 16296_RTLENTRYF 16297#endif 16298item_compare2(s1, s2) 16299 const void *s1; 16300 const void *s2; 16301{ 16302 int res; 16303 typval_T rettv; 16304 typval_T argv[3]; 16305 int dummy; 16306 16307 /* shortcut after failure in previous call; compare all items equal */ 16308 if (item_compare_func_err) 16309 return 0; 16310 16311 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 16312 * in the copy without changing the original list items. */ 16313 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 16314 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 16315 16316 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 16317 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 16318 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 16319 clear_tv(&argv[0]); 16320 clear_tv(&argv[1]); 16321 16322 if (res == FAIL) 16323 res = ITEM_COMPARE_FAIL; 16324 else 16325 res = get_tv_number_chk(&rettv, &item_compare_func_err); 16326 if (item_compare_func_err) 16327 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 16328 clear_tv(&rettv); 16329 return res; 16330} 16331 16332/* 16333 * "sort({list})" function 16334 */ 16335 static void 16336f_sort(argvars, rettv) 16337 typval_T *argvars; 16338 typval_T *rettv; 16339{ 16340 list_T *l; 16341 listitem_T *li; 16342 listitem_T **ptrs; 16343 long len; 16344 long i; 16345 16346 if (argvars[0].v_type != VAR_LIST) 16347 EMSG2(_(e_listarg), "sort()"); 16348 else 16349 { 16350 l = argvars[0].vval.v_list; 16351 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 16352 return; 16353 rettv->vval.v_list = l; 16354 rettv->v_type = VAR_LIST; 16355 ++l->lv_refcount; 16356 16357 len = list_len(l); 16358 if (len <= 1) 16359 return; /* short list sorts pretty quickly */ 16360 16361 item_compare_ic = FALSE; 16362 item_compare_func = NULL; 16363 if (argvars[1].v_type != VAR_UNKNOWN) 16364 { 16365 if (argvars[1].v_type == VAR_FUNC) 16366 item_compare_func = argvars[1].vval.v_string; 16367 else 16368 { 16369 int error = FALSE; 16370 16371 i = get_tv_number_chk(&argvars[1], &error); 16372 if (error) 16373 return; /* type error; errmsg already given */ 16374 if (i == 1) 16375 item_compare_ic = TRUE; 16376 else 16377 item_compare_func = get_tv_string(&argvars[1]); 16378 } 16379 } 16380 16381 /* Make an array with each entry pointing to an item in the List. */ 16382 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 16383 if (ptrs == NULL) 16384 return; 16385 i = 0; 16386 for (li = l->lv_first; li != NULL; li = li->li_next) 16387 ptrs[i++] = li; 16388 16389 item_compare_func_err = FALSE; 16390 /* test the compare function */ 16391 if (item_compare_func != NULL 16392 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 16393 == ITEM_COMPARE_FAIL) 16394 EMSG(_("E702: Sort compare function failed")); 16395 else 16396 { 16397 /* Sort the array with item pointers. */ 16398 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 16399 item_compare_func == NULL ? item_compare : item_compare2); 16400 16401 if (!item_compare_func_err) 16402 { 16403 /* Clear the List and append the items in the sorted order. */ 16404 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 16405 l->lv_len = 0; 16406 for (i = 0; i < len; ++i) 16407 list_append(l, ptrs[i]); 16408 } 16409 } 16410 16411 vim_free(ptrs); 16412 } 16413} 16414 16415/* 16416 * "soundfold({word})" function 16417 */ 16418 static void 16419f_soundfold(argvars, rettv) 16420 typval_T *argvars; 16421 typval_T *rettv; 16422{ 16423 char_u *s; 16424 16425 rettv->v_type = VAR_STRING; 16426 s = get_tv_string(&argvars[0]); 16427#ifdef FEAT_SPELL 16428 rettv->vval.v_string = eval_soundfold(s); 16429#else 16430 rettv->vval.v_string = vim_strsave(s); 16431#endif 16432} 16433 16434/* 16435 * "spellbadword()" function 16436 */ 16437 static void 16438f_spellbadword(argvars, rettv) 16439 typval_T *argvars UNUSED; 16440 typval_T *rettv; 16441{ 16442 char_u *word = (char_u *)""; 16443 hlf_T attr = HLF_COUNT; 16444 int len = 0; 16445 16446 if (rettv_list_alloc(rettv) == FAIL) 16447 return; 16448 16449#ifdef FEAT_SPELL 16450 if (argvars[0].v_type == VAR_UNKNOWN) 16451 { 16452 /* Find the start and length of the badly spelled word. */ 16453 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 16454 if (len != 0) 16455 word = ml_get_cursor(); 16456 } 16457 else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) 16458 { 16459 char_u *str = get_tv_string_chk(&argvars[0]); 16460 int capcol = -1; 16461 16462 if (str != NULL) 16463 { 16464 /* Check the argument for spelling. */ 16465 while (*str != NUL) 16466 { 16467 len = spell_check(curwin, str, &attr, &capcol, FALSE); 16468 if (attr != HLF_COUNT) 16469 { 16470 word = str; 16471 break; 16472 } 16473 str += len; 16474 } 16475 } 16476 } 16477#endif 16478 16479 list_append_string(rettv->vval.v_list, word, len); 16480 list_append_string(rettv->vval.v_list, (char_u *)( 16481 attr == HLF_SPB ? "bad" : 16482 attr == HLF_SPR ? "rare" : 16483 attr == HLF_SPL ? "local" : 16484 attr == HLF_SPC ? "caps" : 16485 ""), -1); 16486} 16487 16488/* 16489 * "spellsuggest()" function 16490 */ 16491 static void 16492f_spellsuggest(argvars, rettv) 16493 typval_T *argvars UNUSED; 16494 typval_T *rettv; 16495{ 16496#ifdef FEAT_SPELL 16497 char_u *str; 16498 int typeerr = FALSE; 16499 int maxcount; 16500 garray_T ga; 16501 int i; 16502 listitem_T *li; 16503 int need_capital = FALSE; 16504#endif 16505 16506 if (rettv_list_alloc(rettv) == FAIL) 16507 return; 16508 16509#ifdef FEAT_SPELL 16510 if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) 16511 { 16512 str = get_tv_string(&argvars[0]); 16513 if (argvars[1].v_type != VAR_UNKNOWN) 16514 { 16515 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 16516 if (maxcount <= 0) 16517 return; 16518 if (argvars[2].v_type != VAR_UNKNOWN) 16519 { 16520 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 16521 if (typeerr) 16522 return; 16523 } 16524 } 16525 else 16526 maxcount = 25; 16527 16528 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 16529 16530 for (i = 0; i < ga.ga_len; ++i) 16531 { 16532 str = ((char_u **)ga.ga_data)[i]; 16533 16534 li = listitem_alloc(); 16535 if (li == NULL) 16536 vim_free(str); 16537 else 16538 { 16539 li->li_tv.v_type = VAR_STRING; 16540 li->li_tv.v_lock = 0; 16541 li->li_tv.vval.v_string = str; 16542 list_append(rettv->vval.v_list, li); 16543 } 16544 } 16545 ga_clear(&ga); 16546 } 16547#endif 16548} 16549 16550 static void 16551f_split(argvars, rettv) 16552 typval_T *argvars; 16553 typval_T *rettv; 16554{ 16555 char_u *str; 16556 char_u *end; 16557 char_u *pat = NULL; 16558 regmatch_T regmatch; 16559 char_u patbuf[NUMBUFLEN]; 16560 char_u *save_cpo; 16561 int match; 16562 colnr_T col = 0; 16563 int keepempty = FALSE; 16564 int typeerr = FALSE; 16565 16566 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 16567 save_cpo = p_cpo; 16568 p_cpo = (char_u *)""; 16569 16570 str = get_tv_string(&argvars[0]); 16571 if (argvars[1].v_type != VAR_UNKNOWN) 16572 { 16573 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 16574 if (pat == NULL) 16575 typeerr = TRUE; 16576 if (argvars[2].v_type != VAR_UNKNOWN) 16577 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 16578 } 16579 if (pat == NULL || *pat == NUL) 16580 pat = (char_u *)"[\\x01- ]\\+"; 16581 16582 if (rettv_list_alloc(rettv) == FAIL) 16583 return; 16584 if (typeerr) 16585 return; 16586 16587 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 16588 if (regmatch.regprog != NULL) 16589 { 16590 regmatch.rm_ic = FALSE; 16591 while (*str != NUL || keepempty) 16592 { 16593 if (*str == NUL) 16594 match = FALSE; /* empty item at the end */ 16595 else 16596 match = vim_regexec_nl(®match, str, col); 16597 if (match) 16598 end = regmatch.startp[0]; 16599 else 16600 end = str + STRLEN(str); 16601 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 16602 && *str != NUL && match && end < regmatch.endp[0])) 16603 { 16604 if (list_append_string(rettv->vval.v_list, str, 16605 (int)(end - str)) == FAIL) 16606 break; 16607 } 16608 if (!match) 16609 break; 16610 /* Advance to just after the match. */ 16611 if (regmatch.endp[0] > str) 16612 col = 0; 16613 else 16614 { 16615 /* Don't get stuck at the same match. */ 16616#ifdef FEAT_MBYTE 16617 col = (*mb_ptr2len)(regmatch.endp[0]); 16618#else 16619 col = 1; 16620#endif 16621 } 16622 str = regmatch.endp[0]; 16623 } 16624 16625 vim_free(regmatch.regprog); 16626 } 16627 16628 p_cpo = save_cpo; 16629} 16630 16631#ifdef FEAT_FLOAT 16632/* 16633 * "sqrt()" function 16634 */ 16635 static void 16636f_sqrt(argvars, rettv) 16637 typval_T *argvars; 16638 typval_T *rettv; 16639{ 16640 float_T f; 16641 16642 rettv->v_type = VAR_FLOAT; 16643 if (get_float_arg(argvars, &f) == OK) 16644 rettv->vval.v_float = sqrt(f); 16645 else 16646 rettv->vval.v_float = 0.0; 16647} 16648 16649/* 16650 * "str2float()" function 16651 */ 16652 static void 16653f_str2float(argvars, rettv) 16654 typval_T *argvars; 16655 typval_T *rettv; 16656{ 16657 char_u *p = skipwhite(get_tv_string(&argvars[0])); 16658 16659 if (*p == '+') 16660 p = skipwhite(p + 1); 16661 (void)string2float(p, &rettv->vval.v_float); 16662 rettv->v_type = VAR_FLOAT; 16663} 16664#endif 16665 16666/* 16667 * "str2nr()" function 16668 */ 16669 static void 16670f_str2nr(argvars, rettv) 16671 typval_T *argvars; 16672 typval_T *rettv; 16673{ 16674 int base = 10; 16675 char_u *p; 16676 long n; 16677 16678 if (argvars[1].v_type != VAR_UNKNOWN) 16679 { 16680 base = get_tv_number(&argvars[1]); 16681 if (base != 8 && base != 10 && base != 16) 16682 { 16683 EMSG(_(e_invarg)); 16684 return; 16685 } 16686 } 16687 16688 p = skipwhite(get_tv_string(&argvars[0])); 16689 if (*p == '+') 16690 p = skipwhite(p + 1); 16691 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 16692 rettv->vval.v_number = n; 16693} 16694 16695#ifdef HAVE_STRFTIME 16696/* 16697 * "strftime({format}[, {time}])" function 16698 */ 16699 static void 16700f_strftime(argvars, rettv) 16701 typval_T *argvars; 16702 typval_T *rettv; 16703{ 16704 char_u result_buf[256]; 16705 struct tm *curtime; 16706 time_t seconds; 16707 char_u *p; 16708 16709 rettv->v_type = VAR_STRING; 16710 16711 p = get_tv_string(&argvars[0]); 16712 if (argvars[1].v_type == VAR_UNKNOWN) 16713 seconds = time(NULL); 16714 else 16715 seconds = (time_t)get_tv_number(&argvars[1]); 16716 curtime = localtime(&seconds); 16717 /* MSVC returns NULL for an invalid value of seconds. */ 16718 if (curtime == NULL) 16719 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 16720 else 16721 { 16722# ifdef FEAT_MBYTE 16723 vimconv_T conv; 16724 char_u *enc; 16725 16726 conv.vc_type = CONV_NONE; 16727 enc = enc_locale(); 16728 convert_setup(&conv, p_enc, enc); 16729 if (conv.vc_type != CONV_NONE) 16730 p = string_convert(&conv, p, NULL); 16731# endif 16732 if (p != NULL) 16733 (void)strftime((char *)result_buf, sizeof(result_buf), 16734 (char *)p, curtime); 16735 else 16736 result_buf[0] = NUL; 16737 16738# ifdef FEAT_MBYTE 16739 if (conv.vc_type != CONV_NONE) 16740 vim_free(p); 16741 convert_setup(&conv, enc, p_enc); 16742 if (conv.vc_type != CONV_NONE) 16743 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 16744 else 16745# endif 16746 rettv->vval.v_string = vim_strsave(result_buf); 16747 16748# ifdef FEAT_MBYTE 16749 /* Release conversion descriptors */ 16750 convert_setup(&conv, NULL, NULL); 16751 vim_free(enc); 16752# endif 16753 } 16754} 16755#endif 16756 16757/* 16758 * "stridx()" function 16759 */ 16760 static void 16761f_stridx(argvars, rettv) 16762 typval_T *argvars; 16763 typval_T *rettv; 16764{ 16765 char_u buf[NUMBUFLEN]; 16766 char_u *needle; 16767 char_u *haystack; 16768 char_u *save_haystack; 16769 char_u *pos; 16770 int start_idx; 16771 16772 needle = get_tv_string_chk(&argvars[1]); 16773 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 16774 rettv->vval.v_number = -1; 16775 if (needle == NULL || haystack == NULL) 16776 return; /* type error; errmsg already given */ 16777 16778 if (argvars[2].v_type != VAR_UNKNOWN) 16779 { 16780 int error = FALSE; 16781 16782 start_idx = get_tv_number_chk(&argvars[2], &error); 16783 if (error || start_idx >= (int)STRLEN(haystack)) 16784 return; 16785 if (start_idx >= 0) 16786 haystack += start_idx; 16787 } 16788 16789 pos = (char_u *)strstr((char *)haystack, (char *)needle); 16790 if (pos != NULL) 16791 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 16792} 16793 16794/* 16795 * "string()" function 16796 */ 16797 static void 16798f_string(argvars, rettv) 16799 typval_T *argvars; 16800 typval_T *rettv; 16801{ 16802 char_u *tofree; 16803 char_u numbuf[NUMBUFLEN]; 16804 16805 rettv->v_type = VAR_STRING; 16806 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 16807 /* Make a copy if we have a value but it's not in allocated memory. */ 16808 if (rettv->vval.v_string != NULL && tofree == NULL) 16809 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 16810} 16811 16812/* 16813 * "strlen()" function 16814 */ 16815 static void 16816f_strlen(argvars, rettv) 16817 typval_T *argvars; 16818 typval_T *rettv; 16819{ 16820 rettv->vval.v_number = (varnumber_T)(STRLEN( 16821 get_tv_string(&argvars[0]))); 16822} 16823 16824/* 16825 * "strchars()" function 16826 */ 16827 static void 16828f_strchars(argvars, rettv) 16829 typval_T *argvars; 16830 typval_T *rettv; 16831{ 16832 char_u *s = get_tv_string(&argvars[0]); 16833#ifdef FEAT_MBYTE 16834 varnumber_T len = 0; 16835 16836 while (*s != NUL) 16837 { 16838 mb_cptr2char_adv(&s); 16839 ++len; 16840 } 16841 rettv->vval.v_number = len; 16842#else 16843 rettv->vval.v_number = (varnumber_T)(STRLEN(s)); 16844#endif 16845} 16846 16847/* 16848 * "strdisplaywidth()" function 16849 */ 16850 static void 16851f_strdisplaywidth(argvars, rettv) 16852 typval_T *argvars; 16853 typval_T *rettv; 16854{ 16855 char_u *s = get_tv_string(&argvars[0]); 16856 int col = 0; 16857 16858 if (argvars[1].v_type != VAR_UNKNOWN) 16859 col = get_tv_number(&argvars[1]); 16860 16861 rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col); 16862} 16863 16864/* 16865 * "strwidth()" function 16866 */ 16867 static void 16868f_strwidth(argvars, rettv) 16869 typval_T *argvars; 16870 typval_T *rettv; 16871{ 16872 char_u *s = get_tv_string(&argvars[0]); 16873 16874 rettv->vval.v_number = (varnumber_T)( 16875#ifdef FEAT_MBYTE 16876 mb_string2cells(s, -1) 16877#else 16878 STRLEN(s) 16879#endif 16880 ); 16881} 16882 16883/* 16884 * "strpart()" function 16885 */ 16886 static void 16887f_strpart(argvars, rettv) 16888 typval_T *argvars; 16889 typval_T *rettv; 16890{ 16891 char_u *p; 16892 int n; 16893 int len; 16894 int slen; 16895 int error = FALSE; 16896 16897 p = get_tv_string(&argvars[0]); 16898 slen = (int)STRLEN(p); 16899 16900 n = get_tv_number_chk(&argvars[1], &error); 16901 if (error) 16902 len = 0; 16903 else if (argvars[2].v_type != VAR_UNKNOWN) 16904 len = get_tv_number(&argvars[2]); 16905 else 16906 len = slen - n; /* default len: all bytes that are available. */ 16907 16908 /* 16909 * Only return the overlap between the specified part and the actual 16910 * string. 16911 */ 16912 if (n < 0) 16913 { 16914 len += n; 16915 n = 0; 16916 } 16917 else if (n > slen) 16918 n = slen; 16919 if (len < 0) 16920 len = 0; 16921 else if (n + len > slen) 16922 len = slen - n; 16923 16924 rettv->v_type = VAR_STRING; 16925 rettv->vval.v_string = vim_strnsave(p + n, len); 16926} 16927 16928/* 16929 * "strridx()" function 16930 */ 16931 static void 16932f_strridx(argvars, rettv) 16933 typval_T *argvars; 16934 typval_T *rettv; 16935{ 16936 char_u buf[NUMBUFLEN]; 16937 char_u *needle; 16938 char_u *haystack; 16939 char_u *rest; 16940 char_u *lastmatch = NULL; 16941 int haystack_len, end_idx; 16942 16943 needle = get_tv_string_chk(&argvars[1]); 16944 haystack = get_tv_string_buf_chk(&argvars[0], buf); 16945 16946 rettv->vval.v_number = -1; 16947 if (needle == NULL || haystack == NULL) 16948 return; /* type error; errmsg already given */ 16949 16950 haystack_len = (int)STRLEN(haystack); 16951 if (argvars[2].v_type != VAR_UNKNOWN) 16952 { 16953 /* Third argument: upper limit for index */ 16954 end_idx = get_tv_number_chk(&argvars[2], NULL); 16955 if (end_idx < 0) 16956 return; /* can never find a match */ 16957 } 16958 else 16959 end_idx = haystack_len; 16960 16961 if (*needle == NUL) 16962 { 16963 /* Empty string matches past the end. */ 16964 lastmatch = haystack + end_idx; 16965 } 16966 else 16967 { 16968 for (rest = haystack; *rest != '\0'; ++rest) 16969 { 16970 rest = (char_u *)strstr((char *)rest, (char *)needle); 16971 if (rest == NULL || rest > haystack + end_idx) 16972 break; 16973 lastmatch = rest; 16974 } 16975 } 16976 16977 if (lastmatch == NULL) 16978 rettv->vval.v_number = -1; 16979 else 16980 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 16981} 16982 16983/* 16984 * "strtrans()" function 16985 */ 16986 static void 16987f_strtrans(argvars, rettv) 16988 typval_T *argvars; 16989 typval_T *rettv; 16990{ 16991 rettv->v_type = VAR_STRING; 16992 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 16993} 16994 16995/* 16996 * "submatch()" function 16997 */ 16998 static void 16999f_submatch(argvars, rettv) 17000 typval_T *argvars; 17001 typval_T *rettv; 17002{ 17003 rettv->v_type = VAR_STRING; 17004 rettv->vval.v_string = 17005 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 17006} 17007 17008/* 17009 * "substitute()" function 17010 */ 17011 static void 17012f_substitute(argvars, rettv) 17013 typval_T *argvars; 17014 typval_T *rettv; 17015{ 17016 char_u patbuf[NUMBUFLEN]; 17017 char_u subbuf[NUMBUFLEN]; 17018 char_u flagsbuf[NUMBUFLEN]; 17019 17020 char_u *str = get_tv_string_chk(&argvars[0]); 17021 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 17022 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 17023 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 17024 17025 rettv->v_type = VAR_STRING; 17026 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 17027 rettv->vval.v_string = NULL; 17028 else 17029 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 17030} 17031 17032/* 17033 * "synID(lnum, col, trans)" function 17034 */ 17035 static void 17036f_synID(argvars, rettv) 17037 typval_T *argvars UNUSED; 17038 typval_T *rettv; 17039{ 17040 int id = 0; 17041#ifdef FEAT_SYN_HL 17042 long lnum; 17043 long col; 17044 int trans; 17045 int transerr = FALSE; 17046 17047 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17048 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17049 trans = get_tv_number_chk(&argvars[2], &transerr); 17050 17051 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17052 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 17053 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE); 17054#endif 17055 17056 rettv->vval.v_number = id; 17057} 17058 17059/* 17060 * "synIDattr(id, what [, mode])" function 17061 */ 17062 static void 17063f_synIDattr(argvars, rettv) 17064 typval_T *argvars UNUSED; 17065 typval_T *rettv; 17066{ 17067 char_u *p = NULL; 17068#ifdef FEAT_SYN_HL 17069 int id; 17070 char_u *what; 17071 char_u *mode; 17072 char_u modebuf[NUMBUFLEN]; 17073 int modec; 17074 17075 id = get_tv_number(&argvars[0]); 17076 what = get_tv_string(&argvars[1]); 17077 if (argvars[2].v_type != VAR_UNKNOWN) 17078 { 17079 mode = get_tv_string_buf(&argvars[2], modebuf); 17080 modec = TOLOWER_ASC(mode[0]); 17081 if (modec != 't' && modec != 'c' && modec != 'g') 17082 modec = 0; /* replace invalid with current */ 17083 } 17084 else 17085 { 17086#ifdef FEAT_GUI 17087 if (gui.in_use) 17088 modec = 'g'; 17089 else 17090#endif 17091 if (t_colors > 1) 17092 modec = 'c'; 17093 else 17094 modec = 't'; 17095 } 17096 17097 17098 switch (TOLOWER_ASC(what[0])) 17099 { 17100 case 'b': 17101 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 17102 p = highlight_color(id, what, modec); 17103 else /* bold */ 17104 p = highlight_has_attr(id, HL_BOLD, modec); 17105 break; 17106 17107 case 'f': /* fg[#] or font */ 17108 p = highlight_color(id, what, modec); 17109 break; 17110 17111 case 'i': 17112 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 17113 p = highlight_has_attr(id, HL_INVERSE, modec); 17114 else /* italic */ 17115 p = highlight_has_attr(id, HL_ITALIC, modec); 17116 break; 17117 17118 case 'n': /* name */ 17119 p = get_highlight_name(NULL, id - 1); 17120 break; 17121 17122 case 'r': /* reverse */ 17123 p = highlight_has_attr(id, HL_INVERSE, modec); 17124 break; 17125 17126 case 's': 17127 if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ 17128 p = highlight_color(id, what, modec); 17129 else /* standout */ 17130 p = highlight_has_attr(id, HL_STANDOUT, modec); 17131 break; 17132 17133 case 'u': 17134 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 17135 /* underline */ 17136 p = highlight_has_attr(id, HL_UNDERLINE, modec); 17137 else 17138 /* undercurl */ 17139 p = highlight_has_attr(id, HL_UNDERCURL, modec); 17140 break; 17141 } 17142 17143 if (p != NULL) 17144 p = vim_strsave(p); 17145#endif 17146 rettv->v_type = VAR_STRING; 17147 rettv->vval.v_string = p; 17148} 17149 17150/* 17151 * "synIDtrans(id)" function 17152 */ 17153 static void 17154f_synIDtrans(argvars, rettv) 17155 typval_T *argvars UNUSED; 17156 typval_T *rettv; 17157{ 17158 int id; 17159 17160#ifdef FEAT_SYN_HL 17161 id = get_tv_number(&argvars[0]); 17162 17163 if (id > 0) 17164 id = syn_get_final_id(id); 17165 else 17166#endif 17167 id = 0; 17168 17169 rettv->vval.v_number = id; 17170} 17171 17172/* 17173 * "synconcealed(lnum, col)" function 17174 */ 17175 static void 17176f_synconcealed(argvars, rettv) 17177 typval_T *argvars UNUSED; 17178 typval_T *rettv; 17179{ 17180#if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 17181 long lnum; 17182 long col; 17183 int syntax_flags = 0; 17184 int cchar; 17185 int matchid = 0; 17186 char_u str[NUMBUFLEN]; 17187#endif 17188 17189 rettv->v_type = VAR_LIST; 17190 rettv->vval.v_list = NULL; 17191 17192#if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL) 17193 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17194 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17195 17196 vim_memset(str, NUL, sizeof(str)); 17197 17198 if (rettv_list_alloc(rettv) != FAIL) 17199 { 17200 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17201 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 17202 && curwin->w_p_cole > 0) 17203 { 17204 (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE); 17205 syntax_flags = get_syntax_info(&matchid); 17206 17207 /* get the conceal character */ 17208 if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) 17209 { 17210 cchar = syn_get_sub_char(); 17211 if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) 17212 cchar = lcs_conceal; 17213 if (cchar != NUL) 17214 { 17215# ifdef FEAT_MBYTE 17216 if (has_mbyte) 17217 (*mb_char2bytes)(cchar, str); 17218 else 17219# endif 17220 str[0] = cchar; 17221 } 17222 } 17223 } 17224 17225 list_append_number(rettv->vval.v_list, 17226 (syntax_flags & HL_CONCEAL) != 0); 17227 /* -1 to auto-determine strlen */ 17228 list_append_string(rettv->vval.v_list, str, -1); 17229 list_append_number(rettv->vval.v_list, matchid); 17230 } 17231#endif 17232} 17233 17234/* 17235 * "synstack(lnum, col)" function 17236 */ 17237 static void 17238f_synstack(argvars, rettv) 17239 typval_T *argvars UNUSED; 17240 typval_T *rettv; 17241{ 17242#ifdef FEAT_SYN_HL 17243 long lnum; 17244 long col; 17245 int i; 17246 int id; 17247#endif 17248 17249 rettv->v_type = VAR_LIST; 17250 rettv->vval.v_list = NULL; 17251 17252#ifdef FEAT_SYN_HL 17253 lnum = get_tv_lnum(argvars); /* -1 on type error */ 17254 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 17255 17256 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 17257 && col >= 0 && col <= (long)STRLEN(ml_get(lnum)) 17258 && rettv_list_alloc(rettv) != FAIL) 17259 { 17260 (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); 17261 for (i = 0; ; ++i) 17262 { 17263 id = syn_get_stack_item(i); 17264 if (id < 0) 17265 break; 17266 if (list_append_number(rettv->vval.v_list, id) == FAIL) 17267 break; 17268 } 17269 } 17270#endif 17271} 17272 17273/* 17274 * "system()" function 17275 */ 17276 static void 17277f_system(argvars, rettv) 17278 typval_T *argvars; 17279 typval_T *rettv; 17280{ 17281 char_u *res = NULL; 17282 char_u *p; 17283 char_u *infile = NULL; 17284 char_u buf[NUMBUFLEN]; 17285 int err = FALSE; 17286 FILE *fd; 17287 17288 if (check_restricted() || check_secure()) 17289 goto done; 17290 17291 if (argvars[1].v_type != VAR_UNKNOWN) 17292 { 17293 /* 17294 * Write the string to a temp file, to be used for input of the shell 17295 * command. 17296 */ 17297 if ((infile = vim_tempname('i')) == NULL) 17298 { 17299 EMSG(_(e_notmp)); 17300 goto done; 17301 } 17302 17303 fd = mch_fopen((char *)infile, WRITEBIN); 17304 if (fd == NULL) 17305 { 17306 EMSG2(_(e_notopen), infile); 17307 goto done; 17308 } 17309 p = get_tv_string_buf_chk(&argvars[1], buf); 17310 if (p == NULL) 17311 { 17312 fclose(fd); 17313 goto done; /* type error; errmsg already given */ 17314 } 17315 if (fwrite(p, STRLEN(p), 1, fd) != 1) 17316 err = TRUE; 17317 if (fclose(fd) != 0) 17318 err = TRUE; 17319 if (err) 17320 { 17321 EMSG(_("E677: Error writing temp file")); 17322 goto done; 17323 } 17324 } 17325 17326 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 17327 SHELL_SILENT | SHELL_COOKED); 17328 17329#ifdef USE_CR 17330 /* translate <CR> into <NL> */ 17331 if (res != NULL) 17332 { 17333 char_u *s; 17334 17335 for (s = res; *s; ++s) 17336 { 17337 if (*s == CAR) 17338 *s = NL; 17339 } 17340 } 17341#else 17342# ifdef USE_CRNL 17343 /* translate <CR><NL> into <NL> */ 17344 if (res != NULL) 17345 { 17346 char_u *s, *d; 17347 17348 d = res; 17349 for (s = res; *s; ++s) 17350 { 17351 if (s[0] == CAR && s[1] == NL) 17352 ++s; 17353 *d++ = *s; 17354 } 17355 *d = NUL; 17356 } 17357# endif 17358#endif 17359 17360done: 17361 if (infile != NULL) 17362 { 17363 mch_remove(infile); 17364 vim_free(infile); 17365 } 17366 rettv->v_type = VAR_STRING; 17367 rettv->vval.v_string = res; 17368} 17369 17370/* 17371 * "tabpagebuflist()" function 17372 */ 17373 static void 17374f_tabpagebuflist(argvars, rettv) 17375 typval_T *argvars UNUSED; 17376 typval_T *rettv UNUSED; 17377{ 17378#ifdef FEAT_WINDOWS 17379 tabpage_T *tp; 17380 win_T *wp = NULL; 17381 17382 if (argvars[0].v_type == VAR_UNKNOWN) 17383 wp = firstwin; 17384 else 17385 { 17386 tp = find_tabpage((int)get_tv_number(&argvars[0])); 17387 if (tp != NULL) 17388 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 17389 } 17390 if (wp != NULL && rettv_list_alloc(rettv) != FAIL) 17391 { 17392 for (; wp != NULL; wp = wp->w_next) 17393 if (list_append_number(rettv->vval.v_list, 17394 wp->w_buffer->b_fnum) == FAIL) 17395 break; 17396 } 17397#endif 17398} 17399 17400 17401/* 17402 * "tabpagenr()" function 17403 */ 17404 static void 17405f_tabpagenr(argvars, rettv) 17406 typval_T *argvars UNUSED; 17407 typval_T *rettv; 17408{ 17409 int nr = 1; 17410#ifdef FEAT_WINDOWS 17411 char_u *arg; 17412 17413 if (argvars[0].v_type != VAR_UNKNOWN) 17414 { 17415 arg = get_tv_string_chk(&argvars[0]); 17416 nr = 0; 17417 if (arg != NULL) 17418 { 17419 if (STRCMP(arg, "$") == 0) 17420 nr = tabpage_index(NULL) - 1; 17421 else 17422 EMSG2(_(e_invexpr2), arg); 17423 } 17424 } 17425 else 17426 nr = tabpage_index(curtab); 17427#endif 17428 rettv->vval.v_number = nr; 17429} 17430 17431 17432#ifdef FEAT_WINDOWS 17433static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 17434 17435/* 17436 * Common code for tabpagewinnr() and winnr(). 17437 */ 17438 static int 17439get_winnr(tp, argvar) 17440 tabpage_T *tp; 17441 typval_T *argvar; 17442{ 17443 win_T *twin; 17444 int nr = 1; 17445 win_T *wp; 17446 char_u *arg; 17447 17448 twin = (tp == curtab) ? curwin : tp->tp_curwin; 17449 if (argvar->v_type != VAR_UNKNOWN) 17450 { 17451 arg = get_tv_string_chk(argvar); 17452 if (arg == NULL) 17453 nr = 0; /* type error; errmsg already given */ 17454 else if (STRCMP(arg, "$") == 0) 17455 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 17456 else if (STRCMP(arg, "#") == 0) 17457 { 17458 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 17459 if (twin == NULL) 17460 nr = 0; 17461 } 17462 else 17463 { 17464 EMSG2(_(e_invexpr2), arg); 17465 nr = 0; 17466 } 17467 } 17468 17469 if (nr > 0) 17470 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 17471 wp != twin; wp = wp->w_next) 17472 { 17473 if (wp == NULL) 17474 { 17475 /* didn't find it in this tabpage */ 17476 nr = 0; 17477 break; 17478 } 17479 ++nr; 17480 } 17481 return nr; 17482} 17483#endif 17484 17485/* 17486 * "tabpagewinnr()" function 17487 */ 17488 static void 17489f_tabpagewinnr(argvars, rettv) 17490 typval_T *argvars UNUSED; 17491 typval_T *rettv; 17492{ 17493 int nr = 1; 17494#ifdef FEAT_WINDOWS 17495 tabpage_T *tp; 17496 17497 tp = find_tabpage((int)get_tv_number(&argvars[0])); 17498 if (tp == NULL) 17499 nr = 0; 17500 else 17501 nr = get_winnr(tp, &argvars[1]); 17502#endif 17503 rettv->vval.v_number = nr; 17504} 17505 17506 17507/* 17508 * "tagfiles()" function 17509 */ 17510 static void 17511f_tagfiles(argvars, rettv) 17512 typval_T *argvars UNUSED; 17513 typval_T *rettv; 17514{ 17515 char_u fname[MAXPATHL + 1]; 17516 tagname_T tn; 17517 int first; 17518 17519 if (rettv_list_alloc(rettv) == FAIL) 17520 return; 17521 17522 for (first = TRUE; ; first = FALSE) 17523 if (get_tagfname(&tn, first, fname) == FAIL 17524 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 17525 break; 17526 tagname_free(&tn); 17527} 17528 17529/* 17530 * "taglist()" function 17531 */ 17532 static void 17533f_taglist(argvars, rettv) 17534 typval_T *argvars; 17535 typval_T *rettv; 17536{ 17537 char_u *tag_pattern; 17538 17539 tag_pattern = get_tv_string(&argvars[0]); 17540 17541 rettv->vval.v_number = FALSE; 17542 if (*tag_pattern == NUL) 17543 return; 17544 17545 if (rettv_list_alloc(rettv) == OK) 17546 (void)get_tags(rettv->vval.v_list, tag_pattern); 17547} 17548 17549/* 17550 * "tempname()" function 17551 */ 17552 static void 17553f_tempname(argvars, rettv) 17554 typval_T *argvars UNUSED; 17555 typval_T *rettv; 17556{ 17557 static int x = 'A'; 17558 17559 rettv->v_type = VAR_STRING; 17560 rettv->vval.v_string = vim_tempname(x); 17561 17562 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 17563 * names. Skip 'I' and 'O', they are used for shell redirection. */ 17564 do 17565 { 17566 if (x == 'Z') 17567 x = '0'; 17568 else if (x == '9') 17569 x = 'A'; 17570 else 17571 { 17572#ifdef EBCDIC 17573 if (x == 'I') 17574 x = 'J'; 17575 else if (x == 'R') 17576 x = 'S'; 17577 else 17578#endif 17579 ++x; 17580 } 17581 } while (x == 'I' || x == 'O'); 17582} 17583 17584/* 17585 * "test(list)" function: Just checking the walls... 17586 */ 17587 static void 17588f_test(argvars, rettv) 17589 typval_T *argvars UNUSED; 17590 typval_T *rettv UNUSED; 17591{ 17592 /* Used for unit testing. Change the code below to your liking. */ 17593#if 0 17594 listitem_T *li; 17595 list_T *l; 17596 char_u *bad, *good; 17597 17598 if (argvars[0].v_type != VAR_LIST) 17599 return; 17600 l = argvars[0].vval.v_list; 17601 if (l == NULL) 17602 return; 17603 li = l->lv_first; 17604 if (li == NULL) 17605 return; 17606 bad = get_tv_string(&li->li_tv); 17607 li = li->li_next; 17608 if (li == NULL) 17609 return; 17610 good = get_tv_string(&li->li_tv); 17611 rettv->vval.v_number = test_edit_score(bad, good); 17612#endif 17613} 17614 17615#ifdef FEAT_FLOAT 17616/* 17617 * "tan()" function 17618 */ 17619 static void 17620f_tan(argvars, rettv) 17621 typval_T *argvars; 17622 typval_T *rettv; 17623{ 17624 float_T f; 17625 17626 rettv->v_type = VAR_FLOAT; 17627 if (get_float_arg(argvars, &f) == OK) 17628 rettv->vval.v_float = tan(f); 17629 else 17630 rettv->vval.v_float = 0.0; 17631} 17632 17633/* 17634 * "tanh()" function 17635 */ 17636 static void 17637f_tanh(argvars, rettv) 17638 typval_T *argvars; 17639 typval_T *rettv; 17640{ 17641 float_T f; 17642 17643 rettv->v_type = VAR_FLOAT; 17644 if (get_float_arg(argvars, &f) == OK) 17645 rettv->vval.v_float = tanh(f); 17646 else 17647 rettv->vval.v_float = 0.0; 17648} 17649#endif 17650 17651/* 17652 * "tolower(string)" function 17653 */ 17654 static void 17655f_tolower(argvars, rettv) 17656 typval_T *argvars; 17657 typval_T *rettv; 17658{ 17659 char_u *p; 17660 17661 p = vim_strsave(get_tv_string(&argvars[0])); 17662 rettv->v_type = VAR_STRING; 17663 rettv->vval.v_string = p; 17664 17665 if (p != NULL) 17666 while (*p != NUL) 17667 { 17668#ifdef FEAT_MBYTE 17669 int l; 17670 17671 if (enc_utf8) 17672 { 17673 int c, lc; 17674 17675 c = utf_ptr2char(p); 17676 lc = utf_tolower(c); 17677 l = utf_ptr2len(p); 17678 /* TODO: reallocate string when byte count changes. */ 17679 if (utf_char2len(lc) == l) 17680 utf_char2bytes(lc, p); 17681 p += l; 17682 } 17683 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 17684 p += l; /* skip multi-byte character */ 17685 else 17686#endif 17687 { 17688 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 17689 ++p; 17690 } 17691 } 17692} 17693 17694/* 17695 * "toupper(string)" function 17696 */ 17697 static void 17698f_toupper(argvars, rettv) 17699 typval_T *argvars; 17700 typval_T *rettv; 17701{ 17702 rettv->v_type = VAR_STRING; 17703 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 17704} 17705 17706/* 17707 * "tr(string, fromstr, tostr)" function 17708 */ 17709 static void 17710f_tr(argvars, rettv) 17711 typval_T *argvars; 17712 typval_T *rettv; 17713{ 17714 char_u *instr; 17715 char_u *fromstr; 17716 char_u *tostr; 17717 char_u *p; 17718#ifdef FEAT_MBYTE 17719 int inlen; 17720 int fromlen; 17721 int tolen; 17722 int idx; 17723 char_u *cpstr; 17724 int cplen; 17725 int first = TRUE; 17726#endif 17727 char_u buf[NUMBUFLEN]; 17728 char_u buf2[NUMBUFLEN]; 17729 garray_T ga; 17730 17731 instr = get_tv_string(&argvars[0]); 17732 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 17733 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 17734 17735 /* Default return value: empty string. */ 17736 rettv->v_type = VAR_STRING; 17737 rettv->vval.v_string = NULL; 17738 if (fromstr == NULL || tostr == NULL) 17739 return; /* type error; errmsg already given */ 17740 ga_init2(&ga, (int)sizeof(char), 80); 17741 17742#ifdef FEAT_MBYTE 17743 if (!has_mbyte) 17744#endif 17745 /* not multi-byte: fromstr and tostr must be the same length */ 17746 if (STRLEN(fromstr) != STRLEN(tostr)) 17747 { 17748#ifdef FEAT_MBYTE 17749error: 17750#endif 17751 EMSG2(_(e_invarg2), fromstr); 17752 ga_clear(&ga); 17753 return; 17754 } 17755 17756 /* fromstr and tostr have to contain the same number of chars */ 17757 while (*instr != NUL) 17758 { 17759#ifdef FEAT_MBYTE 17760 if (has_mbyte) 17761 { 17762 inlen = (*mb_ptr2len)(instr); 17763 cpstr = instr; 17764 cplen = inlen; 17765 idx = 0; 17766 for (p = fromstr; *p != NUL; p += fromlen) 17767 { 17768 fromlen = (*mb_ptr2len)(p); 17769 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 17770 { 17771 for (p = tostr; *p != NUL; p += tolen) 17772 { 17773 tolen = (*mb_ptr2len)(p); 17774 if (idx-- == 0) 17775 { 17776 cplen = tolen; 17777 cpstr = p; 17778 break; 17779 } 17780 } 17781 if (*p == NUL) /* tostr is shorter than fromstr */ 17782 goto error; 17783 break; 17784 } 17785 ++idx; 17786 } 17787 17788 if (first && cpstr == instr) 17789 { 17790 /* Check that fromstr and tostr have the same number of 17791 * (multi-byte) characters. Done only once when a character 17792 * of instr doesn't appear in fromstr. */ 17793 first = FALSE; 17794 for (p = tostr; *p != NUL; p += tolen) 17795 { 17796 tolen = (*mb_ptr2len)(p); 17797 --idx; 17798 } 17799 if (idx != 0) 17800 goto error; 17801 } 17802 17803 ga_grow(&ga, cplen); 17804 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 17805 ga.ga_len += cplen; 17806 17807 instr += inlen; 17808 } 17809 else 17810#endif 17811 { 17812 /* When not using multi-byte chars we can do it faster. */ 17813 p = vim_strchr(fromstr, *instr); 17814 if (p != NULL) 17815 ga_append(&ga, tostr[p - fromstr]); 17816 else 17817 ga_append(&ga, *instr); 17818 ++instr; 17819 } 17820 } 17821 17822 /* add a terminating NUL */ 17823 ga_grow(&ga, 1); 17824 ga_append(&ga, NUL); 17825 17826 rettv->vval.v_string = ga.ga_data; 17827} 17828 17829#ifdef FEAT_FLOAT 17830/* 17831 * "trunc({float})" function 17832 */ 17833 static void 17834f_trunc(argvars, rettv) 17835 typval_T *argvars; 17836 typval_T *rettv; 17837{ 17838 float_T f; 17839 17840 rettv->v_type = VAR_FLOAT; 17841 if (get_float_arg(argvars, &f) == OK) 17842 /* trunc() is not in C90, use floor() or ceil() instead. */ 17843 rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); 17844 else 17845 rettv->vval.v_float = 0.0; 17846} 17847#endif 17848 17849/* 17850 * "type(expr)" function 17851 */ 17852 static void 17853f_type(argvars, rettv) 17854 typval_T *argvars; 17855 typval_T *rettv; 17856{ 17857 int n; 17858 17859 switch (argvars[0].v_type) 17860 { 17861 case VAR_NUMBER: n = 0; break; 17862 case VAR_STRING: n = 1; break; 17863 case VAR_FUNC: n = 2; break; 17864 case VAR_LIST: n = 3; break; 17865 case VAR_DICT: n = 4; break; 17866#ifdef FEAT_FLOAT 17867 case VAR_FLOAT: n = 5; break; 17868#endif 17869 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 17870 } 17871 rettv->vval.v_number = n; 17872} 17873 17874/* 17875 * "undofile(name)" function 17876 */ 17877 static void 17878f_undofile(argvars, rettv) 17879 typval_T *argvars; 17880 typval_T *rettv; 17881{ 17882 rettv->v_type = VAR_STRING; 17883#ifdef FEAT_PERSISTENT_UNDO 17884 { 17885 char_u *ffname = FullName_save(get_tv_string(&argvars[0]), FALSE); 17886 17887 if (ffname != NULL) 17888 rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE); 17889 vim_free(ffname); 17890 } 17891#else 17892 rettv->vval.v_string = NULL; 17893#endif 17894} 17895 17896/* 17897 * "undotree()" function 17898 */ 17899 static void 17900f_undotree(argvars, rettv) 17901 typval_T *argvars UNUSED; 17902 typval_T *rettv; 17903{ 17904 if (rettv_dict_alloc(rettv) == OK) 17905 { 17906 dict_T *dict = rettv->vval.v_dict; 17907 list_T *list; 17908 17909 dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL); 17910 dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL); 17911 dict_add_nr_str(dict, "save_last", 17912 (long)curbuf->b_u_save_nr_last, NULL); 17913 dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL); 17914 dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL); 17915 dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL); 17916 17917 list = list_alloc(); 17918 if (list != NULL) 17919 { 17920 u_eval_tree(curbuf->b_u_oldhead, list); 17921 dict_add_list(dict, "entries", list); 17922 } 17923 } 17924} 17925 17926/* 17927 * "values(dict)" function 17928 */ 17929 static void 17930f_values(argvars, rettv) 17931 typval_T *argvars; 17932 typval_T *rettv; 17933{ 17934 dict_list(argvars, rettv, 1); 17935} 17936 17937/* 17938 * "virtcol(string)" function 17939 */ 17940 static void 17941f_virtcol(argvars, rettv) 17942 typval_T *argvars; 17943 typval_T *rettv; 17944{ 17945 colnr_T vcol = 0; 17946 pos_T *fp; 17947 int fnum = curbuf->b_fnum; 17948 17949 fp = var2fpos(&argvars[0], FALSE, &fnum); 17950 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 17951 && fnum == curbuf->b_fnum) 17952 { 17953 getvvcol(curwin, fp, NULL, NULL, &vcol); 17954 ++vcol; 17955 } 17956 17957 rettv->vval.v_number = vcol; 17958} 17959 17960/* 17961 * "visualmode()" function 17962 */ 17963 static void 17964f_visualmode(argvars, rettv) 17965 typval_T *argvars UNUSED; 17966 typval_T *rettv UNUSED; 17967{ 17968#ifdef FEAT_VISUAL 17969 char_u str[2]; 17970 17971 rettv->v_type = VAR_STRING; 17972 str[0] = curbuf->b_visual_mode_eval; 17973 str[1] = NUL; 17974 rettv->vval.v_string = vim_strsave(str); 17975 17976 /* A non-zero number or non-empty string argument: reset mode. */ 17977 if (non_zero_arg(&argvars[0])) 17978 curbuf->b_visual_mode_eval = NUL; 17979#endif 17980} 17981 17982/* 17983 * "winbufnr(nr)" function 17984 */ 17985 static void 17986f_winbufnr(argvars, rettv) 17987 typval_T *argvars; 17988 typval_T *rettv; 17989{ 17990 win_T *wp; 17991 17992 wp = find_win_by_nr(&argvars[0], NULL); 17993 if (wp == NULL) 17994 rettv->vval.v_number = -1; 17995 else 17996 rettv->vval.v_number = wp->w_buffer->b_fnum; 17997} 17998 17999/* 18000 * "wincol()" function 18001 */ 18002 static void 18003f_wincol(argvars, rettv) 18004 typval_T *argvars UNUSED; 18005 typval_T *rettv; 18006{ 18007 validate_cursor(); 18008 rettv->vval.v_number = curwin->w_wcol + 1; 18009} 18010 18011/* 18012 * "winheight(nr)" function 18013 */ 18014 static void 18015f_winheight(argvars, rettv) 18016 typval_T *argvars; 18017 typval_T *rettv; 18018{ 18019 win_T *wp; 18020 18021 wp = find_win_by_nr(&argvars[0], NULL); 18022 if (wp == NULL) 18023 rettv->vval.v_number = -1; 18024 else 18025 rettv->vval.v_number = wp->w_height; 18026} 18027 18028/* 18029 * "winline()" function 18030 */ 18031 static void 18032f_winline(argvars, rettv) 18033 typval_T *argvars UNUSED; 18034 typval_T *rettv; 18035{ 18036 validate_cursor(); 18037 rettv->vval.v_number = curwin->w_wrow + 1; 18038} 18039 18040/* 18041 * "winnr()" function 18042 */ 18043 static void 18044f_winnr(argvars, rettv) 18045 typval_T *argvars UNUSED; 18046 typval_T *rettv; 18047{ 18048 int nr = 1; 18049 18050#ifdef FEAT_WINDOWS 18051 nr = get_winnr(curtab, &argvars[0]); 18052#endif 18053 rettv->vval.v_number = nr; 18054} 18055 18056/* 18057 * "winrestcmd()" function 18058 */ 18059 static void 18060f_winrestcmd(argvars, rettv) 18061 typval_T *argvars UNUSED; 18062 typval_T *rettv; 18063{ 18064#ifdef FEAT_WINDOWS 18065 win_T *wp; 18066 int winnr = 1; 18067 garray_T ga; 18068 char_u buf[50]; 18069 18070 ga_init2(&ga, (int)sizeof(char), 70); 18071 for (wp = firstwin; wp != NULL; wp = wp->w_next) 18072 { 18073 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 18074 ga_concat(&ga, buf); 18075# ifdef FEAT_VERTSPLIT 18076 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 18077 ga_concat(&ga, buf); 18078# endif 18079 ++winnr; 18080 } 18081 ga_append(&ga, NUL); 18082 18083 rettv->vval.v_string = ga.ga_data; 18084#else 18085 rettv->vval.v_string = NULL; 18086#endif 18087 rettv->v_type = VAR_STRING; 18088} 18089 18090/* 18091 * "winrestview()" function 18092 */ 18093 static void 18094f_winrestview(argvars, rettv) 18095 typval_T *argvars; 18096 typval_T *rettv UNUSED; 18097{ 18098 dict_T *dict; 18099 18100 if (argvars[0].v_type != VAR_DICT 18101 || (dict = argvars[0].vval.v_dict) == NULL) 18102 EMSG(_(e_invarg)); 18103 else 18104 { 18105 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 18106 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 18107#ifdef FEAT_VIRTUALEDIT 18108 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 18109#endif 18110 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 18111 curwin->w_set_curswant = FALSE; 18112 18113 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 18114#ifdef FEAT_DIFF 18115 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 18116#endif 18117 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 18118 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 18119 18120 check_cursor(); 18121 changed_cline_bef_curs(); 18122 invalidate_botline(); 18123 redraw_later(VALID); 18124 18125 if (curwin->w_topline == 0) 18126 curwin->w_topline = 1; 18127 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 18128 curwin->w_topline = curbuf->b_ml.ml_line_count; 18129#ifdef FEAT_DIFF 18130 check_topfill(curwin, TRUE); 18131#endif 18132 } 18133} 18134 18135/* 18136 * "winsaveview()" function 18137 */ 18138 static void 18139f_winsaveview(argvars, rettv) 18140 typval_T *argvars UNUSED; 18141 typval_T *rettv; 18142{ 18143 dict_T *dict; 18144 18145 if (rettv_dict_alloc(rettv) == FAIL) 18146 return; 18147 dict = rettv->vval.v_dict; 18148 18149 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 18150 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 18151#ifdef FEAT_VIRTUALEDIT 18152 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 18153#endif 18154 update_curswant(); 18155 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 18156 18157 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 18158#ifdef FEAT_DIFF 18159 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 18160#endif 18161 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 18162 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 18163} 18164 18165/* 18166 * "winwidth(nr)" function 18167 */ 18168 static void 18169f_winwidth(argvars, rettv) 18170 typval_T *argvars; 18171 typval_T *rettv; 18172{ 18173 win_T *wp; 18174 18175 wp = find_win_by_nr(&argvars[0], NULL); 18176 if (wp == NULL) 18177 rettv->vval.v_number = -1; 18178 else 18179#ifdef FEAT_VERTSPLIT 18180 rettv->vval.v_number = wp->w_width; 18181#else 18182 rettv->vval.v_number = Columns; 18183#endif 18184} 18185 18186/* 18187 * "writefile()" function 18188 */ 18189 static void 18190f_writefile(argvars, rettv) 18191 typval_T *argvars; 18192 typval_T *rettv; 18193{ 18194 int binary = FALSE; 18195 char_u *fname; 18196 FILE *fd; 18197 listitem_T *li; 18198 char_u *s; 18199 int ret = 0; 18200 int c; 18201 18202 if (check_restricted() || check_secure()) 18203 return; 18204 18205 if (argvars[0].v_type != VAR_LIST) 18206 { 18207 EMSG2(_(e_listarg), "writefile()"); 18208 return; 18209 } 18210 if (argvars[0].vval.v_list == NULL) 18211 return; 18212 18213 if (argvars[2].v_type != VAR_UNKNOWN 18214 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 18215 binary = TRUE; 18216 18217 /* Always open the file in binary mode, library functions have a mind of 18218 * their own about CR-LF conversion. */ 18219 fname = get_tv_string(&argvars[1]); 18220 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 18221 { 18222 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 18223 ret = -1; 18224 } 18225 else 18226 { 18227 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 18228 li = li->li_next) 18229 { 18230 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 18231 { 18232 if (*s == '\n') 18233 c = putc(NUL, fd); 18234 else 18235 c = putc(*s, fd); 18236 if (c == EOF) 18237 { 18238 ret = -1; 18239 break; 18240 } 18241 } 18242 if (!binary || li->li_next != NULL) 18243 if (putc('\n', fd) == EOF) 18244 { 18245 ret = -1; 18246 break; 18247 } 18248 if (ret < 0) 18249 { 18250 EMSG(_(e_write)); 18251 break; 18252 } 18253 } 18254 fclose(fd); 18255 } 18256 18257 rettv->vval.v_number = ret; 18258} 18259 18260/* 18261 * Translate a String variable into a position. 18262 * Returns NULL when there is an error. 18263 */ 18264 static pos_T * 18265var2fpos(varp, dollar_lnum, fnum) 18266 typval_T *varp; 18267 int dollar_lnum; /* TRUE when $ is last line */ 18268 int *fnum; /* set to fnum for '0, 'A, etc. */ 18269{ 18270 char_u *name; 18271 static pos_T pos; 18272 pos_T *pp; 18273 18274 /* Argument can be [lnum, col, coladd]. */ 18275 if (varp->v_type == VAR_LIST) 18276 { 18277 list_T *l; 18278 int len; 18279 int error = FALSE; 18280 listitem_T *li; 18281 18282 l = varp->vval.v_list; 18283 if (l == NULL) 18284 return NULL; 18285 18286 /* Get the line number */ 18287 pos.lnum = list_find_nr(l, 0L, &error); 18288 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 18289 return NULL; /* invalid line number */ 18290 18291 /* Get the column number */ 18292 pos.col = list_find_nr(l, 1L, &error); 18293 if (error) 18294 return NULL; 18295 len = (long)STRLEN(ml_get(pos.lnum)); 18296 18297 /* We accept "$" for the column number: last column. */ 18298 li = list_find(l, 1L); 18299 if (li != NULL && li->li_tv.v_type == VAR_STRING 18300 && li->li_tv.vval.v_string != NULL 18301 && STRCMP(li->li_tv.vval.v_string, "$") == 0) 18302 pos.col = len + 1; 18303 18304 /* Accept a position up to the NUL after the line. */ 18305 if (pos.col == 0 || (int)pos.col > len + 1) 18306 return NULL; /* invalid column number */ 18307 --pos.col; 18308 18309#ifdef FEAT_VIRTUALEDIT 18310 /* Get the virtual offset. Defaults to zero. */ 18311 pos.coladd = list_find_nr(l, 2L, &error); 18312 if (error) 18313 pos.coladd = 0; 18314#endif 18315 18316 return &pos; 18317 } 18318 18319 name = get_tv_string_chk(varp); 18320 if (name == NULL) 18321 return NULL; 18322 if (name[0] == '.') /* cursor */ 18323 return &curwin->w_cursor; 18324#ifdef FEAT_VISUAL 18325 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ 18326 { 18327 if (VIsual_active) 18328 return &VIsual; 18329 return &curwin->w_cursor; 18330 } 18331#endif 18332 if (name[0] == '\'') /* mark */ 18333 { 18334 pp = getmark_fnum(name[1], FALSE, fnum); 18335 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 18336 return NULL; 18337 return pp; 18338 } 18339 18340#ifdef FEAT_VIRTUALEDIT 18341 pos.coladd = 0; 18342#endif 18343 18344 if (name[0] == 'w' && dollar_lnum) 18345 { 18346 pos.col = 0; 18347 if (name[1] == '0') /* "w0": first visible line */ 18348 { 18349 update_topline(); 18350 pos.lnum = curwin->w_topline; 18351 return &pos; 18352 } 18353 else if (name[1] == '$') /* "w$": last visible line */ 18354 { 18355 validate_botline(); 18356 pos.lnum = curwin->w_botline - 1; 18357 return &pos; 18358 } 18359 } 18360 else if (name[0] == '$') /* last column or line */ 18361 { 18362 if (dollar_lnum) 18363 { 18364 pos.lnum = curbuf->b_ml.ml_line_count; 18365 pos.col = 0; 18366 } 18367 else 18368 { 18369 pos.lnum = curwin->w_cursor.lnum; 18370 pos.col = (colnr_T)STRLEN(ml_get_curline()); 18371 } 18372 return &pos; 18373 } 18374 return NULL; 18375} 18376 18377/* 18378 * Convert list in "arg" into a position and optional file number. 18379 * When "fnump" is NULL there is no file number, only 3 items. 18380 * Note that the column is passed on as-is, the caller may want to decrement 18381 * it to use 1 for the first column. 18382 * Return FAIL when conversion is not possible, doesn't check the position for 18383 * validity. 18384 */ 18385 static int 18386list2fpos(arg, posp, fnump) 18387 typval_T *arg; 18388 pos_T *posp; 18389 int *fnump; 18390{ 18391 list_T *l = arg->vval.v_list; 18392 long i = 0; 18393 long n; 18394 18395 /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there 18396 * when "fnump" isn't NULL and "coladd" is optional. */ 18397 if (arg->v_type != VAR_LIST 18398 || l == NULL 18399 || l->lv_len < (fnump == NULL ? 2 : 3) 18400 || l->lv_len > (fnump == NULL ? 3 : 4)) 18401 return FAIL; 18402 18403 if (fnump != NULL) 18404 { 18405 n = list_find_nr(l, i++, NULL); /* fnum */ 18406 if (n < 0) 18407 return FAIL; 18408 if (n == 0) 18409 n = curbuf->b_fnum; /* current buffer */ 18410 *fnump = n; 18411 } 18412 18413 n = list_find_nr(l, i++, NULL); /* lnum */ 18414 if (n < 0) 18415 return FAIL; 18416 posp->lnum = n; 18417 18418 n = list_find_nr(l, i++, NULL); /* col */ 18419 if (n < 0) 18420 return FAIL; 18421 posp->col = n; 18422 18423#ifdef FEAT_VIRTUALEDIT 18424 n = list_find_nr(l, i, NULL); 18425 if (n < 0) 18426 posp->coladd = 0; 18427 else 18428 posp->coladd = n; 18429#endif 18430 18431 return OK; 18432} 18433 18434/* 18435 * Get the length of an environment variable name. 18436 * Advance "arg" to the first character after the name. 18437 * Return 0 for error. 18438 */ 18439 static int 18440get_env_len(arg) 18441 char_u **arg; 18442{ 18443 char_u *p; 18444 int len; 18445 18446 for (p = *arg; vim_isIDc(*p); ++p) 18447 ; 18448 if (p == *arg) /* no name found */ 18449 return 0; 18450 18451 len = (int)(p - *arg); 18452 *arg = p; 18453 return len; 18454} 18455 18456/* 18457 * Get the length of the name of a function or internal variable. 18458 * "arg" is advanced to the first non-white character after the name. 18459 * Return 0 if something is wrong. 18460 */ 18461 static int 18462get_id_len(arg) 18463 char_u **arg; 18464{ 18465 char_u *p; 18466 int len; 18467 18468 /* Find the end of the name. */ 18469 for (p = *arg; eval_isnamec(*p); ++p) 18470 ; 18471 if (p == *arg) /* no name found */ 18472 return 0; 18473 18474 len = (int)(p - *arg); 18475 *arg = skipwhite(p); 18476 18477 return len; 18478} 18479 18480/* 18481 * Get the length of the name of a variable or function. 18482 * Only the name is recognized, does not handle ".key" or "[idx]". 18483 * "arg" is advanced to the first non-white character after the name. 18484 * Return -1 if curly braces expansion failed. 18485 * Return 0 if something else is wrong. 18486 * If the name contains 'magic' {}'s, expand them and return the 18487 * expanded name in an allocated string via 'alias' - caller must free. 18488 */ 18489 static int 18490get_name_len(arg, alias, evaluate, verbose) 18491 char_u **arg; 18492 char_u **alias; 18493 int evaluate; 18494 int verbose; 18495{ 18496 int len; 18497 char_u *p; 18498 char_u *expr_start; 18499 char_u *expr_end; 18500 18501 *alias = NULL; /* default to no alias */ 18502 18503 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 18504 && (*arg)[2] == (int)KE_SNR) 18505 { 18506 /* hard coded <SNR>, already translated */ 18507 *arg += 3; 18508 return get_id_len(arg) + 3; 18509 } 18510 len = eval_fname_script(*arg); 18511 if (len > 0) 18512 { 18513 /* literal "<SID>", "s:" or "<SNR>" */ 18514 *arg += len; 18515 } 18516 18517 /* 18518 * Find the end of the name; check for {} construction. 18519 */ 18520 p = find_name_end(*arg, &expr_start, &expr_end, 18521 len > 0 ? 0 : FNE_CHECK_START); 18522 if (expr_start != NULL) 18523 { 18524 char_u *temp_string; 18525 18526 if (!evaluate) 18527 { 18528 len += (int)(p - *arg); 18529 *arg = skipwhite(p); 18530 return len; 18531 } 18532 18533 /* 18534 * Include any <SID> etc in the expanded string: 18535 * Thus the -len here. 18536 */ 18537 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 18538 if (temp_string == NULL) 18539 return -1; 18540 *alias = temp_string; 18541 *arg = skipwhite(p); 18542 return (int)STRLEN(temp_string); 18543 } 18544 18545 len += get_id_len(arg); 18546 if (len == 0 && verbose) 18547 EMSG2(_(e_invexpr2), *arg); 18548 18549 return len; 18550} 18551 18552/* 18553 * Find the end of a variable or function name, taking care of magic braces. 18554 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 18555 * start and end of the first magic braces item. 18556 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 18557 * Return a pointer to just after the name. Equal to "arg" if there is no 18558 * valid name. 18559 */ 18560 static char_u * 18561find_name_end(arg, expr_start, expr_end, flags) 18562 char_u *arg; 18563 char_u **expr_start; 18564 char_u **expr_end; 18565 int flags; 18566{ 18567 int mb_nest = 0; 18568 int br_nest = 0; 18569 char_u *p; 18570 18571 if (expr_start != NULL) 18572 { 18573 *expr_start = NULL; 18574 *expr_end = NULL; 18575 } 18576 18577 /* Quick check for valid starting character. */ 18578 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 18579 return arg; 18580 18581 for (p = arg; *p != NUL 18582 && (eval_isnamec(*p) 18583 || *p == '{' 18584 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 18585 || mb_nest != 0 18586 || br_nest != 0); mb_ptr_adv(p)) 18587 { 18588 if (*p == '\'') 18589 { 18590 /* skip over 'string' to avoid counting [ and ] inside it. */ 18591 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 18592 ; 18593 if (*p == NUL) 18594 break; 18595 } 18596 else if (*p == '"') 18597 { 18598 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 18599 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 18600 if (*p == '\\' && p[1] != NUL) 18601 ++p; 18602 if (*p == NUL) 18603 break; 18604 } 18605 18606 if (mb_nest == 0) 18607 { 18608 if (*p == '[') 18609 ++br_nest; 18610 else if (*p == ']') 18611 --br_nest; 18612 } 18613 18614 if (br_nest == 0) 18615 { 18616 if (*p == '{') 18617 { 18618 mb_nest++; 18619 if (expr_start != NULL && *expr_start == NULL) 18620 *expr_start = p; 18621 } 18622 else if (*p == '}') 18623 { 18624 mb_nest--; 18625 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 18626 *expr_end = p; 18627 } 18628 } 18629 } 18630 18631 return p; 18632} 18633 18634/* 18635 * Expands out the 'magic' {}'s in a variable/function name. 18636 * Note that this can call itself recursively, to deal with 18637 * constructs like foo{bar}{baz}{bam} 18638 * The four pointer arguments point to "foo{expre}ss{ion}bar" 18639 * "in_start" ^ 18640 * "expr_start" ^ 18641 * "expr_end" ^ 18642 * "in_end" ^ 18643 * 18644 * Returns a new allocated string, which the caller must free. 18645 * Returns NULL for failure. 18646 */ 18647 static char_u * 18648make_expanded_name(in_start, expr_start, expr_end, in_end) 18649 char_u *in_start; 18650 char_u *expr_start; 18651 char_u *expr_end; 18652 char_u *in_end; 18653{ 18654 char_u c1; 18655 char_u *retval = NULL; 18656 char_u *temp_result; 18657 char_u *nextcmd = NULL; 18658 18659 if (expr_end == NULL || in_end == NULL) 18660 return NULL; 18661 *expr_start = NUL; 18662 *expr_end = NUL; 18663 c1 = *in_end; 18664 *in_end = NUL; 18665 18666 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 18667 if (temp_result != NULL && nextcmd == NULL) 18668 { 18669 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 18670 + (in_end - expr_end) + 1)); 18671 if (retval != NULL) 18672 { 18673 STRCPY(retval, in_start); 18674 STRCAT(retval, temp_result); 18675 STRCAT(retval, expr_end + 1); 18676 } 18677 } 18678 vim_free(temp_result); 18679 18680 *in_end = c1; /* put char back for error messages */ 18681 *expr_start = '{'; 18682 *expr_end = '}'; 18683 18684 if (retval != NULL) 18685 { 18686 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 18687 if (expr_start != NULL) 18688 { 18689 /* Further expansion! */ 18690 temp_result = make_expanded_name(retval, expr_start, 18691 expr_end, temp_result); 18692 vim_free(retval); 18693 retval = temp_result; 18694 } 18695 } 18696 18697 return retval; 18698} 18699 18700/* 18701 * Return TRUE if character "c" can be used in a variable or function name. 18702 * Does not include '{' or '}' for magic braces. 18703 */ 18704 static int 18705eval_isnamec(c) 18706 int c; 18707{ 18708 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 18709} 18710 18711/* 18712 * Return TRUE if character "c" can be used as the first character in a 18713 * variable or function name (excluding '{' and '}'). 18714 */ 18715 static int 18716eval_isnamec1(c) 18717 int c; 18718{ 18719 return (ASCII_ISALPHA(c) || c == '_'); 18720} 18721 18722/* 18723 * Set number v: variable to "val". 18724 */ 18725 void 18726set_vim_var_nr(idx, val) 18727 int idx; 18728 long val; 18729{ 18730 vimvars[idx].vv_nr = val; 18731} 18732 18733/* 18734 * Get number v: variable value. 18735 */ 18736 long 18737get_vim_var_nr(idx) 18738 int idx; 18739{ 18740 return vimvars[idx].vv_nr; 18741} 18742 18743/* 18744 * Get string v: variable value. Uses a static buffer, can only be used once. 18745 */ 18746 char_u * 18747get_vim_var_str(idx) 18748 int idx; 18749{ 18750 return get_tv_string(&vimvars[idx].vv_tv); 18751} 18752 18753/* 18754 * Get List v: variable value. Caller must take care of reference count when 18755 * needed. 18756 */ 18757 list_T * 18758get_vim_var_list(idx) 18759 int idx; 18760{ 18761 return vimvars[idx].vv_list; 18762} 18763 18764/* 18765 * Set v:char to character "c". 18766 */ 18767 void 18768set_vim_var_char(c) 18769 int c; 18770{ 18771#ifdef FEAT_MBYTE 18772 char_u buf[MB_MAXBYTES]; 18773#else 18774 char_u buf[2]; 18775#endif 18776 18777#ifdef FEAT_MBYTE 18778 if (has_mbyte) 18779 buf[(*mb_char2bytes)(c, buf)] = NUL; 18780 else 18781#endif 18782 { 18783 buf[0] = c; 18784 buf[1] = NUL; 18785 } 18786 set_vim_var_string(VV_CHAR, buf, -1); 18787} 18788 18789/* 18790 * Set v:count to "count" and v:count1 to "count1". 18791 * When "set_prevcount" is TRUE first set v:prevcount from v:count. 18792 */ 18793 void 18794set_vcount(count, count1, set_prevcount) 18795 long count; 18796 long count1; 18797 int set_prevcount; 18798{ 18799 if (set_prevcount) 18800 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 18801 vimvars[VV_COUNT].vv_nr = count; 18802 vimvars[VV_COUNT1].vv_nr = count1; 18803} 18804 18805/* 18806 * Set string v: variable to a copy of "val". 18807 */ 18808 void 18809set_vim_var_string(idx, val, len) 18810 int idx; 18811 char_u *val; 18812 int len; /* length of "val" to use or -1 (whole string) */ 18813{ 18814 /* Need to do this (at least) once, since we can't initialize a union. 18815 * Will always be invoked when "v:progname" is set. */ 18816 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 18817 18818 vim_free(vimvars[idx].vv_str); 18819 if (val == NULL) 18820 vimvars[idx].vv_str = NULL; 18821 else if (len == -1) 18822 vimvars[idx].vv_str = vim_strsave(val); 18823 else 18824 vimvars[idx].vv_str = vim_strnsave(val, len); 18825} 18826 18827/* 18828 * Set List v: variable to "val". 18829 */ 18830 void 18831set_vim_var_list(idx, val) 18832 int idx; 18833 list_T *val; 18834{ 18835 list_unref(vimvars[idx].vv_list); 18836 vimvars[idx].vv_list = val; 18837 if (val != NULL) 18838 ++val->lv_refcount; 18839} 18840 18841/* 18842 * Set v:register if needed. 18843 */ 18844 void 18845set_reg_var(c) 18846 int c; 18847{ 18848 char_u regname; 18849 18850 if (c == 0 || c == ' ') 18851 regname = '"'; 18852 else 18853 regname = c; 18854 /* Avoid free/alloc when the value is already right. */ 18855 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 18856 set_vim_var_string(VV_REG, ®name, 1); 18857} 18858 18859/* 18860 * Get or set v:exception. If "oldval" == NULL, return the current value. 18861 * Otherwise, restore the value to "oldval" and return NULL. 18862 * Must always be called in pairs to save and restore v:exception! Does not 18863 * take care of memory allocations. 18864 */ 18865 char_u * 18866v_exception(oldval) 18867 char_u *oldval; 18868{ 18869 if (oldval == NULL) 18870 return vimvars[VV_EXCEPTION].vv_str; 18871 18872 vimvars[VV_EXCEPTION].vv_str = oldval; 18873 return NULL; 18874} 18875 18876/* 18877 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 18878 * Otherwise, restore the value to "oldval" and return NULL. 18879 * Must always be called in pairs to save and restore v:throwpoint! Does not 18880 * take care of memory allocations. 18881 */ 18882 char_u * 18883v_throwpoint(oldval) 18884 char_u *oldval; 18885{ 18886 if (oldval == NULL) 18887 return vimvars[VV_THROWPOINT].vv_str; 18888 18889 vimvars[VV_THROWPOINT].vv_str = oldval; 18890 return NULL; 18891} 18892 18893#if defined(FEAT_AUTOCMD) || defined(PROTO) 18894/* 18895 * Set v:cmdarg. 18896 * If "eap" != NULL, use "eap" to generate the value and return the old value. 18897 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 18898 * Must always be called in pairs! 18899 */ 18900 char_u * 18901set_cmdarg(eap, oldarg) 18902 exarg_T *eap; 18903 char_u *oldarg; 18904{ 18905 char_u *oldval; 18906 char_u *newval; 18907 unsigned len; 18908 18909 oldval = vimvars[VV_CMDARG].vv_str; 18910 if (eap == NULL) 18911 { 18912 vim_free(oldval); 18913 vimvars[VV_CMDARG].vv_str = oldarg; 18914 return NULL; 18915 } 18916 18917 if (eap->force_bin == FORCE_BIN) 18918 len = 6; 18919 else if (eap->force_bin == FORCE_NOBIN) 18920 len = 8; 18921 else 18922 len = 0; 18923 18924 if (eap->read_edit) 18925 len += 7; 18926 18927 if (eap->force_ff != 0) 18928 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 18929# ifdef FEAT_MBYTE 18930 if (eap->force_enc != 0) 18931 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 18932 if (eap->bad_char != 0) 18933 len += 7 + 4; /* " ++bad=" + "keep" or "drop" */ 18934# endif 18935 18936 newval = alloc(len + 1); 18937 if (newval == NULL) 18938 return NULL; 18939 18940 if (eap->force_bin == FORCE_BIN) 18941 sprintf((char *)newval, " ++bin"); 18942 else if (eap->force_bin == FORCE_NOBIN) 18943 sprintf((char *)newval, " ++nobin"); 18944 else 18945 *newval = NUL; 18946 18947 if (eap->read_edit) 18948 STRCAT(newval, " ++edit"); 18949 18950 if (eap->force_ff != 0) 18951 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 18952 eap->cmd + eap->force_ff); 18953# ifdef FEAT_MBYTE 18954 if (eap->force_enc != 0) 18955 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 18956 eap->cmd + eap->force_enc); 18957 if (eap->bad_char == BAD_KEEP) 18958 STRCPY(newval + STRLEN(newval), " ++bad=keep"); 18959 else if (eap->bad_char == BAD_DROP) 18960 STRCPY(newval + STRLEN(newval), " ++bad=drop"); 18961 else if (eap->bad_char != 0) 18962 sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char); 18963# endif 18964 vimvars[VV_CMDARG].vv_str = newval; 18965 return oldval; 18966} 18967#endif 18968 18969/* 18970 * Get the value of internal variable "name". 18971 * Return OK or FAIL. 18972 */ 18973 static int 18974get_var_tv(name, len, rettv, verbose) 18975 char_u *name; 18976 int len; /* length of "name" */ 18977 typval_T *rettv; /* NULL when only checking existence */ 18978 int verbose; /* may give error message */ 18979{ 18980 int ret = OK; 18981 typval_T *tv = NULL; 18982 typval_T atv; 18983 dictitem_T *v; 18984 int cc; 18985 18986 /* truncate the name, so that we can use strcmp() */ 18987 cc = name[len]; 18988 name[len] = NUL; 18989 18990 /* 18991 * Check for "b:changedtick". 18992 */ 18993 if (STRCMP(name, "b:changedtick") == 0) 18994 { 18995 atv.v_type = VAR_NUMBER; 18996 atv.vval.v_number = curbuf->b_changedtick; 18997 tv = &atv; 18998 } 18999 19000 /* 19001 * Check for user-defined variables. 19002 */ 19003 else 19004 { 19005 v = find_var(name, NULL); 19006 if (v != NULL) 19007 tv = &v->di_tv; 19008 } 19009 19010 if (tv == NULL) 19011 { 19012 if (rettv != NULL && verbose) 19013 EMSG2(_(e_undefvar), name); 19014 ret = FAIL; 19015 } 19016 else if (rettv != NULL) 19017 copy_tv(tv, rettv); 19018 19019 name[len] = cc; 19020 19021 return ret; 19022} 19023 19024/* 19025 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 19026 * Also handle function call with Funcref variable: func(expr) 19027 * Can all be combined: dict.func(expr)[idx]['func'](expr) 19028 */ 19029 static int 19030handle_subscript(arg, rettv, evaluate, verbose) 19031 char_u **arg; 19032 typval_T *rettv; 19033 int evaluate; /* do more than finding the end */ 19034 int verbose; /* give error messages */ 19035{ 19036 int ret = OK; 19037 dict_T *selfdict = NULL; 19038 char_u *s; 19039 int len; 19040 typval_T functv; 19041 19042 while (ret == OK 19043 && (**arg == '[' 19044 || (**arg == '.' && rettv->v_type == VAR_DICT) 19045 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 19046 && !vim_iswhite(*(*arg - 1))) 19047 { 19048 if (**arg == '(') 19049 { 19050 /* need to copy the funcref so that we can clear rettv */ 19051 functv = *rettv; 19052 rettv->v_type = VAR_UNKNOWN; 19053 19054 /* Invoke the function. Recursive! */ 19055 s = functv.vval.v_string; 19056 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 19057 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 19058 &len, evaluate, selfdict); 19059 19060 /* Clear the funcref afterwards, so that deleting it while 19061 * evaluating the arguments is possible (see test55). */ 19062 clear_tv(&functv); 19063 19064 /* Stop the expression evaluation when immediately aborting on 19065 * error, or when an interrupt occurred or an exception was thrown 19066 * but not caught. */ 19067 if (aborting()) 19068 { 19069 if (ret == OK) 19070 clear_tv(rettv); 19071 ret = FAIL; 19072 } 19073 dict_unref(selfdict); 19074 selfdict = NULL; 19075 } 19076 else /* **arg == '[' || **arg == '.' */ 19077 { 19078 dict_unref(selfdict); 19079 if (rettv->v_type == VAR_DICT) 19080 { 19081 selfdict = rettv->vval.v_dict; 19082 if (selfdict != NULL) 19083 ++selfdict->dv_refcount; 19084 } 19085 else 19086 selfdict = NULL; 19087 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 19088 { 19089 clear_tv(rettv); 19090 ret = FAIL; 19091 } 19092 } 19093 } 19094 dict_unref(selfdict); 19095 return ret; 19096} 19097 19098/* 19099 * Allocate memory for a variable type-value, and make it empty (0 or NULL 19100 * value). 19101 */ 19102 static typval_T * 19103alloc_tv() 19104{ 19105 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 19106} 19107 19108/* 19109 * Allocate memory for a variable type-value, and assign a string to it. 19110 * The string "s" must have been allocated, it is consumed. 19111 * Return NULL for out of memory, the variable otherwise. 19112 */ 19113 static typval_T * 19114alloc_string_tv(s) 19115 char_u *s; 19116{ 19117 typval_T *rettv; 19118 19119 rettv = alloc_tv(); 19120 if (rettv != NULL) 19121 { 19122 rettv->v_type = VAR_STRING; 19123 rettv->vval.v_string = s; 19124 } 19125 else 19126 vim_free(s); 19127 return rettv; 19128} 19129 19130/* 19131 * Free the memory for a variable type-value. 19132 */ 19133 void 19134free_tv(varp) 19135 typval_T *varp; 19136{ 19137 if (varp != NULL) 19138 { 19139 switch (varp->v_type) 19140 { 19141 case VAR_FUNC: 19142 func_unref(varp->vval.v_string); 19143 /*FALLTHROUGH*/ 19144 case VAR_STRING: 19145 vim_free(varp->vval.v_string); 19146 break; 19147 case VAR_LIST: 19148 list_unref(varp->vval.v_list); 19149 break; 19150 case VAR_DICT: 19151 dict_unref(varp->vval.v_dict); 19152 break; 19153 case VAR_NUMBER: 19154#ifdef FEAT_FLOAT 19155 case VAR_FLOAT: 19156#endif 19157 case VAR_UNKNOWN: 19158 break; 19159 default: 19160 EMSG2(_(e_intern2), "free_tv()"); 19161 break; 19162 } 19163 vim_free(varp); 19164 } 19165} 19166 19167/* 19168 * Free the memory for a variable value and set the value to NULL or 0. 19169 */ 19170 void 19171clear_tv(varp) 19172 typval_T *varp; 19173{ 19174 if (varp != NULL) 19175 { 19176 switch (varp->v_type) 19177 { 19178 case VAR_FUNC: 19179 func_unref(varp->vval.v_string); 19180 /*FALLTHROUGH*/ 19181 case VAR_STRING: 19182 vim_free(varp->vval.v_string); 19183 varp->vval.v_string = NULL; 19184 break; 19185 case VAR_LIST: 19186 list_unref(varp->vval.v_list); 19187 varp->vval.v_list = NULL; 19188 break; 19189 case VAR_DICT: 19190 dict_unref(varp->vval.v_dict); 19191 varp->vval.v_dict = NULL; 19192 break; 19193 case VAR_NUMBER: 19194 varp->vval.v_number = 0; 19195 break; 19196#ifdef FEAT_FLOAT 19197 case VAR_FLOAT: 19198 varp->vval.v_float = 0.0; 19199 break; 19200#endif 19201 case VAR_UNKNOWN: 19202 break; 19203 default: 19204 EMSG2(_(e_intern2), "clear_tv()"); 19205 } 19206 varp->v_lock = 0; 19207 } 19208} 19209 19210/* 19211 * Set the value of a variable to NULL without freeing items. 19212 */ 19213 static void 19214init_tv(varp) 19215 typval_T *varp; 19216{ 19217 if (varp != NULL) 19218 vim_memset(varp, 0, sizeof(typval_T)); 19219} 19220 19221/* 19222 * Get the number value of a variable. 19223 * If it is a String variable, uses vim_str2nr(). 19224 * For incompatible types, return 0. 19225 * get_tv_number_chk() is similar to get_tv_number(), but informs the 19226 * caller of incompatible types: it sets *denote to TRUE if "denote" 19227 * is not NULL or returns -1 otherwise. 19228 */ 19229 static long 19230get_tv_number(varp) 19231 typval_T *varp; 19232{ 19233 int error = FALSE; 19234 19235 return get_tv_number_chk(varp, &error); /* return 0L on error */ 19236} 19237 19238 long 19239get_tv_number_chk(varp, denote) 19240 typval_T *varp; 19241 int *denote; 19242{ 19243 long n = 0L; 19244 19245 switch (varp->v_type) 19246 { 19247 case VAR_NUMBER: 19248 return (long)(varp->vval.v_number); 19249#ifdef FEAT_FLOAT 19250 case VAR_FLOAT: 19251 EMSG(_("E805: Using a Float as a Number")); 19252 break; 19253#endif 19254 case VAR_FUNC: 19255 EMSG(_("E703: Using a Funcref as a Number")); 19256 break; 19257 case VAR_STRING: 19258 if (varp->vval.v_string != NULL) 19259 vim_str2nr(varp->vval.v_string, NULL, NULL, 19260 TRUE, TRUE, &n, NULL); 19261 return n; 19262 case VAR_LIST: 19263 EMSG(_("E745: Using a List as a Number")); 19264 break; 19265 case VAR_DICT: 19266 EMSG(_("E728: Using a Dictionary as a Number")); 19267 break; 19268 default: 19269 EMSG2(_(e_intern2), "get_tv_number()"); 19270 break; 19271 } 19272 if (denote == NULL) /* useful for values that must be unsigned */ 19273 n = -1; 19274 else 19275 *denote = TRUE; 19276 return n; 19277} 19278 19279/* 19280 * Get the lnum from the first argument. 19281 * Also accepts ".", "$", etc., but that only works for the current buffer. 19282 * Returns -1 on error. 19283 */ 19284 static linenr_T 19285get_tv_lnum(argvars) 19286 typval_T *argvars; 19287{ 19288 typval_T rettv; 19289 linenr_T lnum; 19290 19291 lnum = get_tv_number_chk(&argvars[0], NULL); 19292 if (lnum == 0) /* no valid number, try using line() */ 19293 { 19294 rettv.v_type = VAR_NUMBER; 19295 f_line(argvars, &rettv); 19296 lnum = rettv.vval.v_number; 19297 clear_tv(&rettv); 19298 } 19299 return lnum; 19300} 19301 19302/* 19303 * Get the lnum from the first argument. 19304 * Also accepts "$", then "buf" is used. 19305 * Returns 0 on error. 19306 */ 19307 static linenr_T 19308get_tv_lnum_buf(argvars, buf) 19309 typval_T *argvars; 19310 buf_T *buf; 19311{ 19312 if (argvars[0].v_type == VAR_STRING 19313 && argvars[0].vval.v_string != NULL 19314 && argvars[0].vval.v_string[0] == '$' 19315 && buf != NULL) 19316 return buf->b_ml.ml_line_count; 19317 return get_tv_number_chk(&argvars[0], NULL); 19318} 19319 19320/* 19321 * Get the string value of a variable. 19322 * If it is a Number variable, the number is converted into a string. 19323 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 19324 * get_tv_string_buf() uses a given buffer. 19325 * If the String variable has never been set, return an empty string. 19326 * Never returns NULL; 19327 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 19328 * NULL on error. 19329 */ 19330 static char_u * 19331get_tv_string(varp) 19332 typval_T *varp; 19333{ 19334 static char_u mybuf[NUMBUFLEN]; 19335 19336 return get_tv_string_buf(varp, mybuf); 19337} 19338 19339 static char_u * 19340get_tv_string_buf(varp, buf) 19341 typval_T *varp; 19342 char_u *buf; 19343{ 19344 char_u *res = get_tv_string_buf_chk(varp, buf); 19345 19346 return res != NULL ? res : (char_u *)""; 19347} 19348 19349 char_u * 19350get_tv_string_chk(varp) 19351 typval_T *varp; 19352{ 19353 static char_u mybuf[NUMBUFLEN]; 19354 19355 return get_tv_string_buf_chk(varp, mybuf); 19356} 19357 19358 static char_u * 19359get_tv_string_buf_chk(varp, buf) 19360 typval_T *varp; 19361 char_u *buf; 19362{ 19363 switch (varp->v_type) 19364 { 19365 case VAR_NUMBER: 19366 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 19367 return buf; 19368 case VAR_FUNC: 19369 EMSG(_("E729: using Funcref as a String")); 19370 break; 19371 case VAR_LIST: 19372 EMSG(_("E730: using List as a String")); 19373 break; 19374 case VAR_DICT: 19375 EMSG(_("E731: using Dictionary as a String")); 19376 break; 19377#ifdef FEAT_FLOAT 19378 case VAR_FLOAT: 19379 EMSG(_("E806: using Float as a String")); 19380 break; 19381#endif 19382 case VAR_STRING: 19383 if (varp->vval.v_string != NULL) 19384 return varp->vval.v_string; 19385 return (char_u *)""; 19386 default: 19387 EMSG2(_(e_intern2), "get_tv_string_buf()"); 19388 break; 19389 } 19390 return NULL; 19391} 19392 19393/* 19394 * Find variable "name" in the list of variables. 19395 * Return a pointer to it if found, NULL if not found. 19396 * Careful: "a:0" variables don't have a name. 19397 * When "htp" is not NULL we are writing to the variable, set "htp" to the 19398 * hashtab_T used. 19399 */ 19400 static dictitem_T * 19401find_var(name, htp) 19402 char_u *name; 19403 hashtab_T **htp; 19404{ 19405 char_u *varname; 19406 hashtab_T *ht; 19407 19408 ht = find_var_ht(name, &varname); 19409 if (htp != NULL) 19410 *htp = ht; 19411 if (ht == NULL) 19412 return NULL; 19413 return find_var_in_ht(ht, varname, htp != NULL); 19414} 19415 19416/* 19417 * Find variable "varname" in hashtab "ht". 19418 * Returns NULL if not found. 19419 */ 19420 static dictitem_T * 19421find_var_in_ht(ht, varname, writing) 19422 hashtab_T *ht; 19423 char_u *varname; 19424 int writing; 19425{ 19426 hashitem_T *hi; 19427 19428 if (*varname == NUL) 19429 { 19430 /* Must be something like "s:", otherwise "ht" would be NULL. */ 19431 switch (varname[-2]) 19432 { 19433 case 's': return &SCRIPT_SV(current_SID)->sv_var; 19434 case 'g': return &globvars_var; 19435 case 'v': return &vimvars_var; 19436 case 'b': return &curbuf->b_bufvar; 19437 case 'w': return &curwin->w_winvar; 19438#ifdef FEAT_WINDOWS 19439 case 't': return &curtab->tp_winvar; 19440#endif 19441 case 'l': return current_funccal == NULL 19442 ? NULL : ¤t_funccal->l_vars_var; 19443 case 'a': return current_funccal == NULL 19444 ? NULL : ¤t_funccal->l_avars_var; 19445 } 19446 return NULL; 19447 } 19448 19449 hi = hash_find(ht, varname); 19450 if (HASHITEM_EMPTY(hi)) 19451 { 19452 /* For global variables we may try auto-loading the script. If it 19453 * worked find the variable again. Don't auto-load a script if it was 19454 * loaded already, otherwise it would be loaded every time when 19455 * checking if a function name is a Funcref variable. */ 19456 if (ht == &globvarht && !writing 19457 && script_autoload(varname, FALSE) && !aborting()) 19458 hi = hash_find(ht, varname); 19459 if (HASHITEM_EMPTY(hi)) 19460 return NULL; 19461 } 19462 return HI2DI(hi); 19463} 19464 19465/* 19466 * Find the hashtab used for a variable name. 19467 * Set "varname" to the start of name without ':'. 19468 */ 19469 static hashtab_T * 19470find_var_ht(name, varname) 19471 char_u *name; 19472 char_u **varname; 19473{ 19474 hashitem_T *hi; 19475 19476 if (name[1] != ':') 19477 { 19478 /* The name must not start with a colon or #. */ 19479 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 19480 return NULL; 19481 *varname = name; 19482 19483 /* "version" is "v:version" in all scopes */ 19484 hi = hash_find(&compat_hashtab, name); 19485 if (!HASHITEM_EMPTY(hi)) 19486 return &compat_hashtab; 19487 19488 if (current_funccal == NULL) 19489 return &globvarht; /* global variable */ 19490 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 19491 } 19492 *varname = name + 2; 19493 if (*name == 'g') /* global variable */ 19494 return &globvarht; 19495 /* There must be no ':' or '#' in the rest of the name, unless g: is used 19496 */ 19497 if (vim_strchr(name + 2, ':') != NULL 19498 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 19499 return NULL; 19500 if (*name == 'b') /* buffer variable */ 19501 return &curbuf->b_vars.dv_hashtab; 19502 if (*name == 'w') /* window variable */ 19503 return &curwin->w_vars.dv_hashtab; 19504#ifdef FEAT_WINDOWS 19505 if (*name == 't') /* tab page variable */ 19506 return &curtab->tp_vars.dv_hashtab; 19507#endif 19508 if (*name == 'v') /* v: variable */ 19509 return &vimvarht; 19510 if (*name == 'a' && current_funccal != NULL) /* function argument */ 19511 return ¤t_funccal->l_avars.dv_hashtab; 19512 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 19513 return ¤t_funccal->l_vars.dv_hashtab; 19514 if (*name == 's' /* script variable */ 19515 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 19516 return &SCRIPT_VARS(current_SID); 19517 return NULL; 19518} 19519 19520/* 19521 * Get the string value of a (global/local) variable. 19522 * Note: see get_tv_string() for how long the pointer remains valid. 19523 * Returns NULL when it doesn't exist. 19524 */ 19525 char_u * 19526get_var_value(name) 19527 char_u *name; 19528{ 19529 dictitem_T *v; 19530 19531 v = find_var(name, NULL); 19532 if (v == NULL) 19533 return NULL; 19534 return get_tv_string(&v->di_tv); 19535} 19536 19537/* 19538 * Allocate a new hashtab for a sourced script. It will be used while 19539 * sourcing this script and when executing functions defined in the script. 19540 */ 19541 void 19542new_script_vars(id) 19543 scid_T id; 19544{ 19545 int i; 19546 hashtab_T *ht; 19547 scriptvar_T *sv; 19548 19549 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 19550 { 19551 /* Re-allocating ga_data means that an ht_array pointing to 19552 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 19553 * at its init value. Also reset "v_dict", it's always the same. */ 19554 for (i = 1; i <= ga_scripts.ga_len; ++i) 19555 { 19556 ht = &SCRIPT_VARS(i); 19557 if (ht->ht_mask == HT_INIT_SIZE - 1) 19558 ht->ht_array = ht->ht_smallarray; 19559 sv = SCRIPT_SV(i); 19560 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 19561 } 19562 19563 while (ga_scripts.ga_len < id) 19564 { 19565 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = 19566 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); 19567 init_var_dict(&sv->sv_dict, &sv->sv_var); 19568 ++ga_scripts.ga_len; 19569 } 19570 } 19571} 19572 19573/* 19574 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 19575 * point to it. 19576 */ 19577 void 19578init_var_dict(dict, dict_var) 19579 dict_T *dict; 19580 dictitem_T *dict_var; 19581{ 19582 hash_init(&dict->dv_hashtab); 19583 dict->dv_refcount = DO_NOT_FREE_CNT; 19584 dict->dv_copyID = 0; 19585 dict_var->di_tv.vval.v_dict = dict; 19586 dict_var->di_tv.v_type = VAR_DICT; 19587 dict_var->di_tv.v_lock = VAR_FIXED; 19588 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19589 dict_var->di_key[0] = NUL; 19590} 19591 19592/* 19593 * Clean up a list of internal variables. 19594 * Frees all allocated variables and the value they contain. 19595 * Clears hashtab "ht", does not free it. 19596 */ 19597 void 19598vars_clear(ht) 19599 hashtab_T *ht; 19600{ 19601 vars_clear_ext(ht, TRUE); 19602} 19603 19604/* 19605 * Like vars_clear(), but only free the value if "free_val" is TRUE. 19606 */ 19607 static void 19608vars_clear_ext(ht, free_val) 19609 hashtab_T *ht; 19610 int free_val; 19611{ 19612 int todo; 19613 hashitem_T *hi; 19614 dictitem_T *v; 19615 19616 hash_lock(ht); 19617 todo = (int)ht->ht_used; 19618 for (hi = ht->ht_array; todo > 0; ++hi) 19619 { 19620 if (!HASHITEM_EMPTY(hi)) 19621 { 19622 --todo; 19623 19624 /* Free the variable. Don't remove it from the hashtab, 19625 * ht_array might change then. hash_clear() takes care of it 19626 * later. */ 19627 v = HI2DI(hi); 19628 if (free_val) 19629 clear_tv(&v->di_tv); 19630 if ((v->di_flags & DI_FLAGS_FIX) == 0) 19631 vim_free(v); 19632 } 19633 } 19634 hash_clear(ht); 19635 ht->ht_used = 0; 19636} 19637 19638/* 19639 * Delete a variable from hashtab "ht" at item "hi". 19640 * Clear the variable value and free the dictitem. 19641 */ 19642 static void 19643delete_var(ht, hi) 19644 hashtab_T *ht; 19645 hashitem_T *hi; 19646{ 19647 dictitem_T *di = HI2DI(hi); 19648 19649 hash_remove(ht, hi); 19650 clear_tv(&di->di_tv); 19651 vim_free(di); 19652} 19653 19654/* 19655 * List the value of one internal variable. 19656 */ 19657 static void 19658list_one_var(v, prefix, first) 19659 dictitem_T *v; 19660 char_u *prefix; 19661 int *first; 19662{ 19663 char_u *tofree; 19664 char_u *s; 19665 char_u numbuf[NUMBUFLEN]; 19666 19667 current_copyID += COPYID_INC; 19668 s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID); 19669 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 19670 s == NULL ? (char_u *)"" : s, first); 19671 vim_free(tofree); 19672} 19673 19674 static void 19675list_one_var_a(prefix, name, type, string, first) 19676 char_u *prefix; 19677 char_u *name; 19678 int type; 19679 char_u *string; 19680 int *first; /* when TRUE clear rest of screen and set to FALSE */ 19681{ 19682 /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ 19683 msg_start(); 19684 msg_puts(prefix); 19685 if (name != NULL) /* "a:" vars don't have a name stored */ 19686 msg_puts(name); 19687 msg_putchar(' '); 19688 msg_advance(22); 19689 if (type == VAR_NUMBER) 19690 msg_putchar('#'); 19691 else if (type == VAR_FUNC) 19692 msg_putchar('*'); 19693 else if (type == VAR_LIST) 19694 { 19695 msg_putchar('['); 19696 if (*string == '[') 19697 ++string; 19698 } 19699 else if (type == VAR_DICT) 19700 { 19701 msg_putchar('{'); 19702 if (*string == '{') 19703 ++string; 19704 } 19705 else 19706 msg_putchar(' '); 19707 19708 msg_outtrans(string); 19709 19710 if (type == VAR_FUNC) 19711 msg_puts((char_u *)"()"); 19712 if (*first) 19713 { 19714 msg_clr_eos(); 19715 *first = FALSE; 19716 } 19717} 19718 19719/* 19720 * Set variable "name" to value in "tv". 19721 * If the variable already exists, the value is updated. 19722 * Otherwise the variable is created. 19723 */ 19724 static void 19725set_var(name, tv, copy) 19726 char_u *name; 19727 typval_T *tv; 19728 int copy; /* make copy of value in "tv" */ 19729{ 19730 dictitem_T *v; 19731 char_u *varname; 19732 hashtab_T *ht; 19733 char_u *p; 19734 19735 ht = find_var_ht(name, &varname); 19736 if (ht == NULL || *varname == NUL) 19737 { 19738 EMSG2(_(e_illvar), name); 19739 return; 19740 } 19741 v = find_var_in_ht(ht, varname, TRUE); 19742 19743 if (tv->v_type == VAR_FUNC) 19744 { 19745 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 19746 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 19747 ? name[2] : name[0])) 19748 { 19749 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 19750 return; 19751 } 19752 /* Don't allow hiding a function. When "v" is not NULL we migth be 19753 * assigning another function to the same var, the type is checked 19754 * below. */ 19755 if (v == NULL && function_exists(name)) 19756 { 19757 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 19758 name); 19759 return; 19760 } 19761 } 19762 19763 if (v != NULL) 19764 { 19765 /* existing variable, need to clear the value */ 19766 if (var_check_ro(v->di_flags, name) 19767 || tv_check_lock(v->di_tv.v_lock, name)) 19768 return; 19769 if (v->di_tv.v_type != tv->v_type 19770 && !((v->di_tv.v_type == VAR_STRING 19771 || v->di_tv.v_type == VAR_NUMBER) 19772 && (tv->v_type == VAR_STRING 19773 || tv->v_type == VAR_NUMBER)) 19774#ifdef FEAT_FLOAT 19775 && !((v->di_tv.v_type == VAR_NUMBER 19776 || v->di_tv.v_type == VAR_FLOAT) 19777 && (tv->v_type == VAR_NUMBER 19778 || tv->v_type == VAR_FLOAT)) 19779#endif 19780 ) 19781 { 19782 EMSG2(_("E706: Variable type mismatch for: %s"), name); 19783 return; 19784 } 19785 19786 /* 19787 * Handle setting internal v: variables separately: we don't change 19788 * the type. 19789 */ 19790 if (ht == &vimvarht) 19791 { 19792 if (v->di_tv.v_type == VAR_STRING) 19793 { 19794 vim_free(v->di_tv.vval.v_string); 19795 if (copy || tv->v_type != VAR_STRING) 19796 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 19797 else 19798 { 19799 /* Take over the string to avoid an extra alloc/free. */ 19800 v->di_tv.vval.v_string = tv->vval.v_string; 19801 tv->vval.v_string = NULL; 19802 } 19803 } 19804 else if (v->di_tv.v_type != VAR_NUMBER) 19805 EMSG2(_(e_intern2), "set_var()"); 19806 else 19807 { 19808 v->di_tv.vval.v_number = get_tv_number(tv); 19809 if (STRCMP(varname, "searchforward") == 0) 19810 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 19811 } 19812 return; 19813 } 19814 19815 clear_tv(&v->di_tv); 19816 } 19817 else /* add a new variable */ 19818 { 19819 /* Can't add "v:" variable. */ 19820 if (ht == &vimvarht) 19821 { 19822 EMSG2(_(e_illvar), name); 19823 return; 19824 } 19825 19826 /* Make sure the variable name is valid. */ 19827 for (p = varname; *p != NUL; ++p) 19828 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 19829 && *p != AUTOLOAD_CHAR) 19830 { 19831 EMSG2(_(e_illvar), varname); 19832 return; 19833 } 19834 19835 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19836 + STRLEN(varname))); 19837 if (v == NULL) 19838 return; 19839 STRCPY(v->di_key, varname); 19840 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 19841 { 19842 vim_free(v); 19843 return; 19844 } 19845 v->di_flags = 0; 19846 } 19847 19848 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 19849 copy_tv(tv, &v->di_tv); 19850 else 19851 { 19852 v->di_tv = *tv; 19853 v->di_tv.v_lock = 0; 19854 init_tv(tv); 19855 } 19856} 19857 19858/* 19859 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 19860 * Also give an error message. 19861 */ 19862 static int 19863var_check_ro(flags, name) 19864 int flags; 19865 char_u *name; 19866{ 19867 if (flags & DI_FLAGS_RO) 19868 { 19869 EMSG2(_(e_readonlyvar), name); 19870 return TRUE; 19871 } 19872 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 19873 { 19874 EMSG2(_(e_readonlysbx), name); 19875 return TRUE; 19876 } 19877 return FALSE; 19878} 19879 19880/* 19881 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 19882 * Also give an error message. 19883 */ 19884 static int 19885var_check_fixed(flags, name) 19886 int flags; 19887 char_u *name; 19888{ 19889 if (flags & DI_FLAGS_FIX) 19890 { 19891 EMSG2(_("E795: Cannot delete variable %s"), name); 19892 return TRUE; 19893 } 19894 return FALSE; 19895} 19896 19897/* 19898 * Return TRUE if typeval "tv" is set to be locked (immutable). 19899 * Also give an error message, using "name". 19900 */ 19901 static int 19902tv_check_lock(lock, name) 19903 int lock; 19904 char_u *name; 19905{ 19906 if (lock & VAR_LOCKED) 19907 { 19908 EMSG2(_("E741: Value is locked: %s"), 19909 name == NULL ? (char_u *)_("Unknown") : name); 19910 return TRUE; 19911 } 19912 if (lock & VAR_FIXED) 19913 { 19914 EMSG2(_("E742: Cannot change value of %s"), 19915 name == NULL ? (char_u *)_("Unknown") : name); 19916 return TRUE; 19917 } 19918 return FALSE; 19919} 19920 19921/* 19922 * Copy the values from typval_T "from" to typval_T "to". 19923 * When needed allocates string or increases reference count. 19924 * Does not make a copy of a list or dict but copies the reference! 19925 * It is OK for "from" and "to" to point to the same item. This is used to 19926 * make a copy later. 19927 */ 19928 void 19929copy_tv(from, to) 19930 typval_T *from; 19931 typval_T *to; 19932{ 19933 to->v_type = from->v_type; 19934 to->v_lock = 0; 19935 switch (from->v_type) 19936 { 19937 case VAR_NUMBER: 19938 to->vval.v_number = from->vval.v_number; 19939 break; 19940#ifdef FEAT_FLOAT 19941 case VAR_FLOAT: 19942 to->vval.v_float = from->vval.v_float; 19943 break; 19944#endif 19945 case VAR_STRING: 19946 case VAR_FUNC: 19947 if (from->vval.v_string == NULL) 19948 to->vval.v_string = NULL; 19949 else 19950 { 19951 to->vval.v_string = vim_strsave(from->vval.v_string); 19952 if (from->v_type == VAR_FUNC) 19953 func_ref(to->vval.v_string); 19954 } 19955 break; 19956 case VAR_LIST: 19957 if (from->vval.v_list == NULL) 19958 to->vval.v_list = NULL; 19959 else 19960 { 19961 to->vval.v_list = from->vval.v_list; 19962 ++to->vval.v_list->lv_refcount; 19963 } 19964 break; 19965 case VAR_DICT: 19966 if (from->vval.v_dict == NULL) 19967 to->vval.v_dict = NULL; 19968 else 19969 { 19970 to->vval.v_dict = from->vval.v_dict; 19971 ++to->vval.v_dict->dv_refcount; 19972 } 19973 break; 19974 default: 19975 EMSG2(_(e_intern2), "copy_tv()"); 19976 break; 19977 } 19978} 19979 19980/* 19981 * Make a copy of an item. 19982 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 19983 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 19984 * reference to an already copied list/dict can be used. 19985 * Returns FAIL or OK. 19986 */ 19987 static int 19988item_copy(from, to, deep, copyID) 19989 typval_T *from; 19990 typval_T *to; 19991 int deep; 19992 int copyID; 19993{ 19994 static int recurse = 0; 19995 int ret = OK; 19996 19997 if (recurse >= DICT_MAXNEST) 19998 { 19999 EMSG(_("E698: variable nested too deep for making a copy")); 20000 return FAIL; 20001 } 20002 ++recurse; 20003 20004 switch (from->v_type) 20005 { 20006 case VAR_NUMBER: 20007#ifdef FEAT_FLOAT 20008 case VAR_FLOAT: 20009#endif 20010 case VAR_STRING: 20011 case VAR_FUNC: 20012 copy_tv(from, to); 20013 break; 20014 case VAR_LIST: 20015 to->v_type = VAR_LIST; 20016 to->v_lock = 0; 20017 if (from->vval.v_list == NULL) 20018 to->vval.v_list = NULL; 20019 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 20020 { 20021 /* use the copy made earlier */ 20022 to->vval.v_list = from->vval.v_list->lv_copylist; 20023 ++to->vval.v_list->lv_refcount; 20024 } 20025 else 20026 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 20027 if (to->vval.v_list == NULL) 20028 ret = FAIL; 20029 break; 20030 case VAR_DICT: 20031 to->v_type = VAR_DICT; 20032 to->v_lock = 0; 20033 if (from->vval.v_dict == NULL) 20034 to->vval.v_dict = NULL; 20035 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 20036 { 20037 /* use the copy made earlier */ 20038 to->vval.v_dict = from->vval.v_dict->dv_copydict; 20039 ++to->vval.v_dict->dv_refcount; 20040 } 20041 else 20042 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 20043 if (to->vval.v_dict == NULL) 20044 ret = FAIL; 20045 break; 20046 default: 20047 EMSG2(_(e_intern2), "item_copy()"); 20048 ret = FAIL; 20049 } 20050 --recurse; 20051 return ret; 20052} 20053 20054/* 20055 * ":echo expr1 ..." print each argument separated with a space, add a 20056 * newline at the end. 20057 * ":echon expr1 ..." print each argument plain. 20058 */ 20059 void 20060ex_echo(eap) 20061 exarg_T *eap; 20062{ 20063 char_u *arg = eap->arg; 20064 typval_T rettv; 20065 char_u *tofree; 20066 char_u *p; 20067 int needclr = TRUE; 20068 int atstart = TRUE; 20069 char_u numbuf[NUMBUFLEN]; 20070 20071 if (eap->skip) 20072 ++emsg_skip; 20073 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 20074 { 20075 /* If eval1() causes an error message the text from the command may 20076 * still need to be cleared. E.g., "echo 22,44". */ 20077 need_clr_eos = needclr; 20078 20079 p = arg; 20080 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 20081 { 20082 /* 20083 * Report the invalid expression unless the expression evaluation 20084 * has been cancelled due to an aborting error, an interrupt, or an 20085 * exception. 20086 */ 20087 if (!aborting()) 20088 EMSG2(_(e_invexpr2), p); 20089 need_clr_eos = FALSE; 20090 break; 20091 } 20092 need_clr_eos = FALSE; 20093 20094 if (!eap->skip) 20095 { 20096 if (atstart) 20097 { 20098 atstart = FALSE; 20099 /* Call msg_start() after eval1(), evaluating the expression 20100 * may cause a message to appear. */ 20101 if (eap->cmdidx == CMD_echo) 20102 msg_start(); 20103 } 20104 else if (eap->cmdidx == CMD_echo) 20105 msg_puts_attr((char_u *)" ", echo_attr); 20106 current_copyID += COPYID_INC; 20107 p = echo_string(&rettv, &tofree, numbuf, current_copyID); 20108 if (p != NULL) 20109 for ( ; *p != NUL && !got_int; ++p) 20110 { 20111 if (*p == '\n' || *p == '\r' || *p == TAB) 20112 { 20113 if (*p != TAB && needclr) 20114 { 20115 /* remove any text still there from the command */ 20116 msg_clr_eos(); 20117 needclr = FALSE; 20118 } 20119 msg_putchar_attr(*p, echo_attr); 20120 } 20121 else 20122 { 20123#ifdef FEAT_MBYTE 20124 if (has_mbyte) 20125 { 20126 int i = (*mb_ptr2len)(p); 20127 20128 (void)msg_outtrans_len_attr(p, i, echo_attr); 20129 p += i - 1; 20130 } 20131 else 20132#endif 20133 (void)msg_outtrans_len_attr(p, 1, echo_attr); 20134 } 20135 } 20136 vim_free(tofree); 20137 } 20138 clear_tv(&rettv); 20139 arg = skipwhite(arg); 20140 } 20141 eap->nextcmd = check_nextcmd(arg); 20142 20143 if (eap->skip) 20144 --emsg_skip; 20145 else 20146 { 20147 /* remove text that may still be there from the command */ 20148 if (needclr) 20149 msg_clr_eos(); 20150 if (eap->cmdidx == CMD_echo) 20151 msg_end(); 20152 } 20153} 20154 20155/* 20156 * ":echohl {name}". 20157 */ 20158 void 20159ex_echohl(eap) 20160 exarg_T *eap; 20161{ 20162 int id; 20163 20164 id = syn_name2id(eap->arg); 20165 if (id == 0) 20166 echo_attr = 0; 20167 else 20168 echo_attr = syn_id2attr(id); 20169} 20170 20171/* 20172 * ":execute expr1 ..." execute the result of an expression. 20173 * ":echomsg expr1 ..." Print a message 20174 * ":echoerr expr1 ..." Print an error 20175 * Each gets spaces around each argument and a newline at the end for 20176 * echo commands 20177 */ 20178 void 20179ex_execute(eap) 20180 exarg_T *eap; 20181{ 20182 char_u *arg = eap->arg; 20183 typval_T rettv; 20184 int ret = OK; 20185 char_u *p; 20186 garray_T ga; 20187 int len; 20188 int save_did_emsg; 20189 20190 ga_init2(&ga, 1, 80); 20191 20192 if (eap->skip) 20193 ++emsg_skip; 20194 while (*arg != NUL && *arg != '|' && *arg != '\n') 20195 { 20196 p = arg; 20197 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 20198 { 20199 /* 20200 * Report the invalid expression unless the expression evaluation 20201 * has been cancelled due to an aborting error, an interrupt, or an 20202 * exception. 20203 */ 20204 if (!aborting()) 20205 EMSG2(_(e_invexpr2), p); 20206 ret = FAIL; 20207 break; 20208 } 20209 20210 if (!eap->skip) 20211 { 20212 p = get_tv_string(&rettv); 20213 len = (int)STRLEN(p); 20214 if (ga_grow(&ga, len + 2) == FAIL) 20215 { 20216 clear_tv(&rettv); 20217 ret = FAIL; 20218 break; 20219 } 20220 if (ga.ga_len) 20221 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 20222 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 20223 ga.ga_len += len; 20224 } 20225 20226 clear_tv(&rettv); 20227 arg = skipwhite(arg); 20228 } 20229 20230 if (ret != FAIL && ga.ga_data != NULL) 20231 { 20232 if (eap->cmdidx == CMD_echomsg) 20233 { 20234 MSG_ATTR(ga.ga_data, echo_attr); 20235 out_flush(); 20236 } 20237 else if (eap->cmdidx == CMD_echoerr) 20238 { 20239 /* We don't want to abort following commands, restore did_emsg. */ 20240 save_did_emsg = did_emsg; 20241 EMSG((char_u *)ga.ga_data); 20242 if (!force_abort) 20243 did_emsg = save_did_emsg; 20244 } 20245 else if (eap->cmdidx == CMD_execute) 20246 do_cmdline((char_u *)ga.ga_data, 20247 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 20248 } 20249 20250 ga_clear(&ga); 20251 20252 if (eap->skip) 20253 --emsg_skip; 20254 20255 eap->nextcmd = check_nextcmd(arg); 20256} 20257 20258/* 20259 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 20260 * "arg" points to the "&" or '+' when called, to "option" when returning. 20261 * Returns NULL when no option name found. Otherwise pointer to the char 20262 * after the option name. 20263 */ 20264 static char_u * 20265find_option_end(arg, opt_flags) 20266 char_u **arg; 20267 int *opt_flags; 20268{ 20269 char_u *p = *arg; 20270 20271 ++p; 20272 if (*p == 'g' && p[1] == ':') 20273 { 20274 *opt_flags = OPT_GLOBAL; 20275 p += 2; 20276 } 20277 else if (*p == 'l' && p[1] == ':') 20278 { 20279 *opt_flags = OPT_LOCAL; 20280 p += 2; 20281 } 20282 else 20283 *opt_flags = 0; 20284 20285 if (!ASCII_ISALPHA(*p)) 20286 return NULL; 20287 *arg = p; 20288 20289 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 20290 p += 4; /* termcap option */ 20291 else 20292 while (ASCII_ISALPHA(*p)) 20293 ++p; 20294 return p; 20295} 20296 20297/* 20298 * ":function" 20299 */ 20300 void 20301ex_function(eap) 20302 exarg_T *eap; 20303{ 20304 char_u *theline; 20305 int j; 20306 int c; 20307 int saved_did_emsg; 20308 char_u *name = NULL; 20309 char_u *p; 20310 char_u *arg; 20311 char_u *line_arg = NULL; 20312 garray_T newargs; 20313 garray_T newlines; 20314 int varargs = FALSE; 20315 int mustend = FALSE; 20316 int flags = 0; 20317 ufunc_T *fp; 20318 int indent; 20319 int nesting; 20320 char_u *skip_until = NULL; 20321 dictitem_T *v; 20322 funcdict_T fudi; 20323 static int func_nr = 0; /* number for nameless function */ 20324 int paren; 20325 hashtab_T *ht; 20326 int todo; 20327 hashitem_T *hi; 20328 int sourcing_lnum_off; 20329 20330 /* 20331 * ":function" without argument: list functions. 20332 */ 20333 if (ends_excmd(*eap->arg)) 20334 { 20335 if (!eap->skip) 20336 { 20337 todo = (int)func_hashtab.ht_used; 20338 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 20339 { 20340 if (!HASHITEM_EMPTY(hi)) 20341 { 20342 --todo; 20343 fp = HI2UF(hi); 20344 if (!isdigit(*fp->uf_name)) 20345 list_func_head(fp, FALSE); 20346 } 20347 } 20348 } 20349 eap->nextcmd = check_nextcmd(eap->arg); 20350 return; 20351 } 20352 20353 /* 20354 * ":function /pat": list functions matching pattern. 20355 */ 20356 if (*eap->arg == '/') 20357 { 20358 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 20359 if (!eap->skip) 20360 { 20361 regmatch_T regmatch; 20362 20363 c = *p; 20364 *p = NUL; 20365 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 20366 *p = c; 20367 if (regmatch.regprog != NULL) 20368 { 20369 regmatch.rm_ic = p_ic; 20370 20371 todo = (int)func_hashtab.ht_used; 20372 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 20373 { 20374 if (!HASHITEM_EMPTY(hi)) 20375 { 20376 --todo; 20377 fp = HI2UF(hi); 20378 if (!isdigit(*fp->uf_name) 20379 && vim_regexec(®match, fp->uf_name, 0)) 20380 list_func_head(fp, FALSE); 20381 } 20382 } 20383 vim_free(regmatch.regprog); 20384 } 20385 } 20386 if (*p == '/') 20387 ++p; 20388 eap->nextcmd = check_nextcmd(p); 20389 return; 20390 } 20391 20392 /* 20393 * Get the function name. There are these situations: 20394 * func normal function name 20395 * "name" == func, "fudi.fd_dict" == NULL 20396 * dict.func new dictionary entry 20397 * "name" == NULL, "fudi.fd_dict" set, 20398 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 20399 * dict.func existing dict entry with a Funcref 20400 * "name" == func, "fudi.fd_dict" set, 20401 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 20402 * dict.func existing dict entry that's not a Funcref 20403 * "name" == NULL, "fudi.fd_dict" set, 20404 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 20405 */ 20406 p = eap->arg; 20407 name = trans_function_name(&p, eap->skip, 0, &fudi); 20408 paren = (vim_strchr(p, '(') != NULL); 20409 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 20410 { 20411 /* 20412 * Return on an invalid expression in braces, unless the expression 20413 * evaluation has been cancelled due to an aborting error, an 20414 * interrupt, or an exception. 20415 */ 20416 if (!aborting()) 20417 { 20418 if (!eap->skip && fudi.fd_newkey != NULL) 20419 EMSG2(_(e_dictkey), fudi.fd_newkey); 20420 vim_free(fudi.fd_newkey); 20421 return; 20422 } 20423 else 20424 eap->skip = TRUE; 20425 } 20426 20427 /* An error in a function call during evaluation of an expression in magic 20428 * braces should not cause the function not to be defined. */ 20429 saved_did_emsg = did_emsg; 20430 did_emsg = FALSE; 20431 20432 /* 20433 * ":function func" with only function name: list function. 20434 */ 20435 if (!paren) 20436 { 20437 if (!ends_excmd(*skipwhite(p))) 20438 { 20439 EMSG(_(e_trailing)); 20440 goto ret_free; 20441 } 20442 eap->nextcmd = check_nextcmd(p); 20443 if (eap->nextcmd != NULL) 20444 *p = NUL; 20445 if (!eap->skip && !got_int) 20446 { 20447 fp = find_func(name); 20448 if (fp != NULL) 20449 { 20450 list_func_head(fp, TRUE); 20451 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 20452 { 20453 if (FUNCLINE(fp, j) == NULL) 20454 continue; 20455 msg_putchar('\n'); 20456 msg_outnum((long)(j + 1)); 20457 if (j < 9) 20458 msg_putchar(' '); 20459 if (j < 99) 20460 msg_putchar(' '); 20461 msg_prt_line(FUNCLINE(fp, j), FALSE); 20462 out_flush(); /* show a line at a time */ 20463 ui_breakcheck(); 20464 } 20465 if (!got_int) 20466 { 20467 msg_putchar('\n'); 20468 msg_puts((char_u *)" endfunction"); 20469 } 20470 } 20471 else 20472 emsg_funcname(N_("E123: Undefined function: %s"), name); 20473 } 20474 goto ret_free; 20475 } 20476 20477 /* 20478 * ":function name(arg1, arg2)" Define function. 20479 */ 20480 p = skipwhite(p); 20481 if (*p != '(') 20482 { 20483 if (!eap->skip) 20484 { 20485 EMSG2(_("E124: Missing '(': %s"), eap->arg); 20486 goto ret_free; 20487 } 20488 /* attempt to continue by skipping some text */ 20489 if (vim_strchr(p, '(') != NULL) 20490 p = vim_strchr(p, '('); 20491 } 20492 p = skipwhite(p + 1); 20493 20494 ga_init2(&newargs, (int)sizeof(char_u *), 3); 20495 ga_init2(&newlines, (int)sizeof(char_u *), 3); 20496 20497 if (!eap->skip) 20498 { 20499 /* Check the name of the function. Unless it's a dictionary function 20500 * (that we are overwriting). */ 20501 if (name != NULL) 20502 arg = name; 20503 else 20504 arg = fudi.fd_newkey; 20505 if (arg != NULL && (fudi.fd_di == NULL 20506 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 20507 { 20508 if (*arg == K_SPECIAL) 20509 j = 3; 20510 else 20511 j = 0; 20512 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 20513 : eval_isnamec(arg[j]))) 20514 ++j; 20515 if (arg[j] != NUL) 20516 emsg_funcname((char *)e_invarg2, arg); 20517 } 20518 } 20519 20520 /* 20521 * Isolate the arguments: "arg1, arg2, ...)" 20522 */ 20523 while (*p != ')') 20524 { 20525 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 20526 { 20527 varargs = TRUE; 20528 p += 3; 20529 mustend = TRUE; 20530 } 20531 else 20532 { 20533 arg = p; 20534 while (ASCII_ISALNUM(*p) || *p == '_') 20535 ++p; 20536 if (arg == p || isdigit(*arg) 20537 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 20538 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 20539 { 20540 if (!eap->skip) 20541 EMSG2(_("E125: Illegal argument: %s"), arg); 20542 break; 20543 } 20544 if (ga_grow(&newargs, 1) == FAIL) 20545 goto erret; 20546 c = *p; 20547 *p = NUL; 20548 arg = vim_strsave(arg); 20549 if (arg == NULL) 20550 goto erret; 20551 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 20552 *p = c; 20553 newargs.ga_len++; 20554 if (*p == ',') 20555 ++p; 20556 else 20557 mustend = TRUE; 20558 } 20559 p = skipwhite(p); 20560 if (mustend && *p != ')') 20561 { 20562 if (!eap->skip) 20563 EMSG2(_(e_invarg2), eap->arg); 20564 break; 20565 } 20566 } 20567 ++p; /* skip the ')' */ 20568 20569 /* find extra arguments "range", "dict" and "abort" */ 20570 for (;;) 20571 { 20572 p = skipwhite(p); 20573 if (STRNCMP(p, "range", 5) == 0) 20574 { 20575 flags |= FC_RANGE; 20576 p += 5; 20577 } 20578 else if (STRNCMP(p, "dict", 4) == 0) 20579 { 20580 flags |= FC_DICT; 20581 p += 4; 20582 } 20583 else if (STRNCMP(p, "abort", 5) == 0) 20584 { 20585 flags |= FC_ABORT; 20586 p += 5; 20587 } 20588 else 20589 break; 20590 } 20591 20592 /* When there is a line break use what follows for the function body. 20593 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 20594 if (*p == '\n') 20595 line_arg = p + 1; 20596 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 20597 EMSG(_(e_trailing)); 20598 20599 /* 20600 * Read the body of the function, until ":endfunction" is found. 20601 */ 20602 if (KeyTyped) 20603 { 20604 /* Check if the function already exists, don't let the user type the 20605 * whole function before telling him it doesn't work! For a script we 20606 * need to skip the body to be able to find what follows. */ 20607 if (!eap->skip && !eap->forceit) 20608 { 20609 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 20610 EMSG(_(e_funcdict)); 20611 else if (name != NULL && find_func(name) != NULL) 20612 emsg_funcname(e_funcexts, name); 20613 } 20614 20615 if (!eap->skip && did_emsg) 20616 goto erret; 20617 20618 msg_putchar('\n'); /* don't overwrite the function name */ 20619 cmdline_row = msg_row; 20620 } 20621 20622 indent = 2; 20623 nesting = 0; 20624 for (;;) 20625 { 20626 msg_scroll = TRUE; 20627 need_wait_return = FALSE; 20628 sourcing_lnum_off = sourcing_lnum; 20629 20630 if (line_arg != NULL) 20631 { 20632 /* Use eap->arg, split up in parts by line breaks. */ 20633 theline = line_arg; 20634 p = vim_strchr(theline, '\n'); 20635 if (p == NULL) 20636 line_arg += STRLEN(line_arg); 20637 else 20638 { 20639 *p = NUL; 20640 line_arg = p + 1; 20641 } 20642 } 20643 else if (eap->getline == NULL) 20644 theline = getcmdline(':', 0L, indent); 20645 else 20646 theline = eap->getline(':', eap->cookie, indent); 20647 if (KeyTyped) 20648 lines_left = Rows - 1; 20649 if (theline == NULL) 20650 { 20651 EMSG(_("E126: Missing :endfunction")); 20652 goto erret; 20653 } 20654 20655 /* Detect line continuation: sourcing_lnum increased more than one. */ 20656 if (sourcing_lnum > sourcing_lnum_off + 1) 20657 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 20658 else 20659 sourcing_lnum_off = 0; 20660 20661 if (skip_until != NULL) 20662 { 20663 /* between ":append" and "." and between ":python <<EOF" and "EOF" 20664 * don't check for ":endfunc". */ 20665 if (STRCMP(theline, skip_until) == 0) 20666 { 20667 vim_free(skip_until); 20668 skip_until = NULL; 20669 } 20670 } 20671 else 20672 { 20673 /* skip ':' and blanks*/ 20674 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 20675 ; 20676 20677 /* Check for "endfunction". */ 20678 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 20679 { 20680 if (line_arg == NULL) 20681 vim_free(theline); 20682 break; 20683 } 20684 20685 /* Increase indent inside "if", "while", "for" and "try", decrease 20686 * at "end". */ 20687 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 20688 indent -= 2; 20689 else if (STRNCMP(p, "if", 2) == 0 20690 || STRNCMP(p, "wh", 2) == 0 20691 || STRNCMP(p, "for", 3) == 0 20692 || STRNCMP(p, "try", 3) == 0) 20693 indent += 2; 20694 20695 /* Check for defining a function inside this function. */ 20696 if (checkforcmd(&p, "function", 2)) 20697 { 20698 if (*p == '!') 20699 p = skipwhite(p + 1); 20700 p += eval_fname_script(p); 20701 if (ASCII_ISALPHA(*p)) 20702 { 20703 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 20704 if (*skipwhite(p) == '(') 20705 { 20706 ++nesting; 20707 indent += 2; 20708 } 20709 } 20710 } 20711 20712 /* Check for ":append" or ":insert". */ 20713 p = skip_range(p, NULL); 20714 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 20715 || (p[0] == 'i' 20716 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 20717 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 20718 skip_until = vim_strsave((char_u *)"."); 20719 20720 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 20721 arg = skipwhite(skiptowhite(p)); 20722 if (arg[0] == '<' && arg[1] =='<' 20723 && ((p[0] == 'p' && p[1] == 'y' 20724 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 20725 || (p[0] == 'p' && p[1] == 'e' 20726 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 20727 || (p[0] == 't' && p[1] == 'c' 20728 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 20729 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 20730 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 20731 || (p[0] == 'm' && p[1] == 'z' 20732 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 20733 )) 20734 { 20735 /* ":python <<" continues until a dot, like ":append" */ 20736 p = skipwhite(arg + 2); 20737 if (*p == NUL) 20738 skip_until = vim_strsave((char_u *)"."); 20739 else 20740 skip_until = vim_strsave(p); 20741 } 20742 } 20743 20744 /* Add the line to the function. */ 20745 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 20746 { 20747 if (line_arg == NULL) 20748 vim_free(theline); 20749 goto erret; 20750 } 20751 20752 /* Copy the line to newly allocated memory. get_one_sourceline() 20753 * allocates 250 bytes per line, this saves 80% on average. The cost 20754 * is an extra alloc/free. */ 20755 p = vim_strsave(theline); 20756 if (p != NULL) 20757 { 20758 if (line_arg == NULL) 20759 vim_free(theline); 20760 theline = p; 20761 } 20762 20763 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 20764 20765 /* Add NULL lines for continuation lines, so that the line count is 20766 * equal to the index in the growarray. */ 20767 while (sourcing_lnum_off-- > 0) 20768 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 20769 20770 /* Check for end of eap->arg. */ 20771 if (line_arg != NULL && *line_arg == NUL) 20772 line_arg = NULL; 20773 } 20774 20775 /* Don't define the function when skipping commands or when an error was 20776 * detected. */ 20777 if (eap->skip || did_emsg) 20778 goto erret; 20779 20780 /* 20781 * If there are no errors, add the function 20782 */ 20783 if (fudi.fd_dict == NULL) 20784 { 20785 v = find_var(name, &ht); 20786 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 20787 { 20788 emsg_funcname(N_("E707: Function name conflicts with variable: %s"), 20789 name); 20790 goto erret; 20791 } 20792 20793 fp = find_func(name); 20794 if (fp != NULL) 20795 { 20796 if (!eap->forceit) 20797 { 20798 emsg_funcname(e_funcexts, name); 20799 goto erret; 20800 } 20801 if (fp->uf_calls > 0) 20802 { 20803 emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), 20804 name); 20805 goto erret; 20806 } 20807 /* redefine existing function */ 20808 ga_clear_strings(&(fp->uf_args)); 20809 ga_clear_strings(&(fp->uf_lines)); 20810 vim_free(name); 20811 name = NULL; 20812 } 20813 } 20814 else 20815 { 20816 char numbuf[20]; 20817 20818 fp = NULL; 20819 if (fudi.fd_newkey == NULL && !eap->forceit) 20820 { 20821 EMSG(_(e_funcdict)); 20822 goto erret; 20823 } 20824 if (fudi.fd_di == NULL) 20825 { 20826 /* Can't add a function to a locked dictionary */ 20827 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 20828 goto erret; 20829 } 20830 /* Can't change an existing function if it is locked */ 20831 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 20832 goto erret; 20833 20834 /* Give the function a sequential number. Can only be used with a 20835 * Funcref! */ 20836 vim_free(name); 20837 sprintf(numbuf, "%d", ++func_nr); 20838 name = vim_strsave((char_u *)numbuf); 20839 if (name == NULL) 20840 goto erret; 20841 } 20842 20843 if (fp == NULL) 20844 { 20845 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 20846 { 20847 int slen, plen; 20848 char_u *scriptname; 20849 20850 /* Check that the autoload name matches the script name. */ 20851 j = FAIL; 20852 if (sourcing_name != NULL) 20853 { 20854 scriptname = autoload_name(name); 20855 if (scriptname != NULL) 20856 { 20857 p = vim_strchr(scriptname, '/'); 20858 plen = (int)STRLEN(p); 20859 slen = (int)STRLEN(sourcing_name); 20860 if (slen > plen && fnamecmp(p, 20861 sourcing_name + slen - plen) == 0) 20862 j = OK; 20863 vim_free(scriptname); 20864 } 20865 } 20866 if (j == FAIL) 20867 { 20868 EMSG2(_("E746: Function name does not match script file name: %s"), name); 20869 goto erret; 20870 } 20871 } 20872 20873 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 20874 if (fp == NULL) 20875 goto erret; 20876 20877 if (fudi.fd_dict != NULL) 20878 { 20879 if (fudi.fd_di == NULL) 20880 { 20881 /* add new dict entry */ 20882 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 20883 if (fudi.fd_di == NULL) 20884 { 20885 vim_free(fp); 20886 goto erret; 20887 } 20888 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 20889 { 20890 vim_free(fudi.fd_di); 20891 vim_free(fp); 20892 goto erret; 20893 } 20894 } 20895 else 20896 /* overwrite existing dict entry */ 20897 clear_tv(&fudi.fd_di->di_tv); 20898 fudi.fd_di->di_tv.v_type = VAR_FUNC; 20899 fudi.fd_di->di_tv.v_lock = 0; 20900 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 20901 fp->uf_refcount = 1; 20902 20903 /* behave like "dict" was used */ 20904 flags |= FC_DICT; 20905 } 20906 20907 /* insert the new function in the function list */ 20908 STRCPY(fp->uf_name, name); 20909 hash_add(&func_hashtab, UF2HIKEY(fp)); 20910 } 20911 fp->uf_args = newargs; 20912 fp->uf_lines = newlines; 20913#ifdef FEAT_PROFILE 20914 fp->uf_tml_count = NULL; 20915 fp->uf_tml_total = NULL; 20916 fp->uf_tml_self = NULL; 20917 fp->uf_profiling = FALSE; 20918 if (prof_def_func()) 20919 func_do_profile(fp); 20920#endif 20921 fp->uf_varargs = varargs; 20922 fp->uf_flags = flags; 20923 fp->uf_calls = 0; 20924 fp->uf_script_ID = current_SID; 20925 goto ret_free; 20926 20927erret: 20928 ga_clear_strings(&newargs); 20929 ga_clear_strings(&newlines); 20930ret_free: 20931 vim_free(skip_until); 20932 vim_free(fudi.fd_newkey); 20933 vim_free(name); 20934 did_emsg |= saved_did_emsg; 20935} 20936 20937/* 20938 * Get a function name, translating "<SID>" and "<SNR>". 20939 * Also handles a Funcref in a List or Dictionary. 20940 * Returns the function name in allocated memory, or NULL for failure. 20941 * flags: 20942 * TFN_INT: internal function name OK 20943 * TFN_QUIET: be quiet 20944 * Advances "pp" to just after the function name (if no error). 20945 */ 20946 static char_u * 20947trans_function_name(pp, skip, flags, fdp) 20948 char_u **pp; 20949 int skip; /* only find the end, don't evaluate */ 20950 int flags; 20951 funcdict_T *fdp; /* return: info about dictionary used */ 20952{ 20953 char_u *name = NULL; 20954 char_u *start; 20955 char_u *end; 20956 int lead; 20957 char_u sid_buf[20]; 20958 int len; 20959 lval_T lv; 20960 20961 if (fdp != NULL) 20962 vim_memset(fdp, 0, sizeof(funcdict_T)); 20963 start = *pp; 20964 20965 /* Check for hard coded <SNR>: already translated function ID (from a user 20966 * command). */ 20967 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 20968 && (*pp)[2] == (int)KE_SNR) 20969 { 20970 *pp += 3; 20971 len = get_id_len(pp) + 3; 20972 return vim_strnsave(start, len); 20973 } 20974 20975 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 20976 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 20977 lead = eval_fname_script(start); 20978 if (lead > 2) 20979 start += lead; 20980 20981 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 20982 lead > 2 ? 0 : FNE_CHECK_START); 20983 if (end == start) 20984 { 20985 if (!skip) 20986 EMSG(_("E129: Function name required")); 20987 goto theend; 20988 } 20989 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 20990 { 20991 /* 20992 * Report an invalid expression in braces, unless the expression 20993 * evaluation has been cancelled due to an aborting error, an 20994 * interrupt, or an exception. 20995 */ 20996 if (!aborting()) 20997 { 20998 if (end != NULL) 20999 EMSG2(_(e_invarg2), start); 21000 } 21001 else 21002 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 21003 goto theend; 21004 } 21005 21006 if (lv.ll_tv != NULL) 21007 { 21008 if (fdp != NULL) 21009 { 21010 fdp->fd_dict = lv.ll_dict; 21011 fdp->fd_newkey = lv.ll_newkey; 21012 lv.ll_newkey = NULL; 21013 fdp->fd_di = lv.ll_di; 21014 } 21015 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 21016 { 21017 name = vim_strsave(lv.ll_tv->vval.v_string); 21018 *pp = end; 21019 } 21020 else 21021 { 21022 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 21023 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 21024 EMSG(_(e_funcref)); 21025 else 21026 *pp = end; 21027 name = NULL; 21028 } 21029 goto theend; 21030 } 21031 21032 if (lv.ll_name == NULL) 21033 { 21034 /* Error found, but continue after the function name. */ 21035 *pp = end; 21036 goto theend; 21037 } 21038 21039 /* Check if the name is a Funcref. If so, use the value. */ 21040 if (lv.ll_exp_name != NULL) 21041 { 21042 len = (int)STRLEN(lv.ll_exp_name); 21043 name = deref_func_name(lv.ll_exp_name, &len); 21044 if (name == lv.ll_exp_name) 21045 name = NULL; 21046 } 21047 else 21048 { 21049 len = (int)(end - *pp); 21050 name = deref_func_name(*pp, &len); 21051 if (name == *pp) 21052 name = NULL; 21053 } 21054 if (name != NULL) 21055 { 21056 name = vim_strsave(name); 21057 *pp = end; 21058 goto theend; 21059 } 21060 21061 if (lv.ll_exp_name != NULL) 21062 { 21063 len = (int)STRLEN(lv.ll_exp_name); 21064 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 21065 && STRNCMP(lv.ll_name, "s:", 2) == 0) 21066 { 21067 /* When there was "s:" already or the name expanded to get a 21068 * leading "s:" then remove it. */ 21069 lv.ll_name += 2; 21070 len -= 2; 21071 lead = 2; 21072 } 21073 } 21074 else 21075 { 21076 if (lead == 2) /* skip over "s:" */ 21077 lv.ll_name += 2; 21078 len = (int)(end - lv.ll_name); 21079 } 21080 21081 /* 21082 * Copy the function name to allocated memory. 21083 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 21084 * Accept <SNR>123_name() outside a script. 21085 */ 21086 if (skip) 21087 lead = 0; /* do nothing */ 21088 else if (lead > 0) 21089 { 21090 lead = 3; 21091 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 21092 || eval_fname_sid(*pp)) 21093 { 21094 /* It's "s:" or "<SID>" */ 21095 if (current_SID <= 0) 21096 { 21097 EMSG(_(e_usingsid)); 21098 goto theend; 21099 } 21100 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 21101 lead += (int)STRLEN(sid_buf); 21102 } 21103 } 21104 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 21105 { 21106 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 21107 goto theend; 21108 } 21109 name = alloc((unsigned)(len + lead + 1)); 21110 if (name != NULL) 21111 { 21112 if (lead > 0) 21113 { 21114 name[0] = K_SPECIAL; 21115 name[1] = KS_EXTRA; 21116 name[2] = (int)KE_SNR; 21117 if (lead > 3) /* If it's "<SID>" */ 21118 STRCPY(name + 3, sid_buf); 21119 } 21120 mch_memmove(name + lead, lv.ll_name, (size_t)len); 21121 name[len + lead] = NUL; 21122 } 21123 *pp = end; 21124 21125theend: 21126 clear_lval(&lv); 21127 return name; 21128} 21129 21130/* 21131 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 21132 * Return 2 if "p" starts with "s:". 21133 * Return 0 otherwise. 21134 */ 21135 static int 21136eval_fname_script(p) 21137 char_u *p; 21138{ 21139 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 21140 || STRNICMP(p + 1, "SNR>", 4) == 0)) 21141 return 5; 21142 if (p[0] == 's' && p[1] == ':') 21143 return 2; 21144 return 0; 21145} 21146 21147/* 21148 * Return TRUE if "p" starts with "<SID>" or "s:". 21149 * Only works if eval_fname_script() returned non-zero for "p"! 21150 */ 21151 static int 21152eval_fname_sid(p) 21153 char_u *p; 21154{ 21155 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 21156} 21157 21158/* 21159 * List the head of the function: "name(arg1, arg2)". 21160 */ 21161 static void 21162list_func_head(fp, indent) 21163 ufunc_T *fp; 21164 int indent; 21165{ 21166 int j; 21167 21168 msg_start(); 21169 if (indent) 21170 MSG_PUTS(" "); 21171 MSG_PUTS("function "); 21172 if (fp->uf_name[0] == K_SPECIAL) 21173 { 21174 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 21175 msg_puts(fp->uf_name + 3); 21176 } 21177 else 21178 msg_puts(fp->uf_name); 21179 msg_putchar('('); 21180 for (j = 0; j < fp->uf_args.ga_len; ++j) 21181 { 21182 if (j) 21183 MSG_PUTS(", "); 21184 msg_puts(FUNCARG(fp, j)); 21185 } 21186 if (fp->uf_varargs) 21187 { 21188 if (j) 21189 MSG_PUTS(", "); 21190 MSG_PUTS("..."); 21191 } 21192 msg_putchar(')'); 21193 msg_clr_eos(); 21194 if (p_verbose > 0) 21195 last_set_msg(fp->uf_script_ID); 21196} 21197 21198/* 21199 * Find a function by name, return pointer to it in ufuncs. 21200 * Return NULL for unknown function. 21201 */ 21202 static ufunc_T * 21203find_func(name) 21204 char_u *name; 21205{ 21206 hashitem_T *hi; 21207 21208 hi = hash_find(&func_hashtab, name); 21209 if (!HASHITEM_EMPTY(hi)) 21210 return HI2UF(hi); 21211 return NULL; 21212} 21213 21214#if defined(EXITFREE) || defined(PROTO) 21215 void 21216free_all_functions() 21217{ 21218 hashitem_T *hi; 21219 21220 /* Need to start all over every time, because func_free() may change the 21221 * hash table. */ 21222 while (func_hashtab.ht_used > 0) 21223 for (hi = func_hashtab.ht_array; ; ++hi) 21224 if (!HASHITEM_EMPTY(hi)) 21225 { 21226 func_free(HI2UF(hi)); 21227 break; 21228 } 21229} 21230#endif 21231 21232/* 21233 * Return TRUE if a function "name" exists. 21234 */ 21235 static int 21236function_exists(name) 21237 char_u *name; 21238{ 21239 char_u *nm = name; 21240 char_u *p; 21241 int n = FALSE; 21242 21243 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 21244 nm = skipwhite(nm); 21245 21246 /* Only accept "funcname", "funcname ", "funcname (..." and 21247 * "funcname(...", not "funcname!...". */ 21248 if (p != NULL && (*nm == NUL || *nm == '(')) 21249 { 21250 if (builtin_function(p)) 21251 n = (find_internal_func(p) >= 0); 21252 else 21253 n = (find_func(p) != NULL); 21254 } 21255 vim_free(p); 21256 return n; 21257} 21258 21259/* 21260 * Return TRUE if "name" looks like a builtin function name: starts with a 21261 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 21262 */ 21263 static int 21264builtin_function(name) 21265 char_u *name; 21266{ 21267 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 21268 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 21269} 21270 21271#if defined(FEAT_PROFILE) || defined(PROTO) 21272/* 21273 * Start profiling function "fp". 21274 */ 21275 static void 21276func_do_profile(fp) 21277 ufunc_T *fp; 21278{ 21279 int len = fp->uf_lines.ga_len; 21280 21281 if (len == 0) 21282 len = 1; /* avoid getting error for allocating zero bytes */ 21283 fp->uf_tm_count = 0; 21284 profile_zero(&fp->uf_tm_self); 21285 profile_zero(&fp->uf_tm_total); 21286 if (fp->uf_tml_count == NULL) 21287 fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len)); 21288 if (fp->uf_tml_total == NULL) 21289 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 21290 (sizeof(proftime_T) * len)); 21291 if (fp->uf_tml_self == NULL) 21292 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 21293 (sizeof(proftime_T) * len)); 21294 fp->uf_tml_idx = -1; 21295 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 21296 || fp->uf_tml_self == NULL) 21297 return; /* out of memory */ 21298 21299 fp->uf_profiling = TRUE; 21300} 21301 21302/* 21303 * Dump the profiling results for all functions in file "fd". 21304 */ 21305 void 21306func_dump_profile(fd) 21307 FILE *fd; 21308{ 21309 hashitem_T *hi; 21310 int todo; 21311 ufunc_T *fp; 21312 int i; 21313 ufunc_T **sorttab; 21314 int st_len = 0; 21315 21316 todo = (int)func_hashtab.ht_used; 21317 if (todo == 0) 21318 return; /* nothing to dump */ 21319 21320 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 21321 21322 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 21323 { 21324 if (!HASHITEM_EMPTY(hi)) 21325 { 21326 --todo; 21327 fp = HI2UF(hi); 21328 if (fp->uf_profiling) 21329 { 21330 if (sorttab != NULL) 21331 sorttab[st_len++] = fp; 21332 21333 if (fp->uf_name[0] == K_SPECIAL) 21334 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 21335 else 21336 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 21337 if (fp->uf_tm_count == 1) 21338 fprintf(fd, "Called 1 time\n"); 21339 else 21340 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 21341 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 21342 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 21343 fprintf(fd, "\n"); 21344 fprintf(fd, "count total (s) self (s)\n"); 21345 21346 for (i = 0; i < fp->uf_lines.ga_len; ++i) 21347 { 21348 if (FUNCLINE(fp, i) == NULL) 21349 continue; 21350 prof_func_line(fd, fp->uf_tml_count[i], 21351 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 21352 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 21353 } 21354 fprintf(fd, "\n"); 21355 } 21356 } 21357 } 21358 21359 if (sorttab != NULL && st_len > 0) 21360 { 21361 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 21362 prof_total_cmp); 21363 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 21364 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 21365 prof_self_cmp); 21366 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 21367 } 21368 21369 vim_free(sorttab); 21370} 21371 21372 static void 21373prof_sort_list(fd, sorttab, st_len, title, prefer_self) 21374 FILE *fd; 21375 ufunc_T **sorttab; 21376 int st_len; 21377 char *title; 21378 int prefer_self; /* when equal print only self time */ 21379{ 21380 int i; 21381 ufunc_T *fp; 21382 21383 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 21384 fprintf(fd, "count total (s) self (s) function\n"); 21385 for (i = 0; i < 20 && i < st_len; ++i) 21386 { 21387 fp = sorttab[i]; 21388 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 21389 prefer_self); 21390 if (fp->uf_name[0] == K_SPECIAL) 21391 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 21392 else 21393 fprintf(fd, " %s()\n", fp->uf_name); 21394 } 21395 fprintf(fd, "\n"); 21396} 21397 21398/* 21399 * Print the count and times for one function or function line. 21400 */ 21401 static void 21402prof_func_line(fd, count, total, self, prefer_self) 21403 FILE *fd; 21404 int count; 21405 proftime_T *total; 21406 proftime_T *self; 21407 int prefer_self; /* when equal print only self time */ 21408{ 21409 if (count > 0) 21410 { 21411 fprintf(fd, "%5d ", count); 21412 if (prefer_self && profile_equal(total, self)) 21413 fprintf(fd, " "); 21414 else 21415 fprintf(fd, "%s ", profile_msg(total)); 21416 if (!prefer_self && profile_equal(total, self)) 21417 fprintf(fd, " "); 21418 else 21419 fprintf(fd, "%s ", profile_msg(self)); 21420 } 21421 else 21422 fprintf(fd, " "); 21423} 21424 21425/* 21426 * Compare function for total time sorting. 21427 */ 21428 static int 21429#ifdef __BORLANDC__ 21430_RTLENTRYF 21431#endif 21432prof_total_cmp(s1, s2) 21433 const void *s1; 21434 const void *s2; 21435{ 21436 ufunc_T *p1, *p2; 21437 21438 p1 = *(ufunc_T **)s1; 21439 p2 = *(ufunc_T **)s2; 21440 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 21441} 21442 21443/* 21444 * Compare function for self time sorting. 21445 */ 21446 static int 21447#ifdef __BORLANDC__ 21448_RTLENTRYF 21449#endif 21450prof_self_cmp(s1, s2) 21451 const void *s1; 21452 const void *s2; 21453{ 21454 ufunc_T *p1, *p2; 21455 21456 p1 = *(ufunc_T **)s1; 21457 p2 = *(ufunc_T **)s2; 21458 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 21459} 21460 21461#endif 21462 21463/* 21464 * If "name" has a package name try autoloading the script for it. 21465 * Return TRUE if a package was loaded. 21466 */ 21467 static int 21468script_autoload(name, reload) 21469 char_u *name; 21470 int reload; /* load script again when already loaded */ 21471{ 21472 char_u *p; 21473 char_u *scriptname, *tofree; 21474 int ret = FALSE; 21475 int i; 21476 21477 /* Return quickly when autoload disabled. */ 21478 if (no_autoload) 21479 return FALSE; 21480 21481 /* If there is no '#' after name[0] there is no package name. */ 21482 p = vim_strchr(name, AUTOLOAD_CHAR); 21483 if (p == NULL || p == name) 21484 return FALSE; 21485 21486 tofree = scriptname = autoload_name(name); 21487 21488 /* Find the name in the list of previously loaded package names. Skip 21489 * "autoload/", it's always the same. */ 21490 for (i = 0; i < ga_loaded.ga_len; ++i) 21491 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 21492 break; 21493 if (!reload && i < ga_loaded.ga_len) 21494 ret = FALSE; /* was loaded already */ 21495 else 21496 { 21497 /* Remember the name if it wasn't loaded already. */ 21498 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 21499 { 21500 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 21501 tofree = NULL; 21502 } 21503 21504 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 21505 if (source_runtime(scriptname, FALSE) == OK) 21506 ret = TRUE; 21507 } 21508 21509 vim_free(tofree); 21510 return ret; 21511} 21512 21513/* 21514 * Return the autoload script name for a function or variable name. 21515 * Returns NULL when out of memory. 21516 */ 21517 static char_u * 21518autoload_name(name) 21519 char_u *name; 21520{ 21521 char_u *p; 21522 char_u *scriptname; 21523 21524 /* Get the script file name: replace '#' with '/', append ".vim". */ 21525 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 21526 if (scriptname == NULL) 21527 return FALSE; 21528 STRCPY(scriptname, "autoload/"); 21529 STRCAT(scriptname, name); 21530 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 21531 STRCAT(scriptname, ".vim"); 21532 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 21533 *p = '/'; 21534 return scriptname; 21535} 21536 21537#if defined(FEAT_CMDL_COMPL) || defined(PROTO) 21538 21539/* 21540 * Function given to ExpandGeneric() to obtain the list of user defined 21541 * function names. 21542 */ 21543 char_u * 21544get_user_func_name(xp, idx) 21545 expand_T *xp; 21546 int idx; 21547{ 21548 static long_u done; 21549 static hashitem_T *hi; 21550 ufunc_T *fp; 21551 21552 if (idx == 0) 21553 { 21554 done = 0; 21555 hi = func_hashtab.ht_array; 21556 } 21557 if (done < func_hashtab.ht_used) 21558 { 21559 if (done++ > 0) 21560 ++hi; 21561 while (HASHITEM_EMPTY(hi)) 21562 ++hi; 21563 fp = HI2UF(hi); 21564 21565 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 21566 return fp->uf_name; /* prevents overflow */ 21567 21568 cat_func_name(IObuff, fp); 21569 if (xp->xp_context != EXPAND_USER_FUNC) 21570 { 21571 STRCAT(IObuff, "("); 21572 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 21573 STRCAT(IObuff, ")"); 21574 } 21575 return IObuff; 21576 } 21577 return NULL; 21578} 21579 21580#endif /* FEAT_CMDL_COMPL */ 21581 21582/* 21583 * Copy the function name of "fp" to buffer "buf". 21584 * "buf" must be able to hold the function name plus three bytes. 21585 * Takes care of script-local function names. 21586 */ 21587 static void 21588cat_func_name(buf, fp) 21589 char_u *buf; 21590 ufunc_T *fp; 21591{ 21592 if (fp->uf_name[0] == K_SPECIAL) 21593 { 21594 STRCPY(buf, "<SNR>"); 21595 STRCAT(buf, fp->uf_name + 3); 21596 } 21597 else 21598 STRCPY(buf, fp->uf_name); 21599} 21600 21601/* 21602 * ":delfunction {name}" 21603 */ 21604 void 21605ex_delfunction(eap) 21606 exarg_T *eap; 21607{ 21608 ufunc_T *fp = NULL; 21609 char_u *p; 21610 char_u *name; 21611 funcdict_T fudi; 21612 21613 p = eap->arg; 21614 name = trans_function_name(&p, eap->skip, 0, &fudi); 21615 vim_free(fudi.fd_newkey); 21616 if (name == NULL) 21617 { 21618 if (fudi.fd_dict != NULL && !eap->skip) 21619 EMSG(_(e_funcref)); 21620 return; 21621 } 21622 if (!ends_excmd(*skipwhite(p))) 21623 { 21624 vim_free(name); 21625 EMSG(_(e_trailing)); 21626 return; 21627 } 21628 eap->nextcmd = check_nextcmd(p); 21629 if (eap->nextcmd != NULL) 21630 *p = NUL; 21631 21632 if (!eap->skip) 21633 fp = find_func(name); 21634 vim_free(name); 21635 21636 if (!eap->skip) 21637 { 21638 if (fp == NULL) 21639 { 21640 EMSG2(_(e_nofunc), eap->arg); 21641 return; 21642 } 21643 if (fp->uf_calls > 0) 21644 { 21645 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 21646 return; 21647 } 21648 21649 if (fudi.fd_dict != NULL) 21650 { 21651 /* Delete the dict item that refers to the function, it will 21652 * invoke func_unref() and possibly delete the function. */ 21653 dictitem_remove(fudi.fd_dict, fudi.fd_di); 21654 } 21655 else 21656 func_free(fp); 21657 } 21658} 21659 21660/* 21661 * Free a function and remove it from the list of functions. 21662 */ 21663 static void 21664func_free(fp) 21665 ufunc_T *fp; 21666{ 21667 hashitem_T *hi; 21668 21669 /* clear this function */ 21670 ga_clear_strings(&(fp->uf_args)); 21671 ga_clear_strings(&(fp->uf_lines)); 21672#ifdef FEAT_PROFILE 21673 vim_free(fp->uf_tml_count); 21674 vim_free(fp->uf_tml_total); 21675 vim_free(fp->uf_tml_self); 21676#endif 21677 21678 /* remove the function from the function hashtable */ 21679 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 21680 if (HASHITEM_EMPTY(hi)) 21681 EMSG2(_(e_intern2), "func_free()"); 21682 else 21683 hash_remove(&func_hashtab, hi); 21684 21685 vim_free(fp); 21686} 21687 21688/* 21689 * Unreference a Function: decrement the reference count and free it when it 21690 * becomes zero. Only for numbered functions. 21691 */ 21692 static void 21693func_unref(name) 21694 char_u *name; 21695{ 21696 ufunc_T *fp; 21697 21698 if (name != NULL && isdigit(*name)) 21699 { 21700 fp = find_func(name); 21701 if (fp == NULL) 21702 EMSG2(_(e_intern2), "func_unref()"); 21703 else if (--fp->uf_refcount <= 0) 21704 { 21705 /* Only delete it when it's not being used. Otherwise it's done 21706 * when "uf_calls" becomes zero. */ 21707 if (fp->uf_calls == 0) 21708 func_free(fp); 21709 } 21710 } 21711} 21712 21713/* 21714 * Count a reference to a Function. 21715 */ 21716 static void 21717func_ref(name) 21718 char_u *name; 21719{ 21720 ufunc_T *fp; 21721 21722 if (name != NULL && isdigit(*name)) 21723 { 21724 fp = find_func(name); 21725 if (fp == NULL) 21726 EMSG2(_(e_intern2), "func_ref()"); 21727 else 21728 ++fp->uf_refcount; 21729 } 21730} 21731 21732/* 21733 * Call a user function. 21734 */ 21735 static void 21736call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 21737 ufunc_T *fp; /* pointer to function */ 21738 int argcount; /* nr of args */ 21739 typval_T *argvars; /* arguments */ 21740 typval_T *rettv; /* return value */ 21741 linenr_T firstline; /* first line of range */ 21742 linenr_T lastline; /* last line of range */ 21743 dict_T *selfdict; /* Dictionary for "self" */ 21744{ 21745 char_u *save_sourcing_name; 21746 linenr_T save_sourcing_lnum; 21747 scid_T save_current_SID; 21748 funccall_T *fc; 21749 int save_did_emsg; 21750 static int depth = 0; 21751 dictitem_T *v; 21752 int fixvar_idx = 0; /* index in fixvar[] */ 21753 int i; 21754 int ai; 21755 char_u numbuf[NUMBUFLEN]; 21756 char_u *name; 21757#ifdef FEAT_PROFILE 21758 proftime_T wait_start; 21759 proftime_T call_start; 21760#endif 21761 21762 /* If depth of calling is getting too high, don't execute the function */ 21763 if (depth >= p_mfd) 21764 { 21765 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 21766 rettv->v_type = VAR_NUMBER; 21767 rettv->vval.v_number = -1; 21768 return; 21769 } 21770 ++depth; 21771 21772 line_breakcheck(); /* check for CTRL-C hit */ 21773 21774 fc = (funccall_T *)alloc(sizeof(funccall_T)); 21775 fc->caller = current_funccal; 21776 current_funccal = fc; 21777 fc->func = fp; 21778 fc->rettv = rettv; 21779 rettv->vval.v_number = 0; 21780 fc->linenr = 0; 21781 fc->returned = FALSE; 21782 fc->level = ex_nesting_level; 21783 /* Check if this function has a breakpoint. */ 21784 fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 21785 fc->dbg_tick = debug_tick; 21786 21787 /* 21788 * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables 21789 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 21790 * each argument variable and saves a lot of time. 21791 */ 21792 /* 21793 * Init l: variables. 21794 */ 21795 init_var_dict(&fc->l_vars, &fc->l_vars_var); 21796 if (selfdict != NULL) 21797 { 21798 /* Set l:self to "selfdict". Use "name" to avoid a warning from 21799 * some compiler that checks the destination size. */ 21800 v = &fc->fixvar[fixvar_idx++].var; 21801 name = v->di_key; 21802 STRCPY(name, "self"); 21803 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 21804 hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); 21805 v->di_tv.v_type = VAR_DICT; 21806 v->di_tv.v_lock = 0; 21807 v->di_tv.vval.v_dict = selfdict; 21808 ++selfdict->dv_refcount; 21809 } 21810 21811 /* 21812 * Init a: variables. 21813 * Set a:0 to "argcount". 21814 * Set a:000 to a list with room for the "..." arguments. 21815 */ 21816 init_var_dict(&fc->l_avars, &fc->l_avars_var); 21817 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", 21818 (varnumber_T)(argcount - fp->uf_args.ga_len)); 21819 /* Use "name" to avoid a warning from some compiler that checks the 21820 * destination size. */ 21821 v = &fc->fixvar[fixvar_idx++].var; 21822 name = v->di_key; 21823 STRCPY(name, "000"); 21824 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21825 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21826 v->di_tv.v_type = VAR_LIST; 21827 v->di_tv.v_lock = VAR_FIXED; 21828 v->di_tv.vval.v_list = &fc->l_varlist; 21829 vim_memset(&fc->l_varlist, 0, sizeof(list_T)); 21830 fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; 21831 fc->l_varlist.lv_lock = VAR_FIXED; 21832 21833 /* 21834 * Set a:firstline to "firstline" and a:lastline to "lastline". 21835 * Set a:name to named arguments. 21836 * Set a:N to the "..." arguments. 21837 */ 21838 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", 21839 (varnumber_T)firstline); 21840 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", 21841 (varnumber_T)lastline); 21842 for (i = 0; i < argcount; ++i) 21843 { 21844 ai = i - fp->uf_args.ga_len; 21845 if (ai < 0) 21846 /* named argument a:name */ 21847 name = FUNCARG(fp, i); 21848 else 21849 { 21850 /* "..." argument a:1, a:2, etc. */ 21851 sprintf((char *)numbuf, "%d", ai + 1); 21852 name = numbuf; 21853 } 21854 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 21855 { 21856 v = &fc->fixvar[fixvar_idx++].var; 21857 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 21858 } 21859 else 21860 { 21861 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 21862 + STRLEN(name))); 21863 if (v == NULL) 21864 break; 21865 v->di_flags = DI_FLAGS_RO; 21866 } 21867 STRCPY(v->di_key, name); 21868 hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); 21869 21870 /* Note: the values are copied directly to avoid alloc/free. 21871 * "argvars" must have VAR_FIXED for v_lock. */ 21872 v->di_tv = argvars[i]; 21873 v->di_tv.v_lock = VAR_FIXED; 21874 21875 if (ai >= 0 && ai < MAX_FUNC_ARGS) 21876 { 21877 list_append(&fc->l_varlist, &fc->l_listitems[ai]); 21878 fc->l_listitems[ai].li_tv = argvars[i]; 21879 fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; 21880 } 21881 } 21882 21883 /* Don't redraw while executing the function. */ 21884 ++RedrawingDisabled; 21885 save_sourcing_name = sourcing_name; 21886 save_sourcing_lnum = sourcing_lnum; 21887 sourcing_lnum = 1; 21888 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 21889 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 21890 if (sourcing_name != NULL) 21891 { 21892 if (save_sourcing_name != NULL 21893 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 21894 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 21895 else 21896 STRCPY(sourcing_name, "function "); 21897 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 21898 21899 if (p_verbose >= 12) 21900 { 21901 ++no_wait_return; 21902 verbose_enter_scroll(); 21903 21904 smsg((char_u *)_("calling %s"), sourcing_name); 21905 if (p_verbose >= 14) 21906 { 21907 char_u buf[MSG_BUF_LEN]; 21908 char_u numbuf2[NUMBUFLEN]; 21909 char_u *tofree; 21910 char_u *s; 21911 21912 msg_puts((char_u *)"("); 21913 for (i = 0; i < argcount; ++i) 21914 { 21915 if (i > 0) 21916 msg_puts((char_u *)", "); 21917 if (argvars[i].v_type == VAR_NUMBER) 21918 msg_outnum((long)argvars[i].vval.v_number); 21919 else 21920 { 21921 s = tv2string(&argvars[i], &tofree, numbuf2, 0); 21922 if (s != NULL) 21923 { 21924 trunc_string(s, buf, MSG_BUF_CLEN); 21925 msg_puts(buf); 21926 vim_free(tofree); 21927 } 21928 } 21929 } 21930 msg_puts((char_u *)")"); 21931 } 21932 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 21933 21934 verbose_leave_scroll(); 21935 --no_wait_return; 21936 } 21937 } 21938#ifdef FEAT_PROFILE 21939 if (do_profiling == PROF_YES) 21940 { 21941 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 21942 func_do_profile(fp); 21943 if (fp->uf_profiling 21944 || (fc->caller != NULL && fc->caller->func->uf_profiling)) 21945 { 21946 ++fp->uf_tm_count; 21947 profile_start(&call_start); 21948 profile_zero(&fp->uf_tm_children); 21949 } 21950 script_prof_save(&wait_start); 21951 } 21952#endif 21953 21954 save_current_SID = current_SID; 21955 current_SID = fp->uf_script_ID; 21956 save_did_emsg = did_emsg; 21957 did_emsg = FALSE; 21958 21959 /* call do_cmdline() to execute the lines */ 21960 do_cmdline(NULL, get_func_line, (void *)fc, 21961 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 21962 21963 --RedrawingDisabled; 21964 21965 /* when the function was aborted because of an error, return -1 */ 21966 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 21967 { 21968 clear_tv(rettv); 21969 rettv->v_type = VAR_NUMBER; 21970 rettv->vval.v_number = -1; 21971 } 21972 21973#ifdef FEAT_PROFILE 21974 if (do_profiling == PROF_YES && (fp->uf_profiling 21975 || (fc->caller != NULL && fc->caller->func->uf_profiling))) 21976 { 21977 profile_end(&call_start); 21978 profile_sub_wait(&wait_start, &call_start); 21979 profile_add(&fp->uf_tm_total, &call_start); 21980 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 21981 if (fc->caller != NULL && fc->caller->func->uf_profiling) 21982 { 21983 profile_add(&fc->caller->func->uf_tm_children, &call_start); 21984 profile_add(&fc->caller->func->uf_tml_children, &call_start); 21985 } 21986 } 21987#endif 21988 21989 /* when being verbose, mention the return value */ 21990 if (p_verbose >= 12) 21991 { 21992 ++no_wait_return; 21993 verbose_enter_scroll(); 21994 21995 if (aborting()) 21996 smsg((char_u *)_("%s aborted"), sourcing_name); 21997 else if (fc->rettv->v_type == VAR_NUMBER) 21998 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 21999 (long)fc->rettv->vval.v_number); 22000 else 22001 { 22002 char_u buf[MSG_BUF_LEN]; 22003 char_u numbuf2[NUMBUFLEN]; 22004 char_u *tofree; 22005 char_u *s; 22006 22007 /* The value may be very long. Skip the middle part, so that we 22008 * have some idea how it starts and ends. smsg() would always 22009 * truncate it at the end. */ 22010 s = tv2string(fc->rettv, &tofree, numbuf2, 0); 22011 if (s != NULL) 22012 { 22013 trunc_string(s, buf, MSG_BUF_CLEN); 22014 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 22015 vim_free(tofree); 22016 } 22017 } 22018 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 22019 22020 verbose_leave_scroll(); 22021 --no_wait_return; 22022 } 22023 22024 vim_free(sourcing_name); 22025 sourcing_name = save_sourcing_name; 22026 sourcing_lnum = save_sourcing_lnum; 22027 current_SID = save_current_SID; 22028#ifdef FEAT_PROFILE 22029 if (do_profiling == PROF_YES) 22030 script_prof_restore(&wait_start); 22031#endif 22032 22033 if (p_verbose >= 12 && sourcing_name != NULL) 22034 { 22035 ++no_wait_return; 22036 verbose_enter_scroll(); 22037 22038 smsg((char_u *)_("continuing in %s"), sourcing_name); 22039 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 22040 22041 verbose_leave_scroll(); 22042 --no_wait_return; 22043 } 22044 22045 did_emsg |= save_did_emsg; 22046 current_funccal = fc->caller; 22047 --depth; 22048 22049 /* If the a:000 list and the l: and a: dicts are not referenced we can 22050 * free the funccall_T and what's in it. */ 22051 if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT 22052 && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT 22053 && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) 22054 { 22055 free_funccal(fc, FALSE); 22056 } 22057 else 22058 { 22059 hashitem_T *hi; 22060 listitem_T *li; 22061 int todo; 22062 22063 /* "fc" is still in use. This can happen when returning "a:000" or 22064 * assigning "l:" to a global variable. 22065 * Link "fc" in the list for garbage collection later. */ 22066 fc->caller = previous_funccal; 22067 previous_funccal = fc; 22068 22069 /* Make a copy of the a: variables, since we didn't do that above. */ 22070 todo = (int)fc->l_avars.dv_hashtab.ht_used; 22071 for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) 22072 { 22073 if (!HASHITEM_EMPTY(hi)) 22074 { 22075 --todo; 22076 v = HI2DI(hi); 22077 copy_tv(&v->di_tv, &v->di_tv); 22078 } 22079 } 22080 22081 /* Make a copy of the a:000 items, since we didn't do that above. */ 22082 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 22083 copy_tv(&li->li_tv, &li->li_tv); 22084 } 22085} 22086 22087/* 22088 * Return TRUE if items in "fc" do not have "copyID". That means they are not 22089 * referenced from anywhere that is in use. 22090 */ 22091 static int 22092can_free_funccal(fc, copyID) 22093 funccall_T *fc; 22094 int copyID; 22095{ 22096 return (fc->l_varlist.lv_copyID != copyID 22097 && fc->l_vars.dv_copyID != copyID 22098 && fc->l_avars.dv_copyID != copyID); 22099} 22100 22101/* 22102 * Free "fc" and what it contains. 22103 */ 22104 static void 22105free_funccal(fc, free_val) 22106 funccall_T *fc; 22107 int free_val; /* a: vars were allocated */ 22108{ 22109 listitem_T *li; 22110 22111 /* The a: variables typevals may not have been allocated, only free the 22112 * allocated variables. */ 22113 vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); 22114 22115 /* free all l: variables */ 22116 vars_clear(&fc->l_vars.dv_hashtab); 22117 22118 /* Free the a:000 variables if they were allocated. */ 22119 if (free_val) 22120 for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) 22121 clear_tv(&li->li_tv); 22122 22123 vim_free(fc); 22124} 22125 22126/* 22127 * Add a number variable "name" to dict "dp" with value "nr". 22128 */ 22129 static void 22130add_nr_var(dp, v, name, nr) 22131 dict_T *dp; 22132 dictitem_T *v; 22133 char *name; 22134 varnumber_T nr; 22135{ 22136 STRCPY(v->di_key, name); 22137 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 22138 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 22139 v->di_tv.v_type = VAR_NUMBER; 22140 v->di_tv.v_lock = VAR_FIXED; 22141 v->di_tv.vval.v_number = nr; 22142} 22143 22144/* 22145 * ":return [expr]" 22146 */ 22147 void 22148ex_return(eap) 22149 exarg_T *eap; 22150{ 22151 char_u *arg = eap->arg; 22152 typval_T rettv; 22153 int returning = FALSE; 22154 22155 if (current_funccal == NULL) 22156 { 22157 EMSG(_("E133: :return not inside a function")); 22158 return; 22159 } 22160 22161 if (eap->skip) 22162 ++emsg_skip; 22163 22164 eap->nextcmd = NULL; 22165 if ((*arg != NUL && *arg != '|' && *arg != '\n') 22166 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 22167 { 22168 if (!eap->skip) 22169 returning = do_return(eap, FALSE, TRUE, &rettv); 22170 else 22171 clear_tv(&rettv); 22172 } 22173 /* It's safer to return also on error. */ 22174 else if (!eap->skip) 22175 { 22176 /* 22177 * Return unless the expression evaluation has been cancelled due to an 22178 * aborting error, an interrupt, or an exception. 22179 */ 22180 if (!aborting()) 22181 returning = do_return(eap, FALSE, TRUE, NULL); 22182 } 22183 22184 /* When skipping or the return gets pending, advance to the next command 22185 * in this line (!returning). Otherwise, ignore the rest of the line. 22186 * Following lines will be ignored by get_func_line(). */ 22187 if (returning) 22188 eap->nextcmd = NULL; 22189 else if (eap->nextcmd == NULL) /* no argument */ 22190 eap->nextcmd = check_nextcmd(arg); 22191 22192 if (eap->skip) 22193 --emsg_skip; 22194} 22195 22196/* 22197 * Return from a function. Possibly makes the return pending. Also called 22198 * for a pending return at the ":endtry" or after returning from an extra 22199 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 22200 * when called due to a ":return" command. "rettv" may point to a typval_T 22201 * with the return rettv. Returns TRUE when the return can be carried out, 22202 * FALSE when the return gets pending. 22203 */ 22204 int 22205do_return(eap, reanimate, is_cmd, rettv) 22206 exarg_T *eap; 22207 int reanimate; 22208 int is_cmd; 22209 void *rettv; 22210{ 22211 int idx; 22212 struct condstack *cstack = eap->cstack; 22213 22214 if (reanimate) 22215 /* Undo the return. */ 22216 current_funccal->returned = FALSE; 22217 22218 /* 22219 * Cleanup (and inactivate) conditionals, but stop when a try conditional 22220 * not in its finally clause (which then is to be executed next) is found. 22221 * In this case, make the ":return" pending for execution at the ":endtry". 22222 * Otherwise, return normally. 22223 */ 22224 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 22225 if (idx >= 0) 22226 { 22227 cstack->cs_pending[idx] = CSTP_RETURN; 22228 22229 if (!is_cmd && !reanimate) 22230 /* A pending return again gets pending. "rettv" points to an 22231 * allocated variable with the rettv of the original ":return"'s 22232 * argument if present or is NULL else. */ 22233 cstack->cs_rettv[idx] = rettv; 22234 else 22235 { 22236 /* When undoing a return in order to make it pending, get the stored 22237 * return rettv. */ 22238 if (reanimate) 22239 rettv = current_funccal->rettv; 22240 22241 if (rettv != NULL) 22242 { 22243 /* Store the value of the pending return. */ 22244 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 22245 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 22246 else 22247 EMSG(_(e_outofmem)); 22248 } 22249 else 22250 cstack->cs_rettv[idx] = NULL; 22251 22252 if (reanimate) 22253 { 22254 /* The pending return value could be overwritten by a ":return" 22255 * without argument in a finally clause; reset the default 22256 * return value. */ 22257 current_funccal->rettv->v_type = VAR_NUMBER; 22258 current_funccal->rettv->vval.v_number = 0; 22259 } 22260 } 22261 report_make_pending(CSTP_RETURN, rettv); 22262 } 22263 else 22264 { 22265 current_funccal->returned = TRUE; 22266 22267 /* If the return is carried out now, store the return value. For 22268 * a return immediately after reanimation, the value is already 22269 * there. */ 22270 if (!reanimate && rettv != NULL) 22271 { 22272 clear_tv(current_funccal->rettv); 22273 *current_funccal->rettv = *(typval_T *)rettv; 22274 if (!is_cmd) 22275 vim_free(rettv); 22276 } 22277 } 22278 22279 return idx < 0; 22280} 22281 22282/* 22283 * Free the variable with a pending return value. 22284 */ 22285 void 22286discard_pending_return(rettv) 22287 void *rettv; 22288{ 22289 free_tv((typval_T *)rettv); 22290} 22291 22292/* 22293 * Generate a return command for producing the value of "rettv". The result 22294 * is an allocated string. Used by report_pending() for verbose messages. 22295 */ 22296 char_u * 22297get_return_cmd(rettv) 22298 void *rettv; 22299{ 22300 char_u *s = NULL; 22301 char_u *tofree = NULL; 22302 char_u numbuf[NUMBUFLEN]; 22303 22304 if (rettv != NULL) 22305 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 22306 if (s == NULL) 22307 s = (char_u *)""; 22308 22309 STRCPY(IObuff, ":return "); 22310 STRNCPY(IObuff + 8, s, IOSIZE - 8); 22311 if (STRLEN(s) + 8 >= IOSIZE) 22312 STRCPY(IObuff + IOSIZE - 4, "..."); 22313 vim_free(tofree); 22314 return vim_strsave(IObuff); 22315} 22316 22317/* 22318 * Get next function line. 22319 * Called by do_cmdline() to get the next line. 22320 * Returns allocated string, or NULL for end of function. 22321 */ 22322 char_u * 22323get_func_line(c, cookie, indent) 22324 int c UNUSED; 22325 void *cookie; 22326 int indent UNUSED; 22327{ 22328 funccall_T *fcp = (funccall_T *)cookie; 22329 ufunc_T *fp = fcp->func; 22330 char_u *retval; 22331 garray_T *gap; /* growarray with function lines */ 22332 22333 /* If breakpoints have been added/deleted need to check for it. */ 22334 if (fcp->dbg_tick != debug_tick) 22335 { 22336 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 22337 sourcing_lnum); 22338 fcp->dbg_tick = debug_tick; 22339 } 22340#ifdef FEAT_PROFILE 22341 if (do_profiling == PROF_YES) 22342 func_line_end(cookie); 22343#endif 22344 22345 gap = &fp->uf_lines; 22346 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 22347 || fcp->returned) 22348 retval = NULL; 22349 else 22350 { 22351 /* Skip NULL lines (continuation lines). */ 22352 while (fcp->linenr < gap->ga_len 22353 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 22354 ++fcp->linenr; 22355 if (fcp->linenr >= gap->ga_len) 22356 retval = NULL; 22357 else 22358 { 22359 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 22360 sourcing_lnum = fcp->linenr; 22361#ifdef FEAT_PROFILE 22362 if (do_profiling == PROF_YES) 22363 func_line_start(cookie); 22364#endif 22365 } 22366 } 22367 22368 /* Did we encounter a breakpoint? */ 22369 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 22370 { 22371 dbg_breakpoint(fp->uf_name, sourcing_lnum); 22372 /* Find next breakpoint. */ 22373 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 22374 sourcing_lnum); 22375 fcp->dbg_tick = debug_tick; 22376 } 22377 22378 return retval; 22379} 22380 22381#if defined(FEAT_PROFILE) || defined(PROTO) 22382/* 22383 * Called when starting to read a function line. 22384 * "sourcing_lnum" must be correct! 22385 * When skipping lines it may not actually be executed, but we won't find out 22386 * until later and we need to store the time now. 22387 */ 22388 void 22389func_line_start(cookie) 22390 void *cookie; 22391{ 22392 funccall_T *fcp = (funccall_T *)cookie; 22393 ufunc_T *fp = fcp->func; 22394 22395 if (fp->uf_profiling && sourcing_lnum >= 1 22396 && sourcing_lnum <= fp->uf_lines.ga_len) 22397 { 22398 fp->uf_tml_idx = sourcing_lnum - 1; 22399 /* Skip continuation lines. */ 22400 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 22401 --fp->uf_tml_idx; 22402 fp->uf_tml_execed = FALSE; 22403 profile_start(&fp->uf_tml_start); 22404 profile_zero(&fp->uf_tml_children); 22405 profile_get_wait(&fp->uf_tml_wait); 22406 } 22407} 22408 22409/* 22410 * Called when actually executing a function line. 22411 */ 22412 void 22413func_line_exec(cookie) 22414 void *cookie; 22415{ 22416 funccall_T *fcp = (funccall_T *)cookie; 22417 ufunc_T *fp = fcp->func; 22418 22419 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 22420 fp->uf_tml_execed = TRUE; 22421} 22422 22423/* 22424 * Called when done with a function line. 22425 */ 22426 void 22427func_line_end(cookie) 22428 void *cookie; 22429{ 22430 funccall_T *fcp = (funccall_T *)cookie; 22431 ufunc_T *fp = fcp->func; 22432 22433 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 22434 { 22435 if (fp->uf_tml_execed) 22436 { 22437 ++fp->uf_tml_count[fp->uf_tml_idx]; 22438 profile_end(&fp->uf_tml_start); 22439 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 22440 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 22441 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 22442 &fp->uf_tml_children); 22443 } 22444 fp->uf_tml_idx = -1; 22445 } 22446} 22447#endif 22448 22449/* 22450 * Return TRUE if the currently active function should be ended, because a 22451 * return was encountered or an error occurred. Used inside a ":while". 22452 */ 22453 int 22454func_has_ended(cookie) 22455 void *cookie; 22456{ 22457 funccall_T *fcp = (funccall_T *)cookie; 22458 22459 /* Ignore the "abort" flag if the abortion behavior has been changed due to 22460 * an error inside a try conditional. */ 22461 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 22462 || fcp->returned); 22463} 22464 22465/* 22466 * return TRUE if cookie indicates a function which "abort"s on errors. 22467 */ 22468 int 22469func_has_abort(cookie) 22470 void *cookie; 22471{ 22472 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 22473} 22474 22475#if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 22476typedef enum 22477{ 22478 VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */ 22479 VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */ 22480 VAR_FLAVOUR_VIMINFO /* all uppercase */ 22481} var_flavour_T; 22482 22483static var_flavour_T var_flavour __ARGS((char_u *varname)); 22484 22485 static var_flavour_T 22486var_flavour(varname) 22487 char_u *varname; 22488{ 22489 char_u *p = varname; 22490 22491 if (ASCII_ISUPPER(*p)) 22492 { 22493 while (*(++p)) 22494 if (ASCII_ISLOWER(*p)) 22495 return VAR_FLAVOUR_SESSION; 22496 return VAR_FLAVOUR_VIMINFO; 22497 } 22498 else 22499 return VAR_FLAVOUR_DEFAULT; 22500} 22501#endif 22502 22503#if defined(FEAT_VIMINFO) || defined(PROTO) 22504/* 22505 * Restore global vars that start with a capital from the viminfo file 22506 */ 22507 int 22508read_viminfo_varlist(virp, writing) 22509 vir_T *virp; 22510 int writing; 22511{ 22512 char_u *tab; 22513 int type = VAR_NUMBER; 22514 typval_T tv; 22515 22516 if (!writing && (find_viminfo_parameter('!') != NULL)) 22517 { 22518 tab = vim_strchr(virp->vir_line + 1, '\t'); 22519 if (tab != NULL) 22520 { 22521 *tab++ = '\0'; /* isolate the variable name */ 22522 if (*tab == 'S') /* string var */ 22523 type = VAR_STRING; 22524#ifdef FEAT_FLOAT 22525 else if (*tab == 'F') 22526 type = VAR_FLOAT; 22527#endif 22528 22529 tab = vim_strchr(tab, '\t'); 22530 if (tab != NULL) 22531 { 22532 tv.v_type = type; 22533 if (type == VAR_STRING) 22534 tv.vval.v_string = viminfo_readstring(virp, 22535 (int)(tab - virp->vir_line + 1), TRUE); 22536#ifdef FEAT_FLOAT 22537 else if (type == VAR_FLOAT) 22538 (void)string2float(tab + 1, &tv.vval.v_float); 22539#endif 22540 else 22541 tv.vval.v_number = atol((char *)tab + 1); 22542 set_var(virp->vir_line + 1, &tv, FALSE); 22543 if (type == VAR_STRING) 22544 vim_free(tv.vval.v_string); 22545 } 22546 } 22547 } 22548 22549 return viminfo_readline(virp); 22550} 22551 22552/* 22553 * Write global vars that start with a capital to the viminfo file 22554 */ 22555 void 22556write_viminfo_varlist(fp) 22557 FILE *fp; 22558{ 22559 hashitem_T *hi; 22560 dictitem_T *this_var; 22561 int todo; 22562 char *s; 22563 char_u *p; 22564 char_u *tofree; 22565 char_u numbuf[NUMBUFLEN]; 22566 22567 if (find_viminfo_parameter('!') == NULL) 22568 return; 22569 22570 fputs(_("\n# global variables:\n"), fp); 22571 22572 todo = (int)globvarht.ht_used; 22573 for (hi = globvarht.ht_array; todo > 0; ++hi) 22574 { 22575 if (!HASHITEM_EMPTY(hi)) 22576 { 22577 --todo; 22578 this_var = HI2DI(hi); 22579 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 22580 { 22581 switch (this_var->di_tv.v_type) 22582 { 22583 case VAR_STRING: s = "STR"; break; 22584 case VAR_NUMBER: s = "NUM"; break; 22585#ifdef FEAT_FLOAT 22586 case VAR_FLOAT: s = "FLO"; break; 22587#endif 22588 default: continue; 22589 } 22590 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 22591 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 22592 if (p != NULL) 22593 viminfo_writestring(fp, p); 22594 vim_free(tofree); 22595 } 22596 } 22597 } 22598} 22599#endif 22600 22601#if defined(FEAT_SESSION) || defined(PROTO) 22602 int 22603store_session_globals(fd) 22604 FILE *fd; 22605{ 22606 hashitem_T *hi; 22607 dictitem_T *this_var; 22608 int todo; 22609 char_u *p, *t; 22610 22611 todo = (int)globvarht.ht_used; 22612 for (hi = globvarht.ht_array; todo > 0; ++hi) 22613 { 22614 if (!HASHITEM_EMPTY(hi)) 22615 { 22616 --todo; 22617 this_var = HI2DI(hi); 22618 if ((this_var->di_tv.v_type == VAR_NUMBER 22619 || this_var->di_tv.v_type == VAR_STRING) 22620 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 22621 { 22622 /* Escape special characters with a backslash. Turn a LF and 22623 * CR into \n and \r. */ 22624 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 22625 (char_u *)"\\\"\n\r"); 22626 if (p == NULL) /* out of memory */ 22627 break; 22628 for (t = p; *t != NUL; ++t) 22629 if (*t == '\n') 22630 *t = 'n'; 22631 else if (*t == '\r') 22632 *t = 'r'; 22633 if ((fprintf(fd, "let %s = %c%s%c", 22634 this_var->di_key, 22635 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22636 : ' ', 22637 p, 22638 (this_var->di_tv.v_type == VAR_STRING) ? '"' 22639 : ' ') < 0) 22640 || put_eol(fd) == FAIL) 22641 { 22642 vim_free(p); 22643 return FAIL; 22644 } 22645 vim_free(p); 22646 } 22647#ifdef FEAT_FLOAT 22648 else if (this_var->di_tv.v_type == VAR_FLOAT 22649 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 22650 { 22651 float_T f = this_var->di_tv.vval.v_float; 22652 int sign = ' '; 22653 22654 if (f < 0) 22655 { 22656 f = -f; 22657 sign = '-'; 22658 } 22659 if ((fprintf(fd, "let %s = %c&%f", 22660 this_var->di_key, sign, f) < 0) 22661 || put_eol(fd) == FAIL) 22662 return FAIL; 22663 } 22664#endif 22665 } 22666 } 22667 return OK; 22668} 22669#endif 22670 22671/* 22672 * Display script name where an item was last set. 22673 * Should only be invoked when 'verbose' is non-zero. 22674 */ 22675 void 22676last_set_msg(scriptID) 22677 scid_T scriptID; 22678{ 22679 char_u *p; 22680 22681 if (scriptID != 0) 22682 { 22683 p = home_replace_save(NULL, get_scriptname(scriptID)); 22684 if (p != NULL) 22685 { 22686 verbose_enter(); 22687 MSG_PUTS(_("\n\tLast set from ")); 22688 MSG_PUTS(p); 22689 vim_free(p); 22690 verbose_leave(); 22691 } 22692 } 22693} 22694 22695/* 22696 * List v:oldfiles in a nice way. 22697 */ 22698 void 22699ex_oldfiles(eap) 22700 exarg_T *eap UNUSED; 22701{ 22702 list_T *l = vimvars[VV_OLDFILES].vv_list; 22703 listitem_T *li; 22704 int nr = 0; 22705 22706 if (l == NULL) 22707 msg((char_u *)_("No old files")); 22708 else 22709 { 22710 msg_start(); 22711 msg_scroll = TRUE; 22712 for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) 22713 { 22714 msg_outnum((long)++nr); 22715 MSG_PUTS(": "); 22716 msg_outtrans(get_tv_string(&li->li_tv)); 22717 msg_putchar('\n'); 22718 out_flush(); /* output one line at a time */ 22719 ui_breakcheck(); 22720 } 22721 /* Assume "got_int" was set to truncate the listing. */ 22722 got_int = FALSE; 22723 22724#ifdef FEAT_BROWSE_CMD 22725 if (cmdmod.browse) 22726 { 22727 quit_more = FALSE; 22728 nr = prompt_for_number(FALSE); 22729 msg_starthere(); 22730 if (nr > 0) 22731 { 22732 char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), 22733 (long)nr); 22734 22735 if (p != NULL) 22736 { 22737 p = expand_env_save(p); 22738 eap->arg = p; 22739 eap->cmdidx = CMD_edit; 22740 cmdmod.browse = FALSE; 22741 do_exedit(eap, NULL); 22742 vim_free(p); 22743 } 22744 } 22745 } 22746#endif 22747 } 22748} 22749 22750#endif /* FEAT_EVAL */ 22751 22752 22753#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 22754 22755#ifdef WIN3264 22756/* 22757 * Functions for ":8" filename modifier: get 8.3 version of a filename. 22758 */ 22759static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22760static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 22761static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 22762 22763/* 22764 * Get the short path (8.3) for the filename in "fnamep". 22765 * Only works for a valid file name. 22766 * When the path gets longer "fnamep" is changed and the allocated buffer 22767 * is put in "bufp". 22768 * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path. 22769 * Returns OK on success, FAIL on failure. 22770 */ 22771 static int 22772get_short_pathname(fnamep, bufp, fnamelen) 22773 char_u **fnamep; 22774 char_u **bufp; 22775 int *fnamelen; 22776{ 22777 int l, len; 22778 char_u *newbuf; 22779 22780 len = *fnamelen; 22781 l = GetShortPathName(*fnamep, *fnamep, len); 22782 if (l > len - 1) 22783 { 22784 /* If that doesn't work (not enough space), then save the string 22785 * and try again with a new buffer big enough. */ 22786 newbuf = vim_strnsave(*fnamep, l); 22787 if (newbuf == NULL) 22788 return FAIL; 22789 22790 vim_free(*bufp); 22791 *fnamep = *bufp = newbuf; 22792 22793 /* Really should always succeed, as the buffer is big enough. */ 22794 l = GetShortPathName(*fnamep, *fnamep, l+1); 22795 } 22796 22797 *fnamelen = l; 22798 return OK; 22799} 22800 22801/* 22802 * Get the short path (8.3) for the filename in "fname". The converted 22803 * path is returned in "bufp". 22804 * 22805 * Some of the directories specified in "fname" may not exist. This function 22806 * will shorten the existing directories at the beginning of the path and then 22807 * append the remaining non-existing path. 22808 * 22809 * fname - Pointer to the filename to shorten. On return, contains the 22810 * pointer to the shortened pathname 22811 * bufp - Pointer to an allocated buffer for the filename. 22812 * fnamelen - Length of the filename pointed to by fname 22813 * 22814 * Returns OK on success (or nothing done) and FAIL on failure (out of memory). 22815 */ 22816 static int 22817shortpath_for_invalid_fname(fname, bufp, fnamelen) 22818 char_u **fname; 22819 char_u **bufp; 22820 int *fnamelen; 22821{ 22822 char_u *short_fname, *save_fname, *pbuf_unused; 22823 char_u *endp, *save_endp; 22824 char_u ch; 22825 int old_len, len; 22826 int new_len, sfx_len; 22827 int retval = OK; 22828 22829 /* Make a copy */ 22830 old_len = *fnamelen; 22831 save_fname = vim_strnsave(*fname, old_len); 22832 pbuf_unused = NULL; 22833 short_fname = NULL; 22834 22835 endp = save_fname + old_len - 1; /* Find the end of the copy */ 22836 save_endp = endp; 22837 22838 /* 22839 * Try shortening the supplied path till it succeeds by removing one 22840 * directory at a time from the tail of the path. 22841 */ 22842 len = 0; 22843 for (;;) 22844 { 22845 /* go back one path-separator */ 22846 while (endp > save_fname && !after_pathsep(save_fname, endp + 1)) 22847 --endp; 22848 if (endp <= save_fname) 22849 break; /* processed the complete path */ 22850 22851 /* 22852 * Replace the path separator with a NUL and try to shorten the 22853 * resulting path. 22854 */ 22855 ch = *endp; 22856 *endp = 0; 22857 short_fname = save_fname; 22858 len = (int)STRLEN(short_fname) + 1; 22859 if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL) 22860 { 22861 retval = FAIL; 22862 goto theend; 22863 } 22864 *endp = ch; /* preserve the string */ 22865 22866 if (len > 0) 22867 break; /* successfully shortened the path */ 22868 22869 /* failed to shorten the path. Skip the path separator */ 22870 --endp; 22871 } 22872 22873 if (len > 0) 22874 { 22875 /* 22876 * Succeeded in shortening the path. Now concatenate the shortened 22877 * path with the remaining path at the tail. 22878 */ 22879 22880 /* Compute the length of the new path. */ 22881 sfx_len = (int)(save_endp - endp) + 1; 22882 new_len = len + sfx_len; 22883 22884 *fnamelen = new_len; 22885 vim_free(*bufp); 22886 if (new_len > old_len) 22887 { 22888 /* There is not enough space in the currently allocated string, 22889 * copy it to a buffer big enough. */ 22890 *fname = *bufp = vim_strnsave(short_fname, new_len); 22891 if (*fname == NULL) 22892 { 22893 retval = FAIL; 22894 goto theend; 22895 } 22896 } 22897 else 22898 { 22899 /* Transfer short_fname to the main buffer (it's big enough), 22900 * unless get_short_pathname() did its work in-place. */ 22901 *fname = *bufp = save_fname; 22902 if (short_fname != save_fname) 22903 vim_strncpy(save_fname, short_fname, len); 22904 save_fname = NULL; 22905 } 22906 22907 /* concat the not-shortened part of the path */ 22908 vim_strncpy(*fname + len, endp, sfx_len); 22909 (*fname)[new_len] = NUL; 22910 } 22911 22912theend: 22913 vim_free(pbuf_unused); 22914 vim_free(save_fname); 22915 22916 return retval; 22917} 22918 22919/* 22920 * Get a pathname for a partial path. 22921 * Returns OK for success, FAIL for failure. 22922 */ 22923 static int 22924shortpath_for_partial(fnamep, bufp, fnamelen) 22925 char_u **fnamep; 22926 char_u **bufp; 22927 int *fnamelen; 22928{ 22929 int sepcount, len, tflen; 22930 char_u *p; 22931 char_u *pbuf, *tfname; 22932 int hasTilde; 22933 22934 /* Count up the path separators from the RHS.. so we know which part 22935 * of the path to return. */ 22936 sepcount = 0; 22937 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 22938 if (vim_ispathsep(*p)) 22939 ++sepcount; 22940 22941 /* Need full path first (use expand_env() to remove a "~/") */ 22942 hasTilde = (**fnamep == '~'); 22943 if (hasTilde) 22944 pbuf = tfname = expand_env_save(*fnamep); 22945 else 22946 pbuf = tfname = FullName_save(*fnamep, FALSE); 22947 22948 len = tflen = (int)STRLEN(tfname); 22949 22950 if (get_short_pathname(&tfname, &pbuf, &len) == FAIL) 22951 return FAIL; 22952 22953 if (len == 0) 22954 { 22955 /* Don't have a valid filename, so shorten the rest of the 22956 * path if we can. This CAN give us invalid 8.3 filenames, but 22957 * there's not a lot of point in guessing what it might be. 22958 */ 22959 len = tflen; 22960 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL) 22961 return FAIL; 22962 } 22963 22964 /* Count the paths backward to find the beginning of the desired string. */ 22965 for (p = tfname + len - 1; p >= tfname; --p) 22966 { 22967#ifdef FEAT_MBYTE 22968 if (has_mbyte) 22969 p -= mb_head_off(tfname, p); 22970#endif 22971 if (vim_ispathsep(*p)) 22972 { 22973 if (sepcount == 0 || (hasTilde && sepcount == 1)) 22974 break; 22975 else 22976 sepcount --; 22977 } 22978 } 22979 if (hasTilde) 22980 { 22981 --p; 22982 if (p >= tfname) 22983 *p = '~'; 22984 else 22985 return FAIL; 22986 } 22987 else 22988 ++p; 22989 22990 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 22991 vim_free(*bufp); 22992 *fnamelen = (int)STRLEN(p); 22993 *bufp = pbuf; 22994 *fnamep = p; 22995 22996 return OK; 22997} 22998#endif /* WIN3264 */ 22999 23000/* 23001 * Adjust a filename, according to a string of modifiers. 23002 * *fnamep must be NUL terminated when called. When returning, the length is 23003 * determined by *fnamelen. 23004 * Returns VALID_ flags or -1 for failure. 23005 * When there is an error, *fnamep is set to NULL. 23006 */ 23007 int 23008modify_fname(src, usedlen, fnamep, bufp, fnamelen) 23009 char_u *src; /* string with modifiers */ 23010 int *usedlen; /* characters after src that are used */ 23011 char_u **fnamep; /* file name so far */ 23012 char_u **bufp; /* buffer for allocated file name or NULL */ 23013 int *fnamelen; /* length of fnamep */ 23014{ 23015 int valid = 0; 23016 char_u *tail; 23017 char_u *s, *p, *pbuf; 23018 char_u dirname[MAXPATHL]; 23019 int c; 23020 int has_fullname = 0; 23021#ifdef WIN3264 23022 int has_shortname = 0; 23023#endif 23024 23025repeat: 23026 /* ":p" - full path/file_name */ 23027 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 23028 { 23029 has_fullname = 1; 23030 23031 valid |= VALID_PATH; 23032 *usedlen += 2; 23033 23034 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 23035 if ((*fnamep)[0] == '~' 23036#if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 23037 && ((*fnamep)[1] == '/' 23038# ifdef BACKSLASH_IN_FILENAME 23039 || (*fnamep)[1] == '\\' 23040# endif 23041 || (*fnamep)[1] == NUL) 23042 23043#endif 23044 ) 23045 { 23046 *fnamep = expand_env_save(*fnamep); 23047 vim_free(*bufp); /* free any allocated file name */ 23048 *bufp = *fnamep; 23049 if (*fnamep == NULL) 23050 return -1; 23051 } 23052 23053 /* When "/." or "/.." is used: force expansion to get rid of it. */ 23054 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 23055 { 23056 if (vim_ispathsep(*p) 23057 && p[1] == '.' 23058 && (p[2] == NUL 23059 || vim_ispathsep(p[2]) 23060 || (p[2] == '.' 23061 && (p[3] == NUL || vim_ispathsep(p[3]))))) 23062 break; 23063 } 23064 23065 /* FullName_save() is slow, don't use it when not needed. */ 23066 if (*p != NUL || !vim_isAbsName(*fnamep)) 23067 { 23068 *fnamep = FullName_save(*fnamep, *p != NUL); 23069 vim_free(*bufp); /* free any allocated file name */ 23070 *bufp = *fnamep; 23071 if (*fnamep == NULL) 23072 return -1; 23073 } 23074 23075 /* Append a path separator to a directory. */ 23076 if (mch_isdir(*fnamep)) 23077 { 23078 /* Make room for one or two extra characters. */ 23079 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 23080 vim_free(*bufp); /* free any allocated file name */ 23081 *bufp = *fnamep; 23082 if (*fnamep == NULL) 23083 return -1; 23084 add_pathsep(*fnamep); 23085 } 23086 } 23087 23088 /* ":." - path relative to the current directory */ 23089 /* ":~" - path relative to the home directory */ 23090 /* ":8" - shortname path - postponed till after */ 23091 while (src[*usedlen] == ':' 23092 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 23093 { 23094 *usedlen += 2; 23095 if (c == '8') 23096 { 23097#ifdef WIN3264 23098 has_shortname = 1; /* Postpone this. */ 23099#endif 23100 continue; 23101 } 23102 pbuf = NULL; 23103 /* Need full path first (use expand_env() to remove a "~/") */ 23104 if (!has_fullname) 23105 { 23106 if (c == '.' && **fnamep == '~') 23107 p = pbuf = expand_env_save(*fnamep); 23108 else 23109 p = pbuf = FullName_save(*fnamep, FALSE); 23110 } 23111 else 23112 p = *fnamep; 23113 23114 has_fullname = 0; 23115 23116 if (p != NULL) 23117 { 23118 if (c == '.') 23119 { 23120 mch_dirname(dirname, MAXPATHL); 23121 s = shorten_fname(p, dirname); 23122 if (s != NULL) 23123 { 23124 *fnamep = s; 23125 if (pbuf != NULL) 23126 { 23127 vim_free(*bufp); /* free any allocated file name */ 23128 *bufp = pbuf; 23129 pbuf = NULL; 23130 } 23131 } 23132 } 23133 else 23134 { 23135 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 23136 /* Only replace it when it starts with '~' */ 23137 if (*dirname == '~') 23138 { 23139 s = vim_strsave(dirname); 23140 if (s != NULL) 23141 { 23142 *fnamep = s; 23143 vim_free(*bufp); 23144 *bufp = s; 23145 } 23146 } 23147 } 23148 vim_free(pbuf); 23149 } 23150 } 23151 23152 tail = gettail(*fnamep); 23153 *fnamelen = (int)STRLEN(*fnamep); 23154 23155 /* ":h" - head, remove "/file_name", can be repeated */ 23156 /* Don't remove the first "/" or "c:\" */ 23157 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 23158 { 23159 valid |= VALID_HEAD; 23160 *usedlen += 2; 23161 s = get_past_head(*fnamep); 23162 while (tail > s && after_pathsep(s, tail)) 23163 mb_ptr_back(*fnamep, tail); 23164 *fnamelen = (int)(tail - *fnamep); 23165#ifdef VMS 23166 if (*fnamelen > 0) 23167 *fnamelen += 1; /* the path separator is part of the path */ 23168#endif 23169 if (*fnamelen == 0) 23170 { 23171 /* Result is empty. Turn it into "." to make ":cd %:h" work. */ 23172 p = vim_strsave((char_u *)"."); 23173 if (p == NULL) 23174 return -1; 23175 vim_free(*bufp); 23176 *bufp = *fnamep = tail = p; 23177 *fnamelen = 1; 23178 } 23179 else 23180 { 23181 while (tail > s && !after_pathsep(s, tail)) 23182 mb_ptr_back(*fnamep, tail); 23183 } 23184 } 23185 23186 /* ":8" - shortname */ 23187 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 23188 { 23189 *usedlen += 2; 23190#ifdef WIN3264 23191 has_shortname = 1; 23192#endif 23193 } 23194 23195#ifdef WIN3264 23196 /* Check shortname after we have done 'heads' and before we do 'tails' 23197 */ 23198 if (has_shortname) 23199 { 23200 pbuf = NULL; 23201 /* Copy the string if it is shortened by :h */ 23202 if (*fnamelen < (int)STRLEN(*fnamep)) 23203 { 23204 p = vim_strnsave(*fnamep, *fnamelen); 23205 if (p == 0) 23206 return -1; 23207 vim_free(*bufp); 23208 *bufp = *fnamep = p; 23209 } 23210 23211 /* Split into two implementations - makes it easier. First is where 23212 * there isn't a full name already, second is where there is. 23213 */ 23214 if (!has_fullname && !vim_isAbsName(*fnamep)) 23215 { 23216 if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL) 23217 return -1; 23218 } 23219 else 23220 { 23221 int l; 23222 23223 /* Simple case, already have the full-name 23224 * Nearly always shorter, so try first time. */ 23225 l = *fnamelen; 23226 if (get_short_pathname(fnamep, bufp, &l) == FAIL) 23227 return -1; 23228 23229 if (l == 0) 23230 { 23231 /* Couldn't find the filename.. search the paths. 23232 */ 23233 l = *fnamelen; 23234 if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL) 23235 return -1; 23236 } 23237 *fnamelen = l; 23238 } 23239 } 23240#endif /* WIN3264 */ 23241 23242 /* ":t" - tail, just the basename */ 23243 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 23244 { 23245 *usedlen += 2; 23246 *fnamelen -= (int)(tail - *fnamep); 23247 *fnamep = tail; 23248 } 23249 23250 /* ":e" - extension, can be repeated */ 23251 /* ":r" - root, without extension, can be repeated */ 23252 while (src[*usedlen] == ':' 23253 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 23254 { 23255 /* find a '.' in the tail: 23256 * - for second :e: before the current fname 23257 * - otherwise: The last '.' 23258 */ 23259 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 23260 s = *fnamep - 2; 23261 else 23262 s = *fnamep + *fnamelen - 1; 23263 for ( ; s > tail; --s) 23264 if (s[0] == '.') 23265 break; 23266 if (src[*usedlen + 1] == 'e') /* :e */ 23267 { 23268 if (s > tail) 23269 { 23270 *fnamelen += (int)(*fnamep - (s + 1)); 23271 *fnamep = s + 1; 23272#ifdef VMS 23273 /* cut version from the extension */ 23274 s = *fnamep + *fnamelen - 1; 23275 for ( ; s > *fnamep; --s) 23276 if (s[0] == ';') 23277 break; 23278 if (s > *fnamep) 23279 *fnamelen = s - *fnamep; 23280#endif 23281 } 23282 else if (*fnamep <= tail) 23283 *fnamelen = 0; 23284 } 23285 else /* :r */ 23286 { 23287 if (s > tail) /* remove one extension */ 23288 *fnamelen = (int)(s - *fnamep); 23289 } 23290 *usedlen += 2; 23291 } 23292 23293 /* ":s?pat?foo?" - substitute */ 23294 /* ":gs?pat?foo?" - global substitute */ 23295 if (src[*usedlen] == ':' 23296 && (src[*usedlen + 1] == 's' 23297 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 23298 { 23299 char_u *str; 23300 char_u *pat; 23301 char_u *sub; 23302 int sep; 23303 char_u *flags; 23304 int didit = FALSE; 23305 23306 flags = (char_u *)""; 23307 s = src + *usedlen + 2; 23308 if (src[*usedlen + 1] == 'g') 23309 { 23310 flags = (char_u *)"g"; 23311 ++s; 23312 } 23313 23314 sep = *s++; 23315 if (sep) 23316 { 23317 /* find end of pattern */ 23318 p = vim_strchr(s, sep); 23319 if (p != NULL) 23320 { 23321 pat = vim_strnsave(s, (int)(p - s)); 23322 if (pat != NULL) 23323 { 23324 s = p + 1; 23325 /* find end of substitution */ 23326 p = vim_strchr(s, sep); 23327 if (p != NULL) 23328 { 23329 sub = vim_strnsave(s, (int)(p - s)); 23330 str = vim_strnsave(*fnamep, *fnamelen); 23331 if (sub != NULL && str != NULL) 23332 { 23333 *usedlen = (int)(p + 1 - src); 23334 s = do_string_sub(str, pat, sub, flags); 23335 if (s != NULL) 23336 { 23337 *fnamep = s; 23338 *fnamelen = (int)STRLEN(s); 23339 vim_free(*bufp); 23340 *bufp = s; 23341 didit = TRUE; 23342 } 23343 } 23344 vim_free(sub); 23345 vim_free(str); 23346 } 23347 vim_free(pat); 23348 } 23349 } 23350 /* after using ":s", repeat all the modifiers */ 23351 if (didit) 23352 goto repeat; 23353 } 23354 } 23355 23356 return valid; 23357} 23358 23359/* 23360 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 23361 * "flags" can be "g" to do a global substitute. 23362 * Returns an allocated string, NULL for error. 23363 */ 23364 char_u * 23365do_string_sub(str, pat, sub, flags) 23366 char_u *str; 23367 char_u *pat; 23368 char_u *sub; 23369 char_u *flags; 23370{ 23371 int sublen; 23372 regmatch_T regmatch; 23373 int i; 23374 int do_all; 23375 char_u *tail; 23376 garray_T ga; 23377 char_u *ret; 23378 char_u *save_cpo; 23379 23380 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 23381 save_cpo = p_cpo; 23382 p_cpo = empty_option; 23383 23384 ga_init2(&ga, 1, 200); 23385 23386 do_all = (flags[0] == 'g'); 23387 23388 regmatch.rm_ic = p_ic; 23389 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 23390 if (regmatch.regprog != NULL) 23391 { 23392 tail = str; 23393 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 23394 { 23395 /* 23396 * Get some space for a temporary buffer to do the substitution 23397 * into. It will contain: 23398 * - The text up to where the match is. 23399 * - The substituted text. 23400 * - The text after the match. 23401 */ 23402 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 23403 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 23404 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 23405 { 23406 ga_clear(&ga); 23407 break; 23408 } 23409 23410 /* copy the text up to where the match is */ 23411 i = (int)(regmatch.startp[0] - tail); 23412 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 23413 /* add the substituted text */ 23414 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 23415 + ga.ga_len + i, TRUE, TRUE, FALSE); 23416 ga.ga_len += i + sublen - 1; 23417 /* avoid getting stuck on a match with an empty string */ 23418 if (tail == regmatch.endp[0]) 23419 { 23420 if (*tail == NUL) 23421 break; 23422 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 23423 ++ga.ga_len; 23424 } 23425 else 23426 { 23427 tail = regmatch.endp[0]; 23428 if (*tail == NUL) 23429 break; 23430 } 23431 if (!do_all) 23432 break; 23433 } 23434 23435 if (ga.ga_data != NULL) 23436 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 23437 23438 vim_free(regmatch.regprog); 23439 } 23440 23441 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 23442 ga_clear(&ga); 23443 if (p_cpo == empty_option) 23444 p_cpo = save_cpo; 23445 else 23446 /* Darn, evaluating {sub} expression changed the value. */ 23447 free_string_option(save_cpo); 23448 23449 return ret; 23450} 23451 23452#endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 23453