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(MSWIN) 14 # include "vimio.h" /* for mch_open(), must be before vim.h */ 15 #endif 16 17 #include "vim.h" 18 19 #ifdef AMIGA 20 # include <time.h> /* for strftime() */ 21 #endif 22 23 #ifdef MACOS 24 # include <time.h> /* for time_t */ 25 #endif 26 27 #ifdef HAVE_FCNTL_H 28 # include <fcntl.h> 29 #endif 30 31 #if defined(FEAT_EVAL) || defined(PROTO) 32 33 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 34 35 /* 36 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 37 * This avoids adding a pointer to the hashtab item. 38 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 39 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 40 * HI2DI() converts a hashitem pointer to a dictitem pointer. 41 */ 42 static dictitem_T dumdi; 43 #define DI2HIKEY(di) ((di)->di_key) 44 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 45 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 46 47 /* 48 * Structure returned by get_lval() and used by set_var_lval(). 49 * For a plain name: 50 * "name" points to the variable name. 51 * "exp_name" is NULL. 52 * "tv" is NULL 53 * For a magic braces name: 54 * "name" points to the expanded variable name. 55 * "exp_name" is non-NULL, to be freed later. 56 * "tv" is NULL 57 * For an index in a list: 58 * "name" points to the (expanded) variable name. 59 * "exp_name" NULL or non-NULL, to be freed later. 60 * "tv" points to the (first) list item value 61 * "li" points to the (first) list item 62 * "range", "n1", "n2" and "empty2" indicate what items are used. 63 * For an existing Dict item: 64 * "name" points to the (expanded) variable name. 65 * "exp_name" NULL or non-NULL, to be freed later. 66 * "tv" points to the dict item value 67 * "newkey" is NULL 68 * For a non-existing Dict item: 69 * "name" points to the (expanded) variable name. 70 * "exp_name" NULL or non-NULL, to be freed later. 71 * "tv" points to the Dictionary typval_T 72 * "newkey" is the key for the new item. 73 */ 74 typedef struct lval_S 75 { 76 char_u *ll_name; /* start of variable name (can be NULL) */ 77 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 78 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 79 isn't NULL it's the Dict to which to add 80 the item. */ 81 listitem_T *ll_li; /* The list item or NULL. */ 82 list_T *ll_list; /* The list or NULL. */ 83 int ll_range; /* TRUE when a [i:j] range was used */ 84 long ll_n1; /* First index for list */ 85 long ll_n2; /* Second index for list range */ 86 int ll_empty2; /* Second index is empty: [i:] */ 87 dict_T *ll_dict; /* The Dictionary or NULL */ 88 dictitem_T *ll_di; /* The dictitem or NULL */ 89 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 90 } lval_T; 91 92 93 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 94 static char *e_listidx = N_("E684: list index out of range: %ld"); 95 static char *e_undefvar = N_("E121: Undefined variable: %s"); 96 static char *e_missbrac = N_("E111: Missing ']'"); 97 static char *e_listarg = N_("E686: Argument of %s must be a List"); 98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 99 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 100 static char *e_listreq = N_("E714: List required"); 101 static char *e_dictreq = N_("E715: Dictionary required"); 102 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 103 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 104 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 105 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 106 static char *e_funcref = N_("E718: Funcref required"); 107 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 108 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 109 static char *e_nofunc = N_("E130: Unknown function: %s"); 110 static char *e_illvar = N_("E461: Illegal variable name: %s"); 111 /* 112 * All user-defined global variables are stored in dictionary "globvardict". 113 * "globvars_var" is the variable that is used for "g:". 114 */ 115 static dict_T globvardict; 116 static dictitem_T globvars_var; 117 #define globvarht globvardict.dv_hashtab 118 119 /* 120 * Old Vim variables such as "v:version" are also available without the "v:". 121 * Also in functions. We need a special hashtable for them. 122 */ 123 static hashtab_T compat_hashtab; 124 125 /* 126 * When recursively copying lists and dicts we need to remember which ones we 127 * have done to avoid endless recursiveness. This unique ID is used for that. 128 */ 129 static int current_copyID = 0; 130 131 /* 132 * Array to hold the hashtab with variables local to each sourced script. 133 * Each item holds a variable (nameless) that points to the dict_T. 134 */ 135 typedef struct 136 { 137 dictitem_T sv_var; 138 dict_T sv_dict; 139 } scriptvar_T; 140 141 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL}; 142 #define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1]) 143 #define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab) 144 145 static int echo_attr = 0; /* attributes used for ":echo" */ 146 147 /* Values for trans_function_name() argument: */ 148 #define TFN_INT 1 /* internal function name OK */ 149 #define TFN_QUIET 2 /* no error messages */ 150 151 /* 152 * Structure to hold info for a user function. 153 */ 154 typedef struct ufunc ufunc_T; 155 156 struct ufunc 157 { 158 int uf_varargs; /* variable nr of arguments */ 159 int uf_flags; 160 int uf_calls; /* nr of active calls */ 161 garray_T uf_args; /* arguments */ 162 garray_T uf_lines; /* function lines */ 163 #ifdef FEAT_PROFILE 164 int uf_profiling; /* TRUE when func is being profiled */ 165 /* profiling the function as a whole */ 166 int uf_tm_count; /* nr of calls */ 167 proftime_T uf_tm_total; /* time spend in function + children */ 168 proftime_T uf_tm_self; /* time spend in function itself */ 169 proftime_T uf_tm_start; /* time at function call */ 170 proftime_T uf_tm_children; /* time spent in children this call */ 171 /* profiling the function per line */ 172 int *uf_tml_count; /* nr of times line was executed */ 173 proftime_T *uf_tml_total; /* time spend in a line + children */ 174 proftime_T *uf_tml_self; /* time spend in a line itself */ 175 proftime_T uf_tml_start; /* start time for current line */ 176 proftime_T uf_tml_children; /* time spent in children for this line */ 177 proftime_T uf_tml_wait; /* start wait time for current line */ 178 int uf_tml_idx; /* index of line being timed; -1 if none */ 179 int uf_tml_execed; /* line being timed was executed */ 180 #endif 181 scid_T uf_script_ID; /* ID of script where function was defined, 182 used for s: variables */ 183 int uf_refcount; /* for numbered function: reference count */ 184 char_u uf_name[1]; /* name of function (actually longer); can 185 start with <SNR>123_ (<SNR> is K_SPECIAL 186 KS_EXTRA KE_SNR) */ 187 }; 188 189 /* function flags */ 190 #define FC_ABORT 1 /* abort function on error */ 191 #define FC_RANGE 2 /* function accepts range */ 192 #define FC_DICT 4 /* Dict function, uses "self" */ 193 194 #define DEL_REFCOUNT 999999 /* list/dict is being deleted */ 195 196 /* 197 * All user-defined functions are found in this hashtable. 198 */ 199 static hashtab_T func_hashtab; 200 201 /* list heads for garbage collection */ 202 static dict_T *first_dict = NULL; /* list of all dicts */ 203 static list_T *first_list = NULL; /* list of all lists */ 204 205 /* From user function to hashitem and back. */ 206 static ufunc_T dumuf; 207 #define UF2HIKEY(fp) ((fp)->uf_name) 208 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 209 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 210 211 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 212 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 213 214 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 215 #define VAR_SHORT_LEN 20 /* short variable name length */ 216 #define FIXVAR_CNT 12 /* number of fixed variables */ 217 218 /* structure to hold info for a function that is currently being executed. */ 219 typedef struct funccall_S funccall_T; 220 221 struct funccall_S 222 { 223 ufunc_T *func; /* function being called */ 224 int linenr; /* next line to be executed */ 225 int returned; /* ":return" used */ 226 struct /* fixed variables for arguments */ 227 { 228 dictitem_T var; /* variable (without room for name) */ 229 char_u room[VAR_SHORT_LEN]; /* room for the name */ 230 } fixvar[FIXVAR_CNT]; 231 dict_T l_vars; /* l: local function variables */ 232 dictitem_T l_vars_var; /* variable for l: scope */ 233 dict_T l_avars; /* a: argument variables */ 234 dictitem_T l_avars_var; /* variable for a: scope */ 235 list_T l_varlist; /* list for a:000 */ 236 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 237 typval_T *rettv; /* return value */ 238 linenr_T breakpoint; /* next line with breakpoint or zero */ 239 int dbg_tick; /* debug_tick when breakpoint was set */ 240 int level; /* top nesting level of executed function */ 241 #ifdef FEAT_PROFILE 242 proftime_T prof_child; /* time spent in a child */ 243 #endif 244 funccall_T *caller; /* calling function or NULL */ 245 }; 246 247 /* 248 * Info used by a ":for" loop. 249 */ 250 typedef struct 251 { 252 int fi_semicolon; /* TRUE if ending in '; var]' */ 253 int fi_varcount; /* nr of variables in the list */ 254 listwatch_T fi_lw; /* keep an eye on the item used. */ 255 list_T *fi_list; /* list being used */ 256 } forinfo_T; 257 258 /* 259 * Struct used by trans_function_name() 260 */ 261 typedef struct 262 { 263 dict_T *fd_dict; /* Dictionary used */ 264 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 265 dictitem_T *fd_di; /* Dictionary item used */ 266 } funcdict_T; 267 268 269 /* 270 * Array to hold the value of v: variables. 271 * The value is in a dictitem, so that it can also be used in the v: scope. 272 * The reason to use this table anyway is for very quick access to the 273 * variables with the VV_ defines. 274 */ 275 #include "version.h" 276 277 /* values for vv_flags: */ 278 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 279 #define VV_RO 2 /* read-only */ 280 #define VV_RO_SBX 4 /* read-only in the sandbox */ 281 282 #define VV_NAME(s, t) s, {{t}}, {0} 283 284 static struct vimvar 285 { 286 char *vv_name; /* name of variable, without v: */ 287 dictitem_T vv_di; /* value and name for key */ 288 char vv_filler[16]; /* space for LONGEST name below!!! */ 289 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 290 } vimvars[VV_LEN] = 291 { 292 /* 293 * The order here must match the VV_ defines in vim.h! 294 * Initializing a union does not work, leave tv.vval empty to get zero's. 295 */ 296 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 297 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 298 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 299 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 300 {VV_NAME("warningmsg", VAR_STRING), 0}, 301 {VV_NAME("statusmsg", VAR_STRING), 0}, 302 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 303 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 304 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 305 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 306 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 307 {VV_NAME("fname", VAR_STRING), VV_RO}, 308 {VV_NAME("lang", VAR_STRING), VV_RO}, 309 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 310 {VV_NAME("ctype", VAR_STRING), VV_RO}, 311 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 312 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 313 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 314 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 315 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 316 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 317 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 318 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 319 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 320 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 321 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 322 {VV_NAME("progname", VAR_STRING), VV_RO}, 323 {VV_NAME("servername", VAR_STRING), VV_RO}, 324 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 325 {VV_NAME("exception", VAR_STRING), VV_RO}, 326 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 327 {VV_NAME("register", VAR_STRING), VV_RO}, 328 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 329 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 330 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 331 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 332 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 333 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 334 {VV_NAME("fcs_choice", VAR_STRING), 0}, 335 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 336 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 337 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 338 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 339 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 340 {VV_NAME("scrollstart", VAR_STRING), 0}, 341 {VV_NAME("swapname", VAR_STRING), VV_RO}, 342 {VV_NAME("swapchoice", VAR_STRING), 0}, 343 {VV_NAME("swapcommand", VAR_STRING), VV_RO}, 344 {VV_NAME("char", VAR_STRING), VV_RO}, 345 }; 346 347 /* shorthand */ 348 #define vv_type vv_di.di_tv.v_type 349 #define vv_nr vv_di.di_tv.vval.v_number 350 #define vv_str vv_di.di_tv.vval.v_string 351 #define vv_tv vv_di.di_tv 352 353 /* 354 * The v: variables are stored in dictionary "vimvardict". 355 * "vimvars_var" is the variable that is used for the "l:" scope. 356 */ 357 static dict_T vimvardict; 358 static dictitem_T vimvars_var; 359 #define vimvarht vimvardict.dv_hashtab 360 361 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 362 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 363 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 364 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 365 #endif 366 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 367 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 368 static char_u *skip_var_one __ARGS((char_u *arg)); 369 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 370 static void list_glob_vars __ARGS((void)); 371 static void list_buf_vars __ARGS((void)); 372 static void list_win_vars __ARGS((void)); 373 #ifdef FEAT_WINDOWS 374 static void list_tab_vars __ARGS((void)); 375 #endif 376 static void list_vim_vars __ARGS((void)); 377 static void list_script_vars __ARGS((void)); 378 static void list_func_vars __ARGS((void)); 379 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 380 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 381 static int check_changedtick __ARGS((char_u *arg)); 382 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 383 static void clear_lval __ARGS((lval_T *lp)); 384 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 385 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 386 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 387 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 388 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 389 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 390 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 391 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 392 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 393 static int tv_islocked __ARGS((typval_T *tv)); 394 395 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 396 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 398 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 403 404 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 405 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 406 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 407 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 408 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 409 static int rettv_list_alloc __ARGS((typval_T *rettv)); 410 static listitem_T *listitem_alloc __ARGS((void)); 411 static void listitem_free __ARGS((listitem_T *item)); 412 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 413 static long list_len __ARGS((list_T *l)); 414 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 415 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 416 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 417 static listitem_T *list_find __ARGS((list_T *l, long n)); 418 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 419 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 420 static void list_append __ARGS((list_T *l, listitem_T *item)); 421 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 422 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 423 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 424 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 425 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 426 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 427 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 428 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 429 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 430 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 431 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 432 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 433 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 434 static void dict_unref __ARGS((dict_T *d)); 435 static void dict_free __ARGS((dict_T *d)); 436 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 437 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 438 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 439 static void dictitem_free __ARGS((dictitem_T *item)); 440 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 441 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 442 static long dict_len __ARGS((dict_T *d)); 443 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 444 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 445 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 446 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 447 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 448 static char_u *string_quote __ARGS((char_u *str, int function)); 449 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 450 static int find_internal_func __ARGS((char_u *name)); 451 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 452 static 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)); 453 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); 454 static void emsg_funcname __ARGS((char *msg, char_u *name)); 455 456 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 476 #if defined(FEAT_INS_EXPAND) 477 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 480 #endif 481 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 486 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 582 #ifdef vim_mkdir 583 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 584 #endif 585 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 629 #ifdef HAVE_STRFTIME 630 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 631 #endif 632 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 636 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 637 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 654 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 655 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 656 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 657 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 666 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 667 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 668 669 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 670 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum)); 671 static int get_env_len __ARGS((char_u **arg)); 672 static int get_id_len __ARGS((char_u **arg)); 673 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 674 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 675 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 676 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 677 valid character */ 678 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 679 static int eval_isnamec __ARGS((int c)); 680 static int eval_isnamec1 __ARGS((int c)); 681 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 682 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 683 static typval_T *alloc_tv __ARGS((void)); 684 static typval_T *alloc_string_tv __ARGS((char_u *string)); 685 static void init_tv __ARGS((typval_T *varp)); 686 static long get_tv_number __ARGS((typval_T *varp)); 687 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 688 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 689 static char_u *get_tv_string __ARGS((typval_T *varp)); 690 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 691 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 692 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 693 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 694 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 695 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 696 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 697 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 698 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 699 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 700 static int var_check_ro __ARGS((int flags, char_u *name)); 701 static int tv_check_lock __ARGS((int lock, char_u *name)); 702 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 703 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 704 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 705 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 706 static int eval_fname_script __ARGS((char_u *p)); 707 static int eval_fname_sid __ARGS((char_u *p)); 708 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 709 static ufunc_T *find_func __ARGS((char_u *name)); 710 static int function_exists __ARGS((char_u *name)); 711 static int builtin_function __ARGS((char_u *name)); 712 #ifdef FEAT_PROFILE 713 static void func_do_profile __ARGS((ufunc_T *fp)); 714 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 715 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 716 static int 717 # ifdef __BORLANDC__ 718 _RTLENTRYF 719 # endif 720 prof_total_cmp __ARGS((const void *s1, const void *s2)); 721 static int 722 # ifdef __BORLANDC__ 723 _RTLENTRYF 724 # endif 725 prof_self_cmp __ARGS((const void *s1, const void *s2)); 726 #endif 727 static int script_autoload __ARGS((char_u *name, int reload)); 728 static char_u *autoload_name __ARGS((char_u *name)); 729 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 730 static void func_free __ARGS((ufunc_T *fp)); 731 static void func_unref __ARGS((char_u *name)); 732 static void func_ref __ARGS((char_u *name)); 733 static 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)); 734 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 735 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 736 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 737 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 738 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 739 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 740 741 /* Character used as separated in autoload function/variable names. */ 742 #define AUTOLOAD_CHAR '#' 743 744 /* 745 * Initialize the global and v: variables. 746 */ 747 void 748 eval_init() 749 { 750 int i; 751 struct vimvar *p; 752 753 init_var_dict(&globvardict, &globvars_var); 754 init_var_dict(&vimvardict, &vimvars_var); 755 hash_init(&compat_hashtab); 756 hash_init(&func_hashtab); 757 758 for (i = 0; i < VV_LEN; ++i) 759 { 760 p = &vimvars[i]; 761 STRCPY(p->vv_di.di_key, p->vv_name); 762 if (p->vv_flags & VV_RO) 763 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 764 else if (p->vv_flags & VV_RO_SBX) 765 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 766 else 767 p->vv_di.di_flags = DI_FLAGS_FIX; 768 769 /* add to v: scope dict, unless the value is not always available */ 770 if (p->vv_type != VAR_UNKNOWN) 771 hash_add(&vimvarht, p->vv_di.di_key); 772 if (p->vv_flags & VV_COMPAT) 773 /* add to compat scope dict */ 774 hash_add(&compat_hashtab, p->vv_di.di_key); 775 } 776 } 777 778 #if defined(EXITFREE) || defined(PROTO) 779 void 780 eval_clear() 781 { 782 int i; 783 struct vimvar *p; 784 785 for (i = 0; i < VV_LEN; ++i) 786 { 787 p = &vimvars[i]; 788 if (p->vv_di.di_tv.v_type == VAR_STRING) 789 { 790 vim_free(p->vv_di.di_tv.vval.v_string); 791 p->vv_di.di_tv.vval.v_string = NULL; 792 } 793 } 794 hash_clear(&vimvarht); 795 hash_clear(&compat_hashtab); 796 797 /* script-local variables */ 798 for (i = 1; i <= ga_scripts.ga_len; ++i) 799 vars_clear(&SCRIPT_VARS(i)); 800 ga_clear(&ga_scripts); 801 free_scriptnames(); 802 803 /* global variables */ 804 vars_clear(&globvarht); 805 806 /* functions */ 807 free_all_functions(); 808 hash_clear(&func_hashtab); 809 810 /* unreferenced lists and dicts */ 811 (void)garbage_collect(); 812 } 813 #endif 814 815 /* 816 * Return the name of the executed function. 817 */ 818 char_u * 819 func_name(cookie) 820 void *cookie; 821 { 822 return ((funccall_T *)cookie)->func->uf_name; 823 } 824 825 /* 826 * Return the address holding the next breakpoint line for a funccall cookie. 827 */ 828 linenr_T * 829 func_breakpoint(cookie) 830 void *cookie; 831 { 832 return &((funccall_T *)cookie)->breakpoint; 833 } 834 835 /* 836 * Return the address holding the debug tick for a funccall cookie. 837 */ 838 int * 839 func_dbg_tick(cookie) 840 void *cookie; 841 { 842 return &((funccall_T *)cookie)->dbg_tick; 843 } 844 845 /* 846 * Return the nesting level for a funccall cookie. 847 */ 848 int 849 func_level(cookie) 850 void *cookie; 851 { 852 return ((funccall_T *)cookie)->level; 853 } 854 855 /* pointer to funccal for currently active function */ 856 funccall_T *current_funccal = NULL; 857 858 /* 859 * Return TRUE when a function was ended by a ":return" command. 860 */ 861 int 862 current_func_returned() 863 { 864 return current_funccal->returned; 865 } 866 867 868 /* 869 * Set an internal variable to a string value. Creates the variable if it does 870 * not already exist. 871 */ 872 void 873 set_internal_string_var(name, value) 874 char_u *name; 875 char_u *value; 876 { 877 char_u *val; 878 typval_T *tvp; 879 880 val = vim_strsave(value); 881 if (val != NULL) 882 { 883 tvp = alloc_string_tv(val); 884 if (tvp != NULL) 885 { 886 set_var(name, tvp, FALSE); 887 free_tv(tvp); 888 } 889 } 890 } 891 892 static lval_T *redir_lval = NULL; 893 static char_u *redir_endp = NULL; 894 static char_u *redir_varname = NULL; 895 896 /* 897 * Start recording command output to a variable 898 * Returns OK if successfully completed the setup. FAIL otherwise. 899 */ 900 int 901 var_redir_start(name, append) 902 char_u *name; 903 int append; /* append to an existing variable */ 904 { 905 int save_emsg; 906 int err; 907 typval_T tv; 908 909 /* Make sure a valid variable name is specified */ 910 if (!eval_isnamec1(*name)) 911 { 912 EMSG(_(e_invarg)); 913 return FAIL; 914 } 915 916 redir_varname = vim_strsave(name); 917 if (redir_varname == NULL) 918 return FAIL; 919 920 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 921 if (redir_lval == NULL) 922 { 923 var_redir_stop(); 924 return FAIL; 925 } 926 927 /* Parse the variable name (can be a dict or list entry). */ 928 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 929 FNE_CHECK_START); 930 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 931 { 932 if (redir_endp != NULL && *redir_endp != NUL) 933 /* Trailing characters are present after the variable name */ 934 EMSG(_(e_trailing)); 935 else 936 EMSG(_(e_invarg)); 937 var_redir_stop(); 938 return FAIL; 939 } 940 941 /* check if we can write to the variable: set it to or append an empty 942 * string */ 943 save_emsg = did_emsg; 944 did_emsg = FALSE; 945 tv.v_type = VAR_STRING; 946 tv.vval.v_string = (char_u *)""; 947 if (append) 948 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 949 else 950 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 951 err = did_emsg; 952 did_emsg |= save_emsg; 953 if (err) 954 { 955 var_redir_stop(); 956 return FAIL; 957 } 958 if (redir_lval->ll_newkey != NULL) 959 { 960 /* Dictionary item was created, don't do it again. */ 961 vim_free(redir_lval->ll_newkey); 962 redir_lval->ll_newkey = NULL; 963 } 964 965 return OK; 966 } 967 968 /* 969 * Append "value[len]" to the variable set by var_redir_start(). 970 */ 971 void 972 var_redir_str(value, len) 973 char_u *value; 974 int len; 975 { 976 char_u *val; 977 typval_T tv; 978 int save_emsg; 979 int err; 980 981 if (redir_lval == NULL) 982 return; 983 984 if (len == -1) 985 /* Append the entire string */ 986 val = vim_strsave(value); 987 else 988 /* Append only the specified number of characters */ 989 val = vim_strnsave(value, len); 990 if (val == NULL) 991 return; 992 993 tv.v_type = VAR_STRING; 994 tv.vval.v_string = val; 995 996 save_emsg = did_emsg; 997 did_emsg = FALSE; 998 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 999 err = did_emsg; 1000 did_emsg |= save_emsg; 1001 if (err) 1002 var_redir_stop(); 1003 1004 vim_free(tv.vval.v_string); 1005 } 1006 1007 /* 1008 * Stop redirecting command output to a variable. 1009 */ 1010 void 1011 var_redir_stop() 1012 { 1013 if (redir_lval != NULL) 1014 { 1015 clear_lval(redir_lval); 1016 vim_free(redir_lval); 1017 redir_lval = NULL; 1018 } 1019 vim_free(redir_varname); 1020 redir_varname = NULL; 1021 } 1022 1023 # if defined(FEAT_MBYTE) || defined(PROTO) 1024 int 1025 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1026 char_u *enc_from; 1027 char_u *enc_to; 1028 char_u *fname_from; 1029 char_u *fname_to; 1030 { 1031 int err = FALSE; 1032 1033 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1034 set_vim_var_string(VV_CC_TO, enc_to, -1); 1035 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1036 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1037 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1038 err = TRUE; 1039 set_vim_var_string(VV_CC_FROM, NULL, -1); 1040 set_vim_var_string(VV_CC_TO, NULL, -1); 1041 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1042 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1043 1044 if (err) 1045 return FAIL; 1046 return OK; 1047 } 1048 # endif 1049 1050 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1051 int 1052 eval_printexpr(fname, args) 1053 char_u *fname; 1054 char_u *args; 1055 { 1056 int err = FALSE; 1057 1058 set_vim_var_string(VV_FNAME_IN, fname, -1); 1059 set_vim_var_string(VV_CMDARG, args, -1); 1060 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1061 err = TRUE; 1062 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1063 set_vim_var_string(VV_CMDARG, NULL, -1); 1064 1065 if (err) 1066 { 1067 mch_remove(fname); 1068 return FAIL; 1069 } 1070 return OK; 1071 } 1072 # endif 1073 1074 # if defined(FEAT_DIFF) || defined(PROTO) 1075 void 1076 eval_diff(origfile, newfile, outfile) 1077 char_u *origfile; 1078 char_u *newfile; 1079 char_u *outfile; 1080 { 1081 int err = FALSE; 1082 1083 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1084 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1085 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1086 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1087 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1088 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1089 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1090 } 1091 1092 void 1093 eval_patch(origfile, difffile, outfile) 1094 char_u *origfile; 1095 char_u *difffile; 1096 char_u *outfile; 1097 { 1098 int err; 1099 1100 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1101 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1102 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1103 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1104 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1105 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1106 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1107 } 1108 # endif 1109 1110 /* 1111 * Top level evaluation function, returning a boolean. 1112 * Sets "error" to TRUE if there was an error. 1113 * Return TRUE or FALSE. 1114 */ 1115 int 1116 eval_to_bool(arg, error, nextcmd, skip) 1117 char_u *arg; 1118 int *error; 1119 char_u **nextcmd; 1120 int skip; /* only parse, don't execute */ 1121 { 1122 typval_T tv; 1123 int retval = FALSE; 1124 1125 if (skip) 1126 ++emsg_skip; 1127 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1128 *error = TRUE; 1129 else 1130 { 1131 *error = FALSE; 1132 if (!skip) 1133 { 1134 retval = (get_tv_number_chk(&tv, error) != 0); 1135 clear_tv(&tv); 1136 } 1137 } 1138 if (skip) 1139 --emsg_skip; 1140 1141 return retval; 1142 } 1143 1144 /* 1145 * Top level evaluation function, returning a string. If "skip" is TRUE, 1146 * only parsing to "nextcmd" is done, without reporting errors. Return 1147 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1148 */ 1149 char_u * 1150 eval_to_string_skip(arg, nextcmd, skip) 1151 char_u *arg; 1152 char_u **nextcmd; 1153 int skip; /* only parse, don't execute */ 1154 { 1155 typval_T tv; 1156 char_u *retval; 1157 1158 if (skip) 1159 ++emsg_skip; 1160 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1161 retval = NULL; 1162 else 1163 { 1164 retval = vim_strsave(get_tv_string(&tv)); 1165 clear_tv(&tv); 1166 } 1167 if (skip) 1168 --emsg_skip; 1169 1170 return retval; 1171 } 1172 1173 /* 1174 * Skip over an expression at "*pp". 1175 * Return FAIL for an error, OK otherwise. 1176 */ 1177 int 1178 skip_expr(pp) 1179 char_u **pp; 1180 { 1181 typval_T rettv; 1182 1183 *pp = skipwhite(*pp); 1184 return eval1(pp, &rettv, FALSE); 1185 } 1186 1187 /* 1188 * Top level evaluation function, returning a string. 1189 * Return pointer to allocated memory, or NULL for failure. 1190 */ 1191 char_u * 1192 eval_to_string(arg, nextcmd, dolist) 1193 char_u *arg; 1194 char_u **nextcmd; 1195 int dolist; /* turn List into sequence of lines */ 1196 { 1197 typval_T tv; 1198 char_u *retval; 1199 garray_T ga; 1200 1201 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1202 retval = NULL; 1203 else 1204 { 1205 if (dolist && tv.v_type == VAR_LIST) 1206 { 1207 ga_init2(&ga, (int)sizeof(char), 80); 1208 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1209 ga_append(&ga, NUL); 1210 retval = (char_u *)ga.ga_data; 1211 } 1212 else 1213 retval = vim_strsave(get_tv_string(&tv)); 1214 clear_tv(&tv); 1215 } 1216 1217 return retval; 1218 } 1219 1220 /* 1221 * Call eval_to_string() without using current local variables and using 1222 * textlock. When "use_sandbox" is TRUE use the sandbox. 1223 */ 1224 char_u * 1225 eval_to_string_safe(arg, nextcmd, use_sandbox) 1226 char_u *arg; 1227 char_u **nextcmd; 1228 int use_sandbox; 1229 { 1230 char_u *retval; 1231 void *save_funccalp; 1232 1233 save_funccalp = save_funccal(); 1234 if (use_sandbox) 1235 ++sandbox; 1236 ++textlock; 1237 retval = eval_to_string(arg, nextcmd, FALSE); 1238 if (use_sandbox) 1239 --sandbox; 1240 --textlock; 1241 restore_funccal(save_funccalp); 1242 return retval; 1243 } 1244 1245 /* 1246 * Top level evaluation function, returning a number. 1247 * Evaluates "expr" silently. 1248 * Returns -1 for an error. 1249 */ 1250 int 1251 eval_to_number(expr) 1252 char_u *expr; 1253 { 1254 typval_T rettv; 1255 int retval; 1256 char_u *p = skipwhite(expr); 1257 1258 ++emsg_off; 1259 1260 if (eval1(&p, &rettv, TRUE) == FAIL) 1261 retval = -1; 1262 else 1263 { 1264 retval = get_tv_number_chk(&rettv, NULL); 1265 clear_tv(&rettv); 1266 } 1267 --emsg_off; 1268 1269 return retval; 1270 } 1271 1272 /* 1273 * Prepare v: variable "idx" to be used. 1274 * Save the current typeval in "save_tv". 1275 * When not used yet add the variable to the v: hashtable. 1276 */ 1277 static void 1278 prepare_vimvar(idx, save_tv) 1279 int idx; 1280 typval_T *save_tv; 1281 { 1282 *save_tv = vimvars[idx].vv_tv; 1283 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1284 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1285 } 1286 1287 /* 1288 * Restore v: variable "idx" to typeval "save_tv". 1289 * When no longer defined, remove the variable from the v: hashtable. 1290 */ 1291 static void 1292 restore_vimvar(idx, save_tv) 1293 int idx; 1294 typval_T *save_tv; 1295 { 1296 hashitem_T *hi; 1297 1298 clear_tv(&vimvars[idx].vv_tv); 1299 vimvars[idx].vv_tv = *save_tv; 1300 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1301 { 1302 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1303 if (HASHITEM_EMPTY(hi)) 1304 EMSG2(_(e_intern2), "restore_vimvar()"); 1305 else 1306 hash_remove(&vimvarht, hi); 1307 } 1308 } 1309 1310 #if defined(FEAT_SPELL) || defined(PROTO) 1311 /* 1312 * Evaluate an expression to a list with suggestions. 1313 * For the "expr:" part of 'spellsuggest'. 1314 */ 1315 list_T * 1316 eval_spell_expr(badword, expr) 1317 char_u *badword; 1318 char_u *expr; 1319 { 1320 typval_T save_val; 1321 typval_T rettv; 1322 list_T *list = NULL; 1323 char_u *p = skipwhite(expr); 1324 1325 /* Set "v:val" to the bad word. */ 1326 prepare_vimvar(VV_VAL, &save_val); 1327 vimvars[VV_VAL].vv_type = VAR_STRING; 1328 vimvars[VV_VAL].vv_str = badword; 1329 if (p_verbose == 0) 1330 ++emsg_off; 1331 1332 if (eval1(&p, &rettv, TRUE) == OK) 1333 { 1334 if (rettv.v_type != VAR_LIST) 1335 clear_tv(&rettv); 1336 else 1337 list = rettv.vval.v_list; 1338 } 1339 1340 if (p_verbose == 0) 1341 --emsg_off; 1342 vimvars[VV_VAL].vv_str = NULL; 1343 restore_vimvar(VV_VAL, &save_val); 1344 1345 return list; 1346 } 1347 1348 /* 1349 * "list" is supposed to contain two items: a word and a number. Return the 1350 * word in "pp" and the number as the return value. 1351 * Return -1 if anything isn't right. 1352 * Used to get the good word and score from the eval_spell_expr() result. 1353 */ 1354 int 1355 get_spellword(list, pp) 1356 list_T *list; 1357 char_u **pp; 1358 { 1359 listitem_T *li; 1360 1361 li = list->lv_first; 1362 if (li == NULL) 1363 return -1; 1364 *pp = get_tv_string(&li->li_tv); 1365 1366 li = li->li_next; 1367 if (li == NULL) 1368 return -1; 1369 return get_tv_number(&li->li_tv); 1370 } 1371 #endif 1372 1373 /* 1374 * Top level evaluation function. 1375 * Returns an allocated typval_T with the result. 1376 * Returns NULL when there is an error. 1377 */ 1378 typval_T * 1379 eval_expr(arg, nextcmd) 1380 char_u *arg; 1381 char_u **nextcmd; 1382 { 1383 typval_T *tv; 1384 1385 tv = (typval_T *)alloc(sizeof(typval_T)); 1386 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1387 { 1388 vim_free(tv); 1389 tv = NULL; 1390 } 1391 1392 return tv; 1393 } 1394 1395 1396 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1397 /* 1398 * Call some vimL function and return the result in "*rettv". 1399 * Uses argv[argc] for the function arguments. 1400 * Returns OK or FAIL. 1401 */ 1402 static int 1403 call_vim_function(func, argc, argv, safe, rettv) 1404 char_u *func; 1405 int argc; 1406 char_u **argv; 1407 int safe; /* use the sandbox */ 1408 typval_T *rettv; 1409 { 1410 typval_T *argvars; 1411 long n; 1412 int len; 1413 int i; 1414 int doesrange; 1415 void *save_funccalp = NULL; 1416 int ret; 1417 1418 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1419 if (argvars == NULL) 1420 return FAIL; 1421 1422 for (i = 0; i < argc; i++) 1423 { 1424 /* Pass a NULL or empty argument as an empty string */ 1425 if (argv[i] == NULL || *argv[i] == NUL) 1426 { 1427 argvars[i].v_type = VAR_STRING; 1428 argvars[i].vval.v_string = (char_u *)""; 1429 continue; 1430 } 1431 1432 /* Recognize a number argument, the others must be strings. */ 1433 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1434 if (len != 0 && len == (int)STRLEN(argv[i])) 1435 { 1436 argvars[i].v_type = VAR_NUMBER; 1437 argvars[i].vval.v_number = n; 1438 } 1439 else 1440 { 1441 argvars[i].v_type = VAR_STRING; 1442 argvars[i].vval.v_string = argv[i]; 1443 } 1444 } 1445 1446 if (safe) 1447 { 1448 save_funccalp = save_funccal(); 1449 ++sandbox; 1450 } 1451 1452 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1453 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1454 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1455 &doesrange, TRUE, NULL); 1456 if (safe) 1457 { 1458 --sandbox; 1459 restore_funccal(save_funccalp); 1460 } 1461 vim_free(argvars); 1462 1463 if (ret == FAIL) 1464 clear_tv(rettv); 1465 1466 return ret; 1467 } 1468 1469 /* 1470 * Call vimL function "func" and return the result as a string. 1471 * Returns NULL when calling the function fails. 1472 * Uses argv[argc] for the function arguments. 1473 */ 1474 void * 1475 call_func_retstr(func, argc, argv, safe) 1476 char_u *func; 1477 int argc; 1478 char_u **argv; 1479 int safe; /* use the sandbox */ 1480 { 1481 typval_T rettv; 1482 char_u *retval; 1483 1484 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1485 return NULL; 1486 1487 retval = vim_strsave(get_tv_string(&rettv)); 1488 clear_tv(&rettv); 1489 return retval; 1490 } 1491 1492 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1493 /* 1494 * Call vimL function "func" and return the result as a number. 1495 * Returns -1 when calling the function fails. 1496 * Uses argv[argc] for the function arguments. 1497 */ 1498 long 1499 call_func_retnr(func, argc, argv, safe) 1500 char_u *func; 1501 int argc; 1502 char_u **argv; 1503 int safe; /* use the sandbox */ 1504 { 1505 typval_T rettv; 1506 long retval; 1507 1508 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1509 return -1; 1510 1511 retval = get_tv_number_chk(&rettv, NULL); 1512 clear_tv(&rettv); 1513 return retval; 1514 } 1515 #endif 1516 1517 /* 1518 * Call vimL function "func" and return the result as a list 1519 * Uses argv[argc] for the function arguments. 1520 */ 1521 void * 1522 call_func_retlist(func, argc, argv, safe) 1523 char_u *func; 1524 int argc; 1525 char_u **argv; 1526 int safe; /* use the sandbox */ 1527 { 1528 typval_T rettv; 1529 1530 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1531 return NULL; 1532 1533 if (rettv.v_type != VAR_LIST) 1534 { 1535 clear_tv(&rettv); 1536 return NULL; 1537 } 1538 1539 return rettv.vval.v_list; 1540 } 1541 1542 #endif 1543 1544 /* 1545 * Save the current function call pointer, and set it to NULL. 1546 * Used when executing autocommands and for ":source". 1547 */ 1548 void * 1549 save_funccal() 1550 { 1551 funccall_T *fc = current_funccal; 1552 1553 current_funccal = NULL; 1554 return (void *)fc; 1555 } 1556 1557 void 1558 restore_funccal(vfc) 1559 void *vfc; 1560 { 1561 funccall_T *fc = (funccall_T *)vfc; 1562 1563 current_funccal = fc; 1564 } 1565 1566 #if defined(FEAT_PROFILE) || defined(PROTO) 1567 /* 1568 * Prepare profiling for entering a child or something else that is not 1569 * counted for the script/function itself. 1570 * Should always be called in pair with prof_child_exit(). 1571 */ 1572 void 1573 prof_child_enter(tm) 1574 proftime_T *tm; /* place to store waittime */ 1575 { 1576 funccall_T *fc = current_funccal; 1577 1578 if (fc != NULL && fc->func->uf_profiling) 1579 profile_start(&fc->prof_child); 1580 script_prof_save(tm); 1581 } 1582 1583 /* 1584 * Take care of time spent in a child. 1585 * Should always be called after prof_child_enter(). 1586 */ 1587 void 1588 prof_child_exit(tm) 1589 proftime_T *tm; /* where waittime was stored */ 1590 { 1591 funccall_T *fc = current_funccal; 1592 1593 if (fc != NULL && fc->func->uf_profiling) 1594 { 1595 profile_end(&fc->prof_child); 1596 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1597 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1598 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1599 } 1600 script_prof_restore(tm); 1601 } 1602 #endif 1603 1604 1605 #ifdef FEAT_FOLDING 1606 /* 1607 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1608 * it in "*cp". Doesn't give error messages. 1609 */ 1610 int 1611 eval_foldexpr(arg, cp) 1612 char_u *arg; 1613 int *cp; 1614 { 1615 typval_T tv; 1616 int retval; 1617 char_u *s; 1618 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1619 OPT_LOCAL); 1620 1621 ++emsg_off; 1622 if (use_sandbox) 1623 ++sandbox; 1624 ++textlock; 1625 *cp = NUL; 1626 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1627 retval = 0; 1628 else 1629 { 1630 /* If the result is a number, just return the number. */ 1631 if (tv.v_type == VAR_NUMBER) 1632 retval = tv.vval.v_number; 1633 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1634 retval = 0; 1635 else 1636 { 1637 /* If the result is a string, check if there is a non-digit before 1638 * the number. */ 1639 s = tv.vval.v_string; 1640 if (!VIM_ISDIGIT(*s) && *s != '-') 1641 *cp = *s++; 1642 retval = atol((char *)s); 1643 } 1644 clear_tv(&tv); 1645 } 1646 --emsg_off; 1647 if (use_sandbox) 1648 --sandbox; 1649 --textlock; 1650 1651 return retval; 1652 } 1653 #endif 1654 1655 /* 1656 * ":let" list all variable values 1657 * ":let var1 var2" list variable values 1658 * ":let var = expr" assignment command. 1659 * ":let var += expr" assignment command. 1660 * ":let var -= expr" assignment command. 1661 * ":let var .= expr" assignment command. 1662 * ":let [var1, var2] = expr" unpack list. 1663 */ 1664 void 1665 ex_let(eap) 1666 exarg_T *eap; 1667 { 1668 char_u *arg = eap->arg; 1669 char_u *expr = NULL; 1670 typval_T rettv; 1671 int i; 1672 int var_count = 0; 1673 int semicolon = 0; 1674 char_u op[2]; 1675 char_u *argend; 1676 1677 argend = skip_var_list(arg, &var_count, &semicolon); 1678 if (argend == NULL) 1679 return; 1680 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1681 --argend; 1682 expr = vim_strchr(argend, '='); 1683 if (expr == NULL) 1684 { 1685 /* 1686 * ":let" without "=": list variables 1687 */ 1688 if (*arg == '[') 1689 EMSG(_(e_invarg)); 1690 else if (!ends_excmd(*arg)) 1691 /* ":let var1 var2" */ 1692 arg = list_arg_vars(eap, arg); 1693 else if (!eap->skip) 1694 { 1695 /* ":let" */ 1696 list_glob_vars(); 1697 list_buf_vars(); 1698 list_win_vars(); 1699 #ifdef FEAT_WINDOWS 1700 list_tab_vars(); 1701 #endif 1702 list_script_vars(); 1703 list_func_vars(); 1704 list_vim_vars(); 1705 } 1706 eap->nextcmd = check_nextcmd(arg); 1707 } 1708 else 1709 { 1710 op[0] = '='; 1711 op[1] = NUL; 1712 if (expr > argend) 1713 { 1714 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1715 op[0] = expr[-1]; /* +=, -= or .= */ 1716 } 1717 expr = skipwhite(expr + 1); 1718 1719 if (eap->skip) 1720 ++emsg_skip; 1721 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1722 if (eap->skip) 1723 { 1724 if (i != FAIL) 1725 clear_tv(&rettv); 1726 --emsg_skip; 1727 } 1728 else if (i != FAIL) 1729 { 1730 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1731 op); 1732 clear_tv(&rettv); 1733 } 1734 } 1735 } 1736 1737 /* 1738 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1739 * Handles both "var" with any type and "[var, var; var]" with a list type. 1740 * When "nextchars" is not NULL it points to a string with characters that 1741 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1742 * or concatenate. 1743 * Returns OK or FAIL; 1744 */ 1745 static int 1746 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1747 char_u *arg_start; 1748 typval_T *tv; 1749 int copy; /* copy values from "tv", don't move */ 1750 int semicolon; /* from skip_var_list() */ 1751 int var_count; /* from skip_var_list() */ 1752 char_u *nextchars; 1753 { 1754 char_u *arg = arg_start; 1755 list_T *l; 1756 int i; 1757 listitem_T *item; 1758 typval_T ltv; 1759 1760 if (*arg != '[') 1761 { 1762 /* 1763 * ":let var = expr" or ":for var in list" 1764 */ 1765 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1766 return FAIL; 1767 return OK; 1768 } 1769 1770 /* 1771 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1772 */ 1773 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1774 { 1775 EMSG(_(e_listreq)); 1776 return FAIL; 1777 } 1778 1779 i = list_len(l); 1780 if (semicolon == 0 && var_count < i) 1781 { 1782 EMSG(_("E687: Less targets than List items")); 1783 return FAIL; 1784 } 1785 if (var_count - semicolon > i) 1786 { 1787 EMSG(_("E688: More targets than List items")); 1788 return FAIL; 1789 } 1790 1791 item = l->lv_first; 1792 while (*arg != ']') 1793 { 1794 arg = skipwhite(arg + 1); 1795 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1796 item = item->li_next; 1797 if (arg == NULL) 1798 return FAIL; 1799 1800 arg = skipwhite(arg); 1801 if (*arg == ';') 1802 { 1803 /* Put the rest of the list (may be empty) in the var after ';'. 1804 * Create a new list for this. */ 1805 l = list_alloc(); 1806 if (l == NULL) 1807 return FAIL; 1808 while (item != NULL) 1809 { 1810 list_append_tv(l, &item->li_tv); 1811 item = item->li_next; 1812 } 1813 1814 ltv.v_type = VAR_LIST; 1815 ltv.v_lock = 0; 1816 ltv.vval.v_list = l; 1817 l->lv_refcount = 1; 1818 1819 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1820 (char_u *)"]", nextchars); 1821 clear_tv(<v); 1822 if (arg == NULL) 1823 return FAIL; 1824 break; 1825 } 1826 else if (*arg != ',' && *arg != ']') 1827 { 1828 EMSG2(_(e_intern2), "ex_let_vars()"); 1829 return FAIL; 1830 } 1831 } 1832 1833 return OK; 1834 } 1835 1836 /* 1837 * Skip over assignable variable "var" or list of variables "[var, var]". 1838 * Used for ":let varvar = expr" and ":for varvar in expr". 1839 * For "[var, var]" increment "*var_count" for each variable. 1840 * for "[var, var; var]" set "semicolon". 1841 * Return NULL for an error. 1842 */ 1843 static char_u * 1844 skip_var_list(arg, var_count, semicolon) 1845 char_u *arg; 1846 int *var_count; 1847 int *semicolon; 1848 { 1849 char_u *p, *s; 1850 1851 if (*arg == '[') 1852 { 1853 /* "[var, var]": find the matching ']'. */ 1854 p = arg; 1855 for (;;) 1856 { 1857 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1858 s = skip_var_one(p); 1859 if (s == p) 1860 { 1861 EMSG2(_(e_invarg2), p); 1862 return NULL; 1863 } 1864 ++*var_count; 1865 1866 p = skipwhite(s); 1867 if (*p == ']') 1868 break; 1869 else if (*p == ';') 1870 { 1871 if (*semicolon == 1) 1872 { 1873 EMSG(_("Double ; in list of variables")); 1874 return NULL; 1875 } 1876 *semicolon = 1; 1877 } 1878 else if (*p != ',') 1879 { 1880 EMSG2(_(e_invarg2), p); 1881 return NULL; 1882 } 1883 } 1884 return p + 1; 1885 } 1886 else 1887 return skip_var_one(arg); 1888 } 1889 1890 /* 1891 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1892 * l[idx]. 1893 */ 1894 static char_u * 1895 skip_var_one(arg) 1896 char_u *arg; 1897 { 1898 if (*arg == '@' && arg[1] != NUL) 1899 return arg + 2; 1900 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1901 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1902 } 1903 1904 /* 1905 * List variables for hashtab "ht" with prefix "prefix". 1906 * If "empty" is TRUE also list NULL strings as empty strings. 1907 */ 1908 static void 1909 list_hashtable_vars(ht, prefix, empty) 1910 hashtab_T *ht; 1911 char_u *prefix; 1912 int empty; 1913 { 1914 hashitem_T *hi; 1915 dictitem_T *di; 1916 int todo; 1917 1918 todo = (int)ht->ht_used; 1919 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1920 { 1921 if (!HASHITEM_EMPTY(hi)) 1922 { 1923 --todo; 1924 di = HI2DI(hi); 1925 if (empty || di->di_tv.v_type != VAR_STRING 1926 || di->di_tv.vval.v_string != NULL) 1927 list_one_var(di, prefix); 1928 } 1929 } 1930 } 1931 1932 /* 1933 * List global variables. 1934 */ 1935 static void 1936 list_glob_vars() 1937 { 1938 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1939 } 1940 1941 /* 1942 * List buffer variables. 1943 */ 1944 static void 1945 list_buf_vars() 1946 { 1947 char_u numbuf[NUMBUFLEN]; 1948 1949 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1950 1951 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1952 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1953 } 1954 1955 /* 1956 * List window variables. 1957 */ 1958 static void 1959 list_win_vars() 1960 { 1961 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1962 } 1963 1964 #ifdef FEAT_WINDOWS 1965 /* 1966 * List tab page variables. 1967 */ 1968 static void 1969 list_tab_vars() 1970 { 1971 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE); 1972 } 1973 #endif 1974 1975 /* 1976 * List Vim variables. 1977 */ 1978 static void 1979 list_vim_vars() 1980 { 1981 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1982 } 1983 1984 /* 1985 * List script-local variables, if there is a script. 1986 */ 1987 static void 1988 list_script_vars() 1989 { 1990 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 1991 list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE); 1992 } 1993 1994 /* 1995 * List function variables, if there is a function. 1996 */ 1997 static void 1998 list_func_vars() 1999 { 2000 if (current_funccal != NULL) 2001 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2002 (char_u *)"l:", FALSE); 2003 } 2004 2005 /* 2006 * List variables in "arg". 2007 */ 2008 static char_u * 2009 list_arg_vars(eap, arg) 2010 exarg_T *eap; 2011 char_u *arg; 2012 { 2013 int error = FALSE; 2014 int len; 2015 char_u *name; 2016 char_u *name_start; 2017 char_u *arg_subsc; 2018 char_u *tofree; 2019 typval_T tv; 2020 2021 while (!ends_excmd(*arg) && !got_int) 2022 { 2023 if (error || eap->skip) 2024 { 2025 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2026 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2027 { 2028 emsg_severe = TRUE; 2029 EMSG(_(e_trailing)); 2030 break; 2031 } 2032 } 2033 else 2034 { 2035 /* get_name_len() takes care of expanding curly braces */ 2036 name_start = name = arg; 2037 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2038 if (len <= 0) 2039 { 2040 /* This is mainly to keep test 49 working: when expanding 2041 * curly braces fails overrule the exception error message. */ 2042 if (len < 0 && !aborting()) 2043 { 2044 emsg_severe = TRUE; 2045 EMSG2(_(e_invarg2), arg); 2046 break; 2047 } 2048 error = TRUE; 2049 } 2050 else 2051 { 2052 if (tofree != NULL) 2053 name = tofree; 2054 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2055 error = TRUE; 2056 else 2057 { 2058 /* handle d.key, l[idx], f(expr) */ 2059 arg_subsc = arg; 2060 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2061 error = TRUE; 2062 else 2063 { 2064 if (arg == arg_subsc && len == 2 && name[1] == ':') 2065 { 2066 switch (*name) 2067 { 2068 case 'g': list_glob_vars(); break; 2069 case 'b': list_buf_vars(); break; 2070 case 'w': list_win_vars(); break; 2071 #ifdef FEAT_WINDOWS 2072 case 't': list_tab_vars(); break; 2073 #endif 2074 case 'v': list_vim_vars(); break; 2075 case 's': list_script_vars(); break; 2076 case 'l': list_func_vars(); break; 2077 default: 2078 EMSG2(_("E738: Can't list variables for %s"), name); 2079 } 2080 } 2081 else 2082 { 2083 char_u numbuf[NUMBUFLEN]; 2084 char_u *tf; 2085 int c; 2086 char_u *s; 2087 2088 s = echo_string(&tv, &tf, numbuf, 0); 2089 c = *arg; 2090 *arg = NUL; 2091 list_one_var_a((char_u *)"", 2092 arg == arg_subsc ? name : name_start, 2093 tv.v_type, s == NULL ? (char_u *)"" : s); 2094 *arg = c; 2095 vim_free(tf); 2096 } 2097 clear_tv(&tv); 2098 } 2099 } 2100 } 2101 2102 vim_free(tofree); 2103 } 2104 2105 arg = skipwhite(arg); 2106 } 2107 2108 return arg; 2109 } 2110 2111 /* 2112 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2113 * Returns a pointer to the char just after the var name. 2114 * Returns NULL if there is an error. 2115 */ 2116 static char_u * 2117 ex_let_one(arg, tv, copy, endchars, op) 2118 char_u *arg; /* points to variable name */ 2119 typval_T *tv; /* value to assign to variable */ 2120 int copy; /* copy value from "tv" */ 2121 char_u *endchars; /* valid chars after variable name or NULL */ 2122 char_u *op; /* "+", "-", "." or NULL*/ 2123 { 2124 int c1; 2125 char_u *name; 2126 char_u *p; 2127 char_u *arg_end = NULL; 2128 int len; 2129 int opt_flags; 2130 char_u *tofree = NULL; 2131 2132 /* 2133 * ":let $VAR = expr": Set environment variable. 2134 */ 2135 if (*arg == '$') 2136 { 2137 /* Find the end of the name. */ 2138 ++arg; 2139 name = arg; 2140 len = get_env_len(&arg); 2141 if (len == 0) 2142 EMSG2(_(e_invarg2), name - 1); 2143 else 2144 { 2145 if (op != NULL && (*op == '+' || *op == '-')) 2146 EMSG2(_(e_letwrong), op); 2147 else if (endchars != NULL 2148 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2149 EMSG(_(e_letunexp)); 2150 else 2151 { 2152 c1 = name[len]; 2153 name[len] = NUL; 2154 p = get_tv_string_chk(tv); 2155 if (p != NULL && op != NULL && *op == '.') 2156 { 2157 int mustfree = FALSE; 2158 char_u *s = vim_getenv(name, &mustfree); 2159 2160 if (s != NULL) 2161 { 2162 p = tofree = concat_str(s, p); 2163 if (mustfree) 2164 vim_free(s); 2165 } 2166 } 2167 if (p != NULL) 2168 { 2169 vim_setenv(name, p); 2170 if (STRICMP(name, "HOME") == 0) 2171 init_homedir(); 2172 else if (didset_vim && STRICMP(name, "VIM") == 0) 2173 didset_vim = FALSE; 2174 else if (didset_vimruntime 2175 && STRICMP(name, "VIMRUNTIME") == 0) 2176 didset_vimruntime = FALSE; 2177 arg_end = arg; 2178 } 2179 name[len] = c1; 2180 vim_free(tofree); 2181 } 2182 } 2183 } 2184 2185 /* 2186 * ":let &option = expr": Set option value. 2187 * ":let &l:option = expr": Set local option value. 2188 * ":let &g:option = expr": Set global option value. 2189 */ 2190 else if (*arg == '&') 2191 { 2192 /* Find the end of the name. */ 2193 p = find_option_end(&arg, &opt_flags); 2194 if (p == NULL || (endchars != NULL 2195 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2196 EMSG(_(e_letunexp)); 2197 else 2198 { 2199 long n; 2200 int opt_type; 2201 long numval; 2202 char_u *stringval = NULL; 2203 char_u *s; 2204 2205 c1 = *p; 2206 *p = NUL; 2207 2208 n = get_tv_number(tv); 2209 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2210 if (s != NULL && op != NULL && *op != '=') 2211 { 2212 opt_type = get_option_value(arg, &numval, 2213 &stringval, opt_flags); 2214 if ((opt_type == 1 && *op == '.') 2215 || (opt_type == 0 && *op != '.')) 2216 EMSG2(_(e_letwrong), op); 2217 else 2218 { 2219 if (opt_type == 1) /* number */ 2220 { 2221 if (*op == '+') 2222 n = numval + n; 2223 else 2224 n = numval - n; 2225 } 2226 else if (opt_type == 0 && stringval != NULL) /* string */ 2227 { 2228 s = concat_str(stringval, s); 2229 vim_free(stringval); 2230 stringval = s; 2231 } 2232 } 2233 } 2234 if (s != NULL) 2235 { 2236 set_option_value(arg, n, s, opt_flags); 2237 arg_end = p; 2238 } 2239 *p = c1; 2240 vim_free(stringval); 2241 } 2242 } 2243 2244 /* 2245 * ":let @r = expr": Set register contents. 2246 */ 2247 else if (*arg == '@') 2248 { 2249 ++arg; 2250 if (op != NULL && (*op == '+' || *op == '-')) 2251 EMSG2(_(e_letwrong), op); 2252 else if (endchars != NULL 2253 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2254 EMSG(_(e_letunexp)); 2255 else 2256 { 2257 char_u *tofree = NULL; 2258 char_u *s; 2259 2260 p = get_tv_string_chk(tv); 2261 if (p != NULL && op != NULL && *op == '.') 2262 { 2263 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2264 if (s != NULL) 2265 { 2266 p = tofree = concat_str(s, p); 2267 vim_free(s); 2268 } 2269 } 2270 if (p != NULL) 2271 { 2272 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2273 arg_end = arg + 1; 2274 } 2275 vim_free(tofree); 2276 } 2277 } 2278 2279 /* 2280 * ":let var = expr": Set internal variable. 2281 * ":let {expr} = expr": Idem, name made with curly braces 2282 */ 2283 else if (eval_isnamec1(*arg) || *arg == '{') 2284 { 2285 lval_T lv; 2286 2287 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2288 if (p != NULL && lv.ll_name != NULL) 2289 { 2290 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2291 EMSG(_(e_letunexp)); 2292 else 2293 { 2294 set_var_lval(&lv, p, tv, copy, op); 2295 arg_end = p; 2296 } 2297 } 2298 clear_lval(&lv); 2299 } 2300 2301 else 2302 EMSG2(_(e_invarg2), arg); 2303 2304 return arg_end; 2305 } 2306 2307 /* 2308 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2309 */ 2310 static int 2311 check_changedtick(arg) 2312 char_u *arg; 2313 { 2314 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2315 { 2316 EMSG2(_(e_readonlyvar), arg); 2317 return TRUE; 2318 } 2319 return FALSE; 2320 } 2321 2322 /* 2323 * Get an lval: variable, Dict item or List item that can be assigned a value 2324 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2325 * "name.key", "name.key[expr]" etc. 2326 * Indexing only works if "name" is an existing List or Dictionary. 2327 * "name" points to the start of the name. 2328 * If "rettv" is not NULL it points to the value to be assigned. 2329 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2330 * wrong; must end in space or cmd separator. 2331 * 2332 * Returns a pointer to just after the name, including indexes. 2333 * When an evaluation error occurs "lp->ll_name" is NULL; 2334 * Returns NULL for a parsing error. Still need to free items in "lp"! 2335 */ 2336 static char_u * 2337 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2338 char_u *name; 2339 typval_T *rettv; 2340 lval_T *lp; 2341 int unlet; 2342 int skip; 2343 int quiet; /* don't give error messages */ 2344 int fne_flags; /* flags for find_name_end() */ 2345 { 2346 char_u *p; 2347 char_u *expr_start, *expr_end; 2348 int cc; 2349 dictitem_T *v; 2350 typval_T var1; 2351 typval_T var2; 2352 int empty1 = FALSE; 2353 listitem_T *ni; 2354 char_u *key = NULL; 2355 int len; 2356 hashtab_T *ht; 2357 2358 /* Clear everything in "lp". */ 2359 vim_memset(lp, 0, sizeof(lval_T)); 2360 2361 if (skip) 2362 { 2363 /* When skipping just find the end of the name. */ 2364 lp->ll_name = name; 2365 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2366 } 2367 2368 /* Find the end of the name. */ 2369 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2370 if (expr_start != NULL) 2371 { 2372 /* Don't expand the name when we already know there is an error. */ 2373 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2374 && *p != '[' && *p != '.') 2375 { 2376 EMSG(_(e_trailing)); 2377 return NULL; 2378 } 2379 2380 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2381 if (lp->ll_exp_name == NULL) 2382 { 2383 /* Report an invalid expression in braces, unless the 2384 * expression evaluation has been cancelled due to an 2385 * aborting error, an interrupt, or an exception. */ 2386 if (!aborting() && !quiet) 2387 { 2388 emsg_severe = TRUE; 2389 EMSG2(_(e_invarg2), name); 2390 return NULL; 2391 } 2392 } 2393 lp->ll_name = lp->ll_exp_name; 2394 } 2395 else 2396 lp->ll_name = name; 2397 2398 /* Without [idx] or .key we are done. */ 2399 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2400 return p; 2401 2402 cc = *p; 2403 *p = NUL; 2404 v = find_var(lp->ll_name, &ht); 2405 if (v == NULL && !quiet) 2406 EMSG2(_(e_undefvar), lp->ll_name); 2407 *p = cc; 2408 if (v == NULL) 2409 return NULL; 2410 2411 /* 2412 * Loop until no more [idx] or .key is following. 2413 */ 2414 lp->ll_tv = &v->di_tv; 2415 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2416 { 2417 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2418 && !(lp->ll_tv->v_type == VAR_DICT 2419 && lp->ll_tv->vval.v_dict != NULL)) 2420 { 2421 if (!quiet) 2422 EMSG(_("E689: Can only index a List or Dictionary")); 2423 return NULL; 2424 } 2425 if (lp->ll_range) 2426 { 2427 if (!quiet) 2428 EMSG(_("E708: [:] must come last")); 2429 return NULL; 2430 } 2431 2432 len = -1; 2433 if (*p == '.') 2434 { 2435 key = p + 1; 2436 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2437 ; 2438 if (len == 0) 2439 { 2440 if (!quiet) 2441 EMSG(_(e_emptykey)); 2442 return NULL; 2443 } 2444 p = key + len; 2445 } 2446 else 2447 { 2448 /* Get the index [expr] or the first index [expr: ]. */ 2449 p = skipwhite(p + 1); 2450 if (*p == ':') 2451 empty1 = TRUE; 2452 else 2453 { 2454 empty1 = FALSE; 2455 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2456 return NULL; 2457 if (get_tv_string_chk(&var1) == NULL) 2458 { 2459 /* not a number or string */ 2460 clear_tv(&var1); 2461 return NULL; 2462 } 2463 } 2464 2465 /* Optionally get the second index [ :expr]. */ 2466 if (*p == ':') 2467 { 2468 if (lp->ll_tv->v_type == VAR_DICT) 2469 { 2470 if (!quiet) 2471 EMSG(_(e_dictrange)); 2472 if (!empty1) 2473 clear_tv(&var1); 2474 return NULL; 2475 } 2476 if (rettv != NULL && (rettv->v_type != VAR_LIST 2477 || rettv->vval.v_list == NULL)) 2478 { 2479 if (!quiet) 2480 EMSG(_("E709: [:] requires a List value")); 2481 if (!empty1) 2482 clear_tv(&var1); 2483 return NULL; 2484 } 2485 p = skipwhite(p + 1); 2486 if (*p == ']') 2487 lp->ll_empty2 = TRUE; 2488 else 2489 { 2490 lp->ll_empty2 = FALSE; 2491 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2492 { 2493 if (!empty1) 2494 clear_tv(&var1); 2495 return NULL; 2496 } 2497 if (get_tv_string_chk(&var2) == NULL) 2498 { 2499 /* not a number or string */ 2500 if (!empty1) 2501 clear_tv(&var1); 2502 clear_tv(&var2); 2503 return NULL; 2504 } 2505 } 2506 lp->ll_range = TRUE; 2507 } 2508 else 2509 lp->ll_range = FALSE; 2510 2511 if (*p != ']') 2512 { 2513 if (!quiet) 2514 EMSG(_(e_missbrac)); 2515 if (!empty1) 2516 clear_tv(&var1); 2517 if (lp->ll_range && !lp->ll_empty2) 2518 clear_tv(&var2); 2519 return NULL; 2520 } 2521 2522 /* Skip to past ']'. */ 2523 ++p; 2524 } 2525 2526 if (lp->ll_tv->v_type == VAR_DICT) 2527 { 2528 if (len == -1) 2529 { 2530 /* "[key]": get key from "var1" */ 2531 key = get_tv_string(&var1); /* is number or string */ 2532 if (*key == NUL) 2533 { 2534 if (!quiet) 2535 EMSG(_(e_emptykey)); 2536 clear_tv(&var1); 2537 return NULL; 2538 } 2539 } 2540 lp->ll_list = NULL; 2541 lp->ll_dict = lp->ll_tv->vval.v_dict; 2542 lp->ll_di = dict_find(lp->ll_dict, key, len); 2543 if (lp->ll_di == NULL) 2544 { 2545 /* Key does not exist in dict: may need to add it. */ 2546 if (*p == '[' || *p == '.' || unlet) 2547 { 2548 if (!quiet) 2549 EMSG2(_(e_dictkey), key); 2550 if (len == -1) 2551 clear_tv(&var1); 2552 return NULL; 2553 } 2554 if (len == -1) 2555 lp->ll_newkey = vim_strsave(key); 2556 else 2557 lp->ll_newkey = vim_strnsave(key, len); 2558 if (len == -1) 2559 clear_tv(&var1); 2560 if (lp->ll_newkey == NULL) 2561 p = NULL; 2562 break; 2563 } 2564 if (len == -1) 2565 clear_tv(&var1); 2566 lp->ll_tv = &lp->ll_di->di_tv; 2567 } 2568 else 2569 { 2570 /* 2571 * Get the number and item for the only or first index of the List. 2572 */ 2573 if (empty1) 2574 lp->ll_n1 = 0; 2575 else 2576 { 2577 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2578 clear_tv(&var1); 2579 } 2580 lp->ll_dict = NULL; 2581 lp->ll_list = lp->ll_tv->vval.v_list; 2582 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2583 if (lp->ll_li == NULL) 2584 { 2585 if (lp->ll_n1 < 0) 2586 { 2587 lp->ll_n1 = 0; 2588 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2589 } 2590 } 2591 if (lp->ll_li == NULL) 2592 { 2593 if (lp->ll_range && !lp->ll_empty2) 2594 clear_tv(&var2); 2595 return NULL; 2596 } 2597 2598 /* 2599 * May need to find the item or absolute index for the second 2600 * index of a range. 2601 * When no index given: "lp->ll_empty2" is TRUE. 2602 * Otherwise "lp->ll_n2" is set to the second index. 2603 */ 2604 if (lp->ll_range && !lp->ll_empty2) 2605 { 2606 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2607 clear_tv(&var2); 2608 if (lp->ll_n2 < 0) 2609 { 2610 ni = list_find(lp->ll_list, lp->ll_n2); 2611 if (ni == NULL) 2612 return NULL; 2613 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2614 } 2615 2616 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2617 if (lp->ll_n1 < 0) 2618 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2619 if (lp->ll_n2 < lp->ll_n1) 2620 return NULL; 2621 } 2622 2623 lp->ll_tv = &lp->ll_li->li_tv; 2624 } 2625 } 2626 2627 return p; 2628 } 2629 2630 /* 2631 * Clear lval "lp" that was filled by get_lval(). 2632 */ 2633 static void 2634 clear_lval(lp) 2635 lval_T *lp; 2636 { 2637 vim_free(lp->ll_exp_name); 2638 vim_free(lp->ll_newkey); 2639 } 2640 2641 /* 2642 * Set a variable that was parsed by get_lval() to "rettv". 2643 * "endp" points to just after the parsed name. 2644 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2645 */ 2646 static void 2647 set_var_lval(lp, endp, rettv, copy, op) 2648 lval_T *lp; 2649 char_u *endp; 2650 typval_T *rettv; 2651 int copy; 2652 char_u *op; 2653 { 2654 int cc; 2655 listitem_T *ri; 2656 dictitem_T *di; 2657 2658 if (lp->ll_tv == NULL) 2659 { 2660 if (!check_changedtick(lp->ll_name)) 2661 { 2662 cc = *endp; 2663 *endp = NUL; 2664 if (op != NULL && *op != '=') 2665 { 2666 typval_T tv; 2667 2668 /* handle +=, -= and .= */ 2669 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2670 &tv, TRUE) == OK) 2671 { 2672 if (tv_op(&tv, rettv, op) == OK) 2673 set_var(lp->ll_name, &tv, FALSE); 2674 clear_tv(&tv); 2675 } 2676 } 2677 else 2678 set_var(lp->ll_name, rettv, copy); 2679 *endp = cc; 2680 } 2681 } 2682 else if (tv_check_lock(lp->ll_newkey == NULL 2683 ? lp->ll_tv->v_lock 2684 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2685 ; 2686 else if (lp->ll_range) 2687 { 2688 /* 2689 * Assign the List values to the list items. 2690 */ 2691 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2692 { 2693 if (op != NULL && *op != '=') 2694 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2695 else 2696 { 2697 clear_tv(&lp->ll_li->li_tv); 2698 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2699 } 2700 ri = ri->li_next; 2701 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2702 break; 2703 if (lp->ll_li->li_next == NULL) 2704 { 2705 /* Need to add an empty item. */ 2706 if (list_append_number(lp->ll_list, 0) == FAIL) 2707 { 2708 ri = NULL; 2709 break; 2710 } 2711 } 2712 lp->ll_li = lp->ll_li->li_next; 2713 ++lp->ll_n1; 2714 } 2715 if (ri != NULL) 2716 EMSG(_("E710: List value has more items than target")); 2717 else if (lp->ll_empty2 2718 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2719 : lp->ll_n1 != lp->ll_n2) 2720 EMSG(_("E711: List value has not enough items")); 2721 } 2722 else 2723 { 2724 /* 2725 * Assign to a List or Dictionary item. 2726 */ 2727 if (lp->ll_newkey != NULL) 2728 { 2729 if (op != NULL && *op != '=') 2730 { 2731 EMSG2(_(e_letwrong), op); 2732 return; 2733 } 2734 2735 /* Need to add an item to the Dictionary. */ 2736 di = dictitem_alloc(lp->ll_newkey); 2737 if (di == NULL) 2738 return; 2739 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2740 { 2741 vim_free(di); 2742 return; 2743 } 2744 lp->ll_tv = &di->di_tv; 2745 } 2746 else if (op != NULL && *op != '=') 2747 { 2748 tv_op(lp->ll_tv, rettv, op); 2749 return; 2750 } 2751 else 2752 clear_tv(lp->ll_tv); 2753 2754 /* 2755 * Assign the value to the variable or list item. 2756 */ 2757 if (copy) 2758 copy_tv(rettv, lp->ll_tv); 2759 else 2760 { 2761 *lp->ll_tv = *rettv; 2762 lp->ll_tv->v_lock = 0; 2763 init_tv(rettv); 2764 } 2765 } 2766 } 2767 2768 /* 2769 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2770 * Returns OK or FAIL. 2771 */ 2772 static int 2773 tv_op(tv1, tv2, op) 2774 typval_T *tv1; 2775 typval_T *tv2; 2776 char_u *op; 2777 { 2778 long n; 2779 char_u numbuf[NUMBUFLEN]; 2780 char_u *s; 2781 2782 /* Can't do anything with a Funcref or a Dict on the right. */ 2783 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2784 { 2785 switch (tv1->v_type) 2786 { 2787 case VAR_DICT: 2788 case VAR_FUNC: 2789 break; 2790 2791 case VAR_LIST: 2792 if (*op != '+' || tv2->v_type != VAR_LIST) 2793 break; 2794 /* List += List */ 2795 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2796 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2797 return OK; 2798 2799 case VAR_NUMBER: 2800 case VAR_STRING: 2801 if (tv2->v_type == VAR_LIST) 2802 break; 2803 if (*op == '+' || *op == '-') 2804 { 2805 /* nr += nr or nr -= nr*/ 2806 n = get_tv_number(tv1); 2807 if (*op == '+') 2808 n += get_tv_number(tv2); 2809 else 2810 n -= get_tv_number(tv2); 2811 clear_tv(tv1); 2812 tv1->v_type = VAR_NUMBER; 2813 tv1->vval.v_number = n; 2814 } 2815 else 2816 { 2817 /* str .= str */ 2818 s = get_tv_string(tv1); 2819 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2820 clear_tv(tv1); 2821 tv1->v_type = VAR_STRING; 2822 tv1->vval.v_string = s; 2823 } 2824 return OK; 2825 } 2826 } 2827 2828 EMSG2(_(e_letwrong), op); 2829 return FAIL; 2830 } 2831 2832 /* 2833 * Add a watcher to a list. 2834 */ 2835 static void 2836 list_add_watch(l, lw) 2837 list_T *l; 2838 listwatch_T *lw; 2839 { 2840 lw->lw_next = l->lv_watch; 2841 l->lv_watch = lw; 2842 } 2843 2844 /* 2845 * Remove a watcher from a list. 2846 * No warning when it isn't found... 2847 */ 2848 static void 2849 list_rem_watch(l, lwrem) 2850 list_T *l; 2851 listwatch_T *lwrem; 2852 { 2853 listwatch_T *lw, **lwp; 2854 2855 lwp = &l->lv_watch; 2856 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2857 { 2858 if (lw == lwrem) 2859 { 2860 *lwp = lw->lw_next; 2861 break; 2862 } 2863 lwp = &lw->lw_next; 2864 } 2865 } 2866 2867 /* 2868 * Just before removing an item from a list: advance watchers to the next 2869 * item. 2870 */ 2871 static void 2872 list_fix_watch(l, item) 2873 list_T *l; 2874 listitem_T *item; 2875 { 2876 listwatch_T *lw; 2877 2878 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2879 if (lw->lw_item == item) 2880 lw->lw_item = item->li_next; 2881 } 2882 2883 /* 2884 * Evaluate the expression used in a ":for var in expr" command. 2885 * "arg" points to "var". 2886 * Set "*errp" to TRUE for an error, FALSE otherwise; 2887 * Return a pointer that holds the info. Null when there is an error. 2888 */ 2889 void * 2890 eval_for_line(arg, errp, nextcmdp, skip) 2891 char_u *arg; 2892 int *errp; 2893 char_u **nextcmdp; 2894 int skip; 2895 { 2896 forinfo_T *fi; 2897 char_u *expr; 2898 typval_T tv; 2899 list_T *l; 2900 2901 *errp = TRUE; /* default: there is an error */ 2902 2903 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2904 if (fi == NULL) 2905 return NULL; 2906 2907 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2908 if (expr == NULL) 2909 return fi; 2910 2911 expr = skipwhite(expr); 2912 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2913 { 2914 EMSG(_("E690: Missing \"in\" after :for")); 2915 return fi; 2916 } 2917 2918 if (skip) 2919 ++emsg_skip; 2920 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2921 { 2922 *errp = FALSE; 2923 if (!skip) 2924 { 2925 l = tv.vval.v_list; 2926 if (tv.v_type != VAR_LIST || l == NULL) 2927 { 2928 EMSG(_(e_listreq)); 2929 clear_tv(&tv); 2930 } 2931 else 2932 { 2933 /* No need to increment the refcount, it's already set for the 2934 * list being used in "tv". */ 2935 fi->fi_list = l; 2936 list_add_watch(l, &fi->fi_lw); 2937 fi->fi_lw.lw_item = l->lv_first; 2938 } 2939 } 2940 } 2941 if (skip) 2942 --emsg_skip; 2943 2944 return fi; 2945 } 2946 2947 /* 2948 * Use the first item in a ":for" list. Advance to the next. 2949 * Assign the values to the variable (list). "arg" points to the first one. 2950 * Return TRUE when a valid item was found, FALSE when at end of list or 2951 * something wrong. 2952 */ 2953 int 2954 next_for_item(fi_void, arg) 2955 void *fi_void; 2956 char_u *arg; 2957 { 2958 forinfo_T *fi = (forinfo_T *)fi_void; 2959 int result; 2960 listitem_T *item; 2961 2962 item = fi->fi_lw.lw_item; 2963 if (item == NULL) 2964 result = FALSE; 2965 else 2966 { 2967 fi->fi_lw.lw_item = item->li_next; 2968 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2969 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2970 } 2971 return result; 2972 } 2973 2974 /* 2975 * Free the structure used to store info used by ":for". 2976 */ 2977 void 2978 free_for_info(fi_void) 2979 void *fi_void; 2980 { 2981 forinfo_T *fi = (forinfo_T *)fi_void; 2982 2983 if (fi != NULL && fi->fi_list != NULL) 2984 { 2985 list_rem_watch(fi->fi_list, &fi->fi_lw); 2986 list_unref(fi->fi_list); 2987 } 2988 vim_free(fi); 2989 } 2990 2991 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2992 2993 void 2994 set_context_for_expression(xp, arg, cmdidx) 2995 expand_T *xp; 2996 char_u *arg; 2997 cmdidx_T cmdidx; 2998 { 2999 int got_eq = FALSE; 3000 int c; 3001 char_u *p; 3002 3003 if (cmdidx == CMD_let) 3004 { 3005 xp->xp_context = EXPAND_USER_VARS; 3006 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3007 { 3008 /* ":let var1 var2 ...": find last space. */ 3009 for (p = arg + STRLEN(arg); p >= arg; ) 3010 { 3011 xp->xp_pattern = p; 3012 mb_ptr_back(arg, p); 3013 if (vim_iswhite(*p)) 3014 break; 3015 } 3016 return; 3017 } 3018 } 3019 else 3020 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3021 : EXPAND_EXPRESSION; 3022 while ((xp->xp_pattern = vim_strpbrk(arg, 3023 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3024 { 3025 c = *xp->xp_pattern; 3026 if (c == '&') 3027 { 3028 c = xp->xp_pattern[1]; 3029 if (c == '&') 3030 { 3031 ++xp->xp_pattern; 3032 xp->xp_context = cmdidx != CMD_let || got_eq 3033 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3034 } 3035 else if (c != ' ') 3036 { 3037 xp->xp_context = EXPAND_SETTINGS; 3038 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3039 xp->xp_pattern += 2; 3040 3041 } 3042 } 3043 else if (c == '$') 3044 { 3045 /* environment variable */ 3046 xp->xp_context = EXPAND_ENV_VARS; 3047 } 3048 else if (c == '=') 3049 { 3050 got_eq = TRUE; 3051 xp->xp_context = EXPAND_EXPRESSION; 3052 } 3053 else if (c == '<' 3054 && xp->xp_context == EXPAND_FUNCTIONS 3055 && vim_strchr(xp->xp_pattern, '(') == NULL) 3056 { 3057 /* Function name can start with "<SNR>" */ 3058 break; 3059 } 3060 else if (cmdidx != CMD_let || got_eq) 3061 { 3062 if (c == '"') /* string */ 3063 { 3064 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3065 if (c == '\\' && xp->xp_pattern[1] != NUL) 3066 ++xp->xp_pattern; 3067 xp->xp_context = EXPAND_NOTHING; 3068 } 3069 else if (c == '\'') /* literal string */ 3070 { 3071 /* Trick: '' is like stopping and starting a literal string. */ 3072 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3073 /* skip */ ; 3074 xp->xp_context = EXPAND_NOTHING; 3075 } 3076 else if (c == '|') 3077 { 3078 if (xp->xp_pattern[1] == '|') 3079 { 3080 ++xp->xp_pattern; 3081 xp->xp_context = EXPAND_EXPRESSION; 3082 } 3083 else 3084 xp->xp_context = EXPAND_COMMANDS; 3085 } 3086 else 3087 xp->xp_context = EXPAND_EXPRESSION; 3088 } 3089 else 3090 /* Doesn't look like something valid, expand as an expression 3091 * anyway. */ 3092 xp->xp_context = EXPAND_EXPRESSION; 3093 arg = xp->xp_pattern; 3094 if (*arg != NUL) 3095 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3096 /* skip */ ; 3097 } 3098 xp->xp_pattern = arg; 3099 } 3100 3101 #endif /* FEAT_CMDL_COMPL */ 3102 3103 /* 3104 * ":1,25call func(arg1, arg2)" function call. 3105 */ 3106 void 3107 ex_call(eap) 3108 exarg_T *eap; 3109 { 3110 char_u *arg = eap->arg; 3111 char_u *startarg; 3112 char_u *name; 3113 char_u *tofree; 3114 int len; 3115 typval_T rettv; 3116 linenr_T lnum; 3117 int doesrange; 3118 int failed = FALSE; 3119 funcdict_T fudi; 3120 3121 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3122 vim_free(fudi.fd_newkey); 3123 if (tofree == NULL) 3124 return; 3125 3126 /* Increase refcount on dictionary, it could get deleted when evaluating 3127 * the arguments. */ 3128 if (fudi.fd_dict != NULL) 3129 ++fudi.fd_dict->dv_refcount; 3130 3131 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3132 len = (int)STRLEN(tofree); 3133 name = deref_func_name(tofree, &len); 3134 3135 /* Skip white space to allow ":call func ()". Not good, but required for 3136 * backward compatibility. */ 3137 startarg = skipwhite(arg); 3138 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3139 3140 if (*startarg != '(') 3141 { 3142 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3143 goto end; 3144 } 3145 3146 /* 3147 * When skipping, evaluate the function once, to find the end of the 3148 * arguments. 3149 * When the function takes a range, this is discovered after the first 3150 * call, and the loop is broken. 3151 */ 3152 if (eap->skip) 3153 { 3154 ++emsg_skip; 3155 lnum = eap->line2; /* do it once, also with an invalid range */ 3156 } 3157 else 3158 lnum = eap->line1; 3159 for ( ; lnum <= eap->line2; ++lnum) 3160 { 3161 if (!eap->skip && eap->addr_count > 0) 3162 { 3163 curwin->w_cursor.lnum = lnum; 3164 curwin->w_cursor.col = 0; 3165 } 3166 arg = startarg; 3167 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3168 eap->line1, eap->line2, &doesrange, 3169 !eap->skip, fudi.fd_dict) == FAIL) 3170 { 3171 failed = TRUE; 3172 break; 3173 } 3174 clear_tv(&rettv); 3175 if (doesrange || eap->skip) 3176 break; 3177 /* Stop when immediately aborting on error, or when an interrupt 3178 * occurred or an exception was thrown but not caught. 3179 * get_func_tv() returned OK, so that the check for trailing 3180 * characters below is executed. */ 3181 if (aborting()) 3182 break; 3183 } 3184 if (eap->skip) 3185 --emsg_skip; 3186 3187 if (!failed) 3188 { 3189 /* Check for trailing illegal characters and a following command. */ 3190 if (!ends_excmd(*arg)) 3191 { 3192 emsg_severe = TRUE; 3193 EMSG(_(e_trailing)); 3194 } 3195 else 3196 eap->nextcmd = check_nextcmd(arg); 3197 } 3198 3199 end: 3200 dict_unref(fudi.fd_dict); 3201 vim_free(tofree); 3202 } 3203 3204 /* 3205 * ":unlet[!] var1 ... " command. 3206 */ 3207 void 3208 ex_unlet(eap) 3209 exarg_T *eap; 3210 { 3211 ex_unletlock(eap, eap->arg, 0); 3212 } 3213 3214 /* 3215 * ":lockvar" and ":unlockvar" commands 3216 */ 3217 void 3218 ex_lockvar(eap) 3219 exarg_T *eap; 3220 { 3221 char_u *arg = eap->arg; 3222 int deep = 2; 3223 3224 if (eap->forceit) 3225 deep = -1; 3226 else if (vim_isdigit(*arg)) 3227 { 3228 deep = getdigits(&arg); 3229 arg = skipwhite(arg); 3230 } 3231 3232 ex_unletlock(eap, arg, deep); 3233 } 3234 3235 /* 3236 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3237 */ 3238 static void 3239 ex_unletlock(eap, argstart, deep) 3240 exarg_T *eap; 3241 char_u *argstart; 3242 int deep; 3243 { 3244 char_u *arg = argstart; 3245 char_u *name_end; 3246 int error = FALSE; 3247 lval_T lv; 3248 3249 do 3250 { 3251 /* Parse the name and find the end. */ 3252 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3253 FNE_CHECK_START); 3254 if (lv.ll_name == NULL) 3255 error = TRUE; /* error but continue parsing */ 3256 if (name_end == NULL || (!vim_iswhite(*name_end) 3257 && !ends_excmd(*name_end))) 3258 { 3259 if (name_end != NULL) 3260 { 3261 emsg_severe = TRUE; 3262 EMSG(_(e_trailing)); 3263 } 3264 if (!(eap->skip || error)) 3265 clear_lval(&lv); 3266 break; 3267 } 3268 3269 if (!error && !eap->skip) 3270 { 3271 if (eap->cmdidx == CMD_unlet) 3272 { 3273 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3274 error = TRUE; 3275 } 3276 else 3277 { 3278 if (do_lock_var(&lv, name_end, deep, 3279 eap->cmdidx == CMD_lockvar) == FAIL) 3280 error = TRUE; 3281 } 3282 } 3283 3284 if (!eap->skip) 3285 clear_lval(&lv); 3286 3287 arg = skipwhite(name_end); 3288 } while (!ends_excmd(*arg)); 3289 3290 eap->nextcmd = check_nextcmd(arg); 3291 } 3292 3293 static int 3294 do_unlet_var(lp, name_end, forceit) 3295 lval_T *lp; 3296 char_u *name_end; 3297 int forceit; 3298 { 3299 int ret = OK; 3300 int cc; 3301 3302 if (lp->ll_tv == NULL) 3303 { 3304 cc = *name_end; 3305 *name_end = NUL; 3306 3307 /* Normal name or expanded name. */ 3308 if (check_changedtick(lp->ll_name)) 3309 ret = FAIL; 3310 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3311 ret = FAIL; 3312 *name_end = cc; 3313 } 3314 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3315 return FAIL; 3316 else if (lp->ll_range) 3317 { 3318 listitem_T *li; 3319 3320 /* Delete a range of List items. */ 3321 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3322 { 3323 li = lp->ll_li->li_next; 3324 listitem_remove(lp->ll_list, lp->ll_li); 3325 lp->ll_li = li; 3326 ++lp->ll_n1; 3327 } 3328 } 3329 else 3330 { 3331 if (lp->ll_list != NULL) 3332 /* unlet a List item. */ 3333 listitem_remove(lp->ll_list, lp->ll_li); 3334 else 3335 /* unlet a Dictionary item. */ 3336 dictitem_remove(lp->ll_dict, lp->ll_di); 3337 } 3338 3339 return ret; 3340 } 3341 3342 /* 3343 * "unlet" a variable. Return OK if it existed, FAIL if not. 3344 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3345 */ 3346 int 3347 do_unlet(name, forceit) 3348 char_u *name; 3349 int forceit; 3350 { 3351 hashtab_T *ht; 3352 hashitem_T *hi; 3353 char_u *varname; 3354 3355 ht = find_var_ht(name, &varname); 3356 if (ht != NULL && *varname != NUL) 3357 { 3358 hi = hash_find(ht, varname); 3359 if (!HASHITEM_EMPTY(hi)) 3360 { 3361 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3362 return FAIL; 3363 delete_var(ht, hi); 3364 return OK; 3365 } 3366 } 3367 if (forceit) 3368 return OK; 3369 EMSG2(_("E108: No such variable: \"%s\""), name); 3370 return FAIL; 3371 } 3372 3373 /* 3374 * Lock or unlock variable indicated by "lp". 3375 * "deep" is the levels to go (-1 for unlimited); 3376 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3377 */ 3378 static int 3379 do_lock_var(lp, name_end, deep, lock) 3380 lval_T *lp; 3381 char_u *name_end; 3382 int deep; 3383 int lock; 3384 { 3385 int ret = OK; 3386 int cc; 3387 dictitem_T *di; 3388 3389 if (deep == 0) /* nothing to do */ 3390 return OK; 3391 3392 if (lp->ll_tv == NULL) 3393 { 3394 cc = *name_end; 3395 *name_end = NUL; 3396 3397 /* Normal name or expanded name. */ 3398 if (check_changedtick(lp->ll_name)) 3399 ret = FAIL; 3400 else 3401 { 3402 di = find_var(lp->ll_name, NULL); 3403 if (di == NULL) 3404 ret = FAIL; 3405 else 3406 { 3407 if (lock) 3408 di->di_flags |= DI_FLAGS_LOCK; 3409 else 3410 di->di_flags &= ~DI_FLAGS_LOCK; 3411 item_lock(&di->di_tv, deep, lock); 3412 } 3413 } 3414 *name_end = cc; 3415 } 3416 else if (lp->ll_range) 3417 { 3418 listitem_T *li = lp->ll_li; 3419 3420 /* (un)lock a range of List items. */ 3421 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3422 { 3423 item_lock(&li->li_tv, deep, lock); 3424 li = li->li_next; 3425 ++lp->ll_n1; 3426 } 3427 } 3428 else if (lp->ll_list != NULL) 3429 /* (un)lock a List item. */ 3430 item_lock(&lp->ll_li->li_tv, deep, lock); 3431 else 3432 /* un(lock) a Dictionary item. */ 3433 item_lock(&lp->ll_di->di_tv, deep, lock); 3434 3435 return ret; 3436 } 3437 3438 /* 3439 * Lock or unlock an item. "deep" is nr of levels to go. 3440 */ 3441 static void 3442 item_lock(tv, deep, lock) 3443 typval_T *tv; 3444 int deep; 3445 int lock; 3446 { 3447 static int recurse = 0; 3448 list_T *l; 3449 listitem_T *li; 3450 dict_T *d; 3451 hashitem_T *hi; 3452 int todo; 3453 3454 if (recurse >= DICT_MAXNEST) 3455 { 3456 EMSG(_("E743: variable nested too deep for (un)lock")); 3457 return; 3458 } 3459 if (deep == 0) 3460 return; 3461 ++recurse; 3462 3463 /* lock/unlock the item itself */ 3464 if (lock) 3465 tv->v_lock |= VAR_LOCKED; 3466 else 3467 tv->v_lock &= ~VAR_LOCKED; 3468 3469 switch (tv->v_type) 3470 { 3471 case VAR_LIST: 3472 if ((l = tv->vval.v_list) != NULL) 3473 { 3474 if (lock) 3475 l->lv_lock |= VAR_LOCKED; 3476 else 3477 l->lv_lock &= ~VAR_LOCKED; 3478 if (deep < 0 || deep > 1) 3479 /* recursive: lock/unlock the items the List contains */ 3480 for (li = l->lv_first; li != NULL; li = li->li_next) 3481 item_lock(&li->li_tv, deep - 1, lock); 3482 } 3483 break; 3484 case VAR_DICT: 3485 if ((d = tv->vval.v_dict) != NULL) 3486 { 3487 if (lock) 3488 d->dv_lock |= VAR_LOCKED; 3489 else 3490 d->dv_lock &= ~VAR_LOCKED; 3491 if (deep < 0 || deep > 1) 3492 { 3493 /* recursive: lock/unlock the items the List contains */ 3494 todo = (int)d->dv_hashtab.ht_used; 3495 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3496 { 3497 if (!HASHITEM_EMPTY(hi)) 3498 { 3499 --todo; 3500 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3501 } 3502 } 3503 } 3504 } 3505 } 3506 --recurse; 3507 } 3508 3509 /* 3510 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3511 * it refers to a List or Dictionary that is locked. 3512 */ 3513 static int 3514 tv_islocked(tv) 3515 typval_T *tv; 3516 { 3517 return (tv->v_lock & VAR_LOCKED) 3518 || (tv->v_type == VAR_LIST 3519 && tv->vval.v_list != NULL 3520 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3521 || (tv->v_type == VAR_DICT 3522 && tv->vval.v_dict != NULL 3523 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3524 } 3525 3526 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3527 /* 3528 * Delete all "menutrans_" variables. 3529 */ 3530 void 3531 del_menutrans_vars() 3532 { 3533 hashitem_T *hi; 3534 int todo; 3535 3536 hash_lock(&globvarht); 3537 todo = (int)globvarht.ht_used; 3538 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3539 { 3540 if (!HASHITEM_EMPTY(hi)) 3541 { 3542 --todo; 3543 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3544 delete_var(&globvarht, hi); 3545 } 3546 } 3547 hash_unlock(&globvarht); 3548 } 3549 #endif 3550 3551 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3552 3553 /* 3554 * Local string buffer for the next two functions to store a variable name 3555 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3556 * get_user_var_name(). 3557 */ 3558 3559 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3560 3561 static char_u *varnamebuf = NULL; 3562 static int varnamebuflen = 0; 3563 3564 /* 3565 * Function to concatenate a prefix and a variable name. 3566 */ 3567 static char_u * 3568 cat_prefix_varname(prefix, name) 3569 int prefix; 3570 char_u *name; 3571 { 3572 int len; 3573 3574 len = (int)STRLEN(name) + 3; 3575 if (len > varnamebuflen) 3576 { 3577 vim_free(varnamebuf); 3578 len += 10; /* some additional space */ 3579 varnamebuf = alloc(len); 3580 if (varnamebuf == NULL) 3581 { 3582 varnamebuflen = 0; 3583 return NULL; 3584 } 3585 varnamebuflen = len; 3586 } 3587 *varnamebuf = prefix; 3588 varnamebuf[1] = ':'; 3589 STRCPY(varnamebuf + 2, name); 3590 return varnamebuf; 3591 } 3592 3593 /* 3594 * Function given to ExpandGeneric() to obtain the list of user defined 3595 * (global/buffer/window/built-in) variable names. 3596 */ 3597 /*ARGSUSED*/ 3598 char_u * 3599 get_user_var_name(xp, idx) 3600 expand_T *xp; 3601 int idx; 3602 { 3603 static long_u gdone; 3604 static long_u bdone; 3605 static long_u wdone; 3606 #ifdef FEAT_WINDOWS 3607 static long_u tdone; 3608 #endif 3609 static int vidx; 3610 static hashitem_T *hi; 3611 hashtab_T *ht; 3612 3613 if (idx == 0) 3614 { 3615 gdone = bdone = wdone = vidx = 0; 3616 #ifdef FEAT_WINDOWS 3617 tdone = 0; 3618 #endif 3619 } 3620 3621 /* Global variables */ 3622 if (gdone < globvarht.ht_used) 3623 { 3624 if (gdone++ == 0) 3625 hi = globvarht.ht_array; 3626 else 3627 ++hi; 3628 while (HASHITEM_EMPTY(hi)) 3629 ++hi; 3630 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3631 return cat_prefix_varname('g', hi->hi_key); 3632 return hi->hi_key; 3633 } 3634 3635 /* b: variables */ 3636 ht = &curbuf->b_vars.dv_hashtab; 3637 if (bdone < ht->ht_used) 3638 { 3639 if (bdone++ == 0) 3640 hi = ht->ht_array; 3641 else 3642 ++hi; 3643 while (HASHITEM_EMPTY(hi)) 3644 ++hi; 3645 return cat_prefix_varname('b', hi->hi_key); 3646 } 3647 if (bdone == ht->ht_used) 3648 { 3649 ++bdone; 3650 return (char_u *)"b:changedtick"; 3651 } 3652 3653 /* w: variables */ 3654 ht = &curwin->w_vars.dv_hashtab; 3655 if (wdone < ht->ht_used) 3656 { 3657 if (wdone++ == 0) 3658 hi = ht->ht_array; 3659 else 3660 ++hi; 3661 while (HASHITEM_EMPTY(hi)) 3662 ++hi; 3663 return cat_prefix_varname('w', hi->hi_key); 3664 } 3665 3666 #ifdef FEAT_WINDOWS 3667 /* t: variables */ 3668 ht = &curtab->tp_vars.dv_hashtab; 3669 if (tdone < ht->ht_used) 3670 { 3671 if (tdone++ == 0) 3672 hi = ht->ht_array; 3673 else 3674 ++hi; 3675 while (HASHITEM_EMPTY(hi)) 3676 ++hi; 3677 return cat_prefix_varname('t', hi->hi_key); 3678 } 3679 #endif 3680 3681 /* v: variables */ 3682 if (vidx < VV_LEN) 3683 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3684 3685 vim_free(varnamebuf); 3686 varnamebuf = NULL; 3687 varnamebuflen = 0; 3688 return NULL; 3689 } 3690 3691 #endif /* FEAT_CMDL_COMPL */ 3692 3693 /* 3694 * types for expressions. 3695 */ 3696 typedef enum 3697 { 3698 TYPE_UNKNOWN = 0 3699 , TYPE_EQUAL /* == */ 3700 , TYPE_NEQUAL /* != */ 3701 , TYPE_GREATER /* > */ 3702 , TYPE_GEQUAL /* >= */ 3703 , TYPE_SMALLER /* < */ 3704 , TYPE_SEQUAL /* <= */ 3705 , TYPE_MATCH /* =~ */ 3706 , TYPE_NOMATCH /* !~ */ 3707 } exptype_T; 3708 3709 /* 3710 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3711 * executed. The function may return OK, but the rettv will be of type 3712 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3713 */ 3714 3715 /* 3716 * Handle zero level expression. 3717 * This calls eval1() and handles error message and nextcmd. 3718 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3719 * Note: "rettv.v_lock" is not set. 3720 * Return OK or FAIL. 3721 */ 3722 static int 3723 eval0(arg, rettv, nextcmd, evaluate) 3724 char_u *arg; 3725 typval_T *rettv; 3726 char_u **nextcmd; 3727 int evaluate; 3728 { 3729 int ret; 3730 char_u *p; 3731 3732 p = skipwhite(arg); 3733 ret = eval1(&p, rettv, evaluate); 3734 if (ret == FAIL || !ends_excmd(*p)) 3735 { 3736 if (ret != FAIL) 3737 clear_tv(rettv); 3738 /* 3739 * Report the invalid expression unless the expression evaluation has 3740 * been cancelled due to an aborting error, an interrupt, or an 3741 * exception. 3742 */ 3743 if (!aborting()) 3744 EMSG2(_(e_invexpr2), arg); 3745 ret = FAIL; 3746 } 3747 if (nextcmd != NULL) 3748 *nextcmd = check_nextcmd(p); 3749 3750 return ret; 3751 } 3752 3753 /* 3754 * Handle top level expression: 3755 * expr1 ? expr0 : expr0 3756 * 3757 * "arg" must point to the first non-white of the expression. 3758 * "arg" is advanced to the next non-white after the recognized expression. 3759 * 3760 * Note: "rettv.v_lock" is not set. 3761 * 3762 * Return OK or FAIL. 3763 */ 3764 static int 3765 eval1(arg, rettv, evaluate) 3766 char_u **arg; 3767 typval_T *rettv; 3768 int evaluate; 3769 { 3770 int result; 3771 typval_T var2; 3772 3773 /* 3774 * Get the first variable. 3775 */ 3776 if (eval2(arg, rettv, evaluate) == FAIL) 3777 return FAIL; 3778 3779 if ((*arg)[0] == '?') 3780 { 3781 result = FALSE; 3782 if (evaluate) 3783 { 3784 int error = FALSE; 3785 3786 if (get_tv_number_chk(rettv, &error) != 0) 3787 result = TRUE; 3788 clear_tv(rettv); 3789 if (error) 3790 return FAIL; 3791 } 3792 3793 /* 3794 * Get the second variable. 3795 */ 3796 *arg = skipwhite(*arg + 1); 3797 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3798 return FAIL; 3799 3800 /* 3801 * Check for the ":". 3802 */ 3803 if ((*arg)[0] != ':') 3804 { 3805 EMSG(_("E109: Missing ':' after '?'")); 3806 if (evaluate && result) 3807 clear_tv(rettv); 3808 return FAIL; 3809 } 3810 3811 /* 3812 * Get the third variable. 3813 */ 3814 *arg = skipwhite(*arg + 1); 3815 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3816 { 3817 if (evaluate && result) 3818 clear_tv(rettv); 3819 return FAIL; 3820 } 3821 if (evaluate && !result) 3822 *rettv = var2; 3823 } 3824 3825 return OK; 3826 } 3827 3828 /* 3829 * Handle first level expression: 3830 * expr2 || expr2 || expr2 logical OR 3831 * 3832 * "arg" must point to the first non-white of the expression. 3833 * "arg" is advanced to the next non-white after the recognized expression. 3834 * 3835 * Return OK or FAIL. 3836 */ 3837 static int 3838 eval2(arg, rettv, evaluate) 3839 char_u **arg; 3840 typval_T *rettv; 3841 int evaluate; 3842 { 3843 typval_T var2; 3844 long result; 3845 int first; 3846 int error = FALSE; 3847 3848 /* 3849 * Get the first variable. 3850 */ 3851 if (eval3(arg, rettv, evaluate) == FAIL) 3852 return FAIL; 3853 3854 /* 3855 * Repeat until there is no following "||". 3856 */ 3857 first = TRUE; 3858 result = FALSE; 3859 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3860 { 3861 if (evaluate && first) 3862 { 3863 if (get_tv_number_chk(rettv, &error) != 0) 3864 result = TRUE; 3865 clear_tv(rettv); 3866 if (error) 3867 return FAIL; 3868 first = FALSE; 3869 } 3870 3871 /* 3872 * Get the second variable. 3873 */ 3874 *arg = skipwhite(*arg + 2); 3875 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3876 return FAIL; 3877 3878 /* 3879 * Compute the result. 3880 */ 3881 if (evaluate && !result) 3882 { 3883 if (get_tv_number_chk(&var2, &error) != 0) 3884 result = TRUE; 3885 clear_tv(&var2); 3886 if (error) 3887 return FAIL; 3888 } 3889 if (evaluate) 3890 { 3891 rettv->v_type = VAR_NUMBER; 3892 rettv->vval.v_number = result; 3893 } 3894 } 3895 3896 return OK; 3897 } 3898 3899 /* 3900 * Handle second level expression: 3901 * expr3 && expr3 && expr3 logical AND 3902 * 3903 * "arg" must point to the first non-white of the expression. 3904 * "arg" is advanced to the next non-white after the recognized expression. 3905 * 3906 * Return OK or FAIL. 3907 */ 3908 static int 3909 eval3(arg, rettv, evaluate) 3910 char_u **arg; 3911 typval_T *rettv; 3912 int evaluate; 3913 { 3914 typval_T var2; 3915 long result; 3916 int first; 3917 int error = FALSE; 3918 3919 /* 3920 * Get the first variable. 3921 */ 3922 if (eval4(arg, rettv, evaluate) == FAIL) 3923 return FAIL; 3924 3925 /* 3926 * Repeat until there is no following "&&". 3927 */ 3928 first = TRUE; 3929 result = TRUE; 3930 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3931 { 3932 if (evaluate && first) 3933 { 3934 if (get_tv_number_chk(rettv, &error) == 0) 3935 result = FALSE; 3936 clear_tv(rettv); 3937 if (error) 3938 return FAIL; 3939 first = FALSE; 3940 } 3941 3942 /* 3943 * Get the second variable. 3944 */ 3945 *arg = skipwhite(*arg + 2); 3946 if (eval4(arg, &var2, evaluate && result) == FAIL) 3947 return FAIL; 3948 3949 /* 3950 * Compute the result. 3951 */ 3952 if (evaluate && result) 3953 { 3954 if (get_tv_number_chk(&var2, &error) == 0) 3955 result = FALSE; 3956 clear_tv(&var2); 3957 if (error) 3958 return FAIL; 3959 } 3960 if (evaluate) 3961 { 3962 rettv->v_type = VAR_NUMBER; 3963 rettv->vval.v_number = result; 3964 } 3965 } 3966 3967 return OK; 3968 } 3969 3970 /* 3971 * Handle third level expression: 3972 * var1 == var2 3973 * var1 =~ var2 3974 * var1 != var2 3975 * var1 !~ var2 3976 * var1 > var2 3977 * var1 >= var2 3978 * var1 < var2 3979 * var1 <= var2 3980 * var1 is var2 3981 * var1 isnot var2 3982 * 3983 * "arg" must point to the first non-white of the expression. 3984 * "arg" is advanced to the next non-white after the recognized expression. 3985 * 3986 * Return OK or FAIL. 3987 */ 3988 static int 3989 eval4(arg, rettv, evaluate) 3990 char_u **arg; 3991 typval_T *rettv; 3992 int evaluate; 3993 { 3994 typval_T var2; 3995 char_u *p; 3996 int i; 3997 exptype_T type = TYPE_UNKNOWN; 3998 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3999 int len = 2; 4000 long n1, n2; 4001 char_u *s1, *s2; 4002 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4003 regmatch_T regmatch; 4004 int ic; 4005 char_u *save_cpo; 4006 4007 /* 4008 * Get the first variable. 4009 */ 4010 if (eval5(arg, rettv, evaluate) == FAIL) 4011 return FAIL; 4012 4013 p = *arg; 4014 switch (p[0]) 4015 { 4016 case '=': if (p[1] == '=') 4017 type = TYPE_EQUAL; 4018 else if (p[1] == '~') 4019 type = TYPE_MATCH; 4020 break; 4021 case '!': if (p[1] == '=') 4022 type = TYPE_NEQUAL; 4023 else if (p[1] == '~') 4024 type = TYPE_NOMATCH; 4025 break; 4026 case '>': if (p[1] != '=') 4027 { 4028 type = TYPE_GREATER; 4029 len = 1; 4030 } 4031 else 4032 type = TYPE_GEQUAL; 4033 break; 4034 case '<': if (p[1] != '=') 4035 { 4036 type = TYPE_SMALLER; 4037 len = 1; 4038 } 4039 else 4040 type = TYPE_SEQUAL; 4041 break; 4042 case 'i': if (p[1] == 's') 4043 { 4044 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4045 len = 5; 4046 if (!vim_isIDc(p[len])) 4047 { 4048 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4049 type_is = TRUE; 4050 } 4051 } 4052 break; 4053 } 4054 4055 /* 4056 * If there is a comparitive operator, use it. 4057 */ 4058 if (type != TYPE_UNKNOWN) 4059 { 4060 /* extra question mark appended: ignore case */ 4061 if (p[len] == '?') 4062 { 4063 ic = TRUE; 4064 ++len; 4065 } 4066 /* extra '#' appended: match case */ 4067 else if (p[len] == '#') 4068 { 4069 ic = FALSE; 4070 ++len; 4071 } 4072 /* nothing appened: use 'ignorecase' */ 4073 else 4074 ic = p_ic; 4075 4076 /* 4077 * Get the second variable. 4078 */ 4079 *arg = skipwhite(p + len); 4080 if (eval5(arg, &var2, evaluate) == FAIL) 4081 { 4082 clear_tv(rettv); 4083 return FAIL; 4084 } 4085 4086 if (evaluate) 4087 { 4088 if (type_is && rettv->v_type != var2.v_type) 4089 { 4090 /* For "is" a different type always means FALSE, for "notis" 4091 * it means TRUE. */ 4092 n1 = (type == TYPE_NEQUAL); 4093 } 4094 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4095 { 4096 if (type_is) 4097 { 4098 n1 = (rettv->v_type == var2.v_type 4099 && rettv->vval.v_list == var2.vval.v_list); 4100 if (type == TYPE_NEQUAL) 4101 n1 = !n1; 4102 } 4103 else if (rettv->v_type != var2.v_type 4104 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4105 { 4106 if (rettv->v_type != var2.v_type) 4107 EMSG(_("E691: Can only compare List with List")); 4108 else 4109 EMSG(_("E692: Invalid operation for Lists")); 4110 clear_tv(rettv); 4111 clear_tv(&var2); 4112 return FAIL; 4113 } 4114 else 4115 { 4116 /* Compare two Lists for being equal or unequal. */ 4117 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4118 if (type == TYPE_NEQUAL) 4119 n1 = !n1; 4120 } 4121 } 4122 4123 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4124 { 4125 if (type_is) 4126 { 4127 n1 = (rettv->v_type == var2.v_type 4128 && rettv->vval.v_dict == var2.vval.v_dict); 4129 if (type == TYPE_NEQUAL) 4130 n1 = !n1; 4131 } 4132 else if (rettv->v_type != var2.v_type 4133 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4134 { 4135 if (rettv->v_type != var2.v_type) 4136 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4137 else 4138 EMSG(_("E736: Invalid operation for Dictionary")); 4139 clear_tv(rettv); 4140 clear_tv(&var2); 4141 return FAIL; 4142 } 4143 else 4144 { 4145 /* Compare two Dictionaries for being equal or unequal. */ 4146 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4147 if (type == TYPE_NEQUAL) 4148 n1 = !n1; 4149 } 4150 } 4151 4152 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4153 { 4154 if (rettv->v_type != var2.v_type 4155 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4156 { 4157 if (rettv->v_type != var2.v_type) 4158 EMSG(_("E693: Can only compare Funcref with Funcref")); 4159 else 4160 EMSG(_("E694: Invalid operation for Funcrefs")); 4161 clear_tv(rettv); 4162 clear_tv(&var2); 4163 return FAIL; 4164 } 4165 else 4166 { 4167 /* Compare two Funcrefs for being equal or unequal. */ 4168 if (rettv->vval.v_string == NULL 4169 || var2.vval.v_string == NULL) 4170 n1 = FALSE; 4171 else 4172 n1 = STRCMP(rettv->vval.v_string, 4173 var2.vval.v_string) == 0; 4174 if (type == TYPE_NEQUAL) 4175 n1 = !n1; 4176 } 4177 } 4178 4179 /* 4180 * If one of the two variables is a number, compare as a number. 4181 * When using "=~" or "!~", always compare as string. 4182 */ 4183 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4184 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4185 { 4186 n1 = get_tv_number(rettv); 4187 n2 = get_tv_number(&var2); 4188 switch (type) 4189 { 4190 case TYPE_EQUAL: n1 = (n1 == n2); break; 4191 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4192 case TYPE_GREATER: n1 = (n1 > n2); break; 4193 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4194 case TYPE_SMALLER: n1 = (n1 < n2); break; 4195 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4196 case TYPE_UNKNOWN: 4197 case TYPE_MATCH: 4198 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4199 } 4200 } 4201 else 4202 { 4203 s1 = get_tv_string_buf(rettv, buf1); 4204 s2 = get_tv_string_buf(&var2, buf2); 4205 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4206 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4207 else 4208 i = 0; 4209 n1 = FALSE; 4210 switch (type) 4211 { 4212 case TYPE_EQUAL: n1 = (i == 0); break; 4213 case TYPE_NEQUAL: n1 = (i != 0); break; 4214 case TYPE_GREATER: n1 = (i > 0); break; 4215 case TYPE_GEQUAL: n1 = (i >= 0); break; 4216 case TYPE_SMALLER: n1 = (i < 0); break; 4217 case TYPE_SEQUAL: n1 = (i <= 0); break; 4218 4219 case TYPE_MATCH: 4220 case TYPE_NOMATCH: 4221 /* avoid 'l' flag in 'cpoptions' */ 4222 save_cpo = p_cpo; 4223 p_cpo = (char_u *)""; 4224 regmatch.regprog = vim_regcomp(s2, 4225 RE_MAGIC + RE_STRING); 4226 regmatch.rm_ic = ic; 4227 if (regmatch.regprog != NULL) 4228 { 4229 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4230 vim_free(regmatch.regprog); 4231 if (type == TYPE_NOMATCH) 4232 n1 = !n1; 4233 } 4234 p_cpo = save_cpo; 4235 break; 4236 4237 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4238 } 4239 } 4240 clear_tv(rettv); 4241 clear_tv(&var2); 4242 rettv->v_type = VAR_NUMBER; 4243 rettv->vval.v_number = n1; 4244 } 4245 } 4246 4247 return OK; 4248 } 4249 4250 /* 4251 * Handle fourth level expression: 4252 * + number addition 4253 * - number subtraction 4254 * . string concatenation 4255 * 4256 * "arg" must point to the first non-white of the expression. 4257 * "arg" is advanced to the next non-white after the recognized expression. 4258 * 4259 * Return OK or FAIL. 4260 */ 4261 static int 4262 eval5(arg, rettv, evaluate) 4263 char_u **arg; 4264 typval_T *rettv; 4265 int evaluate; 4266 { 4267 typval_T var2; 4268 typval_T var3; 4269 int op; 4270 long n1, n2; 4271 char_u *s1, *s2; 4272 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4273 char_u *p; 4274 4275 /* 4276 * Get the first variable. 4277 */ 4278 if (eval6(arg, rettv, evaluate) == FAIL) 4279 return FAIL; 4280 4281 /* 4282 * Repeat computing, until no '+', '-' or '.' is following. 4283 */ 4284 for (;;) 4285 { 4286 op = **arg; 4287 if (op != '+' && op != '-' && op != '.') 4288 break; 4289 4290 if (op != '+' || rettv->v_type != VAR_LIST) 4291 { 4292 /* For "list + ...", an illegal use of the first operand as 4293 * a number cannot be determined before evaluating the 2nd 4294 * operand: if this is also a list, all is ok. 4295 * For "something . ...", "something - ..." or "non-list + ...", 4296 * we know that the first operand needs to be a string or number 4297 * without evaluating the 2nd operand. So check before to avoid 4298 * side effects after an error. */ 4299 if (evaluate && get_tv_string_chk(rettv) == NULL) 4300 { 4301 clear_tv(rettv); 4302 return FAIL; 4303 } 4304 } 4305 4306 /* 4307 * Get the second variable. 4308 */ 4309 *arg = skipwhite(*arg + 1); 4310 if (eval6(arg, &var2, evaluate) == FAIL) 4311 { 4312 clear_tv(rettv); 4313 return FAIL; 4314 } 4315 4316 if (evaluate) 4317 { 4318 /* 4319 * Compute the result. 4320 */ 4321 if (op == '.') 4322 { 4323 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4324 s2 = get_tv_string_buf_chk(&var2, buf2); 4325 if (s2 == NULL) /* type error ? */ 4326 { 4327 clear_tv(rettv); 4328 clear_tv(&var2); 4329 return FAIL; 4330 } 4331 p = concat_str(s1, s2); 4332 clear_tv(rettv); 4333 rettv->v_type = VAR_STRING; 4334 rettv->vval.v_string = p; 4335 } 4336 else if (op == '+' && rettv->v_type == VAR_LIST 4337 && var2.v_type == VAR_LIST) 4338 { 4339 /* concatenate Lists */ 4340 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4341 &var3) == FAIL) 4342 { 4343 clear_tv(rettv); 4344 clear_tv(&var2); 4345 return FAIL; 4346 } 4347 clear_tv(rettv); 4348 *rettv = var3; 4349 } 4350 else 4351 { 4352 int error = FALSE; 4353 4354 n1 = get_tv_number_chk(rettv, &error); 4355 if (error) 4356 { 4357 /* This can only happen for "list + non-list". 4358 * For "non-list + ..." or "something - ...", we returned 4359 * before evaluating the 2nd operand. */ 4360 clear_tv(rettv); 4361 return FAIL; 4362 } 4363 n2 = get_tv_number_chk(&var2, &error); 4364 if (error) 4365 { 4366 clear_tv(rettv); 4367 clear_tv(&var2); 4368 return FAIL; 4369 } 4370 clear_tv(rettv); 4371 if (op == '+') 4372 n1 = n1 + n2; 4373 else 4374 n1 = n1 - n2; 4375 rettv->v_type = VAR_NUMBER; 4376 rettv->vval.v_number = n1; 4377 } 4378 clear_tv(&var2); 4379 } 4380 } 4381 return OK; 4382 } 4383 4384 /* 4385 * Handle fifth level expression: 4386 * * number multiplication 4387 * / number division 4388 * % number modulo 4389 * 4390 * "arg" must point to the first non-white of the expression. 4391 * "arg" is advanced to the next non-white after the recognized expression. 4392 * 4393 * Return OK or FAIL. 4394 */ 4395 static int 4396 eval6(arg, rettv, evaluate) 4397 char_u **arg; 4398 typval_T *rettv; 4399 int evaluate; 4400 { 4401 typval_T var2; 4402 int op; 4403 long n1, n2; 4404 int error = FALSE; 4405 4406 /* 4407 * Get the first variable. 4408 */ 4409 if (eval7(arg, rettv, evaluate) == FAIL) 4410 return FAIL; 4411 4412 /* 4413 * Repeat computing, until no '*', '/' or '%' is following. 4414 */ 4415 for (;;) 4416 { 4417 op = **arg; 4418 if (op != '*' && op != '/' && op != '%') 4419 break; 4420 4421 if (evaluate) 4422 { 4423 n1 = get_tv_number_chk(rettv, &error); 4424 clear_tv(rettv); 4425 if (error) 4426 return FAIL; 4427 } 4428 else 4429 n1 = 0; 4430 4431 /* 4432 * Get the second variable. 4433 */ 4434 *arg = skipwhite(*arg + 1); 4435 if (eval7(arg, &var2, evaluate) == FAIL) 4436 return FAIL; 4437 4438 if (evaluate) 4439 { 4440 n2 = get_tv_number_chk(&var2, &error); 4441 clear_tv(&var2); 4442 if (error) 4443 return FAIL; 4444 4445 /* 4446 * Compute the result. 4447 */ 4448 if (op == '*') 4449 n1 = n1 * n2; 4450 else if (op == '/') 4451 { 4452 if (n2 == 0) /* give an error message? */ 4453 n1 = 0x7fffffffL; 4454 else 4455 n1 = n1 / n2; 4456 } 4457 else 4458 { 4459 if (n2 == 0) /* give an error message? */ 4460 n1 = 0; 4461 else 4462 n1 = n1 % n2; 4463 } 4464 rettv->v_type = VAR_NUMBER; 4465 rettv->vval.v_number = n1; 4466 } 4467 } 4468 4469 return OK; 4470 } 4471 4472 /* 4473 * Handle sixth level expression: 4474 * number number constant 4475 * "string" string contstant 4476 * 'string' literal string contstant 4477 * &option-name option value 4478 * @r register contents 4479 * identifier variable value 4480 * function() function call 4481 * $VAR environment variable 4482 * (expression) nested expression 4483 * [expr, expr] List 4484 * {key: val, key: val} Dictionary 4485 * 4486 * Also handle: 4487 * ! in front logical NOT 4488 * - in front unary minus 4489 * + in front unary plus (ignored) 4490 * trailing [] subscript in String or List 4491 * trailing .name entry in Dictionary 4492 * 4493 * "arg" must point to the first non-white of the expression. 4494 * "arg" is advanced to the next non-white after the recognized expression. 4495 * 4496 * Return OK or FAIL. 4497 */ 4498 static int 4499 eval7(arg, rettv, evaluate) 4500 char_u **arg; 4501 typval_T *rettv; 4502 int evaluate; 4503 { 4504 long n; 4505 int len; 4506 char_u *s; 4507 int val; 4508 char_u *start_leader, *end_leader; 4509 int ret = OK; 4510 char_u *alias; 4511 4512 /* 4513 * Initialise variable so that clear_tv() can't mistake this for a 4514 * string and free a string that isn't there. 4515 */ 4516 rettv->v_type = VAR_UNKNOWN; 4517 4518 /* 4519 * Skip '!' and '-' characters. They are handled later. 4520 */ 4521 start_leader = *arg; 4522 while (**arg == '!' || **arg == '-' || **arg == '+') 4523 *arg = skipwhite(*arg + 1); 4524 end_leader = *arg; 4525 4526 switch (**arg) 4527 { 4528 /* 4529 * Number constant. 4530 */ 4531 case '0': 4532 case '1': 4533 case '2': 4534 case '3': 4535 case '4': 4536 case '5': 4537 case '6': 4538 case '7': 4539 case '8': 4540 case '9': 4541 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4542 *arg += len; 4543 if (evaluate) 4544 { 4545 rettv->v_type = VAR_NUMBER; 4546 rettv->vval.v_number = n; 4547 } 4548 break; 4549 4550 /* 4551 * String constant: "string". 4552 */ 4553 case '"': ret = get_string_tv(arg, rettv, evaluate); 4554 break; 4555 4556 /* 4557 * Literal string constant: 'str''ing'. 4558 */ 4559 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4560 break; 4561 4562 /* 4563 * List: [expr, expr] 4564 */ 4565 case '[': ret = get_list_tv(arg, rettv, evaluate); 4566 break; 4567 4568 /* 4569 * Dictionary: {key: val, key: val} 4570 */ 4571 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4572 break; 4573 4574 /* 4575 * Option value: &name 4576 */ 4577 case '&': ret = get_option_tv(arg, rettv, evaluate); 4578 break; 4579 4580 /* 4581 * Environment variable: $VAR. 4582 */ 4583 case '$': ret = get_env_tv(arg, rettv, evaluate); 4584 break; 4585 4586 /* 4587 * Register contents: @r. 4588 */ 4589 case '@': ++*arg; 4590 if (evaluate) 4591 { 4592 rettv->v_type = VAR_STRING; 4593 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4594 } 4595 if (**arg != NUL) 4596 ++*arg; 4597 break; 4598 4599 /* 4600 * nested expression: (expression). 4601 */ 4602 case '(': *arg = skipwhite(*arg + 1); 4603 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4604 if (**arg == ')') 4605 ++*arg; 4606 else if (ret == OK) 4607 { 4608 EMSG(_("E110: Missing ')'")); 4609 clear_tv(rettv); 4610 ret = FAIL; 4611 } 4612 break; 4613 4614 default: ret = NOTDONE; 4615 break; 4616 } 4617 4618 if (ret == NOTDONE) 4619 { 4620 /* 4621 * Must be a variable or function name. 4622 * Can also be a curly-braces kind of name: {expr}. 4623 */ 4624 s = *arg; 4625 len = get_name_len(arg, &alias, evaluate, TRUE); 4626 if (alias != NULL) 4627 s = alias; 4628 4629 if (len <= 0) 4630 ret = FAIL; 4631 else 4632 { 4633 if (**arg == '(') /* recursive! */ 4634 { 4635 /* If "s" is the name of a variable of type VAR_FUNC 4636 * use its contents. */ 4637 s = deref_func_name(s, &len); 4638 4639 /* Invoke the function. */ 4640 ret = get_func_tv(s, len, rettv, arg, 4641 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4642 &len, evaluate, NULL); 4643 /* Stop the expression evaluation when immediately 4644 * aborting on error, or when an interrupt occurred or 4645 * an exception was thrown but not caught. */ 4646 if (aborting()) 4647 { 4648 if (ret == OK) 4649 clear_tv(rettv); 4650 ret = FAIL; 4651 } 4652 } 4653 else if (evaluate) 4654 ret = get_var_tv(s, len, rettv, TRUE); 4655 else 4656 ret = OK; 4657 } 4658 4659 if (alias != NULL) 4660 vim_free(alias); 4661 } 4662 4663 *arg = skipwhite(*arg); 4664 4665 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4666 * expr(expr). */ 4667 if (ret == OK) 4668 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4669 4670 /* 4671 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4672 */ 4673 if (ret == OK && evaluate && end_leader > start_leader) 4674 { 4675 int error = FALSE; 4676 4677 val = get_tv_number_chk(rettv, &error); 4678 if (error) 4679 { 4680 clear_tv(rettv); 4681 ret = FAIL; 4682 } 4683 else 4684 { 4685 while (end_leader > start_leader) 4686 { 4687 --end_leader; 4688 if (*end_leader == '!') 4689 val = !val; 4690 else if (*end_leader == '-') 4691 val = -val; 4692 } 4693 clear_tv(rettv); 4694 rettv->v_type = VAR_NUMBER; 4695 rettv->vval.v_number = val; 4696 } 4697 } 4698 4699 return ret; 4700 } 4701 4702 /* 4703 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 4704 * "*arg" points to the '[' or '.'. 4705 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4706 */ 4707 static int 4708 eval_index(arg, rettv, evaluate, verbose) 4709 char_u **arg; 4710 typval_T *rettv; 4711 int evaluate; 4712 int verbose; /* give error messages */ 4713 { 4714 int empty1 = FALSE, empty2 = FALSE; 4715 typval_T var1, var2; 4716 long n1, n2 = 0; 4717 long len = -1; 4718 int range = FALSE; 4719 char_u *s; 4720 char_u *key = NULL; 4721 4722 if (rettv->v_type == VAR_FUNC) 4723 { 4724 if (verbose) 4725 EMSG(_("E695: Cannot index a Funcref")); 4726 return FAIL; 4727 } 4728 4729 if (**arg == '.') 4730 { 4731 /* 4732 * dict.name 4733 */ 4734 key = *arg + 1; 4735 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4736 ; 4737 if (len == 0) 4738 return FAIL; 4739 *arg = skipwhite(key + len); 4740 } 4741 else 4742 { 4743 /* 4744 * something[idx] 4745 * 4746 * Get the (first) variable from inside the []. 4747 */ 4748 *arg = skipwhite(*arg + 1); 4749 if (**arg == ':') 4750 empty1 = TRUE; 4751 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4752 return FAIL; 4753 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4754 { 4755 /* not a number or string */ 4756 clear_tv(&var1); 4757 return FAIL; 4758 } 4759 4760 /* 4761 * Get the second variable from inside the [:]. 4762 */ 4763 if (**arg == ':') 4764 { 4765 range = TRUE; 4766 *arg = skipwhite(*arg + 1); 4767 if (**arg == ']') 4768 empty2 = TRUE; 4769 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4770 { 4771 if (!empty1) 4772 clear_tv(&var1); 4773 return FAIL; 4774 } 4775 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4776 { 4777 /* not a number or string */ 4778 if (!empty1) 4779 clear_tv(&var1); 4780 clear_tv(&var2); 4781 return FAIL; 4782 } 4783 } 4784 4785 /* Check for the ']'. */ 4786 if (**arg != ']') 4787 { 4788 if (verbose) 4789 EMSG(_(e_missbrac)); 4790 clear_tv(&var1); 4791 if (range) 4792 clear_tv(&var2); 4793 return FAIL; 4794 } 4795 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4796 } 4797 4798 if (evaluate) 4799 { 4800 n1 = 0; 4801 if (!empty1 && rettv->v_type != VAR_DICT) 4802 { 4803 n1 = get_tv_number(&var1); 4804 clear_tv(&var1); 4805 } 4806 if (range) 4807 { 4808 if (empty2) 4809 n2 = -1; 4810 else 4811 { 4812 n2 = get_tv_number(&var2); 4813 clear_tv(&var2); 4814 } 4815 } 4816 4817 switch (rettv->v_type) 4818 { 4819 case VAR_NUMBER: 4820 case VAR_STRING: 4821 s = get_tv_string(rettv); 4822 len = (long)STRLEN(s); 4823 if (range) 4824 { 4825 /* The resulting variable is a substring. If the indexes 4826 * are out of range the result is empty. */ 4827 if (n1 < 0) 4828 { 4829 n1 = len + n1; 4830 if (n1 < 0) 4831 n1 = 0; 4832 } 4833 if (n2 < 0) 4834 n2 = len + n2; 4835 else if (n2 >= len) 4836 n2 = len; 4837 if (n1 >= len || n2 < 0 || n1 > n2) 4838 s = NULL; 4839 else 4840 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4841 } 4842 else 4843 { 4844 /* The resulting variable is a string of a single 4845 * character. If the index is too big or negative the 4846 * result is empty. */ 4847 if (n1 >= len || n1 < 0) 4848 s = NULL; 4849 else 4850 s = vim_strnsave(s + n1, 1); 4851 } 4852 clear_tv(rettv); 4853 rettv->v_type = VAR_STRING; 4854 rettv->vval.v_string = s; 4855 break; 4856 4857 case VAR_LIST: 4858 len = list_len(rettv->vval.v_list); 4859 if (n1 < 0) 4860 n1 = len + n1; 4861 if (!empty1 && (n1 < 0 || n1 >= len)) 4862 { 4863 /* For a range we allow invalid values and return an empty 4864 * list. A list index out of range is an error. */ 4865 if (!range) 4866 { 4867 if (verbose) 4868 EMSGN(_(e_listidx), n1); 4869 return FAIL; 4870 } 4871 n1 = len; 4872 } 4873 if (range) 4874 { 4875 list_T *l; 4876 listitem_T *item; 4877 4878 if (n2 < 0) 4879 n2 = len + n2; 4880 else if (n2 >= len) 4881 n2 = len - 1; 4882 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 4883 n2 = -1; 4884 l = list_alloc(); 4885 if (l == NULL) 4886 return FAIL; 4887 for (item = list_find(rettv->vval.v_list, n1); 4888 n1 <= n2; ++n1) 4889 { 4890 if (list_append_tv(l, &item->li_tv) == FAIL) 4891 { 4892 list_free(l); 4893 return FAIL; 4894 } 4895 item = item->li_next; 4896 } 4897 clear_tv(rettv); 4898 rettv->v_type = VAR_LIST; 4899 rettv->vval.v_list = l; 4900 ++l->lv_refcount; 4901 } 4902 else 4903 { 4904 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 4905 clear_tv(rettv); 4906 *rettv = var1; 4907 } 4908 break; 4909 4910 case VAR_DICT: 4911 if (range) 4912 { 4913 if (verbose) 4914 EMSG(_(e_dictrange)); 4915 if (len == -1) 4916 clear_tv(&var1); 4917 return FAIL; 4918 } 4919 { 4920 dictitem_T *item; 4921 4922 if (len == -1) 4923 { 4924 key = get_tv_string(&var1); 4925 if (*key == NUL) 4926 { 4927 if (verbose) 4928 EMSG(_(e_emptykey)); 4929 clear_tv(&var1); 4930 return FAIL; 4931 } 4932 } 4933 4934 item = dict_find(rettv->vval.v_dict, key, (int)len); 4935 4936 if (item == NULL && verbose) 4937 EMSG2(_(e_dictkey), key); 4938 if (len == -1) 4939 clear_tv(&var1); 4940 if (item == NULL) 4941 return FAIL; 4942 4943 copy_tv(&item->di_tv, &var1); 4944 clear_tv(rettv); 4945 *rettv = var1; 4946 } 4947 break; 4948 } 4949 } 4950 4951 return OK; 4952 } 4953 4954 /* 4955 * Get an option value. 4956 * "arg" points to the '&' or '+' before the option name. 4957 * "arg" is advanced to character after the option name. 4958 * Return OK or FAIL. 4959 */ 4960 static int 4961 get_option_tv(arg, rettv, evaluate) 4962 char_u **arg; 4963 typval_T *rettv; /* when NULL, only check if option exists */ 4964 int evaluate; 4965 { 4966 char_u *option_end; 4967 long numval; 4968 char_u *stringval; 4969 int opt_type; 4970 int c; 4971 int working = (**arg == '+'); /* has("+option") */ 4972 int ret = OK; 4973 int opt_flags; 4974 4975 /* 4976 * Isolate the option name and find its value. 4977 */ 4978 option_end = find_option_end(arg, &opt_flags); 4979 if (option_end == NULL) 4980 { 4981 if (rettv != NULL) 4982 EMSG2(_("E112: Option name missing: %s"), *arg); 4983 return FAIL; 4984 } 4985 4986 if (!evaluate) 4987 { 4988 *arg = option_end; 4989 return OK; 4990 } 4991 4992 c = *option_end; 4993 *option_end = NUL; 4994 opt_type = get_option_value(*arg, &numval, 4995 rettv == NULL ? NULL : &stringval, opt_flags); 4996 4997 if (opt_type == -3) /* invalid name */ 4998 { 4999 if (rettv != NULL) 5000 EMSG2(_("E113: Unknown option: %s"), *arg); 5001 ret = FAIL; 5002 } 5003 else if (rettv != NULL) 5004 { 5005 if (opt_type == -2) /* hidden string option */ 5006 { 5007 rettv->v_type = VAR_STRING; 5008 rettv->vval.v_string = NULL; 5009 } 5010 else if (opt_type == -1) /* hidden number option */ 5011 { 5012 rettv->v_type = VAR_NUMBER; 5013 rettv->vval.v_number = 0; 5014 } 5015 else if (opt_type == 1) /* number option */ 5016 { 5017 rettv->v_type = VAR_NUMBER; 5018 rettv->vval.v_number = numval; 5019 } 5020 else /* string option */ 5021 { 5022 rettv->v_type = VAR_STRING; 5023 rettv->vval.v_string = stringval; 5024 } 5025 } 5026 else if (working && (opt_type == -2 || opt_type == -1)) 5027 ret = FAIL; 5028 5029 *option_end = c; /* put back for error messages */ 5030 *arg = option_end; 5031 5032 return ret; 5033 } 5034 5035 /* 5036 * Allocate a variable for a string constant. 5037 * Return OK or FAIL. 5038 */ 5039 static int 5040 get_string_tv(arg, rettv, evaluate) 5041 char_u **arg; 5042 typval_T *rettv; 5043 int evaluate; 5044 { 5045 char_u *p; 5046 char_u *name; 5047 int extra = 0; 5048 5049 /* 5050 * Find the end of the string, skipping backslashed characters. 5051 */ 5052 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5053 { 5054 if (*p == '\\' && p[1] != NUL) 5055 { 5056 ++p; 5057 /* A "\<x>" form occupies at least 4 characters, and produces up 5058 * to 6 characters: reserve space for 2 extra */ 5059 if (*p == '<') 5060 extra += 2; 5061 } 5062 } 5063 5064 if (*p != '"') 5065 { 5066 EMSG2(_("E114: Missing quote: %s"), *arg); 5067 return FAIL; 5068 } 5069 5070 /* If only parsing, set *arg and return here */ 5071 if (!evaluate) 5072 { 5073 *arg = p + 1; 5074 return OK; 5075 } 5076 5077 /* 5078 * Copy the string into allocated memory, handling backslashed 5079 * characters. 5080 */ 5081 name = alloc((unsigned)(p - *arg + extra)); 5082 if (name == NULL) 5083 return FAIL; 5084 rettv->v_type = VAR_STRING; 5085 rettv->vval.v_string = name; 5086 5087 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5088 { 5089 if (*p == '\\') 5090 { 5091 switch (*++p) 5092 { 5093 case 'b': *name++ = BS; ++p; break; 5094 case 'e': *name++ = ESC; ++p; break; 5095 case 'f': *name++ = FF; ++p; break; 5096 case 'n': *name++ = NL; ++p; break; 5097 case 'r': *name++ = CAR; ++p; break; 5098 case 't': *name++ = TAB; ++p; break; 5099 5100 case 'X': /* hex: "\x1", "\x12" */ 5101 case 'x': 5102 case 'u': /* Unicode: "\u0023" */ 5103 case 'U': 5104 if (vim_isxdigit(p[1])) 5105 { 5106 int n, nr; 5107 int c = toupper(*p); 5108 5109 if (c == 'X') 5110 n = 2; 5111 else 5112 n = 4; 5113 nr = 0; 5114 while (--n >= 0 && vim_isxdigit(p[1])) 5115 { 5116 ++p; 5117 nr = (nr << 4) + hex2nr(*p); 5118 } 5119 ++p; 5120 #ifdef FEAT_MBYTE 5121 /* For "\u" store the number according to 5122 * 'encoding'. */ 5123 if (c != 'X') 5124 name += (*mb_char2bytes)(nr, name); 5125 else 5126 #endif 5127 *name++ = nr; 5128 } 5129 break; 5130 5131 /* octal: "\1", "\12", "\123" */ 5132 case '0': 5133 case '1': 5134 case '2': 5135 case '3': 5136 case '4': 5137 case '5': 5138 case '6': 5139 case '7': *name = *p++ - '0'; 5140 if (*p >= '0' && *p <= '7') 5141 { 5142 *name = (*name << 3) + *p++ - '0'; 5143 if (*p >= '0' && *p <= '7') 5144 *name = (*name << 3) + *p++ - '0'; 5145 } 5146 ++name; 5147 break; 5148 5149 /* Special key, e.g.: "\<C-W>" */ 5150 case '<': extra = trans_special(&p, name, TRUE); 5151 if (extra != 0) 5152 { 5153 name += extra; 5154 break; 5155 } 5156 /* FALLTHROUGH */ 5157 5158 default: MB_COPY_CHAR(p, name); 5159 break; 5160 } 5161 } 5162 else 5163 MB_COPY_CHAR(p, name); 5164 5165 } 5166 *name = NUL; 5167 *arg = p + 1; 5168 5169 return OK; 5170 } 5171 5172 /* 5173 * Allocate a variable for a 'str''ing' constant. 5174 * Return OK or FAIL. 5175 */ 5176 static int 5177 get_lit_string_tv(arg, rettv, evaluate) 5178 char_u **arg; 5179 typval_T *rettv; 5180 int evaluate; 5181 { 5182 char_u *p; 5183 char_u *str; 5184 int reduce = 0; 5185 5186 /* 5187 * Find the end of the string, skipping ''. 5188 */ 5189 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5190 { 5191 if (*p == '\'') 5192 { 5193 if (p[1] != '\'') 5194 break; 5195 ++reduce; 5196 ++p; 5197 } 5198 } 5199 5200 if (*p != '\'') 5201 { 5202 EMSG2(_("E115: Missing quote: %s"), *arg); 5203 return FAIL; 5204 } 5205 5206 /* If only parsing return after setting "*arg" */ 5207 if (!evaluate) 5208 { 5209 *arg = p + 1; 5210 return OK; 5211 } 5212 5213 /* 5214 * Copy the string into allocated memory, handling '' to ' reduction. 5215 */ 5216 str = alloc((unsigned)((p - *arg) - reduce)); 5217 if (str == NULL) 5218 return FAIL; 5219 rettv->v_type = VAR_STRING; 5220 rettv->vval.v_string = str; 5221 5222 for (p = *arg + 1; *p != NUL; ) 5223 { 5224 if (*p == '\'') 5225 { 5226 if (p[1] != '\'') 5227 break; 5228 ++p; 5229 } 5230 MB_COPY_CHAR(p, str); 5231 } 5232 *str = NUL; 5233 *arg = p + 1; 5234 5235 return OK; 5236 } 5237 5238 /* 5239 * Allocate a variable for a List and fill it from "*arg". 5240 * Return OK or FAIL. 5241 */ 5242 static int 5243 get_list_tv(arg, rettv, evaluate) 5244 char_u **arg; 5245 typval_T *rettv; 5246 int evaluate; 5247 { 5248 list_T *l = NULL; 5249 typval_T tv; 5250 listitem_T *item; 5251 5252 if (evaluate) 5253 { 5254 l = list_alloc(); 5255 if (l == NULL) 5256 return FAIL; 5257 } 5258 5259 *arg = skipwhite(*arg + 1); 5260 while (**arg != ']' && **arg != NUL) 5261 { 5262 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5263 goto failret; 5264 if (evaluate) 5265 { 5266 item = listitem_alloc(); 5267 if (item != NULL) 5268 { 5269 item->li_tv = tv; 5270 item->li_tv.v_lock = 0; 5271 list_append(l, item); 5272 } 5273 else 5274 clear_tv(&tv); 5275 } 5276 5277 if (**arg == ']') 5278 break; 5279 if (**arg != ',') 5280 { 5281 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5282 goto failret; 5283 } 5284 *arg = skipwhite(*arg + 1); 5285 } 5286 5287 if (**arg != ']') 5288 { 5289 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5290 failret: 5291 if (evaluate) 5292 list_free(l); 5293 return FAIL; 5294 } 5295 5296 *arg = skipwhite(*arg + 1); 5297 if (evaluate) 5298 { 5299 rettv->v_type = VAR_LIST; 5300 rettv->vval.v_list = l; 5301 ++l->lv_refcount; 5302 } 5303 5304 return OK; 5305 } 5306 5307 /* 5308 * Allocate an empty header for a list. 5309 * Caller should take care of the reference count. 5310 */ 5311 list_T * 5312 list_alloc() 5313 { 5314 list_T *l; 5315 5316 l = (list_T *)alloc_clear(sizeof(list_T)); 5317 if (l != NULL) 5318 { 5319 /* Prepend the list to the list of lists for garbage collection. */ 5320 if (first_list != NULL) 5321 first_list->lv_used_prev = l; 5322 l->lv_used_prev = NULL; 5323 l->lv_used_next = first_list; 5324 first_list = l; 5325 } 5326 return l; 5327 } 5328 5329 /* 5330 * Allocate an empty list for a return value. 5331 * Returns OK or FAIL. 5332 */ 5333 static int 5334 rettv_list_alloc(rettv) 5335 typval_T *rettv; 5336 { 5337 list_T *l = list_alloc(); 5338 5339 if (l == NULL) 5340 return FAIL; 5341 5342 rettv->vval.v_list = l; 5343 rettv->v_type = VAR_LIST; 5344 ++l->lv_refcount; 5345 return OK; 5346 } 5347 5348 /* 5349 * Unreference a list: decrement the reference count and free it when it 5350 * becomes zero. 5351 */ 5352 void 5353 list_unref(l) 5354 list_T *l; 5355 { 5356 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5357 list_free(l); 5358 } 5359 5360 /* 5361 * Free a list, including all items it points to. 5362 * Ignores the reference count. 5363 */ 5364 void 5365 list_free(l) 5366 list_T *l; 5367 { 5368 listitem_T *item; 5369 5370 /* Avoid that recursive reference to the list frees us again. */ 5371 l->lv_refcount = DEL_REFCOUNT; 5372 5373 /* Remove the list from the list of lists for garbage collection. */ 5374 if (l->lv_used_prev == NULL) 5375 first_list = l->lv_used_next; 5376 else 5377 l->lv_used_prev->lv_used_next = l->lv_used_next; 5378 if (l->lv_used_next != NULL) 5379 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5380 5381 for (item = l->lv_first; item != NULL; item = l->lv_first) 5382 { 5383 /* Remove the item before deleting it. */ 5384 l->lv_first = item->li_next; 5385 listitem_free(item); 5386 } 5387 vim_free(l); 5388 } 5389 5390 /* 5391 * Allocate a list item. 5392 */ 5393 static listitem_T * 5394 listitem_alloc() 5395 { 5396 return (listitem_T *)alloc(sizeof(listitem_T)); 5397 } 5398 5399 /* 5400 * Free a list item. Also clears the value. Does not notify watchers. 5401 */ 5402 static void 5403 listitem_free(item) 5404 listitem_T *item; 5405 { 5406 clear_tv(&item->li_tv); 5407 vim_free(item); 5408 } 5409 5410 /* 5411 * Remove a list item from a List and free it. Also clears the value. 5412 */ 5413 static void 5414 listitem_remove(l, item) 5415 list_T *l; 5416 listitem_T *item; 5417 { 5418 list_remove(l, item, item); 5419 listitem_free(item); 5420 } 5421 5422 /* 5423 * Get the number of items in a list. 5424 */ 5425 static long 5426 list_len(l) 5427 list_T *l; 5428 { 5429 if (l == NULL) 5430 return 0L; 5431 return l->lv_len; 5432 } 5433 5434 /* 5435 * Return TRUE when two lists have exactly the same values. 5436 */ 5437 static int 5438 list_equal(l1, l2, ic) 5439 list_T *l1; 5440 list_T *l2; 5441 int ic; /* ignore case for strings */ 5442 { 5443 listitem_T *item1, *item2; 5444 5445 if (list_len(l1) != list_len(l2)) 5446 return FALSE; 5447 5448 for (item1 = l1->lv_first, item2 = l2->lv_first; 5449 item1 != NULL && item2 != NULL; 5450 item1 = item1->li_next, item2 = item2->li_next) 5451 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5452 return FALSE; 5453 return item1 == NULL && item2 == NULL; 5454 } 5455 5456 #if defined(FEAT_PYTHON) || defined(PROTO) 5457 /* 5458 * Return the dictitem that an entry in a hashtable points to. 5459 */ 5460 dictitem_T * 5461 dict_lookup(hi) 5462 hashitem_T *hi; 5463 { 5464 return HI2DI(hi); 5465 } 5466 #endif 5467 5468 /* 5469 * Return TRUE when two dictionaries have exactly the same key/values. 5470 */ 5471 static int 5472 dict_equal(d1, d2, ic) 5473 dict_T *d1; 5474 dict_T *d2; 5475 int ic; /* ignore case for strings */ 5476 { 5477 hashitem_T *hi; 5478 dictitem_T *item2; 5479 int todo; 5480 5481 if (dict_len(d1) != dict_len(d2)) 5482 return FALSE; 5483 5484 todo = (int)d1->dv_hashtab.ht_used; 5485 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5486 { 5487 if (!HASHITEM_EMPTY(hi)) 5488 { 5489 item2 = dict_find(d2, hi->hi_key, -1); 5490 if (item2 == NULL) 5491 return FALSE; 5492 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5493 return FALSE; 5494 --todo; 5495 } 5496 } 5497 return TRUE; 5498 } 5499 5500 /* 5501 * Return TRUE if "tv1" and "tv2" have the same value. 5502 * Compares the items just like "==" would compare them, but strings and 5503 * numbers are different. 5504 */ 5505 static int 5506 tv_equal(tv1, tv2, ic) 5507 typval_T *tv1; 5508 typval_T *tv2; 5509 int ic; /* ignore case */ 5510 { 5511 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5512 char_u *s1, *s2; 5513 5514 if (tv1->v_type != tv2->v_type) 5515 return FALSE; 5516 5517 switch (tv1->v_type) 5518 { 5519 case VAR_LIST: 5520 /* recursive! */ 5521 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5522 5523 case VAR_DICT: 5524 /* recursive! */ 5525 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5526 5527 case VAR_FUNC: 5528 return (tv1->vval.v_string != NULL 5529 && tv2->vval.v_string != NULL 5530 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5531 5532 case VAR_NUMBER: 5533 return tv1->vval.v_number == tv2->vval.v_number; 5534 5535 case VAR_STRING: 5536 s1 = get_tv_string_buf(tv1, buf1); 5537 s2 = get_tv_string_buf(tv2, buf2); 5538 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5539 } 5540 5541 EMSG2(_(e_intern2), "tv_equal()"); 5542 return TRUE; 5543 } 5544 5545 /* 5546 * Locate item with index "n" in list "l" and return it. 5547 * A negative index is counted from the end; -1 is the last item. 5548 * Returns NULL when "n" is out of range. 5549 */ 5550 static listitem_T * 5551 list_find(l, n) 5552 list_T *l; 5553 long n; 5554 { 5555 listitem_T *item; 5556 long idx; 5557 5558 if (l == NULL) 5559 return NULL; 5560 5561 /* Negative index is relative to the end. */ 5562 if (n < 0) 5563 n = l->lv_len + n; 5564 5565 /* Check for index out of range. */ 5566 if (n < 0 || n >= l->lv_len) 5567 return NULL; 5568 5569 /* When there is a cached index may start search from there. */ 5570 if (l->lv_idx_item != NULL) 5571 { 5572 if (n < l->lv_idx / 2) 5573 { 5574 /* closest to the start of the list */ 5575 item = l->lv_first; 5576 idx = 0; 5577 } 5578 else if (n > (l->lv_idx + l->lv_len) / 2) 5579 { 5580 /* closest to the end of the list */ 5581 item = l->lv_last; 5582 idx = l->lv_len - 1; 5583 } 5584 else 5585 { 5586 /* closest to the cached index */ 5587 item = l->lv_idx_item; 5588 idx = l->lv_idx; 5589 } 5590 } 5591 else 5592 { 5593 if (n < l->lv_len / 2) 5594 { 5595 /* closest to the start of the list */ 5596 item = l->lv_first; 5597 idx = 0; 5598 } 5599 else 5600 { 5601 /* closest to the end of the list */ 5602 item = l->lv_last; 5603 idx = l->lv_len - 1; 5604 } 5605 } 5606 5607 while (n > idx) 5608 { 5609 /* search forward */ 5610 item = item->li_next; 5611 ++idx; 5612 } 5613 while (n < idx) 5614 { 5615 /* search backward */ 5616 item = item->li_prev; 5617 --idx; 5618 } 5619 5620 /* cache the used index */ 5621 l->lv_idx = idx; 5622 l->lv_idx_item = item; 5623 5624 return item; 5625 } 5626 5627 /* 5628 * Get list item "l[idx]" as a number. 5629 */ 5630 static long 5631 list_find_nr(l, idx, errorp) 5632 list_T *l; 5633 long idx; 5634 int *errorp; /* set to TRUE when something wrong */ 5635 { 5636 listitem_T *li; 5637 5638 li = list_find(l, idx); 5639 if (li == NULL) 5640 { 5641 if (errorp != NULL) 5642 *errorp = TRUE; 5643 return -1L; 5644 } 5645 return get_tv_number_chk(&li->li_tv, errorp); 5646 } 5647 5648 /* 5649 * Locate "item" list "l" and return its index. 5650 * Returns -1 when "item" is not in the list. 5651 */ 5652 static long 5653 list_idx_of_item(l, item) 5654 list_T *l; 5655 listitem_T *item; 5656 { 5657 long idx = 0; 5658 listitem_T *li; 5659 5660 if (l == NULL) 5661 return -1; 5662 idx = 0; 5663 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5664 ++idx; 5665 if (li == NULL) 5666 return -1; 5667 return idx; 5668 } 5669 5670 /* 5671 * Append item "item" to the end of list "l". 5672 */ 5673 static void 5674 list_append(l, item) 5675 list_T *l; 5676 listitem_T *item; 5677 { 5678 if (l->lv_last == NULL) 5679 { 5680 /* empty list */ 5681 l->lv_first = item; 5682 l->lv_last = item; 5683 item->li_prev = NULL; 5684 } 5685 else 5686 { 5687 l->lv_last->li_next = item; 5688 item->li_prev = l->lv_last; 5689 l->lv_last = item; 5690 } 5691 ++l->lv_len; 5692 item->li_next = NULL; 5693 } 5694 5695 /* 5696 * Append typval_T "tv" to the end of list "l". 5697 * Return FAIL when out of memory. 5698 */ 5699 static int 5700 list_append_tv(l, tv) 5701 list_T *l; 5702 typval_T *tv; 5703 { 5704 listitem_T *li = listitem_alloc(); 5705 5706 if (li == NULL) 5707 return FAIL; 5708 copy_tv(tv, &li->li_tv); 5709 list_append(l, li); 5710 return OK; 5711 } 5712 5713 /* 5714 * Add a dictionary to a list. Used by getqflist(). 5715 * Return FAIL when out of memory. 5716 */ 5717 int 5718 list_append_dict(list, dict) 5719 list_T *list; 5720 dict_T *dict; 5721 { 5722 listitem_T *li = listitem_alloc(); 5723 5724 if (li == NULL) 5725 return FAIL; 5726 li->li_tv.v_type = VAR_DICT; 5727 li->li_tv.v_lock = 0; 5728 li->li_tv.vval.v_dict = dict; 5729 list_append(list, li); 5730 ++dict->dv_refcount; 5731 return OK; 5732 } 5733 5734 /* 5735 * Make a copy of "str" and append it as an item to list "l". 5736 * When "len" >= 0 use "str[len]". 5737 * Returns FAIL when out of memory. 5738 */ 5739 static int 5740 list_append_string(l, str, len) 5741 list_T *l; 5742 char_u *str; 5743 int len; 5744 { 5745 listitem_T *li = listitem_alloc(); 5746 5747 if (li == NULL) 5748 return FAIL; 5749 list_append(l, li); 5750 li->li_tv.v_type = VAR_STRING; 5751 li->li_tv.v_lock = 0; 5752 if (str == NULL) 5753 li->li_tv.vval.v_string = NULL; 5754 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5755 : vim_strsave(str))) == NULL) 5756 return FAIL; 5757 return OK; 5758 } 5759 5760 /* 5761 * Append "n" to list "l". 5762 * Returns FAIL when out of memory. 5763 */ 5764 static int 5765 list_append_number(l, n) 5766 list_T *l; 5767 varnumber_T n; 5768 { 5769 listitem_T *li; 5770 5771 li = listitem_alloc(); 5772 if (li == NULL) 5773 return FAIL; 5774 li->li_tv.v_type = VAR_NUMBER; 5775 li->li_tv.v_lock = 0; 5776 li->li_tv.vval.v_number = n; 5777 list_append(l, li); 5778 return OK; 5779 } 5780 5781 /* 5782 * Insert typval_T "tv" in list "l" before "item". 5783 * If "item" is NULL append at the end. 5784 * Return FAIL when out of memory. 5785 */ 5786 static int 5787 list_insert_tv(l, tv, item) 5788 list_T *l; 5789 typval_T *tv; 5790 listitem_T *item; 5791 { 5792 listitem_T *ni = listitem_alloc(); 5793 5794 if (ni == NULL) 5795 return FAIL; 5796 copy_tv(tv, &ni->li_tv); 5797 if (item == NULL) 5798 /* Append new item at end of list. */ 5799 list_append(l, ni); 5800 else 5801 { 5802 /* Insert new item before existing item. */ 5803 ni->li_prev = item->li_prev; 5804 ni->li_next = item; 5805 if (item->li_prev == NULL) 5806 { 5807 l->lv_first = ni; 5808 ++l->lv_idx; 5809 } 5810 else 5811 { 5812 item->li_prev->li_next = ni; 5813 l->lv_idx_item = NULL; 5814 } 5815 item->li_prev = ni; 5816 ++l->lv_len; 5817 } 5818 return OK; 5819 } 5820 5821 /* 5822 * Extend "l1" with "l2". 5823 * If "bef" is NULL append at the end, otherwise insert before this item. 5824 * Returns FAIL when out of memory. 5825 */ 5826 static int 5827 list_extend(l1, l2, bef) 5828 list_T *l1; 5829 list_T *l2; 5830 listitem_T *bef; 5831 { 5832 listitem_T *item; 5833 5834 for (item = l2->lv_first; item != NULL; item = item->li_next) 5835 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5836 return FAIL; 5837 return OK; 5838 } 5839 5840 /* 5841 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5842 * Return FAIL when out of memory. 5843 */ 5844 static int 5845 list_concat(l1, l2, tv) 5846 list_T *l1; 5847 list_T *l2; 5848 typval_T *tv; 5849 { 5850 list_T *l; 5851 5852 /* make a copy of the first list. */ 5853 l = list_copy(l1, FALSE, 0); 5854 if (l == NULL) 5855 return FAIL; 5856 tv->v_type = VAR_LIST; 5857 tv->vval.v_list = l; 5858 5859 /* append all items from the second list */ 5860 return list_extend(l, l2, NULL); 5861 } 5862 5863 /* 5864 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5865 * The refcount of the new list is set to 1. 5866 * See item_copy() for "copyID". 5867 * Returns NULL when out of memory. 5868 */ 5869 static list_T * 5870 list_copy(orig, deep, copyID) 5871 list_T *orig; 5872 int deep; 5873 int copyID; 5874 { 5875 list_T *copy; 5876 listitem_T *item; 5877 listitem_T *ni; 5878 5879 if (orig == NULL) 5880 return NULL; 5881 5882 copy = list_alloc(); 5883 if (copy != NULL) 5884 { 5885 if (copyID != 0) 5886 { 5887 /* Do this before adding the items, because one of the items may 5888 * refer back to this list. */ 5889 orig->lv_copyID = copyID; 5890 orig->lv_copylist = copy; 5891 } 5892 for (item = orig->lv_first; item != NULL && !got_int; 5893 item = item->li_next) 5894 { 5895 ni = listitem_alloc(); 5896 if (ni == NULL) 5897 break; 5898 if (deep) 5899 { 5900 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5901 { 5902 vim_free(ni); 5903 break; 5904 } 5905 } 5906 else 5907 copy_tv(&item->li_tv, &ni->li_tv); 5908 list_append(copy, ni); 5909 } 5910 ++copy->lv_refcount; 5911 if (item != NULL) 5912 { 5913 list_unref(copy); 5914 copy = NULL; 5915 } 5916 } 5917 5918 return copy; 5919 } 5920 5921 /* 5922 * Remove items "item" to "item2" from list "l". 5923 * Does not free the listitem or the value! 5924 */ 5925 static void 5926 list_remove(l, item, item2) 5927 list_T *l; 5928 listitem_T *item; 5929 listitem_T *item2; 5930 { 5931 listitem_T *ip; 5932 5933 /* notify watchers */ 5934 for (ip = item; ip != NULL; ip = ip->li_next) 5935 { 5936 --l->lv_len; 5937 list_fix_watch(l, ip); 5938 if (ip == item2) 5939 break; 5940 } 5941 5942 if (item2->li_next == NULL) 5943 l->lv_last = item->li_prev; 5944 else 5945 item2->li_next->li_prev = item->li_prev; 5946 if (item->li_prev == NULL) 5947 l->lv_first = item2->li_next; 5948 else 5949 item->li_prev->li_next = item2->li_next; 5950 l->lv_idx_item = NULL; 5951 } 5952 5953 /* 5954 * Return an allocated string with the string representation of a list. 5955 * May return NULL. 5956 */ 5957 static char_u * 5958 list2string(tv, copyID) 5959 typval_T *tv; 5960 int copyID; 5961 { 5962 garray_T ga; 5963 5964 if (tv->vval.v_list == NULL) 5965 return NULL; 5966 ga_init2(&ga, (int)sizeof(char), 80); 5967 ga_append(&ga, '['); 5968 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 5969 { 5970 vim_free(ga.ga_data); 5971 return NULL; 5972 } 5973 ga_append(&ga, ']'); 5974 ga_append(&ga, NUL); 5975 return (char_u *)ga.ga_data; 5976 } 5977 5978 /* 5979 * Join list "l" into a string in "*gap", using separator "sep". 5980 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5981 * Return FAIL or OK. 5982 */ 5983 static int 5984 list_join(gap, l, sep, echo, copyID) 5985 garray_T *gap; 5986 list_T *l; 5987 char_u *sep; 5988 int echo; 5989 int copyID; 5990 { 5991 int first = TRUE; 5992 char_u *tofree; 5993 char_u numbuf[NUMBUFLEN]; 5994 listitem_T *item; 5995 char_u *s; 5996 5997 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5998 { 5999 if (first) 6000 first = FALSE; 6001 else 6002 ga_concat(gap, sep); 6003 6004 if (echo) 6005 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6006 else 6007 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6008 if (s != NULL) 6009 ga_concat(gap, s); 6010 vim_free(tofree); 6011 if (s == NULL) 6012 return FAIL; 6013 } 6014 return OK; 6015 } 6016 6017 /* 6018 * Garbage collection for lists and dictionaries. 6019 * 6020 * We use reference counts to be able to free most items right away when they 6021 * are no longer used. But for composite items it's possible that it becomes 6022 * unused while the reference count is > 0: When there is a recursive 6023 * reference. Example: 6024 * :let l = [1, 2, 3] 6025 * :let d = {9: l} 6026 * :let l[1] = d 6027 * 6028 * Since this is quite unusual we handle this with garbage collection: every 6029 * once in a while find out which lists and dicts are not referenced from any 6030 * variable. 6031 * 6032 * Here is a good reference text about garbage collection (refers to Python 6033 * but it applies to all reference-counting mechanisms): 6034 * http://python.ca/nas/python/gc/ 6035 */ 6036 6037 /* 6038 * Do garbage collection for lists and dicts. 6039 * Return TRUE if some memory was freed. 6040 */ 6041 int 6042 garbage_collect() 6043 { 6044 dict_T *dd; 6045 list_T *ll; 6046 int copyID = ++current_copyID; 6047 buf_T *buf; 6048 win_T *wp; 6049 int i; 6050 funccall_T *fc; 6051 int did_free = FALSE; 6052 #ifdef FEAT_WINDOWS 6053 tabpage_T *tp; 6054 #endif 6055 6056 /* 6057 * 1. Go through all accessible variables and mark all lists and dicts 6058 * with copyID. 6059 */ 6060 /* script-local variables */ 6061 for (i = 1; i <= ga_scripts.ga_len; ++i) 6062 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6063 6064 /* buffer-local variables */ 6065 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6066 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6067 6068 /* window-local variables */ 6069 FOR_ALL_TAB_WINDOWS(tp, wp) 6070 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6071 6072 #ifdef FEAT_WINDOWS 6073 /* tabpage-local variables */ 6074 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6075 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6076 #endif 6077 6078 /* global variables */ 6079 set_ref_in_ht(&globvarht, copyID); 6080 6081 /* function-local variables */ 6082 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6083 { 6084 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6085 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6086 } 6087 6088 /* 6089 * 2. Go through the list of dicts and free items without the copyID. 6090 */ 6091 for (dd = first_dict; dd != NULL; ) 6092 if (dd->dv_copyID != copyID) 6093 { 6094 dict_free(dd); 6095 did_free = TRUE; 6096 6097 /* restart, next dict may also have been freed */ 6098 dd = first_dict; 6099 } 6100 else 6101 dd = dd->dv_used_next; 6102 6103 /* 6104 * 3. Go through the list of lists and free items without the copyID. 6105 * But don't free a list that has a watcher (used in a for loop), these 6106 * are not referenced anywhere. 6107 */ 6108 for (ll = first_list; ll != NULL; ) 6109 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 6110 { 6111 list_free(ll); 6112 did_free = TRUE; 6113 6114 /* restart, next list may also have been freed */ 6115 ll = first_list; 6116 } 6117 else 6118 ll = ll->lv_used_next; 6119 6120 return did_free; 6121 } 6122 6123 /* 6124 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6125 */ 6126 static void 6127 set_ref_in_ht(ht, copyID) 6128 hashtab_T *ht; 6129 int copyID; 6130 { 6131 int todo; 6132 hashitem_T *hi; 6133 6134 todo = (int)ht->ht_used; 6135 for (hi = ht->ht_array; todo > 0; ++hi) 6136 if (!HASHITEM_EMPTY(hi)) 6137 { 6138 --todo; 6139 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6140 } 6141 } 6142 6143 /* 6144 * Mark all lists and dicts referenced through list "l" with "copyID". 6145 */ 6146 static void 6147 set_ref_in_list(l, copyID) 6148 list_T *l; 6149 int copyID; 6150 { 6151 listitem_T *li; 6152 6153 for (li = l->lv_first; li != NULL; li = li->li_next) 6154 set_ref_in_item(&li->li_tv, copyID); 6155 } 6156 6157 /* 6158 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6159 */ 6160 static void 6161 set_ref_in_item(tv, copyID) 6162 typval_T *tv; 6163 int copyID; 6164 { 6165 dict_T *dd; 6166 list_T *ll; 6167 6168 switch (tv->v_type) 6169 { 6170 case VAR_DICT: 6171 dd = tv->vval.v_dict; 6172 if (dd->dv_copyID != copyID) 6173 { 6174 /* Didn't see this dict yet. */ 6175 dd->dv_copyID = copyID; 6176 set_ref_in_ht(&dd->dv_hashtab, copyID); 6177 } 6178 break; 6179 6180 case VAR_LIST: 6181 ll = tv->vval.v_list; 6182 if (ll->lv_copyID != copyID) 6183 { 6184 /* Didn't see this list yet. */ 6185 ll->lv_copyID = copyID; 6186 set_ref_in_list(ll, copyID); 6187 } 6188 break; 6189 } 6190 return; 6191 } 6192 6193 /* 6194 * Allocate an empty header for a dictionary. 6195 */ 6196 dict_T * 6197 dict_alloc() 6198 { 6199 dict_T *d; 6200 6201 d = (dict_T *)alloc(sizeof(dict_T)); 6202 if (d != NULL) 6203 { 6204 /* Add the list to the hashtable for garbage collection. */ 6205 if (first_dict != NULL) 6206 first_dict->dv_used_prev = d; 6207 d->dv_used_next = first_dict; 6208 d->dv_used_prev = NULL; 6209 6210 hash_init(&d->dv_hashtab); 6211 d->dv_lock = 0; 6212 d->dv_refcount = 0; 6213 d->dv_copyID = 0; 6214 } 6215 return d; 6216 } 6217 6218 /* 6219 * Unreference a Dictionary: decrement the reference count and free it when it 6220 * becomes zero. 6221 */ 6222 static void 6223 dict_unref(d) 6224 dict_T *d; 6225 { 6226 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6227 dict_free(d); 6228 } 6229 6230 /* 6231 * Free a Dictionary, including all items it contains. 6232 * Ignores the reference count. 6233 */ 6234 static void 6235 dict_free(d) 6236 dict_T *d; 6237 { 6238 int todo; 6239 hashitem_T *hi; 6240 dictitem_T *di; 6241 6242 /* Avoid that recursive reference to the dict frees us again. */ 6243 d->dv_refcount = DEL_REFCOUNT; 6244 6245 /* Remove the dict from the list of dicts for garbage collection. */ 6246 if (d->dv_used_prev == NULL) 6247 first_dict = d->dv_used_next; 6248 else 6249 d->dv_used_prev->dv_used_next = d->dv_used_next; 6250 if (d->dv_used_next != NULL) 6251 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6252 6253 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6254 hash_lock(&d->dv_hashtab); 6255 todo = (int)d->dv_hashtab.ht_used; 6256 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6257 { 6258 if (!HASHITEM_EMPTY(hi)) 6259 { 6260 /* Remove the item before deleting it, just in case there is 6261 * something recursive causing trouble. */ 6262 di = HI2DI(hi); 6263 hash_remove(&d->dv_hashtab, hi); 6264 dictitem_free(di); 6265 --todo; 6266 } 6267 } 6268 hash_clear(&d->dv_hashtab); 6269 vim_free(d); 6270 } 6271 6272 /* 6273 * Allocate a Dictionary item. 6274 * The "key" is copied to the new item. 6275 * Note that the value of the item "di_tv" still needs to be initialized! 6276 * Returns NULL when out of memory. 6277 */ 6278 static dictitem_T * 6279 dictitem_alloc(key) 6280 char_u *key; 6281 { 6282 dictitem_T *di; 6283 6284 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6285 if (di != NULL) 6286 { 6287 STRCPY(di->di_key, key); 6288 di->di_flags = 0; 6289 } 6290 return di; 6291 } 6292 6293 /* 6294 * Make a copy of a Dictionary item. 6295 */ 6296 static dictitem_T * 6297 dictitem_copy(org) 6298 dictitem_T *org; 6299 { 6300 dictitem_T *di; 6301 6302 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6303 + STRLEN(org->di_key))); 6304 if (di != NULL) 6305 { 6306 STRCPY(di->di_key, org->di_key); 6307 di->di_flags = 0; 6308 copy_tv(&org->di_tv, &di->di_tv); 6309 } 6310 return di; 6311 } 6312 6313 /* 6314 * Remove item "item" from Dictionary "dict" and free it. 6315 */ 6316 static void 6317 dictitem_remove(dict, item) 6318 dict_T *dict; 6319 dictitem_T *item; 6320 { 6321 hashitem_T *hi; 6322 6323 hi = hash_find(&dict->dv_hashtab, item->di_key); 6324 if (HASHITEM_EMPTY(hi)) 6325 EMSG2(_(e_intern2), "dictitem_remove()"); 6326 else 6327 hash_remove(&dict->dv_hashtab, hi); 6328 dictitem_free(item); 6329 } 6330 6331 /* 6332 * Free a dict item. Also clears the value. 6333 */ 6334 static void 6335 dictitem_free(item) 6336 dictitem_T *item; 6337 { 6338 clear_tv(&item->di_tv); 6339 vim_free(item); 6340 } 6341 6342 /* 6343 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6344 * The refcount of the new dict is set to 1. 6345 * See item_copy() for "copyID". 6346 * Returns NULL when out of memory. 6347 */ 6348 static dict_T * 6349 dict_copy(orig, deep, copyID) 6350 dict_T *orig; 6351 int deep; 6352 int copyID; 6353 { 6354 dict_T *copy; 6355 dictitem_T *di; 6356 int todo; 6357 hashitem_T *hi; 6358 6359 if (orig == NULL) 6360 return NULL; 6361 6362 copy = dict_alloc(); 6363 if (copy != NULL) 6364 { 6365 if (copyID != 0) 6366 { 6367 orig->dv_copyID = copyID; 6368 orig->dv_copydict = copy; 6369 } 6370 todo = (int)orig->dv_hashtab.ht_used; 6371 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6372 { 6373 if (!HASHITEM_EMPTY(hi)) 6374 { 6375 --todo; 6376 6377 di = dictitem_alloc(hi->hi_key); 6378 if (di == NULL) 6379 break; 6380 if (deep) 6381 { 6382 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6383 copyID) == FAIL) 6384 { 6385 vim_free(di); 6386 break; 6387 } 6388 } 6389 else 6390 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6391 if (dict_add(copy, di) == FAIL) 6392 { 6393 dictitem_free(di); 6394 break; 6395 } 6396 } 6397 } 6398 6399 ++copy->dv_refcount; 6400 if (todo > 0) 6401 { 6402 dict_unref(copy); 6403 copy = NULL; 6404 } 6405 } 6406 6407 return copy; 6408 } 6409 6410 /* 6411 * Add item "item" to Dictionary "d". 6412 * Returns FAIL when out of memory and when key already existed. 6413 */ 6414 static int 6415 dict_add(d, item) 6416 dict_T *d; 6417 dictitem_T *item; 6418 { 6419 return hash_add(&d->dv_hashtab, item->di_key); 6420 } 6421 6422 /* 6423 * Add a number or string entry to dictionary "d". 6424 * When "str" is NULL use number "nr", otherwise use "str". 6425 * Returns FAIL when out of memory and when key already exists. 6426 */ 6427 int 6428 dict_add_nr_str(d, key, nr, str) 6429 dict_T *d; 6430 char *key; 6431 long nr; 6432 char_u *str; 6433 { 6434 dictitem_T *item; 6435 6436 item = dictitem_alloc((char_u *)key); 6437 if (item == NULL) 6438 return FAIL; 6439 item->di_tv.v_lock = 0; 6440 if (str == NULL) 6441 { 6442 item->di_tv.v_type = VAR_NUMBER; 6443 item->di_tv.vval.v_number = nr; 6444 } 6445 else 6446 { 6447 item->di_tv.v_type = VAR_STRING; 6448 item->di_tv.vval.v_string = vim_strsave(str); 6449 } 6450 if (dict_add(d, item) == FAIL) 6451 { 6452 dictitem_free(item); 6453 return FAIL; 6454 } 6455 return OK; 6456 } 6457 6458 /* 6459 * Get the number of items in a Dictionary. 6460 */ 6461 static long 6462 dict_len(d) 6463 dict_T *d; 6464 { 6465 if (d == NULL) 6466 return 0L; 6467 return (long)d->dv_hashtab.ht_used; 6468 } 6469 6470 /* 6471 * Find item "key[len]" in Dictionary "d". 6472 * If "len" is negative use strlen(key). 6473 * Returns NULL when not found. 6474 */ 6475 static dictitem_T * 6476 dict_find(d, key, len) 6477 dict_T *d; 6478 char_u *key; 6479 int len; 6480 { 6481 #define AKEYLEN 200 6482 char_u buf[AKEYLEN]; 6483 char_u *akey; 6484 char_u *tofree = NULL; 6485 hashitem_T *hi; 6486 6487 if (len < 0) 6488 akey = key; 6489 else if (len >= AKEYLEN) 6490 { 6491 tofree = akey = vim_strnsave(key, len); 6492 if (akey == NULL) 6493 return NULL; 6494 } 6495 else 6496 { 6497 /* Avoid a malloc/free by using buf[]. */ 6498 vim_strncpy(buf, key, len); 6499 akey = buf; 6500 } 6501 6502 hi = hash_find(&d->dv_hashtab, akey); 6503 vim_free(tofree); 6504 if (HASHITEM_EMPTY(hi)) 6505 return NULL; 6506 return HI2DI(hi); 6507 } 6508 6509 /* 6510 * Get a string item from a dictionary. 6511 * When "save" is TRUE allocate memory for it. 6512 * Returns NULL if the entry doesn't exist or out of memory. 6513 */ 6514 char_u * 6515 get_dict_string(d, key, save) 6516 dict_T *d; 6517 char_u *key; 6518 int save; 6519 { 6520 dictitem_T *di; 6521 char_u *s; 6522 6523 di = dict_find(d, key, -1); 6524 if (di == NULL) 6525 return NULL; 6526 s = get_tv_string(&di->di_tv); 6527 if (save && s != NULL) 6528 s = vim_strsave(s); 6529 return s; 6530 } 6531 6532 /* 6533 * Get a number item from a dictionary. 6534 * Returns 0 if the entry doesn't exist or out of memory. 6535 */ 6536 long 6537 get_dict_number(d, key) 6538 dict_T *d; 6539 char_u *key; 6540 { 6541 dictitem_T *di; 6542 6543 di = dict_find(d, key, -1); 6544 if (di == NULL) 6545 return 0; 6546 return get_tv_number(&di->di_tv); 6547 } 6548 6549 /* 6550 * Return an allocated string with the string representation of a Dictionary. 6551 * May return NULL. 6552 */ 6553 static char_u * 6554 dict2string(tv, copyID) 6555 typval_T *tv; 6556 int copyID; 6557 { 6558 garray_T ga; 6559 int first = TRUE; 6560 char_u *tofree; 6561 char_u numbuf[NUMBUFLEN]; 6562 hashitem_T *hi; 6563 char_u *s; 6564 dict_T *d; 6565 int todo; 6566 6567 if ((d = tv->vval.v_dict) == NULL) 6568 return NULL; 6569 ga_init2(&ga, (int)sizeof(char), 80); 6570 ga_append(&ga, '{'); 6571 6572 todo = (int)d->dv_hashtab.ht_used; 6573 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6574 { 6575 if (!HASHITEM_EMPTY(hi)) 6576 { 6577 --todo; 6578 6579 if (first) 6580 first = FALSE; 6581 else 6582 ga_concat(&ga, (char_u *)", "); 6583 6584 tofree = string_quote(hi->hi_key, FALSE); 6585 if (tofree != NULL) 6586 { 6587 ga_concat(&ga, tofree); 6588 vim_free(tofree); 6589 } 6590 ga_concat(&ga, (char_u *)": "); 6591 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 6592 if (s != NULL) 6593 ga_concat(&ga, s); 6594 vim_free(tofree); 6595 if (s == NULL) 6596 break; 6597 } 6598 } 6599 if (todo > 0) 6600 { 6601 vim_free(ga.ga_data); 6602 return NULL; 6603 } 6604 6605 ga_append(&ga, '}'); 6606 ga_append(&ga, NUL); 6607 return (char_u *)ga.ga_data; 6608 } 6609 6610 /* 6611 * Allocate a variable for a Dictionary and fill it from "*arg". 6612 * Return OK or FAIL. Returns NOTDONE for {expr}. 6613 */ 6614 static int 6615 get_dict_tv(arg, rettv, evaluate) 6616 char_u **arg; 6617 typval_T *rettv; 6618 int evaluate; 6619 { 6620 dict_T *d = NULL; 6621 typval_T tvkey; 6622 typval_T tv; 6623 char_u *key; 6624 dictitem_T *item; 6625 char_u *start = skipwhite(*arg + 1); 6626 char_u buf[NUMBUFLEN]; 6627 6628 /* 6629 * First check if it's not a curly-braces thing: {expr}. 6630 * Must do this without evaluating, otherwise a function may be called 6631 * twice. Unfortunately this means we need to call eval1() twice for the 6632 * first item. 6633 * But {} is an empty Dictionary. 6634 */ 6635 if (*start != '}') 6636 { 6637 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6638 return FAIL; 6639 if (*start == '}') 6640 return NOTDONE; 6641 } 6642 6643 if (evaluate) 6644 { 6645 d = dict_alloc(); 6646 if (d == NULL) 6647 return FAIL; 6648 } 6649 tvkey.v_type = VAR_UNKNOWN; 6650 tv.v_type = VAR_UNKNOWN; 6651 6652 *arg = skipwhite(*arg + 1); 6653 while (**arg != '}' && **arg != NUL) 6654 { 6655 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6656 goto failret; 6657 if (**arg != ':') 6658 { 6659 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6660 clear_tv(&tvkey); 6661 goto failret; 6662 } 6663 key = get_tv_string_buf_chk(&tvkey, buf); 6664 if (key == NULL || *key == NUL) 6665 { 6666 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6667 if (key != NULL) 6668 EMSG(_(e_emptykey)); 6669 clear_tv(&tvkey); 6670 goto failret; 6671 } 6672 6673 *arg = skipwhite(*arg + 1); 6674 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6675 { 6676 clear_tv(&tvkey); 6677 goto failret; 6678 } 6679 if (evaluate) 6680 { 6681 item = dict_find(d, key, -1); 6682 if (item != NULL) 6683 { 6684 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6685 clear_tv(&tvkey); 6686 clear_tv(&tv); 6687 goto failret; 6688 } 6689 item = dictitem_alloc(key); 6690 clear_tv(&tvkey); 6691 if (item != NULL) 6692 { 6693 item->di_tv = tv; 6694 item->di_tv.v_lock = 0; 6695 if (dict_add(d, item) == FAIL) 6696 dictitem_free(item); 6697 } 6698 } 6699 6700 if (**arg == '}') 6701 break; 6702 if (**arg != ',') 6703 { 6704 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6705 goto failret; 6706 } 6707 *arg = skipwhite(*arg + 1); 6708 } 6709 6710 if (**arg != '}') 6711 { 6712 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6713 failret: 6714 if (evaluate) 6715 dict_free(d); 6716 return FAIL; 6717 } 6718 6719 *arg = skipwhite(*arg + 1); 6720 if (evaluate) 6721 { 6722 rettv->v_type = VAR_DICT; 6723 rettv->vval.v_dict = d; 6724 ++d->dv_refcount; 6725 } 6726 6727 return OK; 6728 } 6729 6730 /* 6731 * Return a string with the string representation of a variable. 6732 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6733 * "numbuf" is used for a number. 6734 * Does not put quotes around strings, as ":echo" displays values. 6735 * When "copyID" is not NULL replace recursive lists and dicts with "...". 6736 * May return NULL; 6737 */ 6738 static char_u * 6739 echo_string(tv, tofree, numbuf, copyID) 6740 typval_T *tv; 6741 char_u **tofree; 6742 char_u *numbuf; 6743 int copyID; 6744 { 6745 static int recurse = 0; 6746 char_u *r = NULL; 6747 6748 if (recurse >= DICT_MAXNEST) 6749 { 6750 EMSG(_("E724: variable nested too deep for displaying")); 6751 *tofree = NULL; 6752 return NULL; 6753 } 6754 ++recurse; 6755 6756 switch (tv->v_type) 6757 { 6758 case VAR_FUNC: 6759 *tofree = NULL; 6760 r = tv->vval.v_string; 6761 break; 6762 6763 case VAR_LIST: 6764 if (tv->vval.v_list == NULL) 6765 { 6766 *tofree = NULL; 6767 r = NULL; 6768 } 6769 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 6770 { 6771 *tofree = NULL; 6772 r = (char_u *)"[...]"; 6773 } 6774 else 6775 { 6776 tv->vval.v_list->lv_copyID = copyID; 6777 *tofree = list2string(tv, copyID); 6778 r = *tofree; 6779 } 6780 break; 6781 6782 case VAR_DICT: 6783 if (tv->vval.v_dict == NULL) 6784 { 6785 *tofree = NULL; 6786 r = NULL; 6787 } 6788 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 6789 { 6790 *tofree = NULL; 6791 r = (char_u *)"{...}"; 6792 } 6793 else 6794 { 6795 tv->vval.v_dict->dv_copyID = copyID; 6796 *tofree = dict2string(tv, copyID); 6797 r = *tofree; 6798 } 6799 break; 6800 6801 case VAR_STRING: 6802 case VAR_NUMBER: 6803 *tofree = NULL; 6804 r = get_tv_string_buf(tv, numbuf); 6805 break; 6806 6807 default: 6808 EMSG2(_(e_intern2), "echo_string()"); 6809 *tofree = NULL; 6810 } 6811 6812 --recurse; 6813 return r; 6814 } 6815 6816 /* 6817 * Return a string with the string representation of a variable. 6818 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6819 * "numbuf" is used for a number. 6820 * Puts quotes around strings, so that they can be parsed back by eval(). 6821 * May return NULL; 6822 */ 6823 static char_u * 6824 tv2string(tv, tofree, numbuf, copyID) 6825 typval_T *tv; 6826 char_u **tofree; 6827 char_u *numbuf; 6828 int copyID; 6829 { 6830 switch (tv->v_type) 6831 { 6832 case VAR_FUNC: 6833 *tofree = string_quote(tv->vval.v_string, TRUE); 6834 return *tofree; 6835 case VAR_STRING: 6836 *tofree = string_quote(tv->vval.v_string, FALSE); 6837 return *tofree; 6838 case VAR_NUMBER: 6839 case VAR_LIST: 6840 case VAR_DICT: 6841 break; 6842 default: 6843 EMSG2(_(e_intern2), "tv2string()"); 6844 } 6845 return echo_string(tv, tofree, numbuf, copyID); 6846 } 6847 6848 /* 6849 * Return string "str" in ' quotes, doubling ' characters. 6850 * If "str" is NULL an empty string is assumed. 6851 * If "function" is TRUE make it function('string'). 6852 */ 6853 static char_u * 6854 string_quote(str, function) 6855 char_u *str; 6856 int function; 6857 { 6858 unsigned len; 6859 char_u *p, *r, *s; 6860 6861 len = (function ? 13 : 3); 6862 if (str != NULL) 6863 { 6864 len += (unsigned)STRLEN(str); 6865 for (p = str; *p != NUL; mb_ptr_adv(p)) 6866 if (*p == '\'') 6867 ++len; 6868 } 6869 s = r = alloc(len); 6870 if (r != NULL) 6871 { 6872 if (function) 6873 { 6874 STRCPY(r, "function('"); 6875 r += 10; 6876 } 6877 else 6878 *r++ = '\''; 6879 if (str != NULL) 6880 for (p = str; *p != NUL; ) 6881 { 6882 if (*p == '\'') 6883 *r++ = '\''; 6884 MB_COPY_CHAR(p, r); 6885 } 6886 *r++ = '\''; 6887 if (function) 6888 *r++ = ')'; 6889 *r++ = NUL; 6890 } 6891 return s; 6892 } 6893 6894 /* 6895 * Get the value of an environment variable. 6896 * "arg" is pointing to the '$'. It is advanced to after the name. 6897 * If the environment variable was not set, silently assume it is empty. 6898 * Always return OK. 6899 */ 6900 static int 6901 get_env_tv(arg, rettv, evaluate) 6902 char_u **arg; 6903 typval_T *rettv; 6904 int evaluate; 6905 { 6906 char_u *string = NULL; 6907 int len; 6908 int cc; 6909 char_u *name; 6910 int mustfree = FALSE; 6911 6912 ++*arg; 6913 name = *arg; 6914 len = get_env_len(arg); 6915 if (evaluate) 6916 { 6917 if (len != 0) 6918 { 6919 cc = name[len]; 6920 name[len] = NUL; 6921 /* first try vim_getenv(), fast for normal environment vars */ 6922 string = vim_getenv(name, &mustfree); 6923 if (string != NULL && *string != NUL) 6924 { 6925 if (!mustfree) 6926 string = vim_strsave(string); 6927 } 6928 else 6929 { 6930 if (mustfree) 6931 vim_free(string); 6932 6933 /* next try expanding things like $VIM and ${HOME} */ 6934 string = expand_env_save(name - 1); 6935 if (string != NULL && *string == '$') 6936 { 6937 vim_free(string); 6938 string = NULL; 6939 } 6940 } 6941 name[len] = cc; 6942 } 6943 rettv->v_type = VAR_STRING; 6944 rettv->vval.v_string = string; 6945 } 6946 6947 return OK; 6948 } 6949 6950 /* 6951 * Array with names and number of arguments of all internal functions 6952 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6953 */ 6954 static struct fst 6955 { 6956 char *f_name; /* function name */ 6957 char f_min_argc; /* minimal number of arguments */ 6958 char f_max_argc; /* maximal number of arguments */ 6959 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6960 /* implemenation of function */ 6961 } functions[] = 6962 { 6963 {"add", 2, 2, f_add}, 6964 {"append", 2, 2, f_append}, 6965 {"argc", 0, 0, f_argc}, 6966 {"argidx", 0, 0, f_argidx}, 6967 {"argv", 0, 1, f_argv}, 6968 {"browse", 4, 4, f_browse}, 6969 {"browsedir", 2, 2, f_browsedir}, 6970 {"bufexists", 1, 1, f_bufexists}, 6971 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6972 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6973 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6974 {"buflisted", 1, 1, f_buflisted}, 6975 {"bufloaded", 1, 1, f_bufloaded}, 6976 {"bufname", 1, 1, f_bufname}, 6977 {"bufnr", 1, 2, f_bufnr}, 6978 {"bufwinnr", 1, 1, f_bufwinnr}, 6979 {"byte2line", 1, 1, f_byte2line}, 6980 {"byteidx", 2, 2, f_byteidx}, 6981 {"call", 2, 3, f_call}, 6982 {"changenr", 0, 0, f_changenr}, 6983 {"char2nr", 1, 1, f_char2nr}, 6984 {"cindent", 1, 1, f_cindent}, 6985 {"col", 1, 1, f_col}, 6986 #if defined(FEAT_INS_EXPAND) 6987 {"complete", 2, 2, f_complete}, 6988 {"complete_add", 1, 1, f_complete_add}, 6989 {"complete_check", 0, 0, f_complete_check}, 6990 #endif 6991 {"confirm", 1, 4, f_confirm}, 6992 {"copy", 1, 1, f_copy}, 6993 {"count", 2, 4, f_count}, 6994 {"cscope_connection",0,3, f_cscope_connection}, 6995 {"cursor", 1, 3, f_cursor}, 6996 {"deepcopy", 1, 2, f_deepcopy}, 6997 {"delete", 1, 1, f_delete}, 6998 {"did_filetype", 0, 0, f_did_filetype}, 6999 {"diff_filler", 1, 1, f_diff_filler}, 7000 {"diff_hlID", 2, 2, f_diff_hlID}, 7001 {"empty", 1, 1, f_empty}, 7002 {"escape", 2, 2, f_escape}, 7003 {"eval", 1, 1, f_eval}, 7004 {"eventhandler", 0, 0, f_eventhandler}, 7005 {"executable", 1, 1, f_executable}, 7006 {"exists", 1, 1, f_exists}, 7007 {"expand", 1, 2, f_expand}, 7008 {"extend", 2, 3, f_extend}, 7009 {"feedkeys", 1, 2, f_feedkeys}, 7010 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7011 {"filereadable", 1, 1, f_filereadable}, 7012 {"filewritable", 1, 1, f_filewritable}, 7013 {"filter", 2, 2, f_filter}, 7014 {"finddir", 1, 3, f_finddir}, 7015 {"findfile", 1, 3, f_findfile}, 7016 {"fnamemodify", 2, 2, f_fnamemodify}, 7017 {"foldclosed", 1, 1, f_foldclosed}, 7018 {"foldclosedend", 1, 1, f_foldclosedend}, 7019 {"foldlevel", 1, 1, f_foldlevel}, 7020 {"foldtext", 0, 0, f_foldtext}, 7021 {"foldtextresult", 1, 1, f_foldtextresult}, 7022 {"foreground", 0, 0, f_foreground}, 7023 {"function", 1, 1, f_function}, 7024 {"garbagecollect", 0, 0, f_garbagecollect}, 7025 {"get", 2, 3, f_get}, 7026 {"getbufline", 2, 3, f_getbufline}, 7027 {"getbufvar", 2, 2, f_getbufvar}, 7028 {"getchar", 0, 1, f_getchar}, 7029 {"getcharmod", 0, 0, f_getcharmod}, 7030 {"getcmdline", 0, 0, f_getcmdline}, 7031 {"getcmdpos", 0, 0, f_getcmdpos}, 7032 {"getcmdtype", 0, 0, f_getcmdtype}, 7033 {"getcwd", 0, 0, f_getcwd}, 7034 {"getfontname", 0, 1, f_getfontname}, 7035 {"getfperm", 1, 1, f_getfperm}, 7036 {"getfsize", 1, 1, f_getfsize}, 7037 {"getftime", 1, 1, f_getftime}, 7038 {"getftype", 1, 1, f_getftype}, 7039 {"getline", 1, 2, f_getline}, 7040 {"getloclist", 1, 1, f_getqflist}, 7041 {"getpos", 1, 1, f_getpos}, 7042 {"getqflist", 0, 0, f_getqflist}, 7043 {"getreg", 0, 2, f_getreg}, 7044 {"getregtype", 0, 1, f_getregtype}, 7045 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7046 {"getwinposx", 0, 0, f_getwinposx}, 7047 {"getwinposy", 0, 0, f_getwinposy}, 7048 {"getwinvar", 2, 2, f_getwinvar}, 7049 {"glob", 1, 1, f_glob}, 7050 {"globpath", 2, 2, f_globpath}, 7051 {"has", 1, 1, f_has}, 7052 {"has_key", 2, 2, f_has_key}, 7053 {"hasmapto", 1, 3, f_hasmapto}, 7054 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7055 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7056 {"histadd", 2, 2, f_histadd}, 7057 {"histdel", 1, 2, f_histdel}, 7058 {"histget", 1, 2, f_histget}, 7059 {"histnr", 1, 1, f_histnr}, 7060 {"hlID", 1, 1, f_hlID}, 7061 {"hlexists", 1, 1, f_hlexists}, 7062 {"hostname", 0, 0, f_hostname}, 7063 {"iconv", 3, 3, f_iconv}, 7064 {"indent", 1, 1, f_indent}, 7065 {"index", 2, 4, f_index}, 7066 {"input", 1, 3, f_input}, 7067 {"inputdialog", 1, 3, f_inputdialog}, 7068 {"inputlist", 1, 1, f_inputlist}, 7069 {"inputrestore", 0, 0, f_inputrestore}, 7070 {"inputsave", 0, 0, f_inputsave}, 7071 {"inputsecret", 1, 2, f_inputsecret}, 7072 {"insert", 2, 3, f_insert}, 7073 {"isdirectory", 1, 1, f_isdirectory}, 7074 {"islocked", 1, 1, f_islocked}, 7075 {"items", 1, 1, f_items}, 7076 {"join", 1, 2, f_join}, 7077 {"keys", 1, 1, f_keys}, 7078 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7079 {"len", 1, 1, f_len}, 7080 {"libcall", 3, 3, f_libcall}, 7081 {"libcallnr", 3, 3, f_libcallnr}, 7082 {"line", 1, 1, f_line}, 7083 {"line2byte", 1, 1, f_line2byte}, 7084 {"lispindent", 1, 1, f_lispindent}, 7085 {"localtime", 0, 0, f_localtime}, 7086 {"map", 2, 2, f_map}, 7087 {"maparg", 1, 3, f_maparg}, 7088 {"mapcheck", 1, 3, f_mapcheck}, 7089 {"match", 2, 4, f_match}, 7090 {"matcharg", 1, 1, f_matcharg}, 7091 {"matchend", 2, 4, f_matchend}, 7092 {"matchlist", 2, 4, f_matchlist}, 7093 {"matchstr", 2, 4, f_matchstr}, 7094 {"max", 1, 1, f_max}, 7095 {"min", 1, 1, f_min}, 7096 #ifdef vim_mkdir 7097 {"mkdir", 1, 3, f_mkdir}, 7098 #endif 7099 {"mode", 0, 0, f_mode}, 7100 {"nextnonblank", 1, 1, f_nextnonblank}, 7101 {"nr2char", 1, 1, f_nr2char}, 7102 {"pathshorten", 1, 1, f_pathshorten}, 7103 {"prevnonblank", 1, 1, f_prevnonblank}, 7104 {"printf", 2, 19, f_printf}, 7105 {"pumvisible", 0, 0, f_pumvisible}, 7106 {"range", 1, 3, f_range}, 7107 {"readfile", 1, 3, f_readfile}, 7108 {"reltime", 0, 2, f_reltime}, 7109 {"reltimestr", 1, 1, f_reltimestr}, 7110 {"remote_expr", 2, 3, f_remote_expr}, 7111 {"remote_foreground", 1, 1, f_remote_foreground}, 7112 {"remote_peek", 1, 2, f_remote_peek}, 7113 {"remote_read", 1, 1, f_remote_read}, 7114 {"remote_send", 2, 3, f_remote_send}, 7115 {"remove", 2, 3, f_remove}, 7116 {"rename", 2, 2, f_rename}, 7117 {"repeat", 2, 2, f_repeat}, 7118 {"resolve", 1, 1, f_resolve}, 7119 {"reverse", 1, 1, f_reverse}, 7120 {"search", 1, 3, f_search}, 7121 {"searchdecl", 1, 3, f_searchdecl}, 7122 {"searchpair", 3, 6, f_searchpair}, 7123 {"searchpairpos", 3, 6, f_searchpairpos}, 7124 {"searchpos", 1, 3, f_searchpos}, 7125 {"server2client", 2, 2, f_server2client}, 7126 {"serverlist", 0, 0, f_serverlist}, 7127 {"setbufvar", 3, 3, f_setbufvar}, 7128 {"setcmdpos", 1, 1, f_setcmdpos}, 7129 {"setline", 2, 2, f_setline}, 7130 {"setloclist", 2, 3, f_setloclist}, 7131 {"setpos", 2, 2, f_setpos}, 7132 {"setqflist", 1, 2, f_setqflist}, 7133 {"setreg", 2, 3, f_setreg}, 7134 {"settabwinvar", 4, 4, f_settabwinvar}, 7135 {"setwinvar", 3, 3, f_setwinvar}, 7136 {"simplify", 1, 1, f_simplify}, 7137 {"sort", 1, 2, f_sort}, 7138 {"soundfold", 1, 1, f_soundfold}, 7139 {"spellbadword", 0, 1, f_spellbadword}, 7140 {"spellsuggest", 1, 3, f_spellsuggest}, 7141 {"split", 1, 3, f_split}, 7142 {"str2nr", 1, 2, f_str2nr}, 7143 #ifdef HAVE_STRFTIME 7144 {"strftime", 1, 2, f_strftime}, 7145 #endif 7146 {"stridx", 2, 3, f_stridx}, 7147 {"string", 1, 1, f_string}, 7148 {"strlen", 1, 1, f_strlen}, 7149 {"strpart", 2, 3, f_strpart}, 7150 {"strridx", 2, 3, f_strridx}, 7151 {"strtrans", 1, 1, f_strtrans}, 7152 {"submatch", 1, 1, f_submatch}, 7153 {"substitute", 4, 4, f_substitute}, 7154 {"synID", 3, 3, f_synID}, 7155 {"synIDattr", 2, 3, f_synIDattr}, 7156 {"synIDtrans", 1, 1, f_synIDtrans}, 7157 {"system", 1, 2, f_system}, 7158 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7159 {"tabpagenr", 0, 1, f_tabpagenr}, 7160 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7161 {"tagfiles", 0, 0, f_tagfiles}, 7162 {"taglist", 1, 1, f_taglist}, 7163 {"tempname", 0, 0, f_tempname}, 7164 {"test", 1, 1, f_test}, 7165 {"tolower", 1, 1, f_tolower}, 7166 {"toupper", 1, 1, f_toupper}, 7167 {"tr", 3, 3, f_tr}, 7168 {"type", 1, 1, f_type}, 7169 {"values", 1, 1, f_values}, 7170 {"virtcol", 1, 1, f_virtcol}, 7171 {"visualmode", 0, 1, f_visualmode}, 7172 {"winbufnr", 1, 1, f_winbufnr}, 7173 {"wincol", 0, 0, f_wincol}, 7174 {"winheight", 1, 1, f_winheight}, 7175 {"winline", 0, 0, f_winline}, 7176 {"winnr", 0, 1, f_winnr}, 7177 {"winrestcmd", 0, 0, f_winrestcmd}, 7178 {"winrestview", 1, 1, f_winrestview}, 7179 {"winsaveview", 0, 0, f_winsaveview}, 7180 {"winwidth", 1, 1, f_winwidth}, 7181 {"writefile", 2, 3, f_writefile}, 7182 }; 7183 7184 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7185 7186 /* 7187 * Function given to ExpandGeneric() to obtain the list of internal 7188 * or user defined function names. 7189 */ 7190 char_u * 7191 get_function_name(xp, idx) 7192 expand_T *xp; 7193 int idx; 7194 { 7195 static int intidx = -1; 7196 char_u *name; 7197 7198 if (idx == 0) 7199 intidx = -1; 7200 if (intidx < 0) 7201 { 7202 name = get_user_func_name(xp, idx); 7203 if (name != NULL) 7204 return name; 7205 } 7206 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7207 { 7208 STRCPY(IObuff, functions[intidx].f_name); 7209 STRCAT(IObuff, "("); 7210 if (functions[intidx].f_max_argc == 0) 7211 STRCAT(IObuff, ")"); 7212 return IObuff; 7213 } 7214 7215 return NULL; 7216 } 7217 7218 /* 7219 * Function given to ExpandGeneric() to obtain the list of internal or 7220 * user defined variable or function names. 7221 */ 7222 /*ARGSUSED*/ 7223 char_u * 7224 get_expr_name(xp, idx) 7225 expand_T *xp; 7226 int idx; 7227 { 7228 static int intidx = -1; 7229 char_u *name; 7230 7231 if (idx == 0) 7232 intidx = -1; 7233 if (intidx < 0) 7234 { 7235 name = get_function_name(xp, idx); 7236 if (name != NULL) 7237 return name; 7238 } 7239 return get_user_var_name(xp, ++intidx); 7240 } 7241 7242 #endif /* FEAT_CMDL_COMPL */ 7243 7244 /* 7245 * Find internal function in table above. 7246 * Return index, or -1 if not found 7247 */ 7248 static int 7249 find_internal_func(name) 7250 char_u *name; /* name of the function */ 7251 { 7252 int first = 0; 7253 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7254 int cmp; 7255 int x; 7256 7257 /* 7258 * Find the function name in the table. Binary search. 7259 */ 7260 while (first <= last) 7261 { 7262 x = first + ((unsigned)(last - first) >> 1); 7263 cmp = STRCMP(name, functions[x].f_name); 7264 if (cmp < 0) 7265 last = x - 1; 7266 else if (cmp > 0) 7267 first = x + 1; 7268 else 7269 return x; 7270 } 7271 return -1; 7272 } 7273 7274 /* 7275 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7276 * name it contains, otherwise return "name". 7277 */ 7278 static char_u * 7279 deref_func_name(name, lenp) 7280 char_u *name; 7281 int *lenp; 7282 { 7283 dictitem_T *v; 7284 int cc; 7285 7286 cc = name[*lenp]; 7287 name[*lenp] = NUL; 7288 v = find_var(name, NULL); 7289 name[*lenp] = cc; 7290 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7291 { 7292 if (v->di_tv.vval.v_string == NULL) 7293 { 7294 *lenp = 0; 7295 return (char_u *)""; /* just in case */ 7296 } 7297 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 7298 return v->di_tv.vval.v_string; 7299 } 7300 7301 return name; 7302 } 7303 7304 /* 7305 * Allocate a variable for the result of a function. 7306 * Return OK or FAIL. 7307 */ 7308 static int 7309 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7310 evaluate, selfdict) 7311 char_u *name; /* name of the function */ 7312 int len; /* length of "name" */ 7313 typval_T *rettv; 7314 char_u **arg; /* argument, pointing to the '(' */ 7315 linenr_T firstline; /* first line of range */ 7316 linenr_T lastline; /* last line of range */ 7317 int *doesrange; /* return: function handled range */ 7318 int evaluate; 7319 dict_T *selfdict; /* Dictionary for "self" */ 7320 { 7321 char_u *argp; 7322 int ret = OK; 7323 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 7324 int argcount = 0; /* number of arguments found */ 7325 7326 /* 7327 * Get the arguments. 7328 */ 7329 argp = *arg; 7330 while (argcount < MAX_FUNC_ARGS) 7331 { 7332 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7333 if (*argp == ')' || *argp == ',' || *argp == NUL) 7334 break; 7335 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7336 { 7337 ret = FAIL; 7338 break; 7339 } 7340 ++argcount; 7341 if (*argp != ',') 7342 break; 7343 } 7344 if (*argp == ')') 7345 ++argp; 7346 else 7347 ret = FAIL; 7348 7349 if (ret == OK) 7350 ret = call_func(name, len, rettv, argcount, argvars, 7351 firstline, lastline, doesrange, evaluate, selfdict); 7352 else if (!aborting()) 7353 { 7354 if (argcount == MAX_FUNC_ARGS) 7355 emsg_funcname("E740: Too many arguments for function %s", name); 7356 else 7357 emsg_funcname("E116: Invalid arguments for function %s", name); 7358 } 7359 7360 while (--argcount >= 0) 7361 clear_tv(&argvars[argcount]); 7362 7363 *arg = skipwhite(argp); 7364 return ret; 7365 } 7366 7367 7368 /* 7369 * Call a function with its resolved parameters 7370 * Return OK when the function can't be called, FAIL otherwise. 7371 * Also returns OK when an error was encountered while executing the function. 7372 */ 7373 static int 7374 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7375 doesrange, evaluate, selfdict) 7376 char_u *name; /* name of the function */ 7377 int len; /* length of "name" */ 7378 typval_T *rettv; /* return value goes here */ 7379 int argcount; /* number of "argvars" */ 7380 typval_T *argvars; /* vars for arguments, must have "argcount" 7381 PLUS ONE elements! */ 7382 linenr_T firstline; /* first line of range */ 7383 linenr_T lastline; /* last line of range */ 7384 int *doesrange; /* return: function handled range */ 7385 int evaluate; 7386 dict_T *selfdict; /* Dictionary for "self" */ 7387 { 7388 int ret = FAIL; 7389 #define ERROR_UNKNOWN 0 7390 #define ERROR_TOOMANY 1 7391 #define ERROR_TOOFEW 2 7392 #define ERROR_SCRIPT 3 7393 #define ERROR_DICT 4 7394 #define ERROR_NONE 5 7395 #define ERROR_OTHER 6 7396 int error = ERROR_NONE; 7397 int i; 7398 int llen; 7399 ufunc_T *fp; 7400 int cc; 7401 #define FLEN_FIXED 40 7402 char_u fname_buf[FLEN_FIXED + 1]; 7403 char_u *fname; 7404 7405 /* 7406 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7407 * Change <SNR>123_name() to K_SNR 123_name(). 7408 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7409 */ 7410 cc = name[len]; 7411 name[len] = NUL; 7412 llen = eval_fname_script(name); 7413 if (llen > 0) 7414 { 7415 fname_buf[0] = K_SPECIAL; 7416 fname_buf[1] = KS_EXTRA; 7417 fname_buf[2] = (int)KE_SNR; 7418 i = 3; 7419 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7420 { 7421 if (current_SID <= 0) 7422 error = ERROR_SCRIPT; 7423 else 7424 { 7425 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7426 i = (int)STRLEN(fname_buf); 7427 } 7428 } 7429 if (i + STRLEN(name + llen) < FLEN_FIXED) 7430 { 7431 STRCPY(fname_buf + i, name + llen); 7432 fname = fname_buf; 7433 } 7434 else 7435 { 7436 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7437 if (fname == NULL) 7438 error = ERROR_OTHER; 7439 else 7440 { 7441 mch_memmove(fname, fname_buf, (size_t)i); 7442 STRCPY(fname + i, name + llen); 7443 } 7444 } 7445 } 7446 else 7447 fname = name; 7448 7449 *doesrange = FALSE; 7450 7451 7452 /* execute the function if no errors detected and executing */ 7453 if (evaluate && error == ERROR_NONE) 7454 { 7455 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7456 error = ERROR_UNKNOWN; 7457 7458 if (!builtin_function(fname)) 7459 { 7460 /* 7461 * User defined function. 7462 */ 7463 fp = find_func(fname); 7464 7465 #ifdef FEAT_AUTOCMD 7466 /* Trigger FuncUndefined event, may load the function. */ 7467 if (fp == NULL 7468 && apply_autocmds(EVENT_FUNCUNDEFINED, 7469 fname, fname, TRUE, NULL) 7470 && !aborting()) 7471 { 7472 /* executed an autocommand, search for the function again */ 7473 fp = find_func(fname); 7474 } 7475 #endif 7476 /* Try loading a package. */ 7477 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7478 { 7479 /* loaded a package, search for the function again */ 7480 fp = find_func(fname); 7481 } 7482 7483 if (fp != NULL) 7484 { 7485 if (fp->uf_flags & FC_RANGE) 7486 *doesrange = TRUE; 7487 if (argcount < fp->uf_args.ga_len) 7488 error = ERROR_TOOFEW; 7489 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7490 error = ERROR_TOOMANY; 7491 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7492 error = ERROR_DICT; 7493 else 7494 { 7495 /* 7496 * Call the user function. 7497 * Save and restore search patterns, script variables and 7498 * redo buffer. 7499 */ 7500 save_search_patterns(); 7501 saveRedobuff(); 7502 ++fp->uf_calls; 7503 call_user_func(fp, argcount, argvars, rettv, 7504 firstline, lastline, 7505 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7506 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7507 && fp->uf_refcount <= 0) 7508 /* Function was unreferenced while being used, free it 7509 * now. */ 7510 func_free(fp); 7511 restoreRedobuff(); 7512 restore_search_patterns(); 7513 error = ERROR_NONE; 7514 } 7515 } 7516 } 7517 else 7518 { 7519 /* 7520 * Find the function name in the table, call its implementation. 7521 */ 7522 i = find_internal_func(fname); 7523 if (i >= 0) 7524 { 7525 if (argcount < functions[i].f_min_argc) 7526 error = ERROR_TOOFEW; 7527 else if (argcount > functions[i].f_max_argc) 7528 error = ERROR_TOOMANY; 7529 else 7530 { 7531 argvars[argcount].v_type = VAR_UNKNOWN; 7532 functions[i].f_func(argvars, rettv); 7533 error = ERROR_NONE; 7534 } 7535 } 7536 } 7537 /* 7538 * The function call (or "FuncUndefined" autocommand sequence) might 7539 * have been aborted by an error, an interrupt, or an explicitly thrown 7540 * exception that has not been caught so far. This situation can be 7541 * tested for by calling aborting(). For an error in an internal 7542 * function or for the "E132" error in call_user_func(), however, the 7543 * throw point at which the "force_abort" flag (temporarily reset by 7544 * emsg()) is normally updated has not been reached yet. We need to 7545 * update that flag first to make aborting() reliable. 7546 */ 7547 update_force_abort(); 7548 } 7549 if (error == ERROR_NONE) 7550 ret = OK; 7551 7552 /* 7553 * Report an error unless the argument evaluation or function call has been 7554 * cancelled due to an aborting error, an interrupt, or an exception. 7555 */ 7556 if (!aborting()) 7557 { 7558 switch (error) 7559 { 7560 case ERROR_UNKNOWN: 7561 emsg_funcname(N_("E117: Unknown function: %s"), name); 7562 break; 7563 case ERROR_TOOMANY: 7564 emsg_funcname(e_toomanyarg, name); 7565 break; 7566 case ERROR_TOOFEW: 7567 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 7568 name); 7569 break; 7570 case ERROR_SCRIPT: 7571 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 7572 name); 7573 break; 7574 case ERROR_DICT: 7575 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 7576 name); 7577 break; 7578 } 7579 } 7580 7581 name[len] = cc; 7582 if (fname != name && fname != fname_buf) 7583 vim_free(fname); 7584 7585 return ret; 7586 } 7587 7588 /* 7589 * Give an error message with a function name. Handle <SNR> things. 7590 */ 7591 static void 7592 emsg_funcname(msg, name) 7593 char *msg; 7594 char_u *name; 7595 { 7596 char_u *p; 7597 7598 if (*name == K_SPECIAL) 7599 p = concat_str((char_u *)"<SNR>", name + 3); 7600 else 7601 p = name; 7602 EMSG2(_(msg), p); 7603 if (p != name) 7604 vim_free(p); 7605 } 7606 7607 /********************************************* 7608 * Implementation of the built-in functions 7609 */ 7610 7611 /* 7612 * "add(list, item)" function 7613 */ 7614 static void 7615 f_add(argvars, rettv) 7616 typval_T *argvars; 7617 typval_T *rettv; 7618 { 7619 list_T *l; 7620 7621 rettv->vval.v_number = 1; /* Default: Failed */ 7622 if (argvars[0].v_type == VAR_LIST) 7623 { 7624 if ((l = argvars[0].vval.v_list) != NULL 7625 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7626 && list_append_tv(l, &argvars[1]) == OK) 7627 copy_tv(&argvars[0], rettv); 7628 } 7629 else 7630 EMSG(_(e_listreq)); 7631 } 7632 7633 /* 7634 * "append(lnum, string/list)" function 7635 */ 7636 static void 7637 f_append(argvars, rettv) 7638 typval_T *argvars; 7639 typval_T *rettv; 7640 { 7641 long lnum; 7642 char_u *line; 7643 list_T *l = NULL; 7644 listitem_T *li = NULL; 7645 typval_T *tv; 7646 long added = 0; 7647 7648 lnum = get_tv_lnum(argvars); 7649 if (lnum >= 0 7650 && lnum <= curbuf->b_ml.ml_line_count 7651 && u_save(lnum, lnum + 1) == OK) 7652 { 7653 if (argvars[1].v_type == VAR_LIST) 7654 { 7655 l = argvars[1].vval.v_list; 7656 if (l == NULL) 7657 return; 7658 li = l->lv_first; 7659 } 7660 rettv->vval.v_number = 0; /* Default: Success */ 7661 for (;;) 7662 { 7663 if (l == NULL) 7664 tv = &argvars[1]; /* append a string */ 7665 else if (li == NULL) 7666 break; /* end of list */ 7667 else 7668 tv = &li->li_tv; /* append item from list */ 7669 line = get_tv_string_chk(tv); 7670 if (line == NULL) /* type error */ 7671 { 7672 rettv->vval.v_number = 1; /* Failed */ 7673 break; 7674 } 7675 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7676 ++added; 7677 if (l == NULL) 7678 break; 7679 li = li->li_next; 7680 } 7681 7682 appended_lines_mark(lnum, added); 7683 if (curwin->w_cursor.lnum > lnum) 7684 curwin->w_cursor.lnum += added; 7685 } 7686 else 7687 rettv->vval.v_number = 1; /* Failed */ 7688 } 7689 7690 /* 7691 * "argc()" function 7692 */ 7693 /* ARGSUSED */ 7694 static void 7695 f_argc(argvars, rettv) 7696 typval_T *argvars; 7697 typval_T *rettv; 7698 { 7699 rettv->vval.v_number = ARGCOUNT; 7700 } 7701 7702 /* 7703 * "argidx()" function 7704 */ 7705 /* ARGSUSED */ 7706 static void 7707 f_argidx(argvars, rettv) 7708 typval_T *argvars; 7709 typval_T *rettv; 7710 { 7711 rettv->vval.v_number = curwin->w_arg_idx; 7712 } 7713 7714 /* 7715 * "argv(nr)" function 7716 */ 7717 static void 7718 f_argv(argvars, rettv) 7719 typval_T *argvars; 7720 typval_T *rettv; 7721 { 7722 int idx; 7723 7724 if (argvars[0].v_type != VAR_UNKNOWN) 7725 { 7726 idx = get_tv_number_chk(&argvars[0], NULL); 7727 if (idx >= 0 && idx < ARGCOUNT) 7728 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7729 else 7730 rettv->vval.v_string = NULL; 7731 rettv->v_type = VAR_STRING; 7732 } 7733 else if (rettv_list_alloc(rettv) == OK) 7734 for (idx = 0; idx < ARGCOUNT; ++idx) 7735 list_append_string(rettv->vval.v_list, 7736 alist_name(&ARGLIST[idx]), -1); 7737 } 7738 7739 /* 7740 * "browse(save, title, initdir, default)" function 7741 */ 7742 /* ARGSUSED */ 7743 static void 7744 f_browse(argvars, rettv) 7745 typval_T *argvars; 7746 typval_T *rettv; 7747 { 7748 #ifdef FEAT_BROWSE 7749 int save; 7750 char_u *title; 7751 char_u *initdir; 7752 char_u *defname; 7753 char_u buf[NUMBUFLEN]; 7754 char_u buf2[NUMBUFLEN]; 7755 int error = FALSE; 7756 7757 save = get_tv_number_chk(&argvars[0], &error); 7758 title = get_tv_string_chk(&argvars[1]); 7759 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7760 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7761 7762 if (error || title == NULL || initdir == NULL || defname == NULL) 7763 rettv->vval.v_string = NULL; 7764 else 7765 rettv->vval.v_string = 7766 do_browse(save ? BROWSE_SAVE : 0, 7767 title, defname, NULL, initdir, NULL, curbuf); 7768 #else 7769 rettv->vval.v_string = NULL; 7770 #endif 7771 rettv->v_type = VAR_STRING; 7772 } 7773 7774 /* 7775 * "browsedir(title, initdir)" function 7776 */ 7777 /* ARGSUSED */ 7778 static void 7779 f_browsedir(argvars, rettv) 7780 typval_T *argvars; 7781 typval_T *rettv; 7782 { 7783 #ifdef FEAT_BROWSE 7784 char_u *title; 7785 char_u *initdir; 7786 char_u buf[NUMBUFLEN]; 7787 7788 title = get_tv_string_chk(&argvars[0]); 7789 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7790 7791 if (title == NULL || initdir == NULL) 7792 rettv->vval.v_string = NULL; 7793 else 7794 rettv->vval.v_string = do_browse(BROWSE_DIR, 7795 title, NULL, NULL, initdir, NULL, curbuf); 7796 #else 7797 rettv->vval.v_string = NULL; 7798 #endif 7799 rettv->v_type = VAR_STRING; 7800 } 7801 7802 static buf_T *find_buffer __ARGS((typval_T *avar)); 7803 7804 /* 7805 * Find a buffer by number or exact name. 7806 */ 7807 static buf_T * 7808 find_buffer(avar) 7809 typval_T *avar; 7810 { 7811 buf_T *buf = NULL; 7812 7813 if (avar->v_type == VAR_NUMBER) 7814 buf = buflist_findnr((int)avar->vval.v_number); 7815 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7816 { 7817 buf = buflist_findname_exp(avar->vval.v_string); 7818 if (buf == NULL) 7819 { 7820 /* No full path name match, try a match with a URL or a "nofile" 7821 * buffer, these don't use the full path. */ 7822 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7823 if (buf->b_fname != NULL 7824 && (path_with_url(buf->b_fname) 7825 #ifdef FEAT_QUICKFIX 7826 || bt_nofile(buf) 7827 #endif 7828 ) 7829 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7830 break; 7831 } 7832 } 7833 return buf; 7834 } 7835 7836 /* 7837 * "bufexists(expr)" function 7838 */ 7839 static void 7840 f_bufexists(argvars, rettv) 7841 typval_T *argvars; 7842 typval_T *rettv; 7843 { 7844 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7845 } 7846 7847 /* 7848 * "buflisted(expr)" function 7849 */ 7850 static void 7851 f_buflisted(argvars, rettv) 7852 typval_T *argvars; 7853 typval_T *rettv; 7854 { 7855 buf_T *buf; 7856 7857 buf = find_buffer(&argvars[0]); 7858 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7859 } 7860 7861 /* 7862 * "bufloaded(expr)" function 7863 */ 7864 static void 7865 f_bufloaded(argvars, rettv) 7866 typval_T *argvars; 7867 typval_T *rettv; 7868 { 7869 buf_T *buf; 7870 7871 buf = find_buffer(&argvars[0]); 7872 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7873 } 7874 7875 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7876 7877 /* 7878 * Get buffer by number or pattern. 7879 */ 7880 static buf_T * 7881 get_buf_tv(tv) 7882 typval_T *tv; 7883 { 7884 char_u *name = tv->vval.v_string; 7885 int save_magic; 7886 char_u *save_cpo; 7887 buf_T *buf; 7888 7889 if (tv->v_type == VAR_NUMBER) 7890 return buflist_findnr((int)tv->vval.v_number); 7891 if (tv->v_type != VAR_STRING) 7892 return NULL; 7893 if (name == NULL || *name == NUL) 7894 return curbuf; 7895 if (name[0] == '$' && name[1] == NUL) 7896 return lastbuf; 7897 7898 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7899 save_magic = p_magic; 7900 p_magic = TRUE; 7901 save_cpo = p_cpo; 7902 p_cpo = (char_u *)""; 7903 7904 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7905 TRUE, FALSE)); 7906 7907 p_magic = save_magic; 7908 p_cpo = save_cpo; 7909 7910 /* If not found, try expanding the name, like done for bufexists(). */ 7911 if (buf == NULL) 7912 buf = find_buffer(tv); 7913 7914 return buf; 7915 } 7916 7917 /* 7918 * "bufname(expr)" function 7919 */ 7920 static void 7921 f_bufname(argvars, rettv) 7922 typval_T *argvars; 7923 typval_T *rettv; 7924 { 7925 buf_T *buf; 7926 7927 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7928 ++emsg_off; 7929 buf = get_buf_tv(&argvars[0]); 7930 rettv->v_type = VAR_STRING; 7931 if (buf != NULL && buf->b_fname != NULL) 7932 rettv->vval.v_string = vim_strsave(buf->b_fname); 7933 else 7934 rettv->vval.v_string = NULL; 7935 --emsg_off; 7936 } 7937 7938 /* 7939 * "bufnr(expr)" function 7940 */ 7941 static void 7942 f_bufnr(argvars, rettv) 7943 typval_T *argvars; 7944 typval_T *rettv; 7945 { 7946 buf_T *buf; 7947 int error = FALSE; 7948 char_u *name; 7949 7950 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7951 ++emsg_off; 7952 buf = get_buf_tv(&argvars[0]); 7953 --emsg_off; 7954 7955 /* If the buffer isn't found and the second argument is not zero create a 7956 * new buffer. */ 7957 if (buf == NULL 7958 && argvars[1].v_type != VAR_UNKNOWN 7959 && get_tv_number_chk(&argvars[1], &error) != 0 7960 && !error 7961 && (name = get_tv_string_chk(&argvars[0])) != NULL 7962 && !error) 7963 buf = buflist_new(name, NULL, (linenr_T)1, 0); 7964 7965 if (buf != NULL) 7966 rettv->vval.v_number = buf->b_fnum; 7967 else 7968 rettv->vval.v_number = -1; 7969 } 7970 7971 /* 7972 * "bufwinnr(nr)" function 7973 */ 7974 static void 7975 f_bufwinnr(argvars, rettv) 7976 typval_T *argvars; 7977 typval_T *rettv; 7978 { 7979 #ifdef FEAT_WINDOWS 7980 win_T *wp; 7981 int winnr = 0; 7982 #endif 7983 buf_T *buf; 7984 7985 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7986 ++emsg_off; 7987 buf = get_buf_tv(&argvars[0]); 7988 #ifdef FEAT_WINDOWS 7989 for (wp = firstwin; wp; wp = wp->w_next) 7990 { 7991 ++winnr; 7992 if (wp->w_buffer == buf) 7993 break; 7994 } 7995 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7996 #else 7997 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7998 #endif 7999 --emsg_off; 8000 } 8001 8002 /* 8003 * "byte2line(byte)" function 8004 */ 8005 /*ARGSUSED*/ 8006 static void 8007 f_byte2line(argvars, rettv) 8008 typval_T *argvars; 8009 typval_T *rettv; 8010 { 8011 #ifndef FEAT_BYTEOFF 8012 rettv->vval.v_number = -1; 8013 #else 8014 long boff = 0; 8015 8016 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8017 if (boff < 0) 8018 rettv->vval.v_number = -1; 8019 else 8020 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8021 (linenr_T)0, &boff); 8022 #endif 8023 } 8024 8025 /* 8026 * "byteidx()" function 8027 */ 8028 /*ARGSUSED*/ 8029 static void 8030 f_byteidx(argvars, rettv) 8031 typval_T *argvars; 8032 typval_T *rettv; 8033 { 8034 #ifdef FEAT_MBYTE 8035 char_u *t; 8036 #endif 8037 char_u *str; 8038 long idx; 8039 8040 str = get_tv_string_chk(&argvars[0]); 8041 idx = get_tv_number_chk(&argvars[1], NULL); 8042 rettv->vval.v_number = -1; 8043 if (str == NULL || idx < 0) 8044 return; 8045 8046 #ifdef FEAT_MBYTE 8047 t = str; 8048 for ( ; idx > 0; idx--) 8049 { 8050 if (*t == NUL) /* EOL reached */ 8051 return; 8052 t += (*mb_ptr2len)(t); 8053 } 8054 rettv->vval.v_number = (varnumber_T)(t - str); 8055 #else 8056 if (idx <= STRLEN(str)) 8057 rettv->vval.v_number = idx; 8058 #endif 8059 } 8060 8061 /* 8062 * "call(func, arglist)" function 8063 */ 8064 static void 8065 f_call(argvars, rettv) 8066 typval_T *argvars; 8067 typval_T *rettv; 8068 { 8069 char_u *func; 8070 typval_T argv[MAX_FUNC_ARGS + 1]; 8071 int argc = 0; 8072 listitem_T *item; 8073 int dummy; 8074 dict_T *selfdict = NULL; 8075 8076 rettv->vval.v_number = 0; 8077 if (argvars[1].v_type != VAR_LIST) 8078 { 8079 EMSG(_(e_listreq)); 8080 return; 8081 } 8082 if (argvars[1].vval.v_list == NULL) 8083 return; 8084 8085 if (argvars[0].v_type == VAR_FUNC) 8086 func = argvars[0].vval.v_string; 8087 else 8088 func = get_tv_string(&argvars[0]); 8089 if (*func == NUL) 8090 return; /* type error or empty name */ 8091 8092 if (argvars[2].v_type != VAR_UNKNOWN) 8093 { 8094 if (argvars[2].v_type != VAR_DICT) 8095 { 8096 EMSG(_(e_dictreq)); 8097 return; 8098 } 8099 selfdict = argvars[2].vval.v_dict; 8100 } 8101 8102 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 8103 item = item->li_next) 8104 { 8105 if (argc == MAX_FUNC_ARGS) 8106 { 8107 EMSG(_("E699: Too many arguments")); 8108 break; 8109 } 8110 /* Make a copy of each argument. This is needed to be able to set 8111 * v_lock to VAR_FIXED in the copy without changing the original list. 8112 */ 8113 copy_tv(&item->li_tv, &argv[argc++]); 8114 } 8115 8116 if (item == NULL) 8117 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 8118 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8119 &dummy, TRUE, selfdict); 8120 8121 /* Free the arguments. */ 8122 while (argc > 0) 8123 clear_tv(&argv[--argc]); 8124 } 8125 8126 /* 8127 * "changenr()" function 8128 */ 8129 /*ARGSUSED*/ 8130 static void 8131 f_changenr(argvars, rettv) 8132 typval_T *argvars; 8133 typval_T *rettv; 8134 { 8135 rettv->vval.v_number = curbuf->b_u_seq_cur; 8136 } 8137 8138 /* 8139 * "char2nr(string)" function 8140 */ 8141 static void 8142 f_char2nr(argvars, rettv) 8143 typval_T *argvars; 8144 typval_T *rettv; 8145 { 8146 #ifdef FEAT_MBYTE 8147 if (has_mbyte) 8148 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8149 else 8150 #endif 8151 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8152 } 8153 8154 /* 8155 * "cindent(lnum)" function 8156 */ 8157 static void 8158 f_cindent(argvars, rettv) 8159 typval_T *argvars; 8160 typval_T *rettv; 8161 { 8162 #ifdef FEAT_CINDENT 8163 pos_T pos; 8164 linenr_T lnum; 8165 8166 pos = curwin->w_cursor; 8167 lnum = get_tv_lnum(argvars); 8168 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8169 { 8170 curwin->w_cursor.lnum = lnum; 8171 rettv->vval.v_number = get_c_indent(); 8172 curwin->w_cursor = pos; 8173 } 8174 else 8175 #endif 8176 rettv->vval.v_number = -1; 8177 } 8178 8179 /* 8180 * "col(string)" function 8181 */ 8182 static void 8183 f_col(argvars, rettv) 8184 typval_T *argvars; 8185 typval_T *rettv; 8186 { 8187 colnr_T col = 0; 8188 pos_T *fp; 8189 int fnum = curbuf->b_fnum; 8190 8191 fp = var2fpos(&argvars[0], FALSE, &fnum); 8192 if (fp != NULL && fnum == curbuf->b_fnum) 8193 { 8194 if (fp->col == MAXCOL) 8195 { 8196 /* '> can be MAXCOL, get the length of the line then */ 8197 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8198 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 8199 else 8200 col = MAXCOL; 8201 } 8202 else 8203 { 8204 col = fp->col + 1; 8205 #ifdef FEAT_VIRTUALEDIT 8206 /* col(".") when the cursor is on the NUL at the end of the line 8207 * because of "coladd" can be seen as an extra column. */ 8208 if (virtual_active() && fp == &curwin->w_cursor) 8209 { 8210 char_u *p = ml_get_cursor(); 8211 8212 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8213 curwin->w_virtcol - curwin->w_cursor.coladd)) 8214 { 8215 # ifdef FEAT_MBYTE 8216 int l; 8217 8218 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8219 col += l; 8220 # else 8221 if (*p != NUL && p[1] == NUL) 8222 ++col; 8223 # endif 8224 } 8225 } 8226 #endif 8227 } 8228 } 8229 rettv->vval.v_number = col; 8230 } 8231 8232 #if defined(FEAT_INS_EXPAND) 8233 /* 8234 * "complete()" function 8235 */ 8236 /*ARGSUSED*/ 8237 static void 8238 f_complete(argvars, rettv) 8239 typval_T *argvars; 8240 typval_T *rettv; 8241 { 8242 int startcol; 8243 8244 if ((State & INSERT) == 0) 8245 { 8246 EMSG(_("E785: complete() can only be used in Insert mode")); 8247 return; 8248 } 8249 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 8250 { 8251 EMSG(_(e_invarg)); 8252 return; 8253 } 8254 8255 startcol = get_tv_number_chk(&argvars[0], NULL); 8256 if (startcol <= 0) 8257 return; 8258 8259 set_completion(startcol - 1, argvars[1].vval.v_list); 8260 } 8261 8262 /* 8263 * "complete_add()" function 8264 */ 8265 /*ARGSUSED*/ 8266 static void 8267 f_complete_add(argvars, rettv) 8268 typval_T *argvars; 8269 typval_T *rettv; 8270 { 8271 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 8272 } 8273 8274 /* 8275 * "complete_check()" function 8276 */ 8277 /*ARGSUSED*/ 8278 static void 8279 f_complete_check(argvars, rettv) 8280 typval_T *argvars; 8281 typval_T *rettv; 8282 { 8283 int saved = RedrawingDisabled; 8284 8285 RedrawingDisabled = 0; 8286 ins_compl_check_keys(0); 8287 rettv->vval.v_number = compl_interrupted; 8288 RedrawingDisabled = saved; 8289 } 8290 #endif 8291 8292 /* 8293 * "confirm(message, buttons[, default [, type]])" function 8294 */ 8295 /*ARGSUSED*/ 8296 static void 8297 f_confirm(argvars, rettv) 8298 typval_T *argvars; 8299 typval_T *rettv; 8300 { 8301 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 8302 char_u *message; 8303 char_u *buttons = NULL; 8304 char_u buf[NUMBUFLEN]; 8305 char_u buf2[NUMBUFLEN]; 8306 int def = 1; 8307 int type = VIM_GENERIC; 8308 char_u *typestr; 8309 int error = FALSE; 8310 8311 message = get_tv_string_chk(&argvars[0]); 8312 if (message == NULL) 8313 error = TRUE; 8314 if (argvars[1].v_type != VAR_UNKNOWN) 8315 { 8316 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8317 if (buttons == NULL) 8318 error = TRUE; 8319 if (argvars[2].v_type != VAR_UNKNOWN) 8320 { 8321 def = get_tv_number_chk(&argvars[2], &error); 8322 if (argvars[3].v_type != VAR_UNKNOWN) 8323 { 8324 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8325 if (typestr == NULL) 8326 error = TRUE; 8327 else 8328 { 8329 switch (TOUPPER_ASC(*typestr)) 8330 { 8331 case 'E': type = VIM_ERROR; break; 8332 case 'Q': type = VIM_QUESTION; break; 8333 case 'I': type = VIM_INFO; break; 8334 case 'W': type = VIM_WARNING; break; 8335 case 'G': type = VIM_GENERIC; break; 8336 } 8337 } 8338 } 8339 } 8340 } 8341 8342 if (buttons == NULL || *buttons == NUL) 8343 buttons = (char_u *)_("&Ok"); 8344 8345 if (error) 8346 rettv->vval.v_number = 0; 8347 else 8348 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8349 def, NULL); 8350 #else 8351 rettv->vval.v_number = 0; 8352 #endif 8353 } 8354 8355 /* 8356 * "copy()" function 8357 */ 8358 static void 8359 f_copy(argvars, rettv) 8360 typval_T *argvars; 8361 typval_T *rettv; 8362 { 8363 item_copy(&argvars[0], rettv, FALSE, 0); 8364 } 8365 8366 /* 8367 * "count()" function 8368 */ 8369 static void 8370 f_count(argvars, rettv) 8371 typval_T *argvars; 8372 typval_T *rettv; 8373 { 8374 long n = 0; 8375 int ic = FALSE; 8376 8377 if (argvars[0].v_type == VAR_LIST) 8378 { 8379 listitem_T *li; 8380 list_T *l; 8381 long idx; 8382 8383 if ((l = argvars[0].vval.v_list) != NULL) 8384 { 8385 li = l->lv_first; 8386 if (argvars[2].v_type != VAR_UNKNOWN) 8387 { 8388 int error = FALSE; 8389 8390 ic = get_tv_number_chk(&argvars[2], &error); 8391 if (argvars[3].v_type != VAR_UNKNOWN) 8392 { 8393 idx = get_tv_number_chk(&argvars[3], &error); 8394 if (!error) 8395 { 8396 li = list_find(l, idx); 8397 if (li == NULL) 8398 EMSGN(_(e_listidx), idx); 8399 } 8400 } 8401 if (error) 8402 li = NULL; 8403 } 8404 8405 for ( ; li != NULL; li = li->li_next) 8406 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8407 ++n; 8408 } 8409 } 8410 else if (argvars[0].v_type == VAR_DICT) 8411 { 8412 int todo; 8413 dict_T *d; 8414 hashitem_T *hi; 8415 8416 if ((d = argvars[0].vval.v_dict) != NULL) 8417 { 8418 int error = FALSE; 8419 8420 if (argvars[2].v_type != VAR_UNKNOWN) 8421 { 8422 ic = get_tv_number_chk(&argvars[2], &error); 8423 if (argvars[3].v_type != VAR_UNKNOWN) 8424 EMSG(_(e_invarg)); 8425 } 8426 8427 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 8428 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8429 { 8430 if (!HASHITEM_EMPTY(hi)) 8431 { 8432 --todo; 8433 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8434 ++n; 8435 } 8436 } 8437 } 8438 } 8439 else 8440 EMSG2(_(e_listdictarg), "count()"); 8441 rettv->vval.v_number = n; 8442 } 8443 8444 /* 8445 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8446 * 8447 * Checks the existence of a cscope connection. 8448 */ 8449 /*ARGSUSED*/ 8450 static void 8451 f_cscope_connection(argvars, rettv) 8452 typval_T *argvars; 8453 typval_T *rettv; 8454 { 8455 #ifdef FEAT_CSCOPE 8456 int num = 0; 8457 char_u *dbpath = NULL; 8458 char_u *prepend = NULL; 8459 char_u buf[NUMBUFLEN]; 8460 8461 if (argvars[0].v_type != VAR_UNKNOWN 8462 && argvars[1].v_type != VAR_UNKNOWN) 8463 { 8464 num = (int)get_tv_number(&argvars[0]); 8465 dbpath = get_tv_string(&argvars[1]); 8466 if (argvars[2].v_type != VAR_UNKNOWN) 8467 prepend = get_tv_string_buf(&argvars[2], buf); 8468 } 8469 8470 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8471 #else 8472 rettv->vval.v_number = 0; 8473 #endif 8474 } 8475 8476 /* 8477 * "cursor(lnum, col)" function 8478 * 8479 * Moves the cursor to the specified line and column 8480 */ 8481 /*ARGSUSED*/ 8482 static void 8483 f_cursor(argvars, rettv) 8484 typval_T *argvars; 8485 typval_T *rettv; 8486 { 8487 long line, col; 8488 #ifdef FEAT_VIRTUALEDIT 8489 long coladd = 0; 8490 #endif 8491 8492 if (argvars[1].v_type == VAR_UNKNOWN) 8493 { 8494 pos_T pos; 8495 8496 if (list2fpos(argvars, &pos, NULL) == FAIL) 8497 return; 8498 line = pos.lnum; 8499 col = pos.col; 8500 #ifdef FEAT_VIRTUALEDIT 8501 coladd = pos.coladd; 8502 #endif 8503 } 8504 else 8505 { 8506 line = get_tv_lnum(argvars); 8507 col = get_tv_number_chk(&argvars[1], NULL); 8508 #ifdef FEAT_VIRTUALEDIT 8509 if (argvars[2].v_type != VAR_UNKNOWN) 8510 coladd = get_tv_number_chk(&argvars[2], NULL); 8511 #endif 8512 } 8513 if (line < 0 || col < 0 8514 #ifdef FEAT_VIRTUALEDIT 8515 || coladd < 0 8516 #endif 8517 ) 8518 return; /* type error; errmsg already given */ 8519 if (line > 0) 8520 curwin->w_cursor.lnum = line; 8521 if (col > 0) 8522 curwin->w_cursor.col = col - 1; 8523 #ifdef FEAT_VIRTUALEDIT 8524 curwin->w_cursor.coladd = coladd; 8525 #endif 8526 8527 /* Make sure the cursor is in a valid position. */ 8528 check_cursor(); 8529 #ifdef FEAT_MBYTE 8530 /* Correct cursor for multi-byte character. */ 8531 if (has_mbyte) 8532 mb_adjust_cursor(); 8533 #endif 8534 8535 curwin->w_set_curswant = TRUE; 8536 } 8537 8538 /* 8539 * "deepcopy()" function 8540 */ 8541 static void 8542 f_deepcopy(argvars, rettv) 8543 typval_T *argvars; 8544 typval_T *rettv; 8545 { 8546 int noref = 0; 8547 8548 if (argvars[1].v_type != VAR_UNKNOWN) 8549 noref = get_tv_number_chk(&argvars[1], NULL); 8550 if (noref < 0 || noref > 1) 8551 EMSG(_(e_invarg)); 8552 else 8553 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8554 } 8555 8556 /* 8557 * "delete()" function 8558 */ 8559 static void 8560 f_delete(argvars, rettv) 8561 typval_T *argvars; 8562 typval_T *rettv; 8563 { 8564 if (check_restricted() || check_secure()) 8565 rettv->vval.v_number = -1; 8566 else 8567 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8568 } 8569 8570 /* 8571 * "did_filetype()" function 8572 */ 8573 /*ARGSUSED*/ 8574 static void 8575 f_did_filetype(argvars, rettv) 8576 typval_T *argvars; 8577 typval_T *rettv; 8578 { 8579 #ifdef FEAT_AUTOCMD 8580 rettv->vval.v_number = did_filetype; 8581 #else 8582 rettv->vval.v_number = 0; 8583 #endif 8584 } 8585 8586 /* 8587 * "diff_filler()" function 8588 */ 8589 /*ARGSUSED*/ 8590 static void 8591 f_diff_filler(argvars, rettv) 8592 typval_T *argvars; 8593 typval_T *rettv; 8594 { 8595 #ifdef FEAT_DIFF 8596 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8597 #endif 8598 } 8599 8600 /* 8601 * "diff_hlID()" function 8602 */ 8603 /*ARGSUSED*/ 8604 static void 8605 f_diff_hlID(argvars, rettv) 8606 typval_T *argvars; 8607 typval_T *rettv; 8608 { 8609 #ifdef FEAT_DIFF 8610 linenr_T lnum = get_tv_lnum(argvars); 8611 static linenr_T prev_lnum = 0; 8612 static int changedtick = 0; 8613 static int fnum = 0; 8614 static int change_start = 0; 8615 static int change_end = 0; 8616 static hlf_T hlID = 0; 8617 int filler_lines; 8618 int col; 8619 8620 if (lnum < 0) /* ignore type error in {lnum} arg */ 8621 lnum = 0; 8622 if (lnum != prev_lnum 8623 || changedtick != curbuf->b_changedtick 8624 || fnum != curbuf->b_fnum) 8625 { 8626 /* New line, buffer, change: need to get the values. */ 8627 filler_lines = diff_check(curwin, lnum); 8628 if (filler_lines < 0) 8629 { 8630 if (filler_lines == -1) 8631 { 8632 change_start = MAXCOL; 8633 change_end = -1; 8634 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8635 hlID = HLF_ADD; /* added line */ 8636 else 8637 hlID = HLF_CHD; /* changed line */ 8638 } 8639 else 8640 hlID = HLF_ADD; /* added line */ 8641 } 8642 else 8643 hlID = (hlf_T)0; 8644 prev_lnum = lnum; 8645 changedtick = curbuf->b_changedtick; 8646 fnum = curbuf->b_fnum; 8647 } 8648 8649 if (hlID == HLF_CHD || hlID == HLF_TXD) 8650 { 8651 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8652 if (col >= change_start && col <= change_end) 8653 hlID = HLF_TXD; /* changed text */ 8654 else 8655 hlID = HLF_CHD; /* changed line */ 8656 } 8657 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8658 #endif 8659 } 8660 8661 /* 8662 * "empty({expr})" function 8663 */ 8664 static void 8665 f_empty(argvars, rettv) 8666 typval_T *argvars; 8667 typval_T *rettv; 8668 { 8669 int n; 8670 8671 switch (argvars[0].v_type) 8672 { 8673 case VAR_STRING: 8674 case VAR_FUNC: 8675 n = argvars[0].vval.v_string == NULL 8676 || *argvars[0].vval.v_string == NUL; 8677 break; 8678 case VAR_NUMBER: 8679 n = argvars[0].vval.v_number == 0; 8680 break; 8681 case VAR_LIST: 8682 n = argvars[0].vval.v_list == NULL 8683 || argvars[0].vval.v_list->lv_first == NULL; 8684 break; 8685 case VAR_DICT: 8686 n = argvars[0].vval.v_dict == NULL 8687 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8688 break; 8689 default: 8690 EMSG2(_(e_intern2), "f_empty()"); 8691 n = 0; 8692 } 8693 8694 rettv->vval.v_number = n; 8695 } 8696 8697 /* 8698 * "escape({string}, {chars})" function 8699 */ 8700 static void 8701 f_escape(argvars, rettv) 8702 typval_T *argvars; 8703 typval_T *rettv; 8704 { 8705 char_u buf[NUMBUFLEN]; 8706 8707 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8708 get_tv_string_buf(&argvars[1], buf)); 8709 rettv->v_type = VAR_STRING; 8710 } 8711 8712 /* 8713 * "eval()" function 8714 */ 8715 /*ARGSUSED*/ 8716 static void 8717 f_eval(argvars, rettv) 8718 typval_T *argvars; 8719 typval_T *rettv; 8720 { 8721 char_u *s; 8722 8723 s = get_tv_string_chk(&argvars[0]); 8724 if (s != NULL) 8725 s = skipwhite(s); 8726 8727 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8728 { 8729 rettv->v_type = VAR_NUMBER; 8730 rettv->vval.v_number = 0; 8731 } 8732 else if (*s != NUL) 8733 EMSG(_(e_trailing)); 8734 } 8735 8736 /* 8737 * "eventhandler()" function 8738 */ 8739 /*ARGSUSED*/ 8740 static void 8741 f_eventhandler(argvars, rettv) 8742 typval_T *argvars; 8743 typval_T *rettv; 8744 { 8745 rettv->vval.v_number = vgetc_busy; 8746 } 8747 8748 /* 8749 * "executable()" function 8750 */ 8751 static void 8752 f_executable(argvars, rettv) 8753 typval_T *argvars; 8754 typval_T *rettv; 8755 { 8756 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8757 } 8758 8759 /* 8760 * "exists()" function 8761 */ 8762 static void 8763 f_exists(argvars, rettv) 8764 typval_T *argvars; 8765 typval_T *rettv; 8766 { 8767 char_u *p; 8768 char_u *name; 8769 int n = FALSE; 8770 int len = 0; 8771 8772 p = get_tv_string(&argvars[0]); 8773 if (*p == '$') /* environment variable */ 8774 { 8775 /* first try "normal" environment variables (fast) */ 8776 if (mch_getenv(p + 1) != NULL) 8777 n = TRUE; 8778 else 8779 { 8780 /* try expanding things like $VIM and ${HOME} */ 8781 p = expand_env_save(p); 8782 if (p != NULL && *p != '$') 8783 n = TRUE; 8784 vim_free(p); 8785 } 8786 } 8787 else if (*p == '&' || *p == '+') /* option */ 8788 n = (get_option_tv(&p, NULL, TRUE) == OK); 8789 else if (*p == '*') /* internal or user defined function */ 8790 { 8791 n = function_exists(p + 1); 8792 } 8793 else if (*p == ':') 8794 { 8795 n = cmd_exists(p + 1); 8796 } 8797 else if (*p == '#') 8798 { 8799 #ifdef FEAT_AUTOCMD 8800 if (p[1] == '#') 8801 n = autocmd_supported(p + 2); 8802 else 8803 n = au_exists(p + 1); 8804 #endif 8805 } 8806 else /* internal variable */ 8807 { 8808 char_u *tofree; 8809 typval_T tv; 8810 8811 /* get_name_len() takes care of expanding curly braces */ 8812 name = p; 8813 len = get_name_len(&p, &tofree, TRUE, FALSE); 8814 if (len > 0) 8815 { 8816 if (tofree != NULL) 8817 name = tofree; 8818 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8819 if (n) 8820 { 8821 /* handle d.key, l[idx], f(expr) */ 8822 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8823 if (n) 8824 clear_tv(&tv); 8825 } 8826 } 8827 8828 vim_free(tofree); 8829 } 8830 8831 rettv->vval.v_number = n; 8832 } 8833 8834 /* 8835 * "expand()" function 8836 */ 8837 static void 8838 f_expand(argvars, rettv) 8839 typval_T *argvars; 8840 typval_T *rettv; 8841 { 8842 char_u *s; 8843 int len; 8844 char_u *errormsg; 8845 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8846 expand_T xpc; 8847 int error = FALSE; 8848 8849 rettv->v_type = VAR_STRING; 8850 s = get_tv_string(&argvars[0]); 8851 if (*s == '%' || *s == '#' || *s == '<') 8852 { 8853 ++emsg_off; 8854 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8855 --emsg_off; 8856 } 8857 else 8858 { 8859 /* When the optional second argument is non-zero, don't remove matches 8860 * for 'suffixes' and 'wildignore' */ 8861 if (argvars[1].v_type != VAR_UNKNOWN 8862 && get_tv_number_chk(&argvars[1], &error)) 8863 flags |= WILD_KEEP_ALL; 8864 if (!error) 8865 { 8866 ExpandInit(&xpc); 8867 xpc.xp_context = EXPAND_FILES; 8868 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8869 } 8870 else 8871 rettv->vval.v_string = NULL; 8872 } 8873 } 8874 8875 /* 8876 * "extend(list, list [, idx])" function 8877 * "extend(dict, dict [, action])" function 8878 */ 8879 static void 8880 f_extend(argvars, rettv) 8881 typval_T *argvars; 8882 typval_T *rettv; 8883 { 8884 rettv->vval.v_number = 0; 8885 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8886 { 8887 list_T *l1, *l2; 8888 listitem_T *item; 8889 long before; 8890 int error = FALSE; 8891 8892 l1 = argvars[0].vval.v_list; 8893 l2 = argvars[1].vval.v_list; 8894 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8895 && l2 != NULL) 8896 { 8897 if (argvars[2].v_type != VAR_UNKNOWN) 8898 { 8899 before = get_tv_number_chk(&argvars[2], &error); 8900 if (error) 8901 return; /* type error; errmsg already given */ 8902 8903 if (before == l1->lv_len) 8904 item = NULL; 8905 else 8906 { 8907 item = list_find(l1, before); 8908 if (item == NULL) 8909 { 8910 EMSGN(_(e_listidx), before); 8911 return; 8912 } 8913 } 8914 } 8915 else 8916 item = NULL; 8917 list_extend(l1, l2, item); 8918 8919 copy_tv(&argvars[0], rettv); 8920 } 8921 } 8922 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8923 { 8924 dict_T *d1, *d2; 8925 dictitem_T *di1; 8926 char_u *action; 8927 int i; 8928 hashitem_T *hi2; 8929 int todo; 8930 8931 d1 = argvars[0].vval.v_dict; 8932 d2 = argvars[1].vval.v_dict; 8933 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8934 && d2 != NULL) 8935 { 8936 /* Check the third argument. */ 8937 if (argvars[2].v_type != VAR_UNKNOWN) 8938 { 8939 static char *(av[]) = {"keep", "force", "error"}; 8940 8941 action = get_tv_string_chk(&argvars[2]); 8942 if (action == NULL) 8943 return; /* type error; errmsg already given */ 8944 for (i = 0; i < 3; ++i) 8945 if (STRCMP(action, av[i]) == 0) 8946 break; 8947 if (i == 3) 8948 { 8949 EMSG2(_(e_invarg2), action); 8950 return; 8951 } 8952 } 8953 else 8954 action = (char_u *)"force"; 8955 8956 /* Go over all entries in the second dict and add them to the 8957 * first dict. */ 8958 todo = (int)d2->dv_hashtab.ht_used; 8959 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8960 { 8961 if (!HASHITEM_EMPTY(hi2)) 8962 { 8963 --todo; 8964 di1 = dict_find(d1, hi2->hi_key, -1); 8965 if (di1 == NULL) 8966 { 8967 di1 = dictitem_copy(HI2DI(hi2)); 8968 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8969 dictitem_free(di1); 8970 } 8971 else if (*action == 'e') 8972 { 8973 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8974 break; 8975 } 8976 else if (*action == 'f') 8977 { 8978 clear_tv(&di1->di_tv); 8979 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8980 } 8981 } 8982 } 8983 8984 copy_tv(&argvars[0], rettv); 8985 } 8986 } 8987 else 8988 EMSG2(_(e_listdictarg), "extend()"); 8989 } 8990 8991 /* 8992 * "feedkeys()" function 8993 */ 8994 /*ARGSUSED*/ 8995 static void 8996 f_feedkeys(argvars, rettv) 8997 typval_T *argvars; 8998 typval_T *rettv; 8999 { 9000 int remap = TRUE; 9001 char_u *keys, *flags; 9002 char_u nbuf[NUMBUFLEN]; 9003 int typed = FALSE; 9004 char_u *keys_esc; 9005 9006 rettv->vval.v_number = 0; 9007 keys = get_tv_string(&argvars[0]); 9008 if (*keys != NUL) 9009 { 9010 if (argvars[1].v_type != VAR_UNKNOWN) 9011 { 9012 flags = get_tv_string_buf(&argvars[1], nbuf); 9013 for ( ; *flags != NUL; ++flags) 9014 { 9015 switch (*flags) 9016 { 9017 case 'n': remap = FALSE; break; 9018 case 'm': remap = TRUE; break; 9019 case 't': typed = TRUE; break; 9020 } 9021 } 9022 } 9023 9024 /* Need to escape K_SPECIAL and CSI before putting the string in the 9025 * typeahead buffer. */ 9026 keys_esc = vim_strsave_escape_csi(keys); 9027 if (keys_esc != NULL) 9028 { 9029 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 9030 typebuf.tb_len, !typed, FALSE); 9031 vim_free(keys_esc); 9032 typebuf_was_filled = TRUE; 9033 } 9034 } 9035 } 9036 9037 /* 9038 * "filereadable()" function 9039 */ 9040 static void 9041 f_filereadable(argvars, rettv) 9042 typval_T *argvars; 9043 typval_T *rettv; 9044 { 9045 FILE *fd; 9046 char_u *p; 9047 int n; 9048 9049 p = get_tv_string(&argvars[0]); 9050 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 9051 { 9052 n = TRUE; 9053 fclose(fd); 9054 } 9055 else 9056 n = FALSE; 9057 9058 rettv->vval.v_number = n; 9059 } 9060 9061 /* 9062 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 9063 * rights to write into. 9064 */ 9065 static void 9066 f_filewritable(argvars, rettv) 9067 typval_T *argvars; 9068 typval_T *rettv; 9069 { 9070 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 9071 } 9072 9073 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 9074 9075 static void 9076 findfilendir(argvars, rettv, dir) 9077 typval_T *argvars; 9078 typval_T *rettv; 9079 int dir; 9080 { 9081 #ifdef FEAT_SEARCHPATH 9082 char_u *fname; 9083 char_u *fresult = NULL; 9084 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 9085 char_u *p; 9086 char_u pathbuf[NUMBUFLEN]; 9087 int count = 1; 9088 int first = TRUE; 9089 int error = FALSE; 9090 #endif 9091 9092 rettv->vval.v_string = NULL; 9093 rettv->v_type = VAR_STRING; 9094 9095 #ifdef FEAT_SEARCHPATH 9096 fname = get_tv_string(&argvars[0]); 9097 9098 if (argvars[1].v_type != VAR_UNKNOWN) 9099 { 9100 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 9101 if (p == NULL) 9102 error = TRUE; 9103 else 9104 { 9105 if (*p != NUL) 9106 path = p; 9107 9108 if (argvars[2].v_type != VAR_UNKNOWN) 9109 count = get_tv_number_chk(&argvars[2], &error); 9110 } 9111 } 9112 9113 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 9114 error = TRUE; 9115 9116 if (*fname != NUL && !error) 9117 { 9118 do 9119 { 9120 if (rettv->v_type == VAR_STRING) 9121 vim_free(fresult); 9122 fresult = find_file_in_path_option(first ? fname : NULL, 9123 first ? (int)STRLEN(fname) : 0, 9124 0, first, path, dir, NULL, 9125 dir ? (char_u *)"" : curbuf->b_p_sua); 9126 first = FALSE; 9127 9128 if (fresult != NULL && rettv->v_type == VAR_LIST) 9129 list_append_string(rettv->vval.v_list, fresult, -1); 9130 9131 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 9132 } 9133 9134 if (rettv->v_type == VAR_STRING) 9135 rettv->vval.v_string = fresult; 9136 #endif 9137 } 9138 9139 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 9140 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 9141 9142 /* 9143 * Implementation of map() and filter(). 9144 */ 9145 static void 9146 filter_map(argvars, rettv, map) 9147 typval_T *argvars; 9148 typval_T *rettv; 9149 int map; 9150 { 9151 char_u buf[NUMBUFLEN]; 9152 char_u *expr; 9153 listitem_T *li, *nli; 9154 list_T *l = NULL; 9155 dictitem_T *di; 9156 hashtab_T *ht; 9157 hashitem_T *hi; 9158 dict_T *d = NULL; 9159 typval_T save_val; 9160 typval_T save_key; 9161 int rem; 9162 int todo; 9163 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 9164 int save_did_emsg; 9165 9166 rettv->vval.v_number = 0; 9167 if (argvars[0].v_type == VAR_LIST) 9168 { 9169 if ((l = argvars[0].vval.v_list) == NULL 9170 || (map && tv_check_lock(l->lv_lock, msg))) 9171 return; 9172 } 9173 else if (argvars[0].v_type == VAR_DICT) 9174 { 9175 if ((d = argvars[0].vval.v_dict) == NULL 9176 || (map && tv_check_lock(d->dv_lock, msg))) 9177 return; 9178 } 9179 else 9180 { 9181 EMSG2(_(e_listdictarg), msg); 9182 return; 9183 } 9184 9185 expr = get_tv_string_buf_chk(&argvars[1], buf); 9186 /* On type errors, the preceding call has already displayed an error 9187 * message. Avoid a misleading error message for an empty string that 9188 * was not passed as argument. */ 9189 if (expr != NULL) 9190 { 9191 prepare_vimvar(VV_VAL, &save_val); 9192 expr = skipwhite(expr); 9193 9194 /* We reset "did_emsg" to be able to detect whether an error 9195 * occurred during evaluation of the expression. */ 9196 save_did_emsg = did_emsg; 9197 did_emsg = FALSE; 9198 9199 if (argvars[0].v_type == VAR_DICT) 9200 { 9201 prepare_vimvar(VV_KEY, &save_key); 9202 vimvars[VV_KEY].vv_type = VAR_STRING; 9203 9204 ht = &d->dv_hashtab; 9205 hash_lock(ht); 9206 todo = (int)ht->ht_used; 9207 for (hi = ht->ht_array; todo > 0; ++hi) 9208 { 9209 if (!HASHITEM_EMPTY(hi)) 9210 { 9211 --todo; 9212 di = HI2DI(hi); 9213 if (tv_check_lock(di->di_tv.v_lock, msg)) 9214 break; 9215 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9216 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9217 || did_emsg) 9218 break; 9219 if (!map && rem) 9220 dictitem_remove(d, di); 9221 clear_tv(&vimvars[VV_KEY].vv_tv); 9222 } 9223 } 9224 hash_unlock(ht); 9225 9226 restore_vimvar(VV_KEY, &save_key); 9227 } 9228 else 9229 { 9230 for (li = l->lv_first; li != NULL; li = nli) 9231 { 9232 if (tv_check_lock(li->li_tv.v_lock, msg)) 9233 break; 9234 nli = li->li_next; 9235 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 9236 || did_emsg) 9237 break; 9238 if (!map && rem) 9239 listitem_remove(l, li); 9240 } 9241 } 9242 9243 restore_vimvar(VV_VAL, &save_val); 9244 9245 did_emsg |= save_did_emsg; 9246 } 9247 9248 copy_tv(&argvars[0], rettv); 9249 } 9250 9251 static int 9252 filter_map_one(tv, expr, map, remp) 9253 typval_T *tv; 9254 char_u *expr; 9255 int map; 9256 int *remp; 9257 { 9258 typval_T rettv; 9259 char_u *s; 9260 9261 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 9262 s = expr; 9263 if (eval1(&s, &rettv, TRUE) == FAIL) 9264 return FAIL; 9265 if (*s != NUL) /* check for trailing chars after expr */ 9266 { 9267 EMSG2(_(e_invexpr2), s); 9268 return FAIL; 9269 } 9270 if (map) 9271 { 9272 /* map(): replace the list item value */ 9273 clear_tv(tv); 9274 rettv.v_lock = 0; 9275 *tv = rettv; 9276 } 9277 else 9278 { 9279 int error = FALSE; 9280 9281 /* filter(): when expr is zero remove the item */ 9282 *remp = (get_tv_number_chk(&rettv, &error) == 0); 9283 clear_tv(&rettv); 9284 /* On type error, nothing has been removed; return FAIL to stop the 9285 * loop. The error message was given by get_tv_number_chk(). */ 9286 if (error) 9287 return FAIL; 9288 } 9289 clear_tv(&vimvars[VV_VAL].vv_tv); 9290 return OK; 9291 } 9292 9293 /* 9294 * "filter()" function 9295 */ 9296 static void 9297 f_filter(argvars, rettv) 9298 typval_T *argvars; 9299 typval_T *rettv; 9300 { 9301 filter_map(argvars, rettv, FALSE); 9302 } 9303 9304 /* 9305 * "finddir({fname}[, {path}[, {count}]])" function 9306 */ 9307 static void 9308 f_finddir(argvars, rettv) 9309 typval_T *argvars; 9310 typval_T *rettv; 9311 { 9312 findfilendir(argvars, rettv, TRUE); 9313 } 9314 9315 /* 9316 * "findfile({fname}[, {path}[, {count}]])" function 9317 */ 9318 static void 9319 f_findfile(argvars, rettv) 9320 typval_T *argvars; 9321 typval_T *rettv; 9322 { 9323 findfilendir(argvars, rettv, FALSE); 9324 } 9325 9326 /* 9327 * "fnamemodify({fname}, {mods})" function 9328 */ 9329 static void 9330 f_fnamemodify(argvars, rettv) 9331 typval_T *argvars; 9332 typval_T *rettv; 9333 { 9334 char_u *fname; 9335 char_u *mods; 9336 int usedlen = 0; 9337 int len; 9338 char_u *fbuf = NULL; 9339 char_u buf[NUMBUFLEN]; 9340 9341 fname = get_tv_string_chk(&argvars[0]); 9342 mods = get_tv_string_buf_chk(&argvars[1], buf); 9343 if (fname == NULL || mods == NULL) 9344 fname = NULL; 9345 else 9346 { 9347 len = (int)STRLEN(fname); 9348 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 9349 } 9350 9351 rettv->v_type = VAR_STRING; 9352 if (fname == NULL) 9353 rettv->vval.v_string = NULL; 9354 else 9355 rettv->vval.v_string = vim_strnsave(fname, len); 9356 vim_free(fbuf); 9357 } 9358 9359 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 9360 9361 /* 9362 * "foldclosed()" function 9363 */ 9364 static void 9365 foldclosed_both(argvars, rettv, end) 9366 typval_T *argvars; 9367 typval_T *rettv; 9368 int end; 9369 { 9370 #ifdef FEAT_FOLDING 9371 linenr_T lnum; 9372 linenr_T first, last; 9373 9374 lnum = get_tv_lnum(argvars); 9375 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9376 { 9377 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 9378 { 9379 if (end) 9380 rettv->vval.v_number = (varnumber_T)last; 9381 else 9382 rettv->vval.v_number = (varnumber_T)first; 9383 return; 9384 } 9385 } 9386 #endif 9387 rettv->vval.v_number = -1; 9388 } 9389 9390 /* 9391 * "foldclosed()" function 9392 */ 9393 static void 9394 f_foldclosed(argvars, rettv) 9395 typval_T *argvars; 9396 typval_T *rettv; 9397 { 9398 foldclosed_both(argvars, rettv, FALSE); 9399 } 9400 9401 /* 9402 * "foldclosedend()" function 9403 */ 9404 static void 9405 f_foldclosedend(argvars, rettv) 9406 typval_T *argvars; 9407 typval_T *rettv; 9408 { 9409 foldclosed_both(argvars, rettv, TRUE); 9410 } 9411 9412 /* 9413 * "foldlevel()" function 9414 */ 9415 static void 9416 f_foldlevel(argvars, rettv) 9417 typval_T *argvars; 9418 typval_T *rettv; 9419 { 9420 #ifdef FEAT_FOLDING 9421 linenr_T lnum; 9422 9423 lnum = get_tv_lnum(argvars); 9424 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9425 rettv->vval.v_number = foldLevel(lnum); 9426 else 9427 #endif 9428 rettv->vval.v_number = 0; 9429 } 9430 9431 /* 9432 * "foldtext()" function 9433 */ 9434 /*ARGSUSED*/ 9435 static void 9436 f_foldtext(argvars, rettv) 9437 typval_T *argvars; 9438 typval_T *rettv; 9439 { 9440 #ifdef FEAT_FOLDING 9441 linenr_T lnum; 9442 char_u *s; 9443 char_u *r; 9444 int len; 9445 char *txt; 9446 #endif 9447 9448 rettv->v_type = VAR_STRING; 9449 rettv->vval.v_string = NULL; 9450 #ifdef FEAT_FOLDING 9451 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9452 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9453 <= curbuf->b_ml.ml_line_count 9454 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9455 { 9456 /* Find first non-empty line in the fold. */ 9457 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9458 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9459 { 9460 if (!linewhite(lnum)) 9461 break; 9462 ++lnum; 9463 } 9464 9465 /* Find interesting text in this line. */ 9466 s = skipwhite(ml_get(lnum)); 9467 /* skip C comment-start */ 9468 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9469 { 9470 s = skipwhite(s + 2); 9471 if (*skipwhite(s) == NUL 9472 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9473 { 9474 s = skipwhite(ml_get(lnum + 1)); 9475 if (*s == '*') 9476 s = skipwhite(s + 1); 9477 } 9478 } 9479 txt = _("+-%s%3ld lines: "); 9480 r = alloc((unsigned)(STRLEN(txt) 9481 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9482 + 20 /* for %3ld */ 9483 + STRLEN(s))); /* concatenated */ 9484 if (r != NULL) 9485 { 9486 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9487 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9488 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9489 len = (int)STRLEN(r); 9490 STRCAT(r, s); 9491 /* remove 'foldmarker' and 'commentstring' */ 9492 foldtext_cleanup(r + len); 9493 rettv->vval.v_string = r; 9494 } 9495 } 9496 #endif 9497 } 9498 9499 /* 9500 * "foldtextresult(lnum)" function 9501 */ 9502 /*ARGSUSED*/ 9503 static void 9504 f_foldtextresult(argvars, rettv) 9505 typval_T *argvars; 9506 typval_T *rettv; 9507 { 9508 #ifdef FEAT_FOLDING 9509 linenr_T lnum; 9510 char_u *text; 9511 char_u buf[51]; 9512 foldinfo_T foldinfo; 9513 int fold_count; 9514 #endif 9515 9516 rettv->v_type = VAR_STRING; 9517 rettv->vval.v_string = NULL; 9518 #ifdef FEAT_FOLDING 9519 lnum = get_tv_lnum(argvars); 9520 /* treat illegal types and illegal string values for {lnum} the same */ 9521 if (lnum < 0) 9522 lnum = 0; 9523 fold_count = foldedCount(curwin, lnum, &foldinfo); 9524 if (fold_count > 0) 9525 { 9526 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9527 &foldinfo, buf); 9528 if (text == buf) 9529 text = vim_strsave(text); 9530 rettv->vval.v_string = text; 9531 } 9532 #endif 9533 } 9534 9535 /* 9536 * "foreground()" function 9537 */ 9538 /*ARGSUSED*/ 9539 static void 9540 f_foreground(argvars, rettv) 9541 typval_T *argvars; 9542 typval_T *rettv; 9543 { 9544 rettv->vval.v_number = 0; 9545 #ifdef FEAT_GUI 9546 if (gui.in_use) 9547 gui_mch_set_foreground(); 9548 #else 9549 # ifdef WIN32 9550 win32_set_foreground(); 9551 # endif 9552 #endif 9553 } 9554 9555 /* 9556 * "function()" function 9557 */ 9558 /*ARGSUSED*/ 9559 static void 9560 f_function(argvars, rettv) 9561 typval_T *argvars; 9562 typval_T *rettv; 9563 { 9564 char_u *s; 9565 9566 rettv->vval.v_number = 0; 9567 s = get_tv_string(&argvars[0]); 9568 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9569 EMSG2(_(e_invarg2), s); 9570 else if (!function_exists(s)) 9571 EMSG2(_("E700: Unknown function: %s"), s); 9572 else 9573 { 9574 rettv->vval.v_string = vim_strsave(s); 9575 rettv->v_type = VAR_FUNC; 9576 } 9577 } 9578 9579 /* 9580 * "garbagecollect()" function 9581 */ 9582 /*ARGSUSED*/ 9583 static void 9584 f_garbagecollect(argvars, rettv) 9585 typval_T *argvars; 9586 typval_T *rettv; 9587 { 9588 garbage_collect(); 9589 } 9590 9591 /* 9592 * "get()" function 9593 */ 9594 static void 9595 f_get(argvars, rettv) 9596 typval_T *argvars; 9597 typval_T *rettv; 9598 { 9599 listitem_T *li; 9600 list_T *l; 9601 dictitem_T *di; 9602 dict_T *d; 9603 typval_T *tv = NULL; 9604 9605 if (argvars[0].v_type == VAR_LIST) 9606 { 9607 if ((l = argvars[0].vval.v_list) != NULL) 9608 { 9609 int error = FALSE; 9610 9611 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9612 if (!error && li != NULL) 9613 tv = &li->li_tv; 9614 } 9615 } 9616 else if (argvars[0].v_type == VAR_DICT) 9617 { 9618 if ((d = argvars[0].vval.v_dict) != NULL) 9619 { 9620 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9621 if (di != NULL) 9622 tv = &di->di_tv; 9623 } 9624 } 9625 else 9626 EMSG2(_(e_listdictarg), "get()"); 9627 9628 if (tv == NULL) 9629 { 9630 if (argvars[2].v_type == VAR_UNKNOWN) 9631 rettv->vval.v_number = 0; 9632 else 9633 copy_tv(&argvars[2], rettv); 9634 } 9635 else 9636 copy_tv(tv, rettv); 9637 } 9638 9639 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9640 9641 /* 9642 * Get line or list of lines from buffer "buf" into "rettv". 9643 * Return a range (from start to end) of lines in rettv from the specified 9644 * buffer. 9645 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9646 */ 9647 static void 9648 get_buffer_lines(buf, start, end, retlist, rettv) 9649 buf_T *buf; 9650 linenr_T start; 9651 linenr_T end; 9652 int retlist; 9653 typval_T *rettv; 9654 { 9655 char_u *p; 9656 9657 if (retlist) 9658 { 9659 if (rettv_list_alloc(rettv) == FAIL) 9660 return; 9661 } 9662 else 9663 rettv->vval.v_number = 0; 9664 9665 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9666 return; 9667 9668 if (!retlist) 9669 { 9670 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9671 p = ml_get_buf(buf, start, FALSE); 9672 else 9673 p = (char_u *)""; 9674 9675 rettv->v_type = VAR_STRING; 9676 rettv->vval.v_string = vim_strsave(p); 9677 } 9678 else 9679 { 9680 if (end < start) 9681 return; 9682 9683 if (start < 1) 9684 start = 1; 9685 if (end > buf->b_ml.ml_line_count) 9686 end = buf->b_ml.ml_line_count; 9687 while (start <= end) 9688 if (list_append_string(rettv->vval.v_list, 9689 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 9690 break; 9691 } 9692 } 9693 9694 /* 9695 * "getbufline()" function 9696 */ 9697 static void 9698 f_getbufline(argvars, rettv) 9699 typval_T *argvars; 9700 typval_T *rettv; 9701 { 9702 linenr_T lnum; 9703 linenr_T end; 9704 buf_T *buf; 9705 9706 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9707 ++emsg_off; 9708 buf = get_buf_tv(&argvars[0]); 9709 --emsg_off; 9710 9711 lnum = get_tv_lnum_buf(&argvars[1], buf); 9712 if (argvars[2].v_type == VAR_UNKNOWN) 9713 end = lnum; 9714 else 9715 end = get_tv_lnum_buf(&argvars[2], buf); 9716 9717 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9718 } 9719 9720 /* 9721 * "getbufvar()" function 9722 */ 9723 static void 9724 f_getbufvar(argvars, rettv) 9725 typval_T *argvars; 9726 typval_T *rettv; 9727 { 9728 buf_T *buf; 9729 buf_T *save_curbuf; 9730 char_u *varname; 9731 dictitem_T *v; 9732 9733 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9734 varname = get_tv_string_chk(&argvars[1]); 9735 ++emsg_off; 9736 buf = get_buf_tv(&argvars[0]); 9737 9738 rettv->v_type = VAR_STRING; 9739 rettv->vval.v_string = NULL; 9740 9741 if (buf != NULL && varname != NULL) 9742 { 9743 if (*varname == '&') /* buffer-local-option */ 9744 { 9745 /* set curbuf to be our buf, temporarily */ 9746 save_curbuf = curbuf; 9747 curbuf = buf; 9748 9749 get_option_tv(&varname, rettv, TRUE); 9750 9751 /* restore previous notion of curbuf */ 9752 curbuf = save_curbuf; 9753 } 9754 else 9755 { 9756 if (*varname == NUL) 9757 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9758 * scope prefix before the NUL byte is required by 9759 * find_var_in_ht(). */ 9760 varname = (char_u *)"b:" + 2; 9761 /* look up the variable */ 9762 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9763 if (v != NULL) 9764 copy_tv(&v->di_tv, rettv); 9765 } 9766 } 9767 9768 --emsg_off; 9769 } 9770 9771 /* 9772 * "getchar()" function 9773 */ 9774 static void 9775 f_getchar(argvars, rettv) 9776 typval_T *argvars; 9777 typval_T *rettv; 9778 { 9779 varnumber_T n; 9780 int error = FALSE; 9781 9782 ++no_mapping; 9783 ++allow_keys; 9784 if (argvars[0].v_type == VAR_UNKNOWN) 9785 /* getchar(): blocking wait. */ 9786 n = safe_vgetc(); 9787 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9788 /* getchar(1): only check if char avail */ 9789 n = vpeekc(); 9790 else if (error || vpeekc() == NUL) 9791 /* illegal argument or getchar(0) and no char avail: return zero */ 9792 n = 0; 9793 else 9794 /* getchar(0) and char avail: return char */ 9795 n = safe_vgetc(); 9796 --no_mapping; 9797 --allow_keys; 9798 9799 rettv->vval.v_number = n; 9800 if (IS_SPECIAL(n) || mod_mask != 0) 9801 { 9802 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9803 int i = 0; 9804 9805 /* Turn a special key into three bytes, plus modifier. */ 9806 if (mod_mask != 0) 9807 { 9808 temp[i++] = K_SPECIAL; 9809 temp[i++] = KS_MODIFIER; 9810 temp[i++] = mod_mask; 9811 } 9812 if (IS_SPECIAL(n)) 9813 { 9814 temp[i++] = K_SPECIAL; 9815 temp[i++] = K_SECOND(n); 9816 temp[i++] = K_THIRD(n); 9817 } 9818 #ifdef FEAT_MBYTE 9819 else if (has_mbyte) 9820 i += (*mb_char2bytes)(n, temp + i); 9821 #endif 9822 else 9823 temp[i++] = n; 9824 temp[i++] = NUL; 9825 rettv->v_type = VAR_STRING; 9826 rettv->vval.v_string = vim_strsave(temp); 9827 } 9828 } 9829 9830 /* 9831 * "getcharmod()" function 9832 */ 9833 /*ARGSUSED*/ 9834 static void 9835 f_getcharmod(argvars, rettv) 9836 typval_T *argvars; 9837 typval_T *rettv; 9838 { 9839 rettv->vval.v_number = mod_mask; 9840 } 9841 9842 /* 9843 * "getcmdline()" function 9844 */ 9845 /*ARGSUSED*/ 9846 static void 9847 f_getcmdline(argvars, rettv) 9848 typval_T *argvars; 9849 typval_T *rettv; 9850 { 9851 rettv->v_type = VAR_STRING; 9852 rettv->vval.v_string = get_cmdline_str(); 9853 } 9854 9855 /* 9856 * "getcmdpos()" function 9857 */ 9858 /*ARGSUSED*/ 9859 static void 9860 f_getcmdpos(argvars, rettv) 9861 typval_T *argvars; 9862 typval_T *rettv; 9863 { 9864 rettv->vval.v_number = get_cmdline_pos() + 1; 9865 } 9866 9867 /* 9868 * "getcmdtype()" function 9869 */ 9870 /*ARGSUSED*/ 9871 static void 9872 f_getcmdtype(argvars, rettv) 9873 typval_T *argvars; 9874 typval_T *rettv; 9875 { 9876 rettv->v_type = VAR_STRING; 9877 rettv->vval.v_string = alloc(2); 9878 if (rettv->vval.v_string != NULL) 9879 { 9880 rettv->vval.v_string[0] = get_cmdline_type(); 9881 rettv->vval.v_string[1] = NUL; 9882 } 9883 } 9884 9885 /* 9886 * "getcwd()" function 9887 */ 9888 /*ARGSUSED*/ 9889 static void 9890 f_getcwd(argvars, rettv) 9891 typval_T *argvars; 9892 typval_T *rettv; 9893 { 9894 char_u cwd[MAXPATHL]; 9895 9896 rettv->v_type = VAR_STRING; 9897 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9898 rettv->vval.v_string = NULL; 9899 else 9900 { 9901 rettv->vval.v_string = vim_strsave(cwd); 9902 #ifdef BACKSLASH_IN_FILENAME 9903 if (rettv->vval.v_string != NULL) 9904 slash_adjust(rettv->vval.v_string); 9905 #endif 9906 } 9907 } 9908 9909 /* 9910 * "getfontname()" function 9911 */ 9912 /*ARGSUSED*/ 9913 static void 9914 f_getfontname(argvars, rettv) 9915 typval_T *argvars; 9916 typval_T *rettv; 9917 { 9918 rettv->v_type = VAR_STRING; 9919 rettv->vval.v_string = NULL; 9920 #ifdef FEAT_GUI 9921 if (gui.in_use) 9922 { 9923 GuiFont font; 9924 char_u *name = NULL; 9925 9926 if (argvars[0].v_type == VAR_UNKNOWN) 9927 { 9928 /* Get the "Normal" font. Either the name saved by 9929 * hl_set_font_name() or from the font ID. */ 9930 font = gui.norm_font; 9931 name = hl_get_font_name(); 9932 } 9933 else 9934 { 9935 name = get_tv_string(&argvars[0]); 9936 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9937 return; 9938 font = gui_mch_get_font(name, FALSE); 9939 if (font == NOFONT) 9940 return; /* Invalid font name, return empty string. */ 9941 } 9942 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9943 if (argvars[0].v_type != VAR_UNKNOWN) 9944 gui_mch_free_font(font); 9945 } 9946 #endif 9947 } 9948 9949 /* 9950 * "getfperm({fname})" function 9951 */ 9952 static void 9953 f_getfperm(argvars, rettv) 9954 typval_T *argvars; 9955 typval_T *rettv; 9956 { 9957 char_u *fname; 9958 struct stat st; 9959 char_u *perm = NULL; 9960 char_u flags[] = "rwx"; 9961 int i; 9962 9963 fname = get_tv_string(&argvars[0]); 9964 9965 rettv->v_type = VAR_STRING; 9966 if (mch_stat((char *)fname, &st) >= 0) 9967 { 9968 perm = vim_strsave((char_u *)"---------"); 9969 if (perm != NULL) 9970 { 9971 for (i = 0; i < 9; i++) 9972 { 9973 if (st.st_mode & (1 << (8 - i))) 9974 perm[i] = flags[i % 3]; 9975 } 9976 } 9977 } 9978 rettv->vval.v_string = perm; 9979 } 9980 9981 /* 9982 * "getfsize({fname})" function 9983 */ 9984 static void 9985 f_getfsize(argvars, rettv) 9986 typval_T *argvars; 9987 typval_T *rettv; 9988 { 9989 char_u *fname; 9990 struct stat st; 9991 9992 fname = get_tv_string(&argvars[0]); 9993 9994 rettv->v_type = VAR_NUMBER; 9995 9996 if (mch_stat((char *)fname, &st) >= 0) 9997 { 9998 if (mch_isdir(fname)) 9999 rettv->vval.v_number = 0; 10000 else 10001 rettv->vval.v_number = (varnumber_T)st.st_size; 10002 } 10003 else 10004 rettv->vval.v_number = -1; 10005 } 10006 10007 /* 10008 * "getftime({fname})" function 10009 */ 10010 static void 10011 f_getftime(argvars, rettv) 10012 typval_T *argvars; 10013 typval_T *rettv; 10014 { 10015 char_u *fname; 10016 struct stat st; 10017 10018 fname = get_tv_string(&argvars[0]); 10019 10020 if (mch_stat((char *)fname, &st) >= 0) 10021 rettv->vval.v_number = (varnumber_T)st.st_mtime; 10022 else 10023 rettv->vval.v_number = -1; 10024 } 10025 10026 /* 10027 * "getftype({fname})" function 10028 */ 10029 static void 10030 f_getftype(argvars, rettv) 10031 typval_T *argvars; 10032 typval_T *rettv; 10033 { 10034 char_u *fname; 10035 struct stat st; 10036 char_u *type = NULL; 10037 char *t; 10038 10039 fname = get_tv_string(&argvars[0]); 10040 10041 rettv->v_type = VAR_STRING; 10042 if (mch_lstat((char *)fname, &st) >= 0) 10043 { 10044 #ifdef S_ISREG 10045 if (S_ISREG(st.st_mode)) 10046 t = "file"; 10047 else if (S_ISDIR(st.st_mode)) 10048 t = "dir"; 10049 # ifdef S_ISLNK 10050 else if (S_ISLNK(st.st_mode)) 10051 t = "link"; 10052 # endif 10053 # ifdef S_ISBLK 10054 else if (S_ISBLK(st.st_mode)) 10055 t = "bdev"; 10056 # endif 10057 # ifdef S_ISCHR 10058 else if (S_ISCHR(st.st_mode)) 10059 t = "cdev"; 10060 # endif 10061 # ifdef S_ISFIFO 10062 else if (S_ISFIFO(st.st_mode)) 10063 t = "fifo"; 10064 # endif 10065 # ifdef S_ISSOCK 10066 else if (S_ISSOCK(st.st_mode)) 10067 t = "fifo"; 10068 # endif 10069 else 10070 t = "other"; 10071 #else 10072 # ifdef S_IFMT 10073 switch (st.st_mode & S_IFMT) 10074 { 10075 case S_IFREG: t = "file"; break; 10076 case S_IFDIR: t = "dir"; break; 10077 # ifdef S_IFLNK 10078 case S_IFLNK: t = "link"; break; 10079 # endif 10080 # ifdef S_IFBLK 10081 case S_IFBLK: t = "bdev"; break; 10082 # endif 10083 # ifdef S_IFCHR 10084 case S_IFCHR: t = "cdev"; break; 10085 # endif 10086 # ifdef S_IFIFO 10087 case S_IFIFO: t = "fifo"; break; 10088 # endif 10089 # ifdef S_IFSOCK 10090 case S_IFSOCK: t = "socket"; break; 10091 # endif 10092 default: t = "other"; 10093 } 10094 # else 10095 if (mch_isdir(fname)) 10096 t = "dir"; 10097 else 10098 t = "file"; 10099 # endif 10100 #endif 10101 type = vim_strsave((char_u *)t); 10102 } 10103 rettv->vval.v_string = type; 10104 } 10105 10106 /* 10107 * "getline(lnum, [end])" function 10108 */ 10109 static void 10110 f_getline(argvars, rettv) 10111 typval_T *argvars; 10112 typval_T *rettv; 10113 { 10114 linenr_T lnum; 10115 linenr_T end; 10116 int retlist; 10117 10118 lnum = get_tv_lnum(argvars); 10119 if (argvars[1].v_type == VAR_UNKNOWN) 10120 { 10121 end = 0; 10122 retlist = FALSE; 10123 } 10124 else 10125 { 10126 end = get_tv_lnum(&argvars[1]); 10127 retlist = TRUE; 10128 } 10129 10130 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 10131 } 10132 10133 /* 10134 * "getpos(string)" function 10135 */ 10136 static void 10137 f_getpos(argvars, rettv) 10138 typval_T *argvars; 10139 typval_T *rettv; 10140 { 10141 pos_T *fp; 10142 list_T *l; 10143 int fnum = -1; 10144 10145 if (rettv_list_alloc(rettv) == OK) 10146 { 10147 l = rettv->vval.v_list; 10148 fp = var2fpos(&argvars[0], TRUE, &fnum); 10149 if (fnum != -1) 10150 list_append_number(l, (varnumber_T)fnum); 10151 else 10152 list_append_number(l, (varnumber_T)0); 10153 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 10154 : (varnumber_T)0); 10155 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1 10156 : (varnumber_T)0); 10157 list_append_number(l, 10158 #ifdef FEAT_VIRTUALEDIT 10159 (fp != NULL) ? (varnumber_T)fp->coladd : 10160 #endif 10161 (varnumber_T)0); 10162 } 10163 else 10164 rettv->vval.v_number = FALSE; 10165 } 10166 10167 /* 10168 * "getqflist()" and "getloclist()" functions 10169 */ 10170 /*ARGSUSED*/ 10171 static void 10172 f_getqflist(argvars, rettv) 10173 typval_T *argvars; 10174 typval_T *rettv; 10175 { 10176 #ifdef FEAT_QUICKFIX 10177 win_T *wp; 10178 #endif 10179 10180 rettv->vval.v_number = FALSE; 10181 #ifdef FEAT_QUICKFIX 10182 if (rettv_list_alloc(rettv) == OK) 10183 { 10184 wp = NULL; 10185 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 10186 { 10187 wp = find_win_by_nr(&argvars[0], NULL); 10188 if (wp == NULL) 10189 return; 10190 } 10191 10192 (void)get_errorlist(wp, rettv->vval.v_list); 10193 } 10194 #endif 10195 } 10196 10197 /* 10198 * "getreg()" function 10199 */ 10200 static void 10201 f_getreg(argvars, rettv) 10202 typval_T *argvars; 10203 typval_T *rettv; 10204 { 10205 char_u *strregname; 10206 int regname; 10207 int arg2 = FALSE; 10208 int error = FALSE; 10209 10210 if (argvars[0].v_type != VAR_UNKNOWN) 10211 { 10212 strregname = get_tv_string_chk(&argvars[0]); 10213 error = strregname == NULL; 10214 if (argvars[1].v_type != VAR_UNKNOWN) 10215 arg2 = get_tv_number_chk(&argvars[1], &error); 10216 } 10217 else 10218 strregname = vimvars[VV_REG].vv_str; 10219 regname = (strregname == NULL ? '"' : *strregname); 10220 if (regname == 0) 10221 regname = '"'; 10222 10223 rettv->v_type = VAR_STRING; 10224 rettv->vval.v_string = error ? NULL : 10225 get_reg_contents(regname, TRUE, arg2); 10226 } 10227 10228 /* 10229 * "getregtype()" function 10230 */ 10231 static void 10232 f_getregtype(argvars, rettv) 10233 typval_T *argvars; 10234 typval_T *rettv; 10235 { 10236 char_u *strregname; 10237 int regname; 10238 char_u buf[NUMBUFLEN + 2]; 10239 long reglen = 0; 10240 10241 if (argvars[0].v_type != VAR_UNKNOWN) 10242 { 10243 strregname = get_tv_string_chk(&argvars[0]); 10244 if (strregname == NULL) /* type error; errmsg already given */ 10245 { 10246 rettv->v_type = VAR_STRING; 10247 rettv->vval.v_string = NULL; 10248 return; 10249 } 10250 } 10251 else 10252 /* Default to v:register */ 10253 strregname = vimvars[VV_REG].vv_str; 10254 10255 regname = (strregname == NULL ? '"' : *strregname); 10256 if (regname == 0) 10257 regname = '"'; 10258 10259 buf[0] = NUL; 10260 buf[1] = NUL; 10261 switch (get_reg_type(regname, ®len)) 10262 { 10263 case MLINE: buf[0] = 'V'; break; 10264 case MCHAR: buf[0] = 'v'; break; 10265 #ifdef FEAT_VISUAL 10266 case MBLOCK: 10267 buf[0] = Ctrl_V; 10268 sprintf((char *)buf + 1, "%ld", reglen + 1); 10269 break; 10270 #endif 10271 } 10272 rettv->v_type = VAR_STRING; 10273 rettv->vval.v_string = vim_strsave(buf); 10274 } 10275 10276 /* 10277 * "gettabwinvar()" function 10278 */ 10279 static void 10280 f_gettabwinvar(argvars, rettv) 10281 typval_T *argvars; 10282 typval_T *rettv; 10283 { 10284 getwinvar(argvars, rettv, 1); 10285 } 10286 10287 /* 10288 * "getwinposx()" function 10289 */ 10290 /*ARGSUSED*/ 10291 static void 10292 f_getwinposx(argvars, rettv) 10293 typval_T *argvars; 10294 typval_T *rettv; 10295 { 10296 rettv->vval.v_number = -1; 10297 #ifdef FEAT_GUI 10298 if (gui.in_use) 10299 { 10300 int x, y; 10301 10302 if (gui_mch_get_winpos(&x, &y) == OK) 10303 rettv->vval.v_number = x; 10304 } 10305 #endif 10306 } 10307 10308 /* 10309 * "getwinposy()" function 10310 */ 10311 /*ARGSUSED*/ 10312 static void 10313 f_getwinposy(argvars, rettv) 10314 typval_T *argvars; 10315 typval_T *rettv; 10316 { 10317 rettv->vval.v_number = -1; 10318 #ifdef FEAT_GUI 10319 if (gui.in_use) 10320 { 10321 int x, y; 10322 10323 if (gui_mch_get_winpos(&x, &y) == OK) 10324 rettv->vval.v_number = y; 10325 } 10326 #endif 10327 } 10328 10329 /* 10330 * Find window specifed by "vp" in tabpage "tp". 10331 */ 10332 static win_T * 10333 find_win_by_nr(vp, tp) 10334 typval_T *vp; 10335 tabpage_T *tp; /* NULL for current tab page */ 10336 { 10337 #ifdef FEAT_WINDOWS 10338 win_T *wp; 10339 #endif 10340 int nr; 10341 10342 nr = get_tv_number_chk(vp, NULL); 10343 10344 #ifdef FEAT_WINDOWS 10345 if (nr < 0) 10346 return NULL; 10347 if (nr == 0) 10348 return curwin; 10349 10350 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 10351 wp != NULL; wp = wp->w_next) 10352 if (--nr <= 0) 10353 break; 10354 return wp; 10355 #else 10356 if (nr == 0 || nr == 1) 10357 return curwin; 10358 return NULL; 10359 #endif 10360 } 10361 10362 /* 10363 * "getwinvar()" function 10364 */ 10365 static void 10366 f_getwinvar(argvars, rettv) 10367 typval_T *argvars; 10368 typval_T *rettv; 10369 { 10370 getwinvar(argvars, rettv, 0); 10371 } 10372 10373 /* 10374 * getwinvar() and gettabwinvar() 10375 */ 10376 static void 10377 getwinvar(argvars, rettv, off) 10378 typval_T *argvars; 10379 typval_T *rettv; 10380 int off; /* 1 for gettabwinvar() */ 10381 { 10382 win_T *win, *oldcurwin; 10383 char_u *varname; 10384 dictitem_T *v; 10385 tabpage_T *tp; 10386 10387 #ifdef FEAT_WINDOWS 10388 if (off == 1) 10389 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 10390 else 10391 tp = curtab; 10392 #endif 10393 win = find_win_by_nr(&argvars[off], tp); 10394 varname = get_tv_string_chk(&argvars[off + 1]); 10395 ++emsg_off; 10396 10397 rettv->v_type = VAR_STRING; 10398 rettv->vval.v_string = NULL; 10399 10400 if (win != NULL && varname != NULL) 10401 { 10402 if (*varname == '&') /* window-local-option */ 10403 { 10404 /* Set curwin to be our win, temporarily. Also set curbuf, so 10405 * that we can get buffer-local options. */ 10406 oldcurwin = curwin; 10407 curwin = win; 10408 curbuf = win->w_buffer; 10409 10410 get_option_tv(&varname, rettv, 1); 10411 10412 /* restore previous notion of curwin */ 10413 curwin = oldcurwin; 10414 curbuf = curwin->w_buffer; 10415 } 10416 else 10417 { 10418 if (*varname == NUL) 10419 /* let getwinvar({nr}, "") return the "w:" dictionary. The 10420 * scope prefix before the NUL byte is required by 10421 * find_var_in_ht(). */ 10422 varname = (char_u *)"w:" + 2; 10423 /* look up the variable */ 10424 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 10425 if (v != NULL) 10426 copy_tv(&v->di_tv, rettv); 10427 } 10428 } 10429 10430 --emsg_off; 10431 } 10432 10433 /* 10434 * "glob()" function 10435 */ 10436 static void 10437 f_glob(argvars, rettv) 10438 typval_T *argvars; 10439 typval_T *rettv; 10440 { 10441 expand_T xpc; 10442 10443 ExpandInit(&xpc); 10444 xpc.xp_context = EXPAND_FILES; 10445 rettv->v_type = VAR_STRING; 10446 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 10447 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 10448 } 10449 10450 /* 10451 * "globpath()" function 10452 */ 10453 static void 10454 f_globpath(argvars, rettv) 10455 typval_T *argvars; 10456 typval_T *rettv; 10457 { 10458 char_u buf1[NUMBUFLEN]; 10459 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 10460 10461 rettv->v_type = VAR_STRING; 10462 if (file == NULL) 10463 rettv->vval.v_string = NULL; 10464 else 10465 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 10466 } 10467 10468 /* 10469 * "has()" function 10470 */ 10471 static void 10472 f_has(argvars, rettv) 10473 typval_T *argvars; 10474 typval_T *rettv; 10475 { 10476 int i; 10477 char_u *name; 10478 int n = FALSE; 10479 static char *(has_list[]) = 10480 { 10481 #ifdef AMIGA 10482 "amiga", 10483 # ifdef FEAT_ARP 10484 "arp", 10485 # endif 10486 #endif 10487 #ifdef __BEOS__ 10488 "beos", 10489 #endif 10490 #ifdef MSDOS 10491 # ifdef DJGPP 10492 "dos32", 10493 # else 10494 "dos16", 10495 # endif 10496 #endif 10497 #ifdef MACOS 10498 "mac", 10499 #endif 10500 #if defined(MACOS_X_UNIX) 10501 "macunix", 10502 #endif 10503 #ifdef OS2 10504 "os2", 10505 #endif 10506 #ifdef __QNX__ 10507 "qnx", 10508 #endif 10509 #ifdef RISCOS 10510 "riscos", 10511 #endif 10512 #ifdef UNIX 10513 "unix", 10514 #endif 10515 #ifdef VMS 10516 "vms", 10517 #endif 10518 #ifdef WIN16 10519 "win16", 10520 #endif 10521 #ifdef WIN32 10522 "win32", 10523 #endif 10524 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10525 "win32unix", 10526 #endif 10527 #ifdef WIN64 10528 "win64", 10529 #endif 10530 #ifdef EBCDIC 10531 "ebcdic", 10532 #endif 10533 #ifndef CASE_INSENSITIVE_FILENAME 10534 "fname_case", 10535 #endif 10536 #ifdef FEAT_ARABIC 10537 "arabic", 10538 #endif 10539 #ifdef FEAT_AUTOCMD 10540 "autocmd", 10541 #endif 10542 #ifdef FEAT_BEVAL 10543 "balloon_eval", 10544 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10545 "balloon_multiline", 10546 # endif 10547 #endif 10548 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10549 "builtin_terms", 10550 # ifdef ALL_BUILTIN_TCAPS 10551 "all_builtin_terms", 10552 # endif 10553 #endif 10554 #ifdef FEAT_BYTEOFF 10555 "byte_offset", 10556 #endif 10557 #ifdef FEAT_CINDENT 10558 "cindent", 10559 #endif 10560 #ifdef FEAT_CLIENTSERVER 10561 "clientserver", 10562 #endif 10563 #ifdef FEAT_CLIPBOARD 10564 "clipboard", 10565 #endif 10566 #ifdef FEAT_CMDL_COMPL 10567 "cmdline_compl", 10568 #endif 10569 #ifdef FEAT_CMDHIST 10570 "cmdline_hist", 10571 #endif 10572 #ifdef FEAT_COMMENTS 10573 "comments", 10574 #endif 10575 #ifdef FEAT_CRYPT 10576 "cryptv", 10577 #endif 10578 #ifdef FEAT_CSCOPE 10579 "cscope", 10580 #endif 10581 #ifdef CURSOR_SHAPE 10582 "cursorshape", 10583 #endif 10584 #ifdef DEBUG 10585 "debug", 10586 #endif 10587 #ifdef FEAT_CON_DIALOG 10588 "dialog_con", 10589 #endif 10590 #ifdef FEAT_GUI_DIALOG 10591 "dialog_gui", 10592 #endif 10593 #ifdef FEAT_DIFF 10594 "diff", 10595 #endif 10596 #ifdef FEAT_DIGRAPHS 10597 "digraphs", 10598 #endif 10599 #ifdef FEAT_DND 10600 "dnd", 10601 #endif 10602 #ifdef FEAT_EMACS_TAGS 10603 "emacs_tags", 10604 #endif 10605 "eval", /* always present, of course! */ 10606 #ifdef FEAT_EX_EXTRA 10607 "ex_extra", 10608 #endif 10609 #ifdef FEAT_SEARCH_EXTRA 10610 "extra_search", 10611 #endif 10612 #ifdef FEAT_FKMAP 10613 "farsi", 10614 #endif 10615 #ifdef FEAT_SEARCHPATH 10616 "file_in_path", 10617 #endif 10618 #if defined(UNIX) && !defined(USE_SYSTEM) 10619 "filterpipe", 10620 #endif 10621 #ifdef FEAT_FIND_ID 10622 "find_in_path", 10623 #endif 10624 #ifdef FEAT_FOLDING 10625 "folding", 10626 #endif 10627 #ifdef FEAT_FOOTER 10628 "footer", 10629 #endif 10630 #if !defined(USE_SYSTEM) && defined(UNIX) 10631 "fork", 10632 #endif 10633 #ifdef FEAT_GETTEXT 10634 "gettext", 10635 #endif 10636 #ifdef FEAT_GUI 10637 "gui", 10638 #endif 10639 #ifdef FEAT_GUI_ATHENA 10640 # ifdef FEAT_GUI_NEXTAW 10641 "gui_neXtaw", 10642 # else 10643 "gui_athena", 10644 # endif 10645 #endif 10646 #ifdef FEAT_GUI_GTK 10647 "gui_gtk", 10648 # ifdef HAVE_GTK2 10649 "gui_gtk2", 10650 # endif 10651 #endif 10652 #ifdef FEAT_GUI_MAC 10653 "gui_mac", 10654 #endif 10655 #ifdef FEAT_GUI_MOTIF 10656 "gui_motif", 10657 #endif 10658 #ifdef FEAT_GUI_PHOTON 10659 "gui_photon", 10660 #endif 10661 #ifdef FEAT_GUI_W16 10662 "gui_win16", 10663 #endif 10664 #ifdef FEAT_GUI_W32 10665 "gui_win32", 10666 #endif 10667 #ifdef FEAT_HANGULIN 10668 "hangul_input", 10669 #endif 10670 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10671 "iconv", 10672 #endif 10673 #ifdef FEAT_INS_EXPAND 10674 "insert_expand", 10675 #endif 10676 #ifdef FEAT_JUMPLIST 10677 "jumplist", 10678 #endif 10679 #ifdef FEAT_KEYMAP 10680 "keymap", 10681 #endif 10682 #ifdef FEAT_LANGMAP 10683 "langmap", 10684 #endif 10685 #ifdef FEAT_LIBCALL 10686 "libcall", 10687 #endif 10688 #ifdef FEAT_LINEBREAK 10689 "linebreak", 10690 #endif 10691 #ifdef FEAT_LISP 10692 "lispindent", 10693 #endif 10694 #ifdef FEAT_LISTCMDS 10695 "listcmds", 10696 #endif 10697 #ifdef FEAT_LOCALMAP 10698 "localmap", 10699 #endif 10700 #ifdef FEAT_MENU 10701 "menu", 10702 #endif 10703 #ifdef FEAT_SESSION 10704 "mksession", 10705 #endif 10706 #ifdef FEAT_MODIFY_FNAME 10707 "modify_fname", 10708 #endif 10709 #ifdef FEAT_MOUSE 10710 "mouse", 10711 #endif 10712 #ifdef FEAT_MOUSESHAPE 10713 "mouseshape", 10714 #endif 10715 #if defined(UNIX) || defined(VMS) 10716 # ifdef FEAT_MOUSE_DEC 10717 "mouse_dec", 10718 # endif 10719 # ifdef FEAT_MOUSE_GPM 10720 "mouse_gpm", 10721 # endif 10722 # ifdef FEAT_MOUSE_JSB 10723 "mouse_jsbterm", 10724 # endif 10725 # ifdef FEAT_MOUSE_NET 10726 "mouse_netterm", 10727 # endif 10728 # ifdef FEAT_MOUSE_PTERM 10729 "mouse_pterm", 10730 # endif 10731 # ifdef FEAT_MOUSE_XTERM 10732 "mouse_xterm", 10733 # endif 10734 #endif 10735 #ifdef FEAT_MBYTE 10736 "multi_byte", 10737 #endif 10738 #ifdef FEAT_MBYTE_IME 10739 "multi_byte_ime", 10740 #endif 10741 #ifdef FEAT_MULTI_LANG 10742 "multi_lang", 10743 #endif 10744 #ifdef FEAT_MZSCHEME 10745 #ifndef DYNAMIC_MZSCHEME 10746 "mzscheme", 10747 #endif 10748 #endif 10749 #ifdef FEAT_OLE 10750 "ole", 10751 #endif 10752 #ifdef FEAT_OSFILETYPE 10753 "osfiletype", 10754 #endif 10755 #ifdef FEAT_PATH_EXTRA 10756 "path_extra", 10757 #endif 10758 #ifdef FEAT_PERL 10759 #ifndef DYNAMIC_PERL 10760 "perl", 10761 #endif 10762 #endif 10763 #ifdef FEAT_PYTHON 10764 #ifndef DYNAMIC_PYTHON 10765 "python", 10766 #endif 10767 #endif 10768 #ifdef FEAT_POSTSCRIPT 10769 "postscript", 10770 #endif 10771 #ifdef FEAT_PRINTER 10772 "printer", 10773 #endif 10774 #ifdef FEAT_PROFILE 10775 "profile", 10776 #endif 10777 #ifdef FEAT_RELTIME 10778 "reltime", 10779 #endif 10780 #ifdef FEAT_QUICKFIX 10781 "quickfix", 10782 #endif 10783 #ifdef FEAT_RIGHTLEFT 10784 "rightleft", 10785 #endif 10786 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10787 "ruby", 10788 #endif 10789 #ifdef FEAT_SCROLLBIND 10790 "scrollbind", 10791 #endif 10792 #ifdef FEAT_CMDL_INFO 10793 "showcmd", 10794 "cmdline_info", 10795 #endif 10796 #ifdef FEAT_SIGNS 10797 "signs", 10798 #endif 10799 #ifdef FEAT_SMARTINDENT 10800 "smartindent", 10801 #endif 10802 #ifdef FEAT_SNIFF 10803 "sniff", 10804 #endif 10805 #ifdef FEAT_STL_OPT 10806 "statusline", 10807 #endif 10808 #ifdef FEAT_SUN_WORKSHOP 10809 "sun_workshop", 10810 #endif 10811 #ifdef FEAT_NETBEANS_INTG 10812 "netbeans_intg", 10813 #endif 10814 #ifdef FEAT_SPELL 10815 "spell", 10816 #endif 10817 #ifdef FEAT_SYN_HL 10818 "syntax", 10819 #endif 10820 #if defined(USE_SYSTEM) || !defined(UNIX) 10821 "system", 10822 #endif 10823 #ifdef FEAT_TAG_BINS 10824 "tag_binary", 10825 #endif 10826 #ifdef FEAT_TAG_OLDSTATIC 10827 "tag_old_static", 10828 #endif 10829 #ifdef FEAT_TAG_ANYWHITE 10830 "tag_any_white", 10831 #endif 10832 #ifdef FEAT_TCL 10833 # ifndef DYNAMIC_TCL 10834 "tcl", 10835 # endif 10836 #endif 10837 #ifdef TERMINFO 10838 "terminfo", 10839 #endif 10840 #ifdef FEAT_TERMRESPONSE 10841 "termresponse", 10842 #endif 10843 #ifdef FEAT_TEXTOBJ 10844 "textobjects", 10845 #endif 10846 #ifdef HAVE_TGETENT 10847 "tgetent", 10848 #endif 10849 #ifdef FEAT_TITLE 10850 "title", 10851 #endif 10852 #ifdef FEAT_TOOLBAR 10853 "toolbar", 10854 #endif 10855 #ifdef FEAT_USR_CMDS 10856 "user-commands", /* was accidentally included in 5.4 */ 10857 "user_commands", 10858 #endif 10859 #ifdef FEAT_VIMINFO 10860 "viminfo", 10861 #endif 10862 #ifdef FEAT_VERTSPLIT 10863 "vertsplit", 10864 #endif 10865 #ifdef FEAT_VIRTUALEDIT 10866 "virtualedit", 10867 #endif 10868 #ifdef FEAT_VISUAL 10869 "visual", 10870 #endif 10871 #ifdef FEAT_VISUALEXTRA 10872 "visualextra", 10873 #endif 10874 #ifdef FEAT_VREPLACE 10875 "vreplace", 10876 #endif 10877 #ifdef FEAT_WILDIGN 10878 "wildignore", 10879 #endif 10880 #ifdef FEAT_WILDMENU 10881 "wildmenu", 10882 #endif 10883 #ifdef FEAT_WINDOWS 10884 "windows", 10885 #endif 10886 #ifdef FEAT_WAK 10887 "winaltkeys", 10888 #endif 10889 #ifdef FEAT_WRITEBACKUP 10890 "writebackup", 10891 #endif 10892 #ifdef FEAT_XIM 10893 "xim", 10894 #endif 10895 #ifdef FEAT_XFONTSET 10896 "xfontset", 10897 #endif 10898 #ifdef USE_XSMP 10899 "xsmp", 10900 #endif 10901 #ifdef USE_XSMP_INTERACT 10902 "xsmp_interact", 10903 #endif 10904 #ifdef FEAT_XCLIPBOARD 10905 "xterm_clipboard", 10906 #endif 10907 #ifdef FEAT_XTERM_SAVE 10908 "xterm_save", 10909 #endif 10910 #if defined(UNIX) && defined(FEAT_X11) 10911 "X11", 10912 #endif 10913 NULL 10914 }; 10915 10916 name = get_tv_string(&argvars[0]); 10917 for (i = 0; has_list[i] != NULL; ++i) 10918 if (STRICMP(name, has_list[i]) == 0) 10919 { 10920 n = TRUE; 10921 break; 10922 } 10923 10924 if (n == FALSE) 10925 { 10926 if (STRNICMP(name, "patch", 5) == 0) 10927 n = has_patch(atoi((char *)name + 5)); 10928 else if (STRICMP(name, "vim_starting") == 0) 10929 n = (starting != 0); 10930 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10931 else if (STRICMP(name, "balloon_multiline") == 0) 10932 n = multiline_balloon_available(); 10933 #endif 10934 #ifdef DYNAMIC_TCL 10935 else if (STRICMP(name, "tcl") == 0) 10936 n = tcl_enabled(FALSE); 10937 #endif 10938 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10939 else if (STRICMP(name, "iconv") == 0) 10940 n = iconv_enabled(FALSE); 10941 #endif 10942 #ifdef DYNAMIC_MZSCHEME 10943 else if (STRICMP(name, "mzscheme") == 0) 10944 n = mzscheme_enabled(FALSE); 10945 #endif 10946 #ifdef DYNAMIC_RUBY 10947 else if (STRICMP(name, "ruby") == 0) 10948 n = ruby_enabled(FALSE); 10949 #endif 10950 #ifdef DYNAMIC_PYTHON 10951 else if (STRICMP(name, "python") == 0) 10952 n = python_enabled(FALSE); 10953 #endif 10954 #ifdef DYNAMIC_PERL 10955 else if (STRICMP(name, "perl") == 0) 10956 n = perl_enabled(FALSE); 10957 #endif 10958 #ifdef FEAT_GUI 10959 else if (STRICMP(name, "gui_running") == 0) 10960 n = (gui.in_use || gui.starting); 10961 # ifdef FEAT_GUI_W32 10962 else if (STRICMP(name, "gui_win32s") == 0) 10963 n = gui_is_win32s(); 10964 # endif 10965 # ifdef FEAT_BROWSE 10966 else if (STRICMP(name, "browse") == 0) 10967 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10968 # endif 10969 #endif 10970 #ifdef FEAT_SYN_HL 10971 else if (STRICMP(name, "syntax_items") == 0) 10972 n = syntax_present(curbuf); 10973 #endif 10974 #if defined(WIN3264) 10975 else if (STRICMP(name, "win95") == 0) 10976 n = mch_windows95(); 10977 #endif 10978 #ifdef FEAT_NETBEANS_INTG 10979 else if (STRICMP(name, "netbeans_enabled") == 0) 10980 n = usingNetbeans; 10981 #endif 10982 } 10983 10984 rettv->vval.v_number = n; 10985 } 10986 10987 /* 10988 * "has_key()" function 10989 */ 10990 static void 10991 f_has_key(argvars, rettv) 10992 typval_T *argvars; 10993 typval_T *rettv; 10994 { 10995 rettv->vval.v_number = 0; 10996 if (argvars[0].v_type != VAR_DICT) 10997 { 10998 EMSG(_(e_dictreq)); 10999 return; 11000 } 11001 if (argvars[0].vval.v_dict == NULL) 11002 return; 11003 11004 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 11005 get_tv_string(&argvars[1]), -1) != NULL; 11006 } 11007 11008 /* 11009 * "hasmapto()" function 11010 */ 11011 static void 11012 f_hasmapto(argvars, rettv) 11013 typval_T *argvars; 11014 typval_T *rettv; 11015 { 11016 char_u *name; 11017 char_u *mode; 11018 char_u buf[NUMBUFLEN]; 11019 int abbr = FALSE; 11020 11021 name = get_tv_string(&argvars[0]); 11022 if (argvars[1].v_type == VAR_UNKNOWN) 11023 mode = (char_u *)"nvo"; 11024 else 11025 { 11026 mode = get_tv_string_buf(&argvars[1], buf); 11027 if (argvars[2].v_type != VAR_UNKNOWN) 11028 abbr = get_tv_number(&argvars[2]); 11029 } 11030 11031 if (map_to_exists(name, mode, abbr)) 11032 rettv->vval.v_number = TRUE; 11033 else 11034 rettv->vval.v_number = FALSE; 11035 } 11036 11037 /* 11038 * "histadd()" function 11039 */ 11040 /*ARGSUSED*/ 11041 static void 11042 f_histadd(argvars, rettv) 11043 typval_T *argvars; 11044 typval_T *rettv; 11045 { 11046 #ifdef FEAT_CMDHIST 11047 int histype; 11048 char_u *str; 11049 char_u buf[NUMBUFLEN]; 11050 #endif 11051 11052 rettv->vval.v_number = FALSE; 11053 if (check_restricted() || check_secure()) 11054 return; 11055 #ifdef FEAT_CMDHIST 11056 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11057 histype = str != NULL ? get_histtype(str) : -1; 11058 if (histype >= 0) 11059 { 11060 str = get_tv_string_buf(&argvars[1], buf); 11061 if (*str != NUL) 11062 { 11063 add_to_history(histype, str, FALSE, NUL); 11064 rettv->vval.v_number = TRUE; 11065 return; 11066 } 11067 } 11068 #endif 11069 } 11070 11071 /* 11072 * "histdel()" function 11073 */ 11074 /*ARGSUSED*/ 11075 static void 11076 f_histdel(argvars, rettv) 11077 typval_T *argvars; 11078 typval_T *rettv; 11079 { 11080 #ifdef FEAT_CMDHIST 11081 int n; 11082 char_u buf[NUMBUFLEN]; 11083 char_u *str; 11084 11085 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11086 if (str == NULL) 11087 n = 0; 11088 else if (argvars[1].v_type == VAR_UNKNOWN) 11089 /* only one argument: clear entire history */ 11090 n = clr_history(get_histtype(str)); 11091 else if (argvars[1].v_type == VAR_NUMBER) 11092 /* index given: remove that entry */ 11093 n = del_history_idx(get_histtype(str), 11094 (int)get_tv_number(&argvars[1])); 11095 else 11096 /* string given: remove all matching entries */ 11097 n = del_history_entry(get_histtype(str), 11098 get_tv_string_buf(&argvars[1], buf)); 11099 rettv->vval.v_number = n; 11100 #else 11101 rettv->vval.v_number = 0; 11102 #endif 11103 } 11104 11105 /* 11106 * "histget()" function 11107 */ 11108 /*ARGSUSED*/ 11109 static void 11110 f_histget(argvars, rettv) 11111 typval_T *argvars; 11112 typval_T *rettv; 11113 { 11114 #ifdef FEAT_CMDHIST 11115 int type; 11116 int idx; 11117 char_u *str; 11118 11119 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11120 if (str == NULL) 11121 rettv->vval.v_string = NULL; 11122 else 11123 { 11124 type = get_histtype(str); 11125 if (argvars[1].v_type == VAR_UNKNOWN) 11126 idx = get_history_idx(type); 11127 else 11128 idx = (int)get_tv_number_chk(&argvars[1], NULL); 11129 /* -1 on type error */ 11130 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 11131 } 11132 #else 11133 rettv->vval.v_string = NULL; 11134 #endif 11135 rettv->v_type = VAR_STRING; 11136 } 11137 11138 /* 11139 * "histnr()" function 11140 */ 11141 /*ARGSUSED*/ 11142 static void 11143 f_histnr(argvars, rettv) 11144 typval_T *argvars; 11145 typval_T *rettv; 11146 { 11147 int i; 11148 11149 #ifdef FEAT_CMDHIST 11150 char_u *history = get_tv_string_chk(&argvars[0]); 11151 11152 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 11153 if (i >= HIST_CMD && i < HIST_COUNT) 11154 i = get_history_idx(i); 11155 else 11156 #endif 11157 i = -1; 11158 rettv->vval.v_number = i; 11159 } 11160 11161 /* 11162 * "highlightID(name)" function 11163 */ 11164 static void 11165 f_hlID(argvars, rettv) 11166 typval_T *argvars; 11167 typval_T *rettv; 11168 { 11169 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 11170 } 11171 11172 /* 11173 * "highlight_exists()" function 11174 */ 11175 static void 11176 f_hlexists(argvars, rettv) 11177 typval_T *argvars; 11178 typval_T *rettv; 11179 { 11180 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 11181 } 11182 11183 /* 11184 * "hostname()" function 11185 */ 11186 /*ARGSUSED*/ 11187 static void 11188 f_hostname(argvars, rettv) 11189 typval_T *argvars; 11190 typval_T *rettv; 11191 { 11192 char_u hostname[256]; 11193 11194 mch_get_host_name(hostname, 256); 11195 rettv->v_type = VAR_STRING; 11196 rettv->vval.v_string = vim_strsave(hostname); 11197 } 11198 11199 /* 11200 * iconv() function 11201 */ 11202 /*ARGSUSED*/ 11203 static void 11204 f_iconv(argvars, rettv) 11205 typval_T *argvars; 11206 typval_T *rettv; 11207 { 11208 #ifdef FEAT_MBYTE 11209 char_u buf1[NUMBUFLEN]; 11210 char_u buf2[NUMBUFLEN]; 11211 char_u *from, *to, *str; 11212 vimconv_T vimconv; 11213 #endif 11214 11215 rettv->v_type = VAR_STRING; 11216 rettv->vval.v_string = NULL; 11217 11218 #ifdef FEAT_MBYTE 11219 str = get_tv_string(&argvars[0]); 11220 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 11221 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 11222 vimconv.vc_type = CONV_NONE; 11223 convert_setup(&vimconv, from, to); 11224 11225 /* If the encodings are equal, no conversion needed. */ 11226 if (vimconv.vc_type == CONV_NONE) 11227 rettv->vval.v_string = vim_strsave(str); 11228 else 11229 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 11230 11231 convert_setup(&vimconv, NULL, NULL); 11232 vim_free(from); 11233 vim_free(to); 11234 #endif 11235 } 11236 11237 /* 11238 * "indent()" function 11239 */ 11240 static void 11241 f_indent(argvars, rettv) 11242 typval_T *argvars; 11243 typval_T *rettv; 11244 { 11245 linenr_T lnum; 11246 11247 lnum = get_tv_lnum(argvars); 11248 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11249 rettv->vval.v_number = get_indent_lnum(lnum); 11250 else 11251 rettv->vval.v_number = -1; 11252 } 11253 11254 /* 11255 * "index()" function 11256 */ 11257 static void 11258 f_index(argvars, rettv) 11259 typval_T *argvars; 11260 typval_T *rettv; 11261 { 11262 list_T *l; 11263 listitem_T *item; 11264 long idx = 0; 11265 int ic = FALSE; 11266 11267 rettv->vval.v_number = -1; 11268 if (argvars[0].v_type != VAR_LIST) 11269 { 11270 EMSG(_(e_listreq)); 11271 return; 11272 } 11273 l = argvars[0].vval.v_list; 11274 if (l != NULL) 11275 { 11276 item = l->lv_first; 11277 if (argvars[2].v_type != VAR_UNKNOWN) 11278 { 11279 int error = FALSE; 11280 11281 /* Start at specified item. Use the cached index that list_find() 11282 * sets, so that a negative number also works. */ 11283 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 11284 idx = l->lv_idx; 11285 if (argvars[3].v_type != VAR_UNKNOWN) 11286 ic = get_tv_number_chk(&argvars[3], &error); 11287 if (error) 11288 item = NULL; 11289 } 11290 11291 for ( ; item != NULL; item = item->li_next, ++idx) 11292 if (tv_equal(&item->li_tv, &argvars[1], ic)) 11293 { 11294 rettv->vval.v_number = idx; 11295 break; 11296 } 11297 } 11298 } 11299 11300 static int inputsecret_flag = 0; 11301 11302 /* 11303 * "input()" function 11304 * Also handles inputsecret() when inputsecret is set. 11305 */ 11306 static void 11307 f_input(argvars, rettv) 11308 typval_T *argvars; 11309 typval_T *rettv; 11310 { 11311 char_u *prompt = get_tv_string_chk(&argvars[0]); 11312 char_u *p = NULL; 11313 int c; 11314 char_u buf[NUMBUFLEN]; 11315 int cmd_silent_save = cmd_silent; 11316 char_u *defstr = (char_u *)""; 11317 int xp_type = EXPAND_NOTHING; 11318 char_u *xp_arg = NULL; 11319 11320 rettv->v_type = VAR_STRING; 11321 11322 #ifdef NO_CONSOLE_INPUT 11323 /* While starting up, there is no place to enter text. */ 11324 if (no_console_input()) 11325 { 11326 rettv->vval.v_string = NULL; 11327 return; 11328 } 11329 #endif 11330 11331 cmd_silent = FALSE; /* Want to see the prompt. */ 11332 if (prompt != NULL) 11333 { 11334 /* Only the part of the message after the last NL is considered as 11335 * prompt for the command line */ 11336 p = vim_strrchr(prompt, '\n'); 11337 if (p == NULL) 11338 p = prompt; 11339 else 11340 { 11341 ++p; 11342 c = *p; 11343 *p = NUL; 11344 msg_start(); 11345 msg_clr_eos(); 11346 msg_puts_attr(prompt, echo_attr); 11347 msg_didout = FALSE; 11348 msg_starthere(); 11349 *p = c; 11350 } 11351 cmdline_row = msg_row; 11352 11353 if (argvars[1].v_type != VAR_UNKNOWN) 11354 { 11355 defstr = get_tv_string_buf_chk(&argvars[1], buf); 11356 if (defstr != NULL) 11357 stuffReadbuffSpec(defstr); 11358 11359 if (argvars[2].v_type != VAR_UNKNOWN) 11360 { 11361 char_u *xp_name; 11362 int xp_namelen; 11363 long argt; 11364 11365 rettv->vval.v_string = NULL; 11366 11367 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 11368 if (xp_name == NULL) 11369 return; 11370 11371 xp_namelen = (int)STRLEN(xp_name); 11372 11373 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 11374 &xp_arg) == FAIL) 11375 return; 11376 } 11377 } 11378 11379 if (defstr != NULL) 11380 rettv->vval.v_string = 11381 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 11382 xp_type, xp_arg); 11383 11384 vim_free(xp_arg); 11385 11386 /* since the user typed this, no need to wait for return */ 11387 need_wait_return = FALSE; 11388 msg_didout = FALSE; 11389 } 11390 cmd_silent = cmd_silent_save; 11391 } 11392 11393 /* 11394 * "inputdialog()" function 11395 */ 11396 static void 11397 f_inputdialog(argvars, rettv) 11398 typval_T *argvars; 11399 typval_T *rettv; 11400 { 11401 #if defined(FEAT_GUI_TEXTDIALOG) 11402 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 11403 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 11404 { 11405 char_u *message; 11406 char_u buf[NUMBUFLEN]; 11407 char_u *defstr = (char_u *)""; 11408 11409 message = get_tv_string_chk(&argvars[0]); 11410 if (argvars[1].v_type != VAR_UNKNOWN 11411 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 11412 vim_strncpy(IObuff, defstr, IOSIZE - 1); 11413 else 11414 IObuff[0] = NUL; 11415 if (message != NULL && defstr != NULL 11416 && do_dialog(VIM_QUESTION, NULL, message, 11417 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 11418 rettv->vval.v_string = vim_strsave(IObuff); 11419 else 11420 { 11421 if (message != NULL && defstr != NULL 11422 && argvars[1].v_type != VAR_UNKNOWN 11423 && argvars[2].v_type != VAR_UNKNOWN) 11424 rettv->vval.v_string = vim_strsave( 11425 get_tv_string_buf(&argvars[2], buf)); 11426 else 11427 rettv->vval.v_string = NULL; 11428 } 11429 rettv->v_type = VAR_STRING; 11430 } 11431 else 11432 #endif 11433 f_input(argvars, rettv); 11434 } 11435 11436 /* 11437 * "inputlist()" function 11438 */ 11439 static void 11440 f_inputlist(argvars, rettv) 11441 typval_T *argvars; 11442 typval_T *rettv; 11443 { 11444 listitem_T *li; 11445 int selected; 11446 int mouse_used; 11447 11448 rettv->vval.v_number = 0; 11449 #ifdef NO_CONSOLE_INPUT 11450 /* While starting up, there is no place to enter text. */ 11451 if (no_console_input()) 11452 return; 11453 #endif 11454 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 11455 { 11456 EMSG2(_(e_listarg), "inputlist()"); 11457 return; 11458 } 11459 11460 msg_start(); 11461 lines_left = Rows; /* avoid more prompt */ 11462 msg_scroll = TRUE; 11463 msg_clr_eos(); 11464 11465 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 11466 { 11467 msg_puts(get_tv_string(&li->li_tv)); 11468 msg_putchar('\n'); 11469 } 11470 11471 /* Ask for choice. */ 11472 selected = prompt_for_number(&mouse_used); 11473 if (mouse_used) 11474 selected -= lines_left; 11475 11476 rettv->vval.v_number = selected; 11477 } 11478 11479 11480 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11481 11482 /* 11483 * "inputrestore()" function 11484 */ 11485 /*ARGSUSED*/ 11486 static void 11487 f_inputrestore(argvars, rettv) 11488 typval_T *argvars; 11489 typval_T *rettv; 11490 { 11491 if (ga_userinput.ga_len > 0) 11492 { 11493 --ga_userinput.ga_len; 11494 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11495 + ga_userinput.ga_len); 11496 rettv->vval.v_number = 0; /* OK */ 11497 } 11498 else if (p_verbose > 1) 11499 { 11500 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11501 rettv->vval.v_number = 1; /* Failed */ 11502 } 11503 } 11504 11505 /* 11506 * "inputsave()" function 11507 */ 11508 /*ARGSUSED*/ 11509 static void 11510 f_inputsave(argvars, rettv) 11511 typval_T *argvars; 11512 typval_T *rettv; 11513 { 11514 /* Add an entry to the stack of typehead storage. */ 11515 if (ga_grow(&ga_userinput, 1) == OK) 11516 { 11517 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11518 + ga_userinput.ga_len); 11519 ++ga_userinput.ga_len; 11520 rettv->vval.v_number = 0; /* OK */ 11521 } 11522 else 11523 rettv->vval.v_number = 1; /* Failed */ 11524 } 11525 11526 /* 11527 * "inputsecret()" function 11528 */ 11529 static void 11530 f_inputsecret(argvars, rettv) 11531 typval_T *argvars; 11532 typval_T *rettv; 11533 { 11534 ++cmdline_star; 11535 ++inputsecret_flag; 11536 f_input(argvars, rettv); 11537 --cmdline_star; 11538 --inputsecret_flag; 11539 } 11540 11541 /* 11542 * "insert()" function 11543 */ 11544 static void 11545 f_insert(argvars, rettv) 11546 typval_T *argvars; 11547 typval_T *rettv; 11548 { 11549 long before = 0; 11550 listitem_T *item; 11551 list_T *l; 11552 int error = FALSE; 11553 11554 rettv->vval.v_number = 0; 11555 if (argvars[0].v_type != VAR_LIST) 11556 EMSG2(_(e_listarg), "insert()"); 11557 else if ((l = argvars[0].vval.v_list) != NULL 11558 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11559 { 11560 if (argvars[2].v_type != VAR_UNKNOWN) 11561 before = get_tv_number_chk(&argvars[2], &error); 11562 if (error) 11563 return; /* type error; errmsg already given */ 11564 11565 if (before == l->lv_len) 11566 item = NULL; 11567 else 11568 { 11569 item = list_find(l, before); 11570 if (item == NULL) 11571 { 11572 EMSGN(_(e_listidx), before); 11573 l = NULL; 11574 } 11575 } 11576 if (l != NULL) 11577 { 11578 list_insert_tv(l, &argvars[1], item); 11579 copy_tv(&argvars[0], rettv); 11580 } 11581 } 11582 } 11583 11584 /* 11585 * "isdirectory()" function 11586 */ 11587 static void 11588 f_isdirectory(argvars, rettv) 11589 typval_T *argvars; 11590 typval_T *rettv; 11591 { 11592 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11593 } 11594 11595 /* 11596 * "islocked()" function 11597 */ 11598 static void 11599 f_islocked(argvars, rettv) 11600 typval_T *argvars; 11601 typval_T *rettv; 11602 { 11603 lval_T lv; 11604 char_u *end; 11605 dictitem_T *di; 11606 11607 rettv->vval.v_number = -1; 11608 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11609 FNE_CHECK_START); 11610 if (end != NULL && lv.ll_name != NULL) 11611 { 11612 if (*end != NUL) 11613 EMSG(_(e_trailing)); 11614 else 11615 { 11616 if (lv.ll_tv == NULL) 11617 { 11618 if (check_changedtick(lv.ll_name)) 11619 rettv->vval.v_number = 1; /* always locked */ 11620 else 11621 { 11622 di = find_var(lv.ll_name, NULL); 11623 if (di != NULL) 11624 { 11625 /* Consider a variable locked when: 11626 * 1. the variable itself is locked 11627 * 2. the value of the variable is locked. 11628 * 3. the List or Dict value is locked. 11629 */ 11630 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11631 || tv_islocked(&di->di_tv)); 11632 } 11633 } 11634 } 11635 else if (lv.ll_range) 11636 EMSG(_("E786: Range not allowed")); 11637 else if (lv.ll_newkey != NULL) 11638 EMSG2(_(e_dictkey), lv.ll_newkey); 11639 else if (lv.ll_list != NULL) 11640 /* List item. */ 11641 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11642 else 11643 /* Dictionary item. */ 11644 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11645 } 11646 } 11647 11648 clear_lval(&lv); 11649 } 11650 11651 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11652 11653 /* 11654 * Turn a dict into a list: 11655 * "what" == 0: list of keys 11656 * "what" == 1: list of values 11657 * "what" == 2: list of items 11658 */ 11659 static void 11660 dict_list(argvars, rettv, what) 11661 typval_T *argvars; 11662 typval_T *rettv; 11663 int what; 11664 { 11665 list_T *l2; 11666 dictitem_T *di; 11667 hashitem_T *hi; 11668 listitem_T *li; 11669 listitem_T *li2; 11670 dict_T *d; 11671 int todo; 11672 11673 rettv->vval.v_number = 0; 11674 if (argvars[0].v_type != VAR_DICT) 11675 { 11676 EMSG(_(e_dictreq)); 11677 return; 11678 } 11679 if ((d = argvars[0].vval.v_dict) == NULL) 11680 return; 11681 11682 if (rettv_list_alloc(rettv) == FAIL) 11683 return; 11684 11685 todo = (int)d->dv_hashtab.ht_used; 11686 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11687 { 11688 if (!HASHITEM_EMPTY(hi)) 11689 { 11690 --todo; 11691 di = HI2DI(hi); 11692 11693 li = listitem_alloc(); 11694 if (li == NULL) 11695 break; 11696 list_append(rettv->vval.v_list, li); 11697 11698 if (what == 0) 11699 { 11700 /* keys() */ 11701 li->li_tv.v_type = VAR_STRING; 11702 li->li_tv.v_lock = 0; 11703 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11704 } 11705 else if (what == 1) 11706 { 11707 /* values() */ 11708 copy_tv(&di->di_tv, &li->li_tv); 11709 } 11710 else 11711 { 11712 /* items() */ 11713 l2 = list_alloc(); 11714 li->li_tv.v_type = VAR_LIST; 11715 li->li_tv.v_lock = 0; 11716 li->li_tv.vval.v_list = l2; 11717 if (l2 == NULL) 11718 break; 11719 ++l2->lv_refcount; 11720 11721 li2 = listitem_alloc(); 11722 if (li2 == NULL) 11723 break; 11724 list_append(l2, li2); 11725 li2->li_tv.v_type = VAR_STRING; 11726 li2->li_tv.v_lock = 0; 11727 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11728 11729 li2 = listitem_alloc(); 11730 if (li2 == NULL) 11731 break; 11732 list_append(l2, li2); 11733 copy_tv(&di->di_tv, &li2->li_tv); 11734 } 11735 } 11736 } 11737 } 11738 11739 /* 11740 * "items(dict)" function 11741 */ 11742 static void 11743 f_items(argvars, rettv) 11744 typval_T *argvars; 11745 typval_T *rettv; 11746 { 11747 dict_list(argvars, rettv, 2); 11748 } 11749 11750 /* 11751 * "join()" function 11752 */ 11753 static void 11754 f_join(argvars, rettv) 11755 typval_T *argvars; 11756 typval_T *rettv; 11757 { 11758 garray_T ga; 11759 char_u *sep; 11760 11761 rettv->vval.v_number = 0; 11762 if (argvars[0].v_type != VAR_LIST) 11763 { 11764 EMSG(_(e_listreq)); 11765 return; 11766 } 11767 if (argvars[0].vval.v_list == NULL) 11768 return; 11769 if (argvars[1].v_type == VAR_UNKNOWN) 11770 sep = (char_u *)" "; 11771 else 11772 sep = get_tv_string_chk(&argvars[1]); 11773 11774 rettv->v_type = VAR_STRING; 11775 11776 if (sep != NULL) 11777 { 11778 ga_init2(&ga, (int)sizeof(char), 80); 11779 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 11780 ga_append(&ga, NUL); 11781 rettv->vval.v_string = (char_u *)ga.ga_data; 11782 } 11783 else 11784 rettv->vval.v_string = NULL; 11785 } 11786 11787 /* 11788 * "keys()" function 11789 */ 11790 static void 11791 f_keys(argvars, rettv) 11792 typval_T *argvars; 11793 typval_T *rettv; 11794 { 11795 dict_list(argvars, rettv, 0); 11796 } 11797 11798 /* 11799 * "last_buffer_nr()" function. 11800 */ 11801 /*ARGSUSED*/ 11802 static void 11803 f_last_buffer_nr(argvars, rettv) 11804 typval_T *argvars; 11805 typval_T *rettv; 11806 { 11807 int n = 0; 11808 buf_T *buf; 11809 11810 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11811 if (n < buf->b_fnum) 11812 n = buf->b_fnum; 11813 11814 rettv->vval.v_number = n; 11815 } 11816 11817 /* 11818 * "len()" function 11819 */ 11820 static void 11821 f_len(argvars, rettv) 11822 typval_T *argvars; 11823 typval_T *rettv; 11824 { 11825 switch (argvars[0].v_type) 11826 { 11827 case VAR_STRING: 11828 case VAR_NUMBER: 11829 rettv->vval.v_number = (varnumber_T)STRLEN( 11830 get_tv_string(&argvars[0])); 11831 break; 11832 case VAR_LIST: 11833 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11834 break; 11835 case VAR_DICT: 11836 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11837 break; 11838 default: 11839 EMSG(_("E701: Invalid type for len()")); 11840 break; 11841 } 11842 } 11843 11844 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11845 11846 static void 11847 libcall_common(argvars, rettv, type) 11848 typval_T *argvars; 11849 typval_T *rettv; 11850 int type; 11851 { 11852 #ifdef FEAT_LIBCALL 11853 char_u *string_in; 11854 char_u **string_result; 11855 int nr_result; 11856 #endif 11857 11858 rettv->v_type = type; 11859 if (type == VAR_NUMBER) 11860 rettv->vval.v_number = 0; 11861 else 11862 rettv->vval.v_string = NULL; 11863 11864 if (check_restricted() || check_secure()) 11865 return; 11866 11867 #ifdef FEAT_LIBCALL 11868 /* The first two args must be strings, otherwise its meaningless */ 11869 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11870 { 11871 string_in = NULL; 11872 if (argvars[2].v_type == VAR_STRING) 11873 string_in = argvars[2].vval.v_string; 11874 if (type == VAR_NUMBER) 11875 string_result = NULL; 11876 else 11877 string_result = &rettv->vval.v_string; 11878 if (mch_libcall(argvars[0].vval.v_string, 11879 argvars[1].vval.v_string, 11880 string_in, 11881 argvars[2].vval.v_number, 11882 string_result, 11883 &nr_result) == OK 11884 && type == VAR_NUMBER) 11885 rettv->vval.v_number = nr_result; 11886 } 11887 #endif 11888 } 11889 11890 /* 11891 * "libcall()" function 11892 */ 11893 static void 11894 f_libcall(argvars, rettv) 11895 typval_T *argvars; 11896 typval_T *rettv; 11897 { 11898 libcall_common(argvars, rettv, VAR_STRING); 11899 } 11900 11901 /* 11902 * "libcallnr()" function 11903 */ 11904 static void 11905 f_libcallnr(argvars, rettv) 11906 typval_T *argvars; 11907 typval_T *rettv; 11908 { 11909 libcall_common(argvars, rettv, VAR_NUMBER); 11910 } 11911 11912 /* 11913 * "line(string)" function 11914 */ 11915 static void 11916 f_line(argvars, rettv) 11917 typval_T *argvars; 11918 typval_T *rettv; 11919 { 11920 linenr_T lnum = 0; 11921 pos_T *fp; 11922 int fnum; 11923 11924 fp = var2fpos(&argvars[0], TRUE, &fnum); 11925 if (fp != NULL) 11926 lnum = fp->lnum; 11927 rettv->vval.v_number = lnum; 11928 } 11929 11930 /* 11931 * "line2byte(lnum)" function 11932 */ 11933 /*ARGSUSED*/ 11934 static void 11935 f_line2byte(argvars, rettv) 11936 typval_T *argvars; 11937 typval_T *rettv; 11938 { 11939 #ifndef FEAT_BYTEOFF 11940 rettv->vval.v_number = -1; 11941 #else 11942 linenr_T lnum; 11943 11944 lnum = get_tv_lnum(argvars); 11945 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11946 rettv->vval.v_number = -1; 11947 else 11948 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11949 if (rettv->vval.v_number >= 0) 11950 ++rettv->vval.v_number; 11951 #endif 11952 } 11953 11954 /* 11955 * "lispindent(lnum)" function 11956 */ 11957 static void 11958 f_lispindent(argvars, rettv) 11959 typval_T *argvars; 11960 typval_T *rettv; 11961 { 11962 #ifdef FEAT_LISP 11963 pos_T pos; 11964 linenr_T lnum; 11965 11966 pos = curwin->w_cursor; 11967 lnum = get_tv_lnum(argvars); 11968 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11969 { 11970 curwin->w_cursor.lnum = lnum; 11971 rettv->vval.v_number = get_lisp_indent(); 11972 curwin->w_cursor = pos; 11973 } 11974 else 11975 #endif 11976 rettv->vval.v_number = -1; 11977 } 11978 11979 /* 11980 * "localtime()" function 11981 */ 11982 /*ARGSUSED*/ 11983 static void 11984 f_localtime(argvars, rettv) 11985 typval_T *argvars; 11986 typval_T *rettv; 11987 { 11988 rettv->vval.v_number = (varnumber_T)time(NULL); 11989 } 11990 11991 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11992 11993 static void 11994 get_maparg(argvars, rettv, exact) 11995 typval_T *argvars; 11996 typval_T *rettv; 11997 int exact; 11998 { 11999 char_u *keys; 12000 char_u *which; 12001 char_u buf[NUMBUFLEN]; 12002 char_u *keys_buf = NULL; 12003 char_u *rhs; 12004 int mode; 12005 garray_T ga; 12006 int abbr = FALSE; 12007 12008 /* return empty string for failure */ 12009 rettv->v_type = VAR_STRING; 12010 rettv->vval.v_string = NULL; 12011 12012 keys = get_tv_string(&argvars[0]); 12013 if (*keys == NUL) 12014 return; 12015 12016 if (argvars[1].v_type != VAR_UNKNOWN) 12017 { 12018 which = get_tv_string_buf_chk(&argvars[1], buf); 12019 if (argvars[2].v_type != VAR_UNKNOWN) 12020 abbr = get_tv_number(&argvars[2]); 12021 } 12022 else 12023 which = (char_u *)""; 12024 if (which == NULL) 12025 return; 12026 12027 mode = get_map_mode(&which, 0); 12028 12029 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 12030 rhs = check_map(keys, mode, exact, FALSE, abbr); 12031 vim_free(keys_buf); 12032 if (rhs != NULL) 12033 { 12034 ga_init(&ga); 12035 ga.ga_itemsize = 1; 12036 ga.ga_growsize = 40; 12037 12038 while (*rhs != NUL) 12039 ga_concat(&ga, str2special(&rhs, FALSE)); 12040 12041 ga_append(&ga, NUL); 12042 rettv->vval.v_string = (char_u *)ga.ga_data; 12043 } 12044 } 12045 12046 /* 12047 * "map()" function 12048 */ 12049 static void 12050 f_map(argvars, rettv) 12051 typval_T *argvars; 12052 typval_T *rettv; 12053 { 12054 filter_map(argvars, rettv, TRUE); 12055 } 12056 12057 /* 12058 * "maparg()" function 12059 */ 12060 static void 12061 f_maparg(argvars, rettv) 12062 typval_T *argvars; 12063 typval_T *rettv; 12064 { 12065 get_maparg(argvars, rettv, TRUE); 12066 } 12067 12068 /* 12069 * "mapcheck()" function 12070 */ 12071 static void 12072 f_mapcheck(argvars, rettv) 12073 typval_T *argvars; 12074 typval_T *rettv; 12075 { 12076 get_maparg(argvars, rettv, FALSE); 12077 } 12078 12079 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 12080 12081 static void 12082 find_some_match(argvars, rettv, type) 12083 typval_T *argvars; 12084 typval_T *rettv; 12085 int type; 12086 { 12087 char_u *str = NULL; 12088 char_u *expr = NULL; 12089 char_u *pat; 12090 regmatch_T regmatch; 12091 char_u patbuf[NUMBUFLEN]; 12092 char_u strbuf[NUMBUFLEN]; 12093 char_u *save_cpo; 12094 long start = 0; 12095 long nth = 1; 12096 colnr_T startcol = 0; 12097 int match = 0; 12098 list_T *l = NULL; 12099 listitem_T *li = NULL; 12100 long idx = 0; 12101 char_u *tofree = NULL; 12102 12103 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 12104 save_cpo = p_cpo; 12105 p_cpo = (char_u *)""; 12106 12107 rettv->vval.v_number = -1; 12108 if (type == 3) 12109 { 12110 /* return empty list when there are no matches */ 12111 if (rettv_list_alloc(rettv) == FAIL) 12112 goto theend; 12113 } 12114 else if (type == 2) 12115 { 12116 rettv->v_type = VAR_STRING; 12117 rettv->vval.v_string = NULL; 12118 } 12119 12120 if (argvars[0].v_type == VAR_LIST) 12121 { 12122 if ((l = argvars[0].vval.v_list) == NULL) 12123 goto theend; 12124 li = l->lv_first; 12125 } 12126 else 12127 expr = str = get_tv_string(&argvars[0]); 12128 12129 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 12130 if (pat == NULL) 12131 goto theend; 12132 12133 if (argvars[2].v_type != VAR_UNKNOWN) 12134 { 12135 int error = FALSE; 12136 12137 start = get_tv_number_chk(&argvars[2], &error); 12138 if (error) 12139 goto theend; 12140 if (l != NULL) 12141 { 12142 li = list_find(l, start); 12143 if (li == NULL) 12144 goto theend; 12145 idx = l->lv_idx; /* use the cached index */ 12146 } 12147 else 12148 { 12149 if (start < 0) 12150 start = 0; 12151 if (start > (long)STRLEN(str)) 12152 goto theend; 12153 /* When "count" argument is there ignore matches before "start", 12154 * otherwise skip part of the string. Differs when pattern is "^" 12155 * or "\<". */ 12156 if (argvars[3].v_type != VAR_UNKNOWN) 12157 startcol = start; 12158 else 12159 str += start; 12160 } 12161 12162 if (argvars[3].v_type != VAR_UNKNOWN) 12163 nth = get_tv_number_chk(&argvars[3], &error); 12164 if (error) 12165 goto theend; 12166 } 12167 12168 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 12169 if (regmatch.regprog != NULL) 12170 { 12171 regmatch.rm_ic = p_ic; 12172 12173 for (;;) 12174 { 12175 if (l != NULL) 12176 { 12177 if (li == NULL) 12178 { 12179 match = FALSE; 12180 break; 12181 } 12182 vim_free(tofree); 12183 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 12184 if (str == NULL) 12185 break; 12186 } 12187 12188 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 12189 12190 if (match && --nth <= 0) 12191 break; 12192 if (l == NULL && !match) 12193 break; 12194 12195 /* Advance to just after the match. */ 12196 if (l != NULL) 12197 { 12198 li = li->li_next; 12199 ++idx; 12200 } 12201 else 12202 { 12203 #ifdef FEAT_MBYTE 12204 startcol = (colnr_T)(regmatch.startp[0] 12205 + (*mb_ptr2len)(regmatch.startp[0]) - str); 12206 #else 12207 startcol = regmatch.startp[0] + 1 - str; 12208 #endif 12209 } 12210 } 12211 12212 if (match) 12213 { 12214 if (type == 3) 12215 { 12216 int i; 12217 12218 /* return list with matched string and submatches */ 12219 for (i = 0; i < NSUBEXP; ++i) 12220 { 12221 if (regmatch.endp[i] == NULL) 12222 { 12223 if (list_append_string(rettv->vval.v_list, 12224 (char_u *)"", 0) == FAIL) 12225 break; 12226 } 12227 else if (list_append_string(rettv->vval.v_list, 12228 regmatch.startp[i], 12229 (int)(regmatch.endp[i] - regmatch.startp[i])) 12230 == FAIL) 12231 break; 12232 } 12233 } 12234 else if (type == 2) 12235 { 12236 /* return matched string */ 12237 if (l != NULL) 12238 copy_tv(&li->li_tv, rettv); 12239 else 12240 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 12241 (int)(regmatch.endp[0] - regmatch.startp[0])); 12242 } 12243 else if (l != NULL) 12244 rettv->vval.v_number = idx; 12245 else 12246 { 12247 if (type != 0) 12248 rettv->vval.v_number = 12249 (varnumber_T)(regmatch.startp[0] - str); 12250 else 12251 rettv->vval.v_number = 12252 (varnumber_T)(regmatch.endp[0] - str); 12253 rettv->vval.v_number += (varnumber_T)(str - expr); 12254 } 12255 } 12256 vim_free(regmatch.regprog); 12257 } 12258 12259 theend: 12260 vim_free(tofree); 12261 p_cpo = save_cpo; 12262 } 12263 12264 /* 12265 * "match()" function 12266 */ 12267 static void 12268 f_match(argvars, rettv) 12269 typval_T *argvars; 12270 typval_T *rettv; 12271 { 12272 find_some_match(argvars, rettv, 1); 12273 } 12274 12275 /* 12276 * "matcharg()" function 12277 */ 12278 static void 12279 f_matcharg(argvars, rettv) 12280 typval_T *argvars; 12281 typval_T *rettv; 12282 { 12283 if (rettv_list_alloc(rettv) == OK) 12284 { 12285 #ifdef FEAT_SEARCH_EXTRA 12286 int mi = get_tv_number(&argvars[0]); 12287 12288 if (mi >= 1 && mi <= 3) 12289 { 12290 list_append_string(rettv->vval.v_list, 12291 syn_id2name(curwin->w_match_id[mi - 1]), -1); 12292 list_append_string(rettv->vval.v_list, 12293 curwin->w_match_pat[mi - 1], -1); 12294 } 12295 #endif 12296 } 12297 } 12298 12299 /* 12300 * "matchend()" function 12301 */ 12302 static void 12303 f_matchend(argvars, rettv) 12304 typval_T *argvars; 12305 typval_T *rettv; 12306 { 12307 find_some_match(argvars, rettv, 0); 12308 } 12309 12310 /* 12311 * "matchlist()" function 12312 */ 12313 static void 12314 f_matchlist(argvars, rettv) 12315 typval_T *argvars; 12316 typval_T *rettv; 12317 { 12318 find_some_match(argvars, rettv, 3); 12319 } 12320 12321 /* 12322 * "matchstr()" function 12323 */ 12324 static void 12325 f_matchstr(argvars, rettv) 12326 typval_T *argvars; 12327 typval_T *rettv; 12328 { 12329 find_some_match(argvars, rettv, 2); 12330 } 12331 12332 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 12333 12334 static void 12335 max_min(argvars, rettv, domax) 12336 typval_T *argvars; 12337 typval_T *rettv; 12338 int domax; 12339 { 12340 long n = 0; 12341 long i; 12342 int error = FALSE; 12343 12344 if (argvars[0].v_type == VAR_LIST) 12345 { 12346 list_T *l; 12347 listitem_T *li; 12348 12349 l = argvars[0].vval.v_list; 12350 if (l != NULL) 12351 { 12352 li = l->lv_first; 12353 if (li != NULL) 12354 { 12355 n = get_tv_number_chk(&li->li_tv, &error); 12356 for (;;) 12357 { 12358 li = li->li_next; 12359 if (li == NULL) 12360 break; 12361 i = get_tv_number_chk(&li->li_tv, &error); 12362 if (domax ? i > n : i < n) 12363 n = i; 12364 } 12365 } 12366 } 12367 } 12368 else if (argvars[0].v_type == VAR_DICT) 12369 { 12370 dict_T *d; 12371 int first = TRUE; 12372 hashitem_T *hi; 12373 int todo; 12374 12375 d = argvars[0].vval.v_dict; 12376 if (d != NULL) 12377 { 12378 todo = (int)d->dv_hashtab.ht_used; 12379 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12380 { 12381 if (!HASHITEM_EMPTY(hi)) 12382 { 12383 --todo; 12384 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 12385 if (first) 12386 { 12387 n = i; 12388 first = FALSE; 12389 } 12390 else if (domax ? i > n : i < n) 12391 n = i; 12392 } 12393 } 12394 } 12395 } 12396 else 12397 EMSG(_(e_listdictarg)); 12398 rettv->vval.v_number = error ? 0 : n; 12399 } 12400 12401 /* 12402 * "max()" function 12403 */ 12404 static void 12405 f_max(argvars, rettv) 12406 typval_T *argvars; 12407 typval_T *rettv; 12408 { 12409 max_min(argvars, rettv, TRUE); 12410 } 12411 12412 /* 12413 * "min()" function 12414 */ 12415 static void 12416 f_min(argvars, rettv) 12417 typval_T *argvars; 12418 typval_T *rettv; 12419 { 12420 max_min(argvars, rettv, FALSE); 12421 } 12422 12423 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 12424 12425 /* 12426 * Create the directory in which "dir" is located, and higher levels when 12427 * needed. 12428 */ 12429 static int 12430 mkdir_recurse(dir, prot) 12431 char_u *dir; 12432 int prot; 12433 { 12434 char_u *p; 12435 char_u *updir; 12436 int r = FAIL; 12437 12438 /* Get end of directory name in "dir". 12439 * We're done when it's "/" or "c:/". */ 12440 p = gettail_sep(dir); 12441 if (p <= get_past_head(dir)) 12442 return OK; 12443 12444 /* If the directory exists we're done. Otherwise: create it.*/ 12445 updir = vim_strnsave(dir, (int)(p - dir)); 12446 if (updir == NULL) 12447 return FAIL; 12448 if (mch_isdir(updir)) 12449 r = OK; 12450 else if (mkdir_recurse(updir, prot) == OK) 12451 r = vim_mkdir_emsg(updir, prot); 12452 vim_free(updir); 12453 return r; 12454 } 12455 12456 #ifdef vim_mkdir 12457 /* 12458 * "mkdir()" function 12459 */ 12460 static void 12461 f_mkdir(argvars, rettv) 12462 typval_T *argvars; 12463 typval_T *rettv; 12464 { 12465 char_u *dir; 12466 char_u buf[NUMBUFLEN]; 12467 int prot = 0755; 12468 12469 rettv->vval.v_number = FAIL; 12470 if (check_restricted() || check_secure()) 12471 return; 12472 12473 dir = get_tv_string_buf(&argvars[0], buf); 12474 if (argvars[1].v_type != VAR_UNKNOWN) 12475 { 12476 if (argvars[2].v_type != VAR_UNKNOWN) 12477 prot = get_tv_number_chk(&argvars[2], NULL); 12478 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 12479 mkdir_recurse(dir, prot); 12480 } 12481 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 12482 } 12483 #endif 12484 12485 /* 12486 * "mode()" function 12487 */ 12488 /*ARGSUSED*/ 12489 static void 12490 f_mode(argvars, rettv) 12491 typval_T *argvars; 12492 typval_T *rettv; 12493 { 12494 char_u buf[2]; 12495 12496 #ifdef FEAT_VISUAL 12497 if (VIsual_active) 12498 { 12499 if (VIsual_select) 12500 buf[0] = VIsual_mode + 's' - 'v'; 12501 else 12502 buf[0] = VIsual_mode; 12503 } 12504 else 12505 #endif 12506 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 12507 buf[0] = 'r'; 12508 else if (State & INSERT) 12509 { 12510 if (State & REPLACE_FLAG) 12511 buf[0] = 'R'; 12512 else 12513 buf[0] = 'i'; 12514 } 12515 else if (State & CMDLINE) 12516 buf[0] = 'c'; 12517 else 12518 buf[0] = 'n'; 12519 12520 buf[1] = NUL; 12521 rettv->vval.v_string = vim_strsave(buf); 12522 rettv->v_type = VAR_STRING; 12523 } 12524 12525 /* 12526 * "nextnonblank()" function 12527 */ 12528 static void 12529 f_nextnonblank(argvars, rettv) 12530 typval_T *argvars; 12531 typval_T *rettv; 12532 { 12533 linenr_T lnum; 12534 12535 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12536 { 12537 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12538 { 12539 lnum = 0; 12540 break; 12541 } 12542 if (*skipwhite(ml_get(lnum)) != NUL) 12543 break; 12544 } 12545 rettv->vval.v_number = lnum; 12546 } 12547 12548 /* 12549 * "nr2char()" function 12550 */ 12551 static void 12552 f_nr2char(argvars, rettv) 12553 typval_T *argvars; 12554 typval_T *rettv; 12555 { 12556 char_u buf[NUMBUFLEN]; 12557 12558 #ifdef FEAT_MBYTE 12559 if (has_mbyte) 12560 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12561 else 12562 #endif 12563 { 12564 buf[0] = (char_u)get_tv_number(&argvars[0]); 12565 buf[1] = NUL; 12566 } 12567 rettv->v_type = VAR_STRING; 12568 rettv->vval.v_string = vim_strsave(buf); 12569 } 12570 12571 /* 12572 * "pathshorten()" function 12573 */ 12574 static void 12575 f_pathshorten(argvars, rettv) 12576 typval_T *argvars; 12577 typval_T *rettv; 12578 { 12579 char_u *p; 12580 12581 rettv->v_type = VAR_STRING; 12582 p = get_tv_string_chk(&argvars[0]); 12583 if (p == NULL) 12584 rettv->vval.v_string = NULL; 12585 else 12586 { 12587 p = vim_strsave(p); 12588 rettv->vval.v_string = p; 12589 if (p != NULL) 12590 shorten_dir(p); 12591 } 12592 } 12593 12594 /* 12595 * "prevnonblank()" function 12596 */ 12597 static void 12598 f_prevnonblank(argvars, rettv) 12599 typval_T *argvars; 12600 typval_T *rettv; 12601 { 12602 linenr_T lnum; 12603 12604 lnum = get_tv_lnum(argvars); 12605 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12606 lnum = 0; 12607 else 12608 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12609 --lnum; 12610 rettv->vval.v_number = lnum; 12611 } 12612 12613 #ifdef HAVE_STDARG_H 12614 /* This dummy va_list is here because: 12615 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12616 * - locally in the function results in a "used before set" warning 12617 * - using va_start() to initialize it gives "function with fixed args" error */ 12618 static va_list ap; 12619 #endif 12620 12621 /* 12622 * "printf()" function 12623 */ 12624 static void 12625 f_printf(argvars, rettv) 12626 typval_T *argvars; 12627 typval_T *rettv; 12628 { 12629 rettv->v_type = VAR_STRING; 12630 rettv->vval.v_string = NULL; 12631 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12632 { 12633 char_u buf[NUMBUFLEN]; 12634 int len; 12635 char_u *s; 12636 int saved_did_emsg = did_emsg; 12637 char *fmt; 12638 12639 /* Get the required length, allocate the buffer and do it for real. */ 12640 did_emsg = FALSE; 12641 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12642 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12643 if (!did_emsg) 12644 { 12645 s = alloc(len + 1); 12646 if (s != NULL) 12647 { 12648 rettv->vval.v_string = s; 12649 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12650 } 12651 } 12652 did_emsg |= saved_did_emsg; 12653 } 12654 #endif 12655 } 12656 12657 /* 12658 * "pumvisible()" function 12659 */ 12660 /*ARGSUSED*/ 12661 static void 12662 f_pumvisible(argvars, rettv) 12663 typval_T *argvars; 12664 typval_T *rettv; 12665 { 12666 rettv->vval.v_number = 0; 12667 #ifdef FEAT_INS_EXPAND 12668 if (pum_visible()) 12669 rettv->vval.v_number = 1; 12670 #endif 12671 } 12672 12673 /* 12674 * "range()" function 12675 */ 12676 static void 12677 f_range(argvars, rettv) 12678 typval_T *argvars; 12679 typval_T *rettv; 12680 { 12681 long start; 12682 long end; 12683 long stride = 1; 12684 long i; 12685 int error = FALSE; 12686 12687 start = get_tv_number_chk(&argvars[0], &error); 12688 if (argvars[1].v_type == VAR_UNKNOWN) 12689 { 12690 end = start - 1; 12691 start = 0; 12692 } 12693 else 12694 { 12695 end = get_tv_number_chk(&argvars[1], &error); 12696 if (argvars[2].v_type != VAR_UNKNOWN) 12697 stride = get_tv_number_chk(&argvars[2], &error); 12698 } 12699 12700 rettv->vval.v_number = 0; 12701 if (error) 12702 return; /* type error; errmsg already given */ 12703 if (stride == 0) 12704 EMSG(_("E726: Stride is zero")); 12705 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12706 EMSG(_("E727: Start past end")); 12707 else 12708 { 12709 if (rettv_list_alloc(rettv) == OK) 12710 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12711 if (list_append_number(rettv->vval.v_list, 12712 (varnumber_T)i) == FAIL) 12713 break; 12714 } 12715 } 12716 12717 /* 12718 * "readfile()" function 12719 */ 12720 static void 12721 f_readfile(argvars, rettv) 12722 typval_T *argvars; 12723 typval_T *rettv; 12724 { 12725 int binary = FALSE; 12726 char_u *fname; 12727 FILE *fd; 12728 listitem_T *li; 12729 #define FREAD_SIZE 200 /* optimized for text lines */ 12730 char_u buf[FREAD_SIZE]; 12731 int readlen; /* size of last fread() */ 12732 int buflen; /* nr of valid chars in buf[] */ 12733 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12734 int tolist; /* first byte in buf[] still to be put in list */ 12735 int chop; /* how many CR to chop off */ 12736 char_u *prev = NULL; /* previously read bytes, if any */ 12737 int prevlen = 0; /* length of "prev" if not NULL */ 12738 char_u *s; 12739 int len; 12740 long maxline = MAXLNUM; 12741 long cnt = 0; 12742 12743 if (argvars[1].v_type != VAR_UNKNOWN) 12744 { 12745 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12746 binary = TRUE; 12747 if (argvars[2].v_type != VAR_UNKNOWN) 12748 maxline = get_tv_number(&argvars[2]); 12749 } 12750 12751 if (rettv_list_alloc(rettv) == FAIL) 12752 return; 12753 12754 /* Always open the file in binary mode, library functions have a mind of 12755 * their own about CR-LF conversion. */ 12756 fname = get_tv_string(&argvars[0]); 12757 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12758 { 12759 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12760 return; 12761 } 12762 12763 filtd = 0; 12764 while (cnt < maxline || maxline < 0) 12765 { 12766 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12767 buflen = filtd + readlen; 12768 tolist = 0; 12769 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12770 { 12771 if (buf[filtd] == '\n' || readlen <= 0) 12772 { 12773 /* Only when in binary mode add an empty list item when the 12774 * last line ends in a '\n'. */ 12775 if (!binary && readlen == 0 && filtd == 0) 12776 break; 12777 12778 /* Found end-of-line or end-of-file: add a text line to the 12779 * list. */ 12780 chop = 0; 12781 if (!binary) 12782 while (filtd - chop - 1 >= tolist 12783 && buf[filtd - chop - 1] == '\r') 12784 ++chop; 12785 len = filtd - tolist - chop; 12786 if (prev == NULL) 12787 s = vim_strnsave(buf + tolist, len); 12788 else 12789 { 12790 s = alloc((unsigned)(prevlen + len + 1)); 12791 if (s != NULL) 12792 { 12793 mch_memmove(s, prev, prevlen); 12794 vim_free(prev); 12795 prev = NULL; 12796 mch_memmove(s + prevlen, buf + tolist, len); 12797 s[prevlen + len] = NUL; 12798 } 12799 } 12800 tolist = filtd + 1; 12801 12802 li = listitem_alloc(); 12803 if (li == NULL) 12804 { 12805 vim_free(s); 12806 break; 12807 } 12808 li->li_tv.v_type = VAR_STRING; 12809 li->li_tv.v_lock = 0; 12810 li->li_tv.vval.v_string = s; 12811 list_append(rettv->vval.v_list, li); 12812 12813 if (++cnt >= maxline && maxline >= 0) 12814 break; 12815 if (readlen <= 0) 12816 break; 12817 } 12818 else if (buf[filtd] == NUL) 12819 buf[filtd] = '\n'; 12820 } 12821 if (readlen <= 0) 12822 break; 12823 12824 if (tolist == 0) 12825 { 12826 /* "buf" is full, need to move text to an allocated buffer */ 12827 if (prev == NULL) 12828 { 12829 prev = vim_strnsave(buf, buflen); 12830 prevlen = buflen; 12831 } 12832 else 12833 { 12834 s = alloc((unsigned)(prevlen + buflen)); 12835 if (s != NULL) 12836 { 12837 mch_memmove(s, prev, prevlen); 12838 mch_memmove(s + prevlen, buf, buflen); 12839 vim_free(prev); 12840 prev = s; 12841 prevlen += buflen; 12842 } 12843 } 12844 filtd = 0; 12845 } 12846 else 12847 { 12848 mch_memmove(buf, buf + tolist, buflen - tolist); 12849 filtd -= tolist; 12850 } 12851 } 12852 12853 /* 12854 * For a negative line count use only the lines at the end of the file, 12855 * free the rest. 12856 */ 12857 if (maxline < 0) 12858 while (cnt > -maxline) 12859 { 12860 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 12861 --cnt; 12862 } 12863 12864 vim_free(prev); 12865 fclose(fd); 12866 } 12867 12868 #if defined(FEAT_RELTIME) 12869 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 12870 12871 /* 12872 * Convert a List to proftime_T. 12873 * Return FAIL when there is something wrong. 12874 */ 12875 static int 12876 list2proftime(arg, tm) 12877 typval_T *arg; 12878 proftime_T *tm; 12879 { 12880 long n1, n2; 12881 int error = FALSE; 12882 12883 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 12884 || arg->vval.v_list->lv_len != 2) 12885 return FAIL; 12886 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 12887 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 12888 # ifdef WIN3264 12889 tm->HighPart = n1; 12890 tm->LowPart = n2; 12891 # else 12892 tm->tv_sec = n1; 12893 tm->tv_usec = n2; 12894 # endif 12895 return error ? FAIL : OK; 12896 } 12897 #endif /* FEAT_RELTIME */ 12898 12899 /* 12900 * "reltime()" function 12901 */ 12902 static void 12903 f_reltime(argvars, rettv) 12904 typval_T *argvars; 12905 typval_T *rettv; 12906 { 12907 #ifdef FEAT_RELTIME 12908 proftime_T res; 12909 proftime_T start; 12910 12911 if (argvars[0].v_type == VAR_UNKNOWN) 12912 { 12913 /* No arguments: get current time. */ 12914 profile_start(&res); 12915 } 12916 else if (argvars[1].v_type == VAR_UNKNOWN) 12917 { 12918 if (list2proftime(&argvars[0], &res) == FAIL) 12919 return; 12920 profile_end(&res); 12921 } 12922 else 12923 { 12924 /* Two arguments: compute the difference. */ 12925 if (list2proftime(&argvars[0], &start) == FAIL 12926 || list2proftime(&argvars[1], &res) == FAIL) 12927 return; 12928 profile_sub(&res, &start); 12929 } 12930 12931 if (rettv_list_alloc(rettv) == OK) 12932 { 12933 long n1, n2; 12934 12935 # ifdef WIN3264 12936 n1 = res.HighPart; 12937 n2 = res.LowPart; 12938 # else 12939 n1 = res.tv_sec; 12940 n2 = res.tv_usec; 12941 # endif 12942 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 12943 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 12944 } 12945 #endif 12946 } 12947 12948 /* 12949 * "reltimestr()" function 12950 */ 12951 static void 12952 f_reltimestr(argvars, rettv) 12953 typval_T *argvars; 12954 typval_T *rettv; 12955 { 12956 #ifdef FEAT_RELTIME 12957 proftime_T tm; 12958 #endif 12959 12960 rettv->v_type = VAR_STRING; 12961 rettv->vval.v_string = NULL; 12962 #ifdef FEAT_RELTIME 12963 if (list2proftime(&argvars[0], &tm) == OK) 12964 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 12965 #endif 12966 } 12967 12968 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12969 static void make_connection __ARGS((void)); 12970 static int check_connection __ARGS((void)); 12971 12972 static void 12973 make_connection() 12974 { 12975 if (X_DISPLAY == NULL 12976 # ifdef FEAT_GUI 12977 && !gui.in_use 12978 # endif 12979 ) 12980 { 12981 x_force_connect = TRUE; 12982 setup_term_clip(); 12983 x_force_connect = FALSE; 12984 } 12985 } 12986 12987 static int 12988 check_connection() 12989 { 12990 make_connection(); 12991 if (X_DISPLAY == NULL) 12992 { 12993 EMSG(_("E240: No connection to Vim server")); 12994 return FAIL; 12995 } 12996 return OK; 12997 } 12998 #endif 12999 13000 #ifdef FEAT_CLIENTSERVER 13001 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 13002 13003 static void 13004 remote_common(argvars, rettv, expr) 13005 typval_T *argvars; 13006 typval_T *rettv; 13007 int expr; 13008 { 13009 char_u *server_name; 13010 char_u *keys; 13011 char_u *r = NULL; 13012 char_u buf[NUMBUFLEN]; 13013 # ifdef WIN32 13014 HWND w; 13015 # else 13016 Window w; 13017 # endif 13018 13019 if (check_restricted() || check_secure()) 13020 return; 13021 13022 # ifdef FEAT_X11 13023 if (check_connection() == FAIL) 13024 return; 13025 # endif 13026 13027 server_name = get_tv_string_chk(&argvars[0]); 13028 if (server_name == NULL) 13029 return; /* type error; errmsg already given */ 13030 keys = get_tv_string_buf(&argvars[1], buf); 13031 # ifdef WIN32 13032 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 13033 # else 13034 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 13035 < 0) 13036 # endif 13037 { 13038 if (r != NULL) 13039 EMSG(r); /* sending worked but evaluation failed */ 13040 else 13041 EMSG2(_("E241: Unable to send to %s"), server_name); 13042 return; 13043 } 13044 13045 rettv->vval.v_string = r; 13046 13047 if (argvars[2].v_type != VAR_UNKNOWN) 13048 { 13049 dictitem_T v; 13050 char_u str[30]; 13051 char_u *idvar; 13052 13053 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 13054 v.di_tv.v_type = VAR_STRING; 13055 v.di_tv.vval.v_string = vim_strsave(str); 13056 idvar = get_tv_string_chk(&argvars[2]); 13057 if (idvar != NULL) 13058 set_var(idvar, &v.di_tv, FALSE); 13059 vim_free(v.di_tv.vval.v_string); 13060 } 13061 } 13062 #endif 13063 13064 /* 13065 * "remote_expr()" function 13066 */ 13067 /*ARGSUSED*/ 13068 static void 13069 f_remote_expr(argvars, rettv) 13070 typval_T *argvars; 13071 typval_T *rettv; 13072 { 13073 rettv->v_type = VAR_STRING; 13074 rettv->vval.v_string = NULL; 13075 #ifdef FEAT_CLIENTSERVER 13076 remote_common(argvars, rettv, TRUE); 13077 #endif 13078 } 13079 13080 /* 13081 * "remote_foreground()" function 13082 */ 13083 /*ARGSUSED*/ 13084 static void 13085 f_remote_foreground(argvars, rettv) 13086 typval_T *argvars; 13087 typval_T *rettv; 13088 { 13089 rettv->vval.v_number = 0; 13090 #ifdef FEAT_CLIENTSERVER 13091 # ifdef WIN32 13092 /* On Win32 it's done in this application. */ 13093 { 13094 char_u *server_name = get_tv_string_chk(&argvars[0]); 13095 13096 if (server_name != NULL) 13097 serverForeground(server_name); 13098 } 13099 # else 13100 /* Send a foreground() expression to the server. */ 13101 argvars[1].v_type = VAR_STRING; 13102 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 13103 argvars[2].v_type = VAR_UNKNOWN; 13104 remote_common(argvars, rettv, TRUE); 13105 vim_free(argvars[1].vval.v_string); 13106 # endif 13107 #endif 13108 } 13109 13110 /*ARGSUSED*/ 13111 static void 13112 f_remote_peek(argvars, rettv) 13113 typval_T *argvars; 13114 typval_T *rettv; 13115 { 13116 #ifdef FEAT_CLIENTSERVER 13117 dictitem_T v; 13118 char_u *s = NULL; 13119 # ifdef WIN32 13120 long_u n = 0; 13121 # endif 13122 char_u *serverid; 13123 13124 if (check_restricted() || check_secure()) 13125 { 13126 rettv->vval.v_number = -1; 13127 return; 13128 } 13129 serverid = get_tv_string_chk(&argvars[0]); 13130 if (serverid == NULL) 13131 { 13132 rettv->vval.v_number = -1; 13133 return; /* type error; errmsg already given */ 13134 } 13135 # ifdef WIN32 13136 sscanf(serverid, SCANF_HEX_LONG_U, &n); 13137 if (n == 0) 13138 rettv->vval.v_number = -1; 13139 else 13140 { 13141 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 13142 rettv->vval.v_number = (s != NULL); 13143 } 13144 # else 13145 rettv->vval.v_number = 0; 13146 if (check_connection() == FAIL) 13147 return; 13148 13149 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 13150 serverStrToWin(serverid), &s); 13151 # endif 13152 13153 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 13154 { 13155 char_u *retvar; 13156 13157 v.di_tv.v_type = VAR_STRING; 13158 v.di_tv.vval.v_string = vim_strsave(s); 13159 retvar = get_tv_string_chk(&argvars[1]); 13160 if (retvar != NULL) 13161 set_var(retvar, &v.di_tv, FALSE); 13162 vim_free(v.di_tv.vval.v_string); 13163 } 13164 #else 13165 rettv->vval.v_number = -1; 13166 #endif 13167 } 13168 13169 /*ARGSUSED*/ 13170 static void 13171 f_remote_read(argvars, rettv) 13172 typval_T *argvars; 13173 typval_T *rettv; 13174 { 13175 char_u *r = NULL; 13176 13177 #ifdef FEAT_CLIENTSERVER 13178 char_u *serverid = get_tv_string_chk(&argvars[0]); 13179 13180 if (serverid != NULL && !check_restricted() && !check_secure()) 13181 { 13182 # ifdef WIN32 13183 /* The server's HWND is encoded in the 'id' parameter */ 13184 long_u n = 0; 13185 13186 sscanf(serverid, SCANF_HEX_LONG_U, &n); 13187 if (n != 0) 13188 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 13189 if (r == NULL) 13190 # else 13191 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 13192 serverStrToWin(serverid), &r, FALSE) < 0) 13193 # endif 13194 EMSG(_("E277: Unable to read a server reply")); 13195 } 13196 #endif 13197 rettv->v_type = VAR_STRING; 13198 rettv->vval.v_string = r; 13199 } 13200 13201 /* 13202 * "remote_send()" function 13203 */ 13204 /*ARGSUSED*/ 13205 static void 13206 f_remote_send(argvars, rettv) 13207 typval_T *argvars; 13208 typval_T *rettv; 13209 { 13210 rettv->v_type = VAR_STRING; 13211 rettv->vval.v_string = NULL; 13212 #ifdef FEAT_CLIENTSERVER 13213 remote_common(argvars, rettv, FALSE); 13214 #endif 13215 } 13216 13217 /* 13218 * "remove()" function 13219 */ 13220 static void 13221 f_remove(argvars, rettv) 13222 typval_T *argvars; 13223 typval_T *rettv; 13224 { 13225 list_T *l; 13226 listitem_T *item, *item2; 13227 listitem_T *li; 13228 long idx; 13229 long end; 13230 char_u *key; 13231 dict_T *d; 13232 dictitem_T *di; 13233 13234 rettv->vval.v_number = 0; 13235 if (argvars[0].v_type == VAR_DICT) 13236 { 13237 if (argvars[2].v_type != VAR_UNKNOWN) 13238 EMSG2(_(e_toomanyarg), "remove()"); 13239 else if ((d = argvars[0].vval.v_dict) != NULL 13240 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 13241 { 13242 key = get_tv_string_chk(&argvars[1]); 13243 if (key != NULL) 13244 { 13245 di = dict_find(d, key, -1); 13246 if (di == NULL) 13247 EMSG2(_(e_dictkey), key); 13248 else 13249 { 13250 *rettv = di->di_tv; 13251 init_tv(&di->di_tv); 13252 dictitem_remove(d, di); 13253 } 13254 } 13255 } 13256 } 13257 else if (argvars[0].v_type != VAR_LIST) 13258 EMSG2(_(e_listdictarg), "remove()"); 13259 else if ((l = argvars[0].vval.v_list) != NULL 13260 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 13261 { 13262 int error = FALSE; 13263 13264 idx = get_tv_number_chk(&argvars[1], &error); 13265 if (error) 13266 ; /* type error: do nothing, errmsg already given */ 13267 else if ((item = list_find(l, idx)) == NULL) 13268 EMSGN(_(e_listidx), idx); 13269 else 13270 { 13271 if (argvars[2].v_type == VAR_UNKNOWN) 13272 { 13273 /* Remove one item, return its value. */ 13274 list_remove(l, item, item); 13275 *rettv = item->li_tv; 13276 vim_free(item); 13277 } 13278 else 13279 { 13280 /* Remove range of items, return list with values. */ 13281 end = get_tv_number_chk(&argvars[2], &error); 13282 if (error) 13283 ; /* type error: do nothing */ 13284 else if ((item2 = list_find(l, end)) == NULL) 13285 EMSGN(_(e_listidx), end); 13286 else 13287 { 13288 int cnt = 0; 13289 13290 for (li = item; li != NULL; li = li->li_next) 13291 { 13292 ++cnt; 13293 if (li == item2) 13294 break; 13295 } 13296 if (li == NULL) /* didn't find "item2" after "item" */ 13297 EMSG(_(e_invrange)); 13298 else 13299 { 13300 list_remove(l, item, item2); 13301 if (rettv_list_alloc(rettv) == OK) 13302 { 13303 l = rettv->vval.v_list; 13304 l->lv_first = item; 13305 l->lv_last = item2; 13306 item->li_prev = NULL; 13307 item2->li_next = NULL; 13308 l->lv_len = cnt; 13309 } 13310 } 13311 } 13312 } 13313 } 13314 } 13315 } 13316 13317 /* 13318 * "rename({from}, {to})" function 13319 */ 13320 static void 13321 f_rename(argvars, rettv) 13322 typval_T *argvars; 13323 typval_T *rettv; 13324 { 13325 char_u buf[NUMBUFLEN]; 13326 13327 if (check_restricted() || check_secure()) 13328 rettv->vval.v_number = -1; 13329 else 13330 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 13331 get_tv_string_buf(&argvars[1], buf)); 13332 } 13333 13334 /* 13335 * "repeat()" function 13336 */ 13337 /*ARGSUSED*/ 13338 static void 13339 f_repeat(argvars, rettv) 13340 typval_T *argvars; 13341 typval_T *rettv; 13342 { 13343 char_u *p; 13344 int n; 13345 int slen; 13346 int len; 13347 char_u *r; 13348 int i; 13349 13350 n = get_tv_number(&argvars[1]); 13351 if (argvars[0].v_type == VAR_LIST) 13352 { 13353 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 13354 while (n-- > 0) 13355 if (list_extend(rettv->vval.v_list, 13356 argvars[0].vval.v_list, NULL) == FAIL) 13357 break; 13358 } 13359 else 13360 { 13361 p = get_tv_string(&argvars[0]); 13362 rettv->v_type = VAR_STRING; 13363 rettv->vval.v_string = NULL; 13364 13365 slen = (int)STRLEN(p); 13366 len = slen * n; 13367 if (len <= 0) 13368 return; 13369 13370 r = alloc(len + 1); 13371 if (r != NULL) 13372 { 13373 for (i = 0; i < n; i++) 13374 mch_memmove(r + i * slen, p, (size_t)slen); 13375 r[len] = NUL; 13376 } 13377 13378 rettv->vval.v_string = r; 13379 } 13380 } 13381 13382 /* 13383 * "resolve()" function 13384 */ 13385 static void 13386 f_resolve(argvars, rettv) 13387 typval_T *argvars; 13388 typval_T *rettv; 13389 { 13390 char_u *p; 13391 13392 p = get_tv_string(&argvars[0]); 13393 #ifdef FEAT_SHORTCUT 13394 { 13395 char_u *v = NULL; 13396 13397 v = mch_resolve_shortcut(p); 13398 if (v != NULL) 13399 rettv->vval.v_string = v; 13400 else 13401 rettv->vval.v_string = vim_strsave(p); 13402 } 13403 #else 13404 # ifdef HAVE_READLINK 13405 { 13406 char_u buf[MAXPATHL + 1]; 13407 char_u *cpy; 13408 int len; 13409 char_u *remain = NULL; 13410 char_u *q; 13411 int is_relative_to_current = FALSE; 13412 int has_trailing_pathsep = FALSE; 13413 int limit = 100; 13414 13415 p = vim_strsave(p); 13416 13417 if (p[0] == '.' && (vim_ispathsep(p[1]) 13418 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 13419 is_relative_to_current = TRUE; 13420 13421 len = STRLEN(p); 13422 if (len > 0 && after_pathsep(p, p + len)) 13423 has_trailing_pathsep = TRUE; 13424 13425 q = getnextcomp(p); 13426 if (*q != NUL) 13427 { 13428 /* Separate the first path component in "p", and keep the 13429 * remainder (beginning with the path separator). */ 13430 remain = vim_strsave(q - 1); 13431 q[-1] = NUL; 13432 } 13433 13434 for (;;) 13435 { 13436 for (;;) 13437 { 13438 len = readlink((char *)p, (char *)buf, MAXPATHL); 13439 if (len <= 0) 13440 break; 13441 buf[len] = NUL; 13442 13443 if (limit-- == 0) 13444 { 13445 vim_free(p); 13446 vim_free(remain); 13447 EMSG(_("E655: Too many symbolic links (cycle?)")); 13448 rettv->vval.v_string = NULL; 13449 goto fail; 13450 } 13451 13452 /* Ensure that the result will have a trailing path separator 13453 * if the argument has one. */ 13454 if (remain == NULL && has_trailing_pathsep) 13455 add_pathsep(buf); 13456 13457 /* Separate the first path component in the link value and 13458 * concatenate the remainders. */ 13459 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 13460 if (*q != NUL) 13461 { 13462 if (remain == NULL) 13463 remain = vim_strsave(q - 1); 13464 else 13465 { 13466 cpy = concat_str(q - 1, remain); 13467 if (cpy != NULL) 13468 { 13469 vim_free(remain); 13470 remain = cpy; 13471 } 13472 } 13473 q[-1] = NUL; 13474 } 13475 13476 q = gettail(p); 13477 if (q > p && *q == NUL) 13478 { 13479 /* Ignore trailing path separator. */ 13480 q[-1] = NUL; 13481 q = gettail(p); 13482 } 13483 if (q > p && !mch_isFullName(buf)) 13484 { 13485 /* symlink is relative to directory of argument */ 13486 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 13487 if (cpy != NULL) 13488 { 13489 STRCPY(cpy, p); 13490 STRCPY(gettail(cpy), buf); 13491 vim_free(p); 13492 p = cpy; 13493 } 13494 } 13495 else 13496 { 13497 vim_free(p); 13498 p = vim_strsave(buf); 13499 } 13500 } 13501 13502 if (remain == NULL) 13503 break; 13504 13505 /* Append the first path component of "remain" to "p". */ 13506 q = getnextcomp(remain + 1); 13507 len = q - remain - (*q != NUL); 13508 cpy = vim_strnsave(p, STRLEN(p) + len); 13509 if (cpy != NULL) 13510 { 13511 STRNCAT(cpy, remain, len); 13512 vim_free(p); 13513 p = cpy; 13514 } 13515 /* Shorten "remain". */ 13516 if (*q != NUL) 13517 STRCPY(remain, q - 1); 13518 else 13519 { 13520 vim_free(remain); 13521 remain = NULL; 13522 } 13523 } 13524 13525 /* If the result is a relative path name, make it explicitly relative to 13526 * the current directory if and only if the argument had this form. */ 13527 if (!vim_ispathsep(*p)) 13528 { 13529 if (is_relative_to_current 13530 && *p != NUL 13531 && !(p[0] == '.' 13532 && (p[1] == NUL 13533 || vim_ispathsep(p[1]) 13534 || (p[1] == '.' 13535 && (p[2] == NUL 13536 || vim_ispathsep(p[2])))))) 13537 { 13538 /* Prepend "./". */ 13539 cpy = concat_str((char_u *)"./", p); 13540 if (cpy != NULL) 13541 { 13542 vim_free(p); 13543 p = cpy; 13544 } 13545 } 13546 else if (!is_relative_to_current) 13547 { 13548 /* Strip leading "./". */ 13549 q = p; 13550 while (q[0] == '.' && vim_ispathsep(q[1])) 13551 q += 2; 13552 if (q > p) 13553 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 13554 } 13555 } 13556 13557 /* Ensure that the result will have no trailing path separator 13558 * if the argument had none. But keep "/" or "//". */ 13559 if (!has_trailing_pathsep) 13560 { 13561 q = p + STRLEN(p); 13562 if (after_pathsep(p, q)) 13563 *gettail_sep(p) = NUL; 13564 } 13565 13566 rettv->vval.v_string = p; 13567 } 13568 # else 13569 rettv->vval.v_string = vim_strsave(p); 13570 # endif 13571 #endif 13572 13573 simplify_filename(rettv->vval.v_string); 13574 13575 #ifdef HAVE_READLINK 13576 fail: 13577 #endif 13578 rettv->v_type = VAR_STRING; 13579 } 13580 13581 /* 13582 * "reverse({list})" function 13583 */ 13584 static void 13585 f_reverse(argvars, rettv) 13586 typval_T *argvars; 13587 typval_T *rettv; 13588 { 13589 list_T *l; 13590 listitem_T *li, *ni; 13591 13592 rettv->vval.v_number = 0; 13593 if (argvars[0].v_type != VAR_LIST) 13594 EMSG2(_(e_listarg), "reverse()"); 13595 else if ((l = argvars[0].vval.v_list) != NULL 13596 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 13597 { 13598 li = l->lv_last; 13599 l->lv_first = l->lv_last = NULL; 13600 l->lv_len = 0; 13601 while (li != NULL) 13602 { 13603 ni = li->li_prev; 13604 list_append(l, li); 13605 li = ni; 13606 } 13607 rettv->vval.v_list = l; 13608 rettv->v_type = VAR_LIST; 13609 ++l->lv_refcount; 13610 } 13611 } 13612 13613 #define SP_NOMOVE 0x01 /* don't move cursor */ 13614 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 13615 #define SP_RETCOUNT 0x04 /* return matchcount */ 13616 #define SP_SETPCMARK 0x08 /* set previous context mark */ 13617 #define SP_START 0x10 /* accept match at start position */ 13618 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 13619 #define SP_END 0x40 /* leave cursor at end of match */ 13620 13621 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 13622 13623 /* 13624 * Get flags for a search function. 13625 * Possibly sets "p_ws". 13626 * Returns BACKWARD, FORWARD or zero (for an error). 13627 */ 13628 static int 13629 get_search_arg(varp, flagsp) 13630 typval_T *varp; 13631 int *flagsp; 13632 { 13633 int dir = FORWARD; 13634 char_u *flags; 13635 char_u nbuf[NUMBUFLEN]; 13636 int mask; 13637 13638 if (varp->v_type != VAR_UNKNOWN) 13639 { 13640 flags = get_tv_string_buf_chk(varp, nbuf); 13641 if (flags == NULL) 13642 return 0; /* type error; errmsg already given */ 13643 while (*flags != NUL) 13644 { 13645 switch (*flags) 13646 { 13647 case 'b': dir = BACKWARD; break; 13648 case 'w': p_ws = TRUE; break; 13649 case 'W': p_ws = FALSE; break; 13650 default: mask = 0; 13651 if (flagsp != NULL) 13652 switch (*flags) 13653 { 13654 case 'c': mask = SP_START; break; 13655 case 'e': mask = SP_END; break; 13656 case 'm': mask = SP_RETCOUNT; break; 13657 case 'n': mask = SP_NOMOVE; break; 13658 case 'p': mask = SP_SUBPAT; break; 13659 case 'r': mask = SP_REPEAT; break; 13660 case 's': mask = SP_SETPCMARK; break; 13661 } 13662 if (mask == 0) 13663 { 13664 EMSG2(_(e_invarg2), flags); 13665 dir = 0; 13666 } 13667 else 13668 *flagsp |= mask; 13669 } 13670 if (dir == 0) 13671 break; 13672 ++flags; 13673 } 13674 } 13675 return dir; 13676 } 13677 13678 /* 13679 * Shared by search() and searchpos() functions 13680 */ 13681 static int 13682 search_cmn(argvars, match_pos, flagsp) 13683 typval_T *argvars; 13684 pos_T *match_pos; 13685 int *flagsp; 13686 { 13687 int flags; 13688 char_u *pat; 13689 pos_T pos; 13690 pos_T save_cursor; 13691 int save_p_ws = p_ws; 13692 int dir; 13693 int retval = 0; /* default: FAIL */ 13694 long lnum_stop = 0; 13695 int options = SEARCH_KEEP; 13696 int subpatnum; 13697 13698 pat = get_tv_string(&argvars[0]); 13699 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 13700 if (dir == 0) 13701 goto theend; 13702 flags = *flagsp; 13703 if (flags & SP_START) 13704 options |= SEARCH_START; 13705 if (flags & SP_END) 13706 options |= SEARCH_END; 13707 13708 /* Optional extra argument: line number to stop searching. */ 13709 if (argvars[1].v_type != VAR_UNKNOWN 13710 && argvars[2].v_type != VAR_UNKNOWN) 13711 { 13712 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 13713 if (lnum_stop < 0) 13714 goto theend; 13715 } 13716 13717 /* 13718 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 13719 * Check to make sure only those flags are set. 13720 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13721 * flags cannot be set. Check for that condition also. 13722 */ 13723 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 13724 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13725 { 13726 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13727 goto theend; 13728 } 13729 13730 pos = save_cursor = curwin->w_cursor; 13731 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13732 options, RE_SEARCH, (linenr_T)lnum_stop); 13733 if (subpatnum != FAIL) 13734 { 13735 if (flags & SP_SUBPAT) 13736 retval = subpatnum; 13737 else 13738 retval = pos.lnum; 13739 if (flags & SP_SETPCMARK) 13740 setpcmark(); 13741 curwin->w_cursor = pos; 13742 if (match_pos != NULL) 13743 { 13744 /* Store the match cursor position */ 13745 match_pos->lnum = pos.lnum; 13746 match_pos->col = pos.col + 1; 13747 } 13748 /* "/$" will put the cursor after the end of the line, may need to 13749 * correct that here */ 13750 check_cursor(); 13751 } 13752 13753 /* If 'n' flag is used: restore cursor position. */ 13754 if (flags & SP_NOMOVE) 13755 curwin->w_cursor = save_cursor; 13756 theend: 13757 p_ws = save_p_ws; 13758 13759 return retval; 13760 } 13761 13762 /* 13763 * "search()" function 13764 */ 13765 static void 13766 f_search(argvars, rettv) 13767 typval_T *argvars; 13768 typval_T *rettv; 13769 { 13770 int flags = 0; 13771 13772 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 13773 } 13774 13775 /* 13776 * "searchdecl()" function 13777 */ 13778 static void 13779 f_searchdecl(argvars, rettv) 13780 typval_T *argvars; 13781 typval_T *rettv; 13782 { 13783 int locally = 1; 13784 int thisblock = 0; 13785 int error = FALSE; 13786 char_u *name; 13787 13788 rettv->vval.v_number = 1; /* default: FAIL */ 13789 13790 name = get_tv_string_chk(&argvars[0]); 13791 if (argvars[1].v_type != VAR_UNKNOWN) 13792 { 13793 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13794 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13795 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13796 } 13797 if (!error && name != NULL) 13798 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13799 locally, thisblock, SEARCH_KEEP) == FAIL; 13800 } 13801 13802 /* 13803 * Used by searchpair() and searchpairpos() 13804 */ 13805 static int 13806 searchpair_cmn(argvars, match_pos) 13807 typval_T *argvars; 13808 pos_T *match_pos; 13809 { 13810 char_u *spat, *mpat, *epat; 13811 char_u *skip; 13812 int save_p_ws = p_ws; 13813 int dir; 13814 int flags = 0; 13815 char_u nbuf1[NUMBUFLEN]; 13816 char_u nbuf2[NUMBUFLEN]; 13817 char_u nbuf3[NUMBUFLEN]; 13818 int retval = 0; /* default: FAIL */ 13819 long lnum_stop = 0; 13820 13821 /* Get the three pattern arguments: start, middle, end. */ 13822 spat = get_tv_string_chk(&argvars[0]); 13823 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13824 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13825 if (spat == NULL || mpat == NULL || epat == NULL) 13826 goto theend; /* type error */ 13827 13828 /* Handle the optional fourth argument: flags */ 13829 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13830 if (dir == 0) 13831 goto theend; 13832 13833 /* Don't accept SP_END or SP_SUBPAT. 13834 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13835 */ 13836 if ((flags & (SP_END | SP_SUBPAT)) != 0 13837 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13838 { 13839 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 13840 goto theend; 13841 } 13842 13843 /* Optional fifth argument: skip expression */ 13844 if (argvars[3].v_type == VAR_UNKNOWN 13845 || argvars[4].v_type == VAR_UNKNOWN) 13846 skip = (char_u *)""; 13847 else 13848 { 13849 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13850 if (argvars[5].v_type != VAR_UNKNOWN) 13851 { 13852 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 13853 if (lnum_stop < 0) 13854 goto theend; 13855 } 13856 } 13857 if (skip == NULL) 13858 goto theend; /* type error */ 13859 13860 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 13861 match_pos, lnum_stop); 13862 13863 theend: 13864 p_ws = save_p_ws; 13865 13866 return retval; 13867 } 13868 13869 /* 13870 * "searchpair()" function 13871 */ 13872 static void 13873 f_searchpair(argvars, rettv) 13874 typval_T *argvars; 13875 typval_T *rettv; 13876 { 13877 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 13878 } 13879 13880 /* 13881 * "searchpairpos()" function 13882 */ 13883 static void 13884 f_searchpairpos(argvars, rettv) 13885 typval_T *argvars; 13886 typval_T *rettv; 13887 { 13888 pos_T match_pos; 13889 int lnum = 0; 13890 int col = 0; 13891 13892 rettv->vval.v_number = 0; 13893 13894 if (rettv_list_alloc(rettv) == FAIL) 13895 return; 13896 13897 if (searchpair_cmn(argvars, &match_pos) > 0) 13898 { 13899 lnum = match_pos.lnum; 13900 col = match_pos.col; 13901 } 13902 13903 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 13904 list_append_number(rettv->vval.v_list, (varnumber_T)col); 13905 } 13906 13907 /* 13908 * Search for a start/middle/end thing. 13909 * Used by searchpair(), see its documentation for the details. 13910 * Returns 0 or -1 for no match, 13911 */ 13912 long 13913 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop) 13914 char_u *spat; /* start pattern */ 13915 char_u *mpat; /* middle pattern */ 13916 char_u *epat; /* end pattern */ 13917 int dir; /* BACKWARD or FORWARD */ 13918 char_u *skip; /* skip expression */ 13919 int flags; /* SP_SETPCMARK and other SP_ values */ 13920 pos_T *match_pos; 13921 linenr_T lnum_stop; /* stop at this line if not zero */ 13922 { 13923 char_u *save_cpo; 13924 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13925 long retval = 0; 13926 pos_T pos; 13927 pos_T firstpos; 13928 pos_T foundpos; 13929 pos_T save_cursor; 13930 pos_T save_pos; 13931 int n; 13932 int r; 13933 int nest = 1; 13934 int err; 13935 int options = SEARCH_KEEP; 13936 13937 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13938 save_cpo = p_cpo; 13939 p_cpo = (char_u *)""; 13940 13941 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13942 * start/middle/end (pat3, for the top pair). */ 13943 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13944 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13945 if (pat2 == NULL || pat3 == NULL) 13946 goto theend; 13947 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13948 if (*mpat == NUL) 13949 STRCPY(pat3, pat2); 13950 else 13951 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13952 spat, epat, mpat); 13953 if (flags & SP_START) 13954 options |= SEARCH_START; 13955 13956 save_cursor = curwin->w_cursor; 13957 pos = curwin->w_cursor; 13958 clearpos(&firstpos); 13959 clearpos(&foundpos); 13960 pat = pat3; 13961 for (;;) 13962 { 13963 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13964 options, RE_SEARCH, lnum_stop); 13965 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13966 /* didn't find it or found the first match again: FAIL */ 13967 break; 13968 13969 if (firstpos.lnum == 0) 13970 firstpos = pos; 13971 if (equalpos(pos, foundpos)) 13972 { 13973 /* Found the same position again. Can happen with a pattern that 13974 * has "\zs" at the end and searching backwards. Advance one 13975 * character and try again. */ 13976 if (dir == BACKWARD) 13977 decl(&pos); 13978 else 13979 incl(&pos); 13980 } 13981 foundpos = pos; 13982 13983 /* If the skip pattern matches, ignore this match. */ 13984 if (*skip != NUL) 13985 { 13986 save_pos = curwin->w_cursor; 13987 curwin->w_cursor = pos; 13988 r = eval_to_bool(skip, &err, NULL, FALSE); 13989 curwin->w_cursor = save_pos; 13990 if (err) 13991 { 13992 /* Evaluating {skip} caused an error, break here. */ 13993 curwin->w_cursor = save_cursor; 13994 retval = -1; 13995 break; 13996 } 13997 if (r) 13998 continue; 13999 } 14000 14001 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 14002 { 14003 /* Found end when searching backwards or start when searching 14004 * forward: nested pair. */ 14005 ++nest; 14006 pat = pat2; /* nested, don't search for middle */ 14007 } 14008 else 14009 { 14010 /* Found end when searching forward or start when searching 14011 * backward: end of (nested) pair; or found middle in outer pair. */ 14012 if (--nest == 1) 14013 pat = pat3; /* outer level, search for middle */ 14014 } 14015 14016 if (nest == 0) 14017 { 14018 /* Found the match: return matchcount or line number. */ 14019 if (flags & SP_RETCOUNT) 14020 ++retval; 14021 else 14022 retval = pos.lnum; 14023 if (flags & SP_SETPCMARK) 14024 setpcmark(); 14025 curwin->w_cursor = pos; 14026 if (!(flags & SP_REPEAT)) 14027 break; 14028 nest = 1; /* search for next unmatched */ 14029 } 14030 } 14031 14032 if (match_pos != NULL) 14033 { 14034 /* Store the match cursor position */ 14035 match_pos->lnum = curwin->w_cursor.lnum; 14036 match_pos->col = curwin->w_cursor.col + 1; 14037 } 14038 14039 /* If 'n' flag is used or search failed: restore cursor position. */ 14040 if ((flags & SP_NOMOVE) || retval == 0) 14041 curwin->w_cursor = save_cursor; 14042 14043 theend: 14044 vim_free(pat2); 14045 vim_free(pat3); 14046 p_cpo = save_cpo; 14047 14048 return retval; 14049 } 14050 14051 /* 14052 * "searchpos()" function 14053 */ 14054 static void 14055 f_searchpos(argvars, rettv) 14056 typval_T *argvars; 14057 typval_T *rettv; 14058 { 14059 pos_T match_pos; 14060 int lnum = 0; 14061 int col = 0; 14062 int n; 14063 int flags = 0; 14064 14065 rettv->vval.v_number = 0; 14066 14067 if (rettv_list_alloc(rettv) == FAIL) 14068 return; 14069 14070 n = search_cmn(argvars, &match_pos, &flags); 14071 if (n > 0) 14072 { 14073 lnum = match_pos.lnum; 14074 col = match_pos.col; 14075 } 14076 14077 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 14078 list_append_number(rettv->vval.v_list, (varnumber_T)col); 14079 if (flags & SP_SUBPAT) 14080 list_append_number(rettv->vval.v_list, (varnumber_T)n); 14081 } 14082 14083 14084 /*ARGSUSED*/ 14085 static void 14086 f_server2client(argvars, rettv) 14087 typval_T *argvars; 14088 typval_T *rettv; 14089 { 14090 #ifdef FEAT_CLIENTSERVER 14091 char_u buf[NUMBUFLEN]; 14092 char_u *server = get_tv_string_chk(&argvars[0]); 14093 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 14094 14095 rettv->vval.v_number = -1; 14096 if (server == NULL || reply == NULL) 14097 return; 14098 if (check_restricted() || check_secure()) 14099 return; 14100 # ifdef FEAT_X11 14101 if (check_connection() == FAIL) 14102 return; 14103 # endif 14104 14105 if (serverSendReply(server, reply) < 0) 14106 { 14107 EMSG(_("E258: Unable to send to client")); 14108 return; 14109 } 14110 rettv->vval.v_number = 0; 14111 #else 14112 rettv->vval.v_number = -1; 14113 #endif 14114 } 14115 14116 /*ARGSUSED*/ 14117 static void 14118 f_serverlist(argvars, rettv) 14119 typval_T *argvars; 14120 typval_T *rettv; 14121 { 14122 char_u *r = NULL; 14123 14124 #ifdef FEAT_CLIENTSERVER 14125 # ifdef WIN32 14126 r = serverGetVimNames(); 14127 # else 14128 make_connection(); 14129 if (X_DISPLAY != NULL) 14130 r = serverGetVimNames(X_DISPLAY); 14131 # endif 14132 #endif 14133 rettv->v_type = VAR_STRING; 14134 rettv->vval.v_string = r; 14135 } 14136 14137 /* 14138 * "setbufvar()" function 14139 */ 14140 /*ARGSUSED*/ 14141 static void 14142 f_setbufvar(argvars, rettv) 14143 typval_T *argvars; 14144 typval_T *rettv; 14145 { 14146 buf_T *buf; 14147 #ifdef FEAT_AUTOCMD 14148 aco_save_T aco; 14149 #else 14150 buf_T *save_curbuf; 14151 #endif 14152 char_u *varname, *bufvarname; 14153 typval_T *varp; 14154 char_u nbuf[NUMBUFLEN]; 14155 14156 rettv->vval.v_number = 0; 14157 14158 if (check_restricted() || check_secure()) 14159 return; 14160 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 14161 varname = get_tv_string_chk(&argvars[1]); 14162 buf = get_buf_tv(&argvars[0]); 14163 varp = &argvars[2]; 14164 14165 if (buf != NULL && varname != NULL && varp != NULL) 14166 { 14167 /* set curbuf to be our buf, temporarily */ 14168 #ifdef FEAT_AUTOCMD 14169 aucmd_prepbuf(&aco, buf); 14170 #else 14171 save_curbuf = curbuf; 14172 curbuf = buf; 14173 #endif 14174 14175 if (*varname == '&') 14176 { 14177 long numval; 14178 char_u *strval; 14179 int error = FALSE; 14180 14181 ++varname; 14182 numval = get_tv_number_chk(varp, &error); 14183 strval = get_tv_string_buf_chk(varp, nbuf); 14184 if (!error && strval != NULL) 14185 set_option_value(varname, numval, strval, OPT_LOCAL); 14186 } 14187 else 14188 { 14189 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 14190 if (bufvarname != NULL) 14191 { 14192 STRCPY(bufvarname, "b:"); 14193 STRCPY(bufvarname + 2, varname); 14194 set_var(bufvarname, varp, TRUE); 14195 vim_free(bufvarname); 14196 } 14197 } 14198 14199 /* reset notion of buffer */ 14200 #ifdef FEAT_AUTOCMD 14201 aucmd_restbuf(&aco); 14202 #else 14203 curbuf = save_curbuf; 14204 #endif 14205 } 14206 } 14207 14208 /* 14209 * "setcmdpos()" function 14210 */ 14211 static void 14212 f_setcmdpos(argvars, rettv) 14213 typval_T *argvars; 14214 typval_T *rettv; 14215 { 14216 int pos = (int)get_tv_number(&argvars[0]) - 1; 14217 14218 if (pos >= 0) 14219 rettv->vval.v_number = set_cmdline_pos(pos); 14220 } 14221 14222 /* 14223 * "setline()" function 14224 */ 14225 static void 14226 f_setline(argvars, rettv) 14227 typval_T *argvars; 14228 typval_T *rettv; 14229 { 14230 linenr_T lnum; 14231 char_u *line = NULL; 14232 list_T *l = NULL; 14233 listitem_T *li = NULL; 14234 long added = 0; 14235 linenr_T lcount = curbuf->b_ml.ml_line_count; 14236 14237 lnum = get_tv_lnum(&argvars[0]); 14238 if (argvars[1].v_type == VAR_LIST) 14239 { 14240 l = argvars[1].vval.v_list; 14241 li = l->lv_first; 14242 } 14243 else 14244 line = get_tv_string_chk(&argvars[1]); 14245 14246 rettv->vval.v_number = 0; /* OK */ 14247 for (;;) 14248 { 14249 if (l != NULL) 14250 { 14251 /* list argument, get next string */ 14252 if (li == NULL) 14253 break; 14254 line = get_tv_string_chk(&li->li_tv); 14255 li = li->li_next; 14256 } 14257 14258 rettv->vval.v_number = 1; /* FAIL */ 14259 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 14260 break; 14261 if (lnum <= curbuf->b_ml.ml_line_count) 14262 { 14263 /* existing line, replace it */ 14264 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 14265 { 14266 changed_bytes(lnum, 0); 14267 check_cursor_col(); 14268 rettv->vval.v_number = 0; /* OK */ 14269 } 14270 } 14271 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 14272 { 14273 /* lnum is one past the last line, append the line */ 14274 ++added; 14275 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 14276 rettv->vval.v_number = 0; /* OK */ 14277 } 14278 14279 if (l == NULL) /* only one string argument */ 14280 break; 14281 ++lnum; 14282 } 14283 14284 if (added > 0) 14285 appended_lines_mark(lcount, added); 14286 } 14287 14288 /* 14289 * Used by "setqflist()" and "setloclist()" functions 14290 */ 14291 /*ARGSUSED*/ 14292 static void 14293 set_qf_ll_list(wp, list_arg, action_arg, rettv) 14294 win_T *wp; 14295 typval_T *list_arg; 14296 typval_T *action_arg; 14297 typval_T *rettv; 14298 { 14299 #ifdef FEAT_QUICKFIX 14300 char_u *act; 14301 int action = ' '; 14302 #endif 14303 14304 rettv->vval.v_number = -1; 14305 14306 #ifdef FEAT_QUICKFIX 14307 if (list_arg->v_type != VAR_LIST) 14308 EMSG(_(e_listreq)); 14309 else 14310 { 14311 list_T *l = list_arg->vval.v_list; 14312 14313 if (action_arg->v_type == VAR_STRING) 14314 { 14315 act = get_tv_string_chk(action_arg); 14316 if (act == NULL) 14317 return; /* type error; errmsg already given */ 14318 if (*act == 'a' || *act == 'r') 14319 action = *act; 14320 } 14321 14322 if (l != NULL && set_errorlist(wp, l, action) == OK) 14323 rettv->vval.v_number = 0; 14324 } 14325 #endif 14326 } 14327 14328 /* 14329 * "setloclist()" function 14330 */ 14331 /*ARGSUSED*/ 14332 static void 14333 f_setloclist(argvars, rettv) 14334 typval_T *argvars; 14335 typval_T *rettv; 14336 { 14337 win_T *win; 14338 14339 rettv->vval.v_number = -1; 14340 14341 win = find_win_by_nr(&argvars[0], NULL); 14342 if (win != NULL) 14343 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 14344 } 14345 14346 /* 14347 * "setpos()" function 14348 */ 14349 /*ARGSUSED*/ 14350 static void 14351 f_setpos(argvars, rettv) 14352 typval_T *argvars; 14353 typval_T *rettv; 14354 { 14355 pos_T pos; 14356 int fnum; 14357 char_u *name; 14358 14359 name = get_tv_string_chk(argvars); 14360 if (name != NULL) 14361 { 14362 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 14363 { 14364 --pos.col; 14365 if (name[0] == '.') /* cursor */ 14366 { 14367 if (fnum == curbuf->b_fnum) 14368 { 14369 curwin->w_cursor = pos; 14370 check_cursor(); 14371 } 14372 else 14373 EMSG(_(e_invarg)); 14374 } 14375 else if (name[0] == '\'') /* mark */ 14376 (void)setmark_pos(name[1], &pos, fnum); 14377 else 14378 EMSG(_(e_invarg)); 14379 } 14380 } 14381 } 14382 14383 /* 14384 * "setqflist()" function 14385 */ 14386 /*ARGSUSED*/ 14387 static void 14388 f_setqflist(argvars, rettv) 14389 typval_T *argvars; 14390 typval_T *rettv; 14391 { 14392 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 14393 } 14394 14395 /* 14396 * "setreg()" function 14397 */ 14398 static void 14399 f_setreg(argvars, rettv) 14400 typval_T *argvars; 14401 typval_T *rettv; 14402 { 14403 int regname; 14404 char_u *strregname; 14405 char_u *stropt; 14406 char_u *strval; 14407 int append; 14408 char_u yank_type; 14409 long block_len; 14410 14411 block_len = -1; 14412 yank_type = MAUTO; 14413 append = FALSE; 14414 14415 strregname = get_tv_string_chk(argvars); 14416 rettv->vval.v_number = 1; /* FAIL is default */ 14417 14418 if (strregname == NULL) 14419 return; /* type error; errmsg already given */ 14420 regname = *strregname; 14421 if (regname == 0 || regname == '@') 14422 regname = '"'; 14423 else if (regname == '=') 14424 return; 14425 14426 if (argvars[2].v_type != VAR_UNKNOWN) 14427 { 14428 stropt = get_tv_string_chk(&argvars[2]); 14429 if (stropt == NULL) 14430 return; /* type error */ 14431 for (; *stropt != NUL; ++stropt) 14432 switch (*stropt) 14433 { 14434 case 'a': case 'A': /* append */ 14435 append = TRUE; 14436 break; 14437 case 'v': case 'c': /* character-wise selection */ 14438 yank_type = MCHAR; 14439 break; 14440 case 'V': case 'l': /* line-wise selection */ 14441 yank_type = MLINE; 14442 break; 14443 #ifdef FEAT_VISUAL 14444 case 'b': case Ctrl_V: /* block-wise selection */ 14445 yank_type = MBLOCK; 14446 if (VIM_ISDIGIT(stropt[1])) 14447 { 14448 ++stropt; 14449 block_len = getdigits(&stropt) - 1; 14450 --stropt; 14451 } 14452 break; 14453 #endif 14454 } 14455 } 14456 14457 strval = get_tv_string_chk(&argvars[1]); 14458 if (strval != NULL) 14459 write_reg_contents_ex(regname, strval, -1, 14460 append, yank_type, block_len); 14461 rettv->vval.v_number = 0; 14462 } 14463 14464 /* 14465 * "settabwinvar()" function 14466 */ 14467 static void 14468 f_settabwinvar(argvars, rettv) 14469 typval_T *argvars; 14470 typval_T *rettv; 14471 { 14472 setwinvar(argvars, rettv, 1); 14473 } 14474 14475 /* 14476 * "setwinvar()" function 14477 */ 14478 static void 14479 f_setwinvar(argvars, rettv) 14480 typval_T *argvars; 14481 typval_T *rettv; 14482 { 14483 setwinvar(argvars, rettv, 0); 14484 } 14485 14486 /* 14487 * "setwinvar()" and "settabwinvar()" functions 14488 */ 14489 static void 14490 setwinvar(argvars, rettv, off) 14491 typval_T *argvars; 14492 typval_T *rettv; 14493 int off; 14494 { 14495 win_T *win; 14496 #ifdef FEAT_WINDOWS 14497 win_T *save_curwin; 14498 tabpage_T *save_curtab; 14499 #endif 14500 char_u *varname, *winvarname; 14501 typval_T *varp; 14502 char_u nbuf[NUMBUFLEN]; 14503 tabpage_T *tp; 14504 14505 rettv->vval.v_number = 0; 14506 14507 if (check_restricted() || check_secure()) 14508 return; 14509 14510 #ifdef FEAT_WINDOWS 14511 if (off == 1) 14512 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 14513 else 14514 tp = curtab; 14515 #endif 14516 win = find_win_by_nr(&argvars[off], tp); 14517 varname = get_tv_string_chk(&argvars[off + 1]); 14518 varp = &argvars[off + 2]; 14519 14520 if (win != NULL && varname != NULL && varp != NULL) 14521 { 14522 #ifdef FEAT_WINDOWS 14523 /* set curwin to be our win, temporarily */ 14524 save_curwin = curwin; 14525 save_curtab = curtab; 14526 goto_tabpage_tp(tp); 14527 if (!win_valid(win)) 14528 return; 14529 curwin = win; 14530 curbuf = curwin->w_buffer; 14531 #endif 14532 14533 if (*varname == '&') 14534 { 14535 long numval; 14536 char_u *strval; 14537 int error = FALSE; 14538 14539 ++varname; 14540 numval = get_tv_number_chk(varp, &error); 14541 strval = get_tv_string_buf_chk(varp, nbuf); 14542 if (!error && strval != NULL) 14543 set_option_value(varname, numval, strval, OPT_LOCAL); 14544 } 14545 else 14546 { 14547 winvarname = alloc((unsigned)STRLEN(varname) + 3); 14548 if (winvarname != NULL) 14549 { 14550 STRCPY(winvarname, "w:"); 14551 STRCPY(winvarname + 2, varname); 14552 set_var(winvarname, varp, TRUE); 14553 vim_free(winvarname); 14554 } 14555 } 14556 14557 #ifdef FEAT_WINDOWS 14558 /* Restore current tabpage and window, if still valid (autocomands can 14559 * make them invalid). */ 14560 if (valid_tabpage(save_curtab)) 14561 goto_tabpage_tp(save_curtab); 14562 if (win_valid(save_curwin)) 14563 { 14564 curwin = save_curwin; 14565 curbuf = curwin->w_buffer; 14566 } 14567 #endif 14568 } 14569 } 14570 14571 /* 14572 * "simplify()" function 14573 */ 14574 static void 14575 f_simplify(argvars, rettv) 14576 typval_T *argvars; 14577 typval_T *rettv; 14578 { 14579 char_u *p; 14580 14581 p = get_tv_string(&argvars[0]); 14582 rettv->vval.v_string = vim_strsave(p); 14583 simplify_filename(rettv->vval.v_string); /* simplify in place */ 14584 rettv->v_type = VAR_STRING; 14585 } 14586 14587 static int 14588 #ifdef __BORLANDC__ 14589 _RTLENTRYF 14590 #endif 14591 item_compare __ARGS((const void *s1, const void *s2)); 14592 static int 14593 #ifdef __BORLANDC__ 14594 _RTLENTRYF 14595 #endif 14596 item_compare2 __ARGS((const void *s1, const void *s2)); 14597 14598 static int item_compare_ic; 14599 static char_u *item_compare_func; 14600 static int item_compare_func_err; 14601 #define ITEM_COMPARE_FAIL 999 14602 14603 /* 14604 * Compare functions for f_sort() below. 14605 */ 14606 static int 14607 #ifdef __BORLANDC__ 14608 _RTLENTRYF 14609 #endif 14610 item_compare(s1, s2) 14611 const void *s1; 14612 const void *s2; 14613 { 14614 char_u *p1, *p2; 14615 char_u *tofree1, *tofree2; 14616 int res; 14617 char_u numbuf1[NUMBUFLEN]; 14618 char_u numbuf2[NUMBUFLEN]; 14619 14620 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 14621 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 14622 if (item_compare_ic) 14623 res = STRICMP(p1, p2); 14624 else 14625 res = STRCMP(p1, p2); 14626 vim_free(tofree1); 14627 vim_free(tofree2); 14628 return res; 14629 } 14630 14631 static int 14632 #ifdef __BORLANDC__ 14633 _RTLENTRYF 14634 #endif 14635 item_compare2(s1, s2) 14636 const void *s1; 14637 const void *s2; 14638 { 14639 int res; 14640 typval_T rettv; 14641 typval_T argv[3]; 14642 int dummy; 14643 14644 /* shortcut after failure in previous call; compare all items equal */ 14645 if (item_compare_func_err) 14646 return 0; 14647 14648 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 14649 * in the copy without changing the original list items. */ 14650 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 14651 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 14652 14653 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 14654 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 14655 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 14656 clear_tv(&argv[0]); 14657 clear_tv(&argv[1]); 14658 14659 if (res == FAIL) 14660 res = ITEM_COMPARE_FAIL; 14661 else 14662 /* return value has wrong type */ 14663 res = get_tv_number_chk(&rettv, &item_compare_func_err); 14664 if (item_compare_func_err) 14665 res = ITEM_COMPARE_FAIL; 14666 clear_tv(&rettv); 14667 return res; 14668 } 14669 14670 /* 14671 * "sort({list})" function 14672 */ 14673 static void 14674 f_sort(argvars, rettv) 14675 typval_T *argvars; 14676 typval_T *rettv; 14677 { 14678 list_T *l; 14679 listitem_T *li; 14680 listitem_T **ptrs; 14681 long len; 14682 long i; 14683 14684 rettv->vval.v_number = 0; 14685 if (argvars[0].v_type != VAR_LIST) 14686 EMSG2(_(e_listarg), "sort()"); 14687 else 14688 { 14689 l = argvars[0].vval.v_list; 14690 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 14691 return; 14692 rettv->vval.v_list = l; 14693 rettv->v_type = VAR_LIST; 14694 ++l->lv_refcount; 14695 14696 len = list_len(l); 14697 if (len <= 1) 14698 return; /* short list sorts pretty quickly */ 14699 14700 item_compare_ic = FALSE; 14701 item_compare_func = NULL; 14702 if (argvars[1].v_type != VAR_UNKNOWN) 14703 { 14704 if (argvars[1].v_type == VAR_FUNC) 14705 item_compare_func = argvars[1].vval.v_string; 14706 else 14707 { 14708 int error = FALSE; 14709 14710 i = get_tv_number_chk(&argvars[1], &error); 14711 if (error) 14712 return; /* type error; errmsg already given */ 14713 if (i == 1) 14714 item_compare_ic = TRUE; 14715 else 14716 item_compare_func = get_tv_string(&argvars[1]); 14717 } 14718 } 14719 14720 /* Make an array with each entry pointing to an item in the List. */ 14721 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 14722 if (ptrs == NULL) 14723 return; 14724 i = 0; 14725 for (li = l->lv_first; li != NULL; li = li->li_next) 14726 ptrs[i++] = li; 14727 14728 item_compare_func_err = FALSE; 14729 /* test the compare function */ 14730 if (item_compare_func != NULL 14731 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 14732 == ITEM_COMPARE_FAIL) 14733 EMSG(_("E702: Sort compare function failed")); 14734 else 14735 { 14736 /* Sort the array with item pointers. */ 14737 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 14738 item_compare_func == NULL ? item_compare : item_compare2); 14739 14740 if (!item_compare_func_err) 14741 { 14742 /* Clear the List and append the items in the sorted order. */ 14743 l->lv_first = l->lv_last = NULL; 14744 l->lv_len = 0; 14745 for (i = 0; i < len; ++i) 14746 list_append(l, ptrs[i]); 14747 } 14748 } 14749 14750 vim_free(ptrs); 14751 } 14752 } 14753 14754 /* 14755 * "soundfold({word})" function 14756 */ 14757 static void 14758 f_soundfold(argvars, rettv) 14759 typval_T *argvars; 14760 typval_T *rettv; 14761 { 14762 char_u *s; 14763 14764 rettv->v_type = VAR_STRING; 14765 s = get_tv_string(&argvars[0]); 14766 #ifdef FEAT_SPELL 14767 rettv->vval.v_string = eval_soundfold(s); 14768 #else 14769 rettv->vval.v_string = vim_strsave(s); 14770 #endif 14771 } 14772 14773 /* 14774 * "spellbadword()" function 14775 */ 14776 /* ARGSUSED */ 14777 static void 14778 f_spellbadword(argvars, rettv) 14779 typval_T *argvars; 14780 typval_T *rettv; 14781 { 14782 char_u *word = (char_u *)""; 14783 hlf_T attr = HLF_COUNT; 14784 int len = 0; 14785 14786 if (rettv_list_alloc(rettv) == FAIL) 14787 return; 14788 14789 #ifdef FEAT_SPELL 14790 if (argvars[0].v_type == VAR_UNKNOWN) 14791 { 14792 /* Find the start and length of the badly spelled word. */ 14793 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 14794 if (len != 0) 14795 word = ml_get_cursor(); 14796 } 14797 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14798 { 14799 char_u *str = get_tv_string_chk(&argvars[0]); 14800 int capcol = -1; 14801 14802 if (str != NULL) 14803 { 14804 /* Check the argument for spelling. */ 14805 while (*str != NUL) 14806 { 14807 len = spell_check(curwin, str, &attr, &capcol, FALSE); 14808 if (attr != HLF_COUNT) 14809 { 14810 word = str; 14811 break; 14812 } 14813 str += len; 14814 } 14815 } 14816 } 14817 #endif 14818 14819 list_append_string(rettv->vval.v_list, word, len); 14820 list_append_string(rettv->vval.v_list, (char_u *)( 14821 attr == HLF_SPB ? "bad" : 14822 attr == HLF_SPR ? "rare" : 14823 attr == HLF_SPL ? "local" : 14824 attr == HLF_SPC ? "caps" : 14825 ""), -1); 14826 } 14827 14828 /* 14829 * "spellsuggest()" function 14830 */ 14831 /*ARGSUSED*/ 14832 static void 14833 f_spellsuggest(argvars, rettv) 14834 typval_T *argvars; 14835 typval_T *rettv; 14836 { 14837 #ifdef FEAT_SPELL 14838 char_u *str; 14839 int typeerr = FALSE; 14840 int maxcount; 14841 garray_T ga; 14842 int i; 14843 listitem_T *li; 14844 int need_capital = FALSE; 14845 #endif 14846 14847 if (rettv_list_alloc(rettv) == FAIL) 14848 return; 14849 14850 #ifdef FEAT_SPELL 14851 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14852 { 14853 str = get_tv_string(&argvars[0]); 14854 if (argvars[1].v_type != VAR_UNKNOWN) 14855 { 14856 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 14857 if (maxcount <= 0) 14858 return; 14859 if (argvars[2].v_type != VAR_UNKNOWN) 14860 { 14861 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 14862 if (typeerr) 14863 return; 14864 } 14865 } 14866 else 14867 maxcount = 25; 14868 14869 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 14870 14871 for (i = 0; i < ga.ga_len; ++i) 14872 { 14873 str = ((char_u **)ga.ga_data)[i]; 14874 14875 li = listitem_alloc(); 14876 if (li == NULL) 14877 vim_free(str); 14878 else 14879 { 14880 li->li_tv.v_type = VAR_STRING; 14881 li->li_tv.v_lock = 0; 14882 li->li_tv.vval.v_string = str; 14883 list_append(rettv->vval.v_list, li); 14884 } 14885 } 14886 ga_clear(&ga); 14887 } 14888 #endif 14889 } 14890 14891 static void 14892 f_split(argvars, rettv) 14893 typval_T *argvars; 14894 typval_T *rettv; 14895 { 14896 char_u *str; 14897 char_u *end; 14898 char_u *pat = NULL; 14899 regmatch_T regmatch; 14900 char_u patbuf[NUMBUFLEN]; 14901 char_u *save_cpo; 14902 int match; 14903 colnr_T col = 0; 14904 int keepempty = FALSE; 14905 int typeerr = FALSE; 14906 14907 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14908 save_cpo = p_cpo; 14909 p_cpo = (char_u *)""; 14910 14911 str = get_tv_string(&argvars[0]); 14912 if (argvars[1].v_type != VAR_UNKNOWN) 14913 { 14914 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14915 if (pat == NULL) 14916 typeerr = TRUE; 14917 if (argvars[2].v_type != VAR_UNKNOWN) 14918 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 14919 } 14920 if (pat == NULL || *pat == NUL) 14921 pat = (char_u *)"[\\x01- ]\\+"; 14922 14923 if (rettv_list_alloc(rettv) == FAIL) 14924 return; 14925 if (typeerr) 14926 return; 14927 14928 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14929 if (regmatch.regprog != NULL) 14930 { 14931 regmatch.rm_ic = FALSE; 14932 while (*str != NUL || keepempty) 14933 { 14934 if (*str == NUL) 14935 match = FALSE; /* empty item at the end */ 14936 else 14937 match = vim_regexec_nl(®match, str, col); 14938 if (match) 14939 end = regmatch.startp[0]; 14940 else 14941 end = str + STRLEN(str); 14942 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 14943 && *str != NUL && match && end < regmatch.endp[0])) 14944 { 14945 if (list_append_string(rettv->vval.v_list, str, 14946 (int)(end - str)) == FAIL) 14947 break; 14948 } 14949 if (!match) 14950 break; 14951 /* Advance to just after the match. */ 14952 if (regmatch.endp[0] > str) 14953 col = 0; 14954 else 14955 { 14956 /* Don't get stuck at the same match. */ 14957 #ifdef FEAT_MBYTE 14958 col = (*mb_ptr2len)(regmatch.endp[0]); 14959 #else 14960 col = 1; 14961 #endif 14962 } 14963 str = regmatch.endp[0]; 14964 } 14965 14966 vim_free(regmatch.regprog); 14967 } 14968 14969 p_cpo = save_cpo; 14970 } 14971 14972 /* 14973 * "str2nr()" function 14974 */ 14975 static void 14976 f_str2nr(argvars, rettv) 14977 typval_T *argvars; 14978 typval_T *rettv; 14979 { 14980 int base = 10; 14981 char_u *p; 14982 long n; 14983 14984 if (argvars[1].v_type != VAR_UNKNOWN) 14985 { 14986 base = get_tv_number(&argvars[1]); 14987 if (base != 8 && base != 10 && base != 16) 14988 { 14989 EMSG(_(e_invarg)); 14990 return; 14991 } 14992 } 14993 14994 p = skipwhite(get_tv_string(&argvars[0])); 14995 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 14996 rettv->vval.v_number = n; 14997 } 14998 14999 #ifdef HAVE_STRFTIME 15000 /* 15001 * "strftime({format}[, {time}])" function 15002 */ 15003 static void 15004 f_strftime(argvars, rettv) 15005 typval_T *argvars; 15006 typval_T *rettv; 15007 { 15008 char_u result_buf[256]; 15009 struct tm *curtime; 15010 time_t seconds; 15011 char_u *p; 15012 15013 rettv->v_type = VAR_STRING; 15014 15015 p = get_tv_string(&argvars[0]); 15016 if (argvars[1].v_type == VAR_UNKNOWN) 15017 seconds = time(NULL); 15018 else 15019 seconds = (time_t)get_tv_number(&argvars[1]); 15020 curtime = localtime(&seconds); 15021 /* MSVC returns NULL for an invalid value of seconds. */ 15022 if (curtime == NULL) 15023 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 15024 else 15025 { 15026 # ifdef FEAT_MBYTE 15027 vimconv_T conv; 15028 char_u *enc; 15029 15030 conv.vc_type = CONV_NONE; 15031 enc = enc_locale(); 15032 convert_setup(&conv, p_enc, enc); 15033 if (conv.vc_type != CONV_NONE) 15034 p = string_convert(&conv, p, NULL); 15035 # endif 15036 if (p != NULL) 15037 (void)strftime((char *)result_buf, sizeof(result_buf), 15038 (char *)p, curtime); 15039 else 15040 result_buf[0] = NUL; 15041 15042 # ifdef FEAT_MBYTE 15043 if (conv.vc_type != CONV_NONE) 15044 vim_free(p); 15045 convert_setup(&conv, enc, p_enc); 15046 if (conv.vc_type != CONV_NONE) 15047 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 15048 else 15049 # endif 15050 rettv->vval.v_string = vim_strsave(result_buf); 15051 15052 # ifdef FEAT_MBYTE 15053 /* Release conversion descriptors */ 15054 convert_setup(&conv, NULL, NULL); 15055 vim_free(enc); 15056 # endif 15057 } 15058 } 15059 #endif 15060 15061 /* 15062 * "stridx()" function 15063 */ 15064 static void 15065 f_stridx(argvars, rettv) 15066 typval_T *argvars; 15067 typval_T *rettv; 15068 { 15069 char_u buf[NUMBUFLEN]; 15070 char_u *needle; 15071 char_u *haystack; 15072 char_u *save_haystack; 15073 char_u *pos; 15074 int start_idx; 15075 15076 needle = get_tv_string_chk(&argvars[1]); 15077 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 15078 rettv->vval.v_number = -1; 15079 if (needle == NULL || haystack == NULL) 15080 return; /* type error; errmsg already given */ 15081 15082 if (argvars[2].v_type != VAR_UNKNOWN) 15083 { 15084 int error = FALSE; 15085 15086 start_idx = get_tv_number_chk(&argvars[2], &error); 15087 if (error || start_idx >= (int)STRLEN(haystack)) 15088 return; 15089 if (start_idx >= 0) 15090 haystack += start_idx; 15091 } 15092 15093 pos = (char_u *)strstr((char *)haystack, (char *)needle); 15094 if (pos != NULL) 15095 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 15096 } 15097 15098 /* 15099 * "string()" function 15100 */ 15101 static void 15102 f_string(argvars, rettv) 15103 typval_T *argvars; 15104 typval_T *rettv; 15105 { 15106 char_u *tofree; 15107 char_u numbuf[NUMBUFLEN]; 15108 15109 rettv->v_type = VAR_STRING; 15110 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 15111 if (tofree == NULL) 15112 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 15113 } 15114 15115 /* 15116 * "strlen()" function 15117 */ 15118 static void 15119 f_strlen(argvars, rettv) 15120 typval_T *argvars; 15121 typval_T *rettv; 15122 { 15123 rettv->vval.v_number = (varnumber_T)(STRLEN( 15124 get_tv_string(&argvars[0]))); 15125 } 15126 15127 /* 15128 * "strpart()" function 15129 */ 15130 static void 15131 f_strpart(argvars, rettv) 15132 typval_T *argvars; 15133 typval_T *rettv; 15134 { 15135 char_u *p; 15136 int n; 15137 int len; 15138 int slen; 15139 int error = FALSE; 15140 15141 p = get_tv_string(&argvars[0]); 15142 slen = (int)STRLEN(p); 15143 15144 n = get_tv_number_chk(&argvars[1], &error); 15145 if (error) 15146 len = 0; 15147 else if (argvars[2].v_type != VAR_UNKNOWN) 15148 len = get_tv_number(&argvars[2]); 15149 else 15150 len = slen - n; /* default len: all bytes that are available. */ 15151 15152 /* 15153 * Only return the overlap between the specified part and the actual 15154 * string. 15155 */ 15156 if (n < 0) 15157 { 15158 len += n; 15159 n = 0; 15160 } 15161 else if (n > slen) 15162 n = slen; 15163 if (len < 0) 15164 len = 0; 15165 else if (n + len > slen) 15166 len = slen - n; 15167 15168 rettv->v_type = VAR_STRING; 15169 rettv->vval.v_string = vim_strnsave(p + n, len); 15170 } 15171 15172 /* 15173 * "strridx()" function 15174 */ 15175 static void 15176 f_strridx(argvars, rettv) 15177 typval_T *argvars; 15178 typval_T *rettv; 15179 { 15180 char_u buf[NUMBUFLEN]; 15181 char_u *needle; 15182 char_u *haystack; 15183 char_u *rest; 15184 char_u *lastmatch = NULL; 15185 int haystack_len, end_idx; 15186 15187 needle = get_tv_string_chk(&argvars[1]); 15188 haystack = get_tv_string_buf_chk(&argvars[0], buf); 15189 15190 rettv->vval.v_number = -1; 15191 if (needle == NULL || haystack == NULL) 15192 return; /* type error; errmsg already given */ 15193 15194 haystack_len = (int)STRLEN(haystack); 15195 if (argvars[2].v_type != VAR_UNKNOWN) 15196 { 15197 /* Third argument: upper limit for index */ 15198 end_idx = get_tv_number_chk(&argvars[2], NULL); 15199 if (end_idx < 0) 15200 return; /* can never find a match */ 15201 } 15202 else 15203 end_idx = haystack_len; 15204 15205 if (*needle == NUL) 15206 { 15207 /* Empty string matches past the end. */ 15208 lastmatch = haystack + end_idx; 15209 } 15210 else 15211 { 15212 for (rest = haystack; *rest != '\0'; ++rest) 15213 { 15214 rest = (char_u *)strstr((char *)rest, (char *)needle); 15215 if (rest == NULL || rest > haystack + end_idx) 15216 break; 15217 lastmatch = rest; 15218 } 15219 } 15220 15221 if (lastmatch == NULL) 15222 rettv->vval.v_number = -1; 15223 else 15224 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 15225 } 15226 15227 /* 15228 * "strtrans()" function 15229 */ 15230 static void 15231 f_strtrans(argvars, rettv) 15232 typval_T *argvars; 15233 typval_T *rettv; 15234 { 15235 rettv->v_type = VAR_STRING; 15236 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 15237 } 15238 15239 /* 15240 * "submatch()" function 15241 */ 15242 static void 15243 f_submatch(argvars, rettv) 15244 typval_T *argvars; 15245 typval_T *rettv; 15246 { 15247 rettv->v_type = VAR_STRING; 15248 rettv->vval.v_string = 15249 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 15250 } 15251 15252 /* 15253 * "substitute()" function 15254 */ 15255 static void 15256 f_substitute(argvars, rettv) 15257 typval_T *argvars; 15258 typval_T *rettv; 15259 { 15260 char_u patbuf[NUMBUFLEN]; 15261 char_u subbuf[NUMBUFLEN]; 15262 char_u flagsbuf[NUMBUFLEN]; 15263 15264 char_u *str = get_tv_string_chk(&argvars[0]); 15265 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15266 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 15267 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 15268 15269 rettv->v_type = VAR_STRING; 15270 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 15271 rettv->vval.v_string = NULL; 15272 else 15273 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 15274 } 15275 15276 /* 15277 * "synID(lnum, col, trans)" function 15278 */ 15279 /*ARGSUSED*/ 15280 static void 15281 f_synID(argvars, rettv) 15282 typval_T *argvars; 15283 typval_T *rettv; 15284 { 15285 int id = 0; 15286 #ifdef FEAT_SYN_HL 15287 long lnum; 15288 long col; 15289 int trans; 15290 int transerr = FALSE; 15291 15292 lnum = get_tv_lnum(argvars); /* -1 on type error */ 15293 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 15294 trans = get_tv_number_chk(&argvars[2], &transerr); 15295 15296 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 15297 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 15298 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 15299 #endif 15300 15301 rettv->vval.v_number = id; 15302 } 15303 15304 /* 15305 * "synIDattr(id, what [, mode])" function 15306 */ 15307 /*ARGSUSED*/ 15308 static void 15309 f_synIDattr(argvars, rettv) 15310 typval_T *argvars; 15311 typval_T *rettv; 15312 { 15313 char_u *p = NULL; 15314 #ifdef FEAT_SYN_HL 15315 int id; 15316 char_u *what; 15317 char_u *mode; 15318 char_u modebuf[NUMBUFLEN]; 15319 int modec; 15320 15321 id = get_tv_number(&argvars[0]); 15322 what = get_tv_string(&argvars[1]); 15323 if (argvars[2].v_type != VAR_UNKNOWN) 15324 { 15325 mode = get_tv_string_buf(&argvars[2], modebuf); 15326 modec = TOLOWER_ASC(mode[0]); 15327 if (modec != 't' && modec != 'c' 15328 #ifdef FEAT_GUI 15329 && modec != 'g' 15330 #endif 15331 ) 15332 modec = 0; /* replace invalid with current */ 15333 } 15334 else 15335 { 15336 #ifdef FEAT_GUI 15337 if (gui.in_use) 15338 modec = 'g'; 15339 else 15340 #endif 15341 if (t_colors > 1) 15342 modec = 'c'; 15343 else 15344 modec = 't'; 15345 } 15346 15347 15348 switch (TOLOWER_ASC(what[0])) 15349 { 15350 case 'b': 15351 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 15352 p = highlight_color(id, what, modec); 15353 else /* bold */ 15354 p = highlight_has_attr(id, HL_BOLD, modec); 15355 break; 15356 15357 case 'f': /* fg[#] */ 15358 p = highlight_color(id, what, modec); 15359 break; 15360 15361 case 'i': 15362 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 15363 p = highlight_has_attr(id, HL_INVERSE, modec); 15364 else /* italic */ 15365 p = highlight_has_attr(id, HL_ITALIC, modec); 15366 break; 15367 15368 case 'n': /* name */ 15369 p = get_highlight_name(NULL, id - 1); 15370 break; 15371 15372 case 'r': /* reverse */ 15373 p = highlight_has_attr(id, HL_INVERSE, modec); 15374 break; 15375 15376 case 's': /* standout */ 15377 p = highlight_has_attr(id, HL_STANDOUT, modec); 15378 break; 15379 15380 case 'u': 15381 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 15382 /* underline */ 15383 p = highlight_has_attr(id, HL_UNDERLINE, modec); 15384 else 15385 /* undercurl */ 15386 p = highlight_has_attr(id, HL_UNDERCURL, modec); 15387 break; 15388 } 15389 15390 if (p != NULL) 15391 p = vim_strsave(p); 15392 #endif 15393 rettv->v_type = VAR_STRING; 15394 rettv->vval.v_string = p; 15395 } 15396 15397 /* 15398 * "synIDtrans(id)" function 15399 */ 15400 /*ARGSUSED*/ 15401 static void 15402 f_synIDtrans(argvars, rettv) 15403 typval_T *argvars; 15404 typval_T *rettv; 15405 { 15406 int id; 15407 15408 #ifdef FEAT_SYN_HL 15409 id = get_tv_number(&argvars[0]); 15410 15411 if (id > 0) 15412 id = syn_get_final_id(id); 15413 else 15414 #endif 15415 id = 0; 15416 15417 rettv->vval.v_number = id; 15418 } 15419 15420 /* 15421 * "system()" function 15422 */ 15423 static void 15424 f_system(argvars, rettv) 15425 typval_T *argvars; 15426 typval_T *rettv; 15427 { 15428 char_u *res = NULL; 15429 char_u *p; 15430 char_u *infile = NULL; 15431 char_u buf[NUMBUFLEN]; 15432 int err = FALSE; 15433 FILE *fd; 15434 15435 if (argvars[1].v_type != VAR_UNKNOWN) 15436 { 15437 /* 15438 * Write the string to a temp file, to be used for input of the shell 15439 * command. 15440 */ 15441 if ((infile = vim_tempname('i')) == NULL) 15442 { 15443 EMSG(_(e_notmp)); 15444 return; 15445 } 15446 15447 fd = mch_fopen((char *)infile, WRITEBIN); 15448 if (fd == NULL) 15449 { 15450 EMSG2(_(e_notopen), infile); 15451 goto done; 15452 } 15453 p = get_tv_string_buf_chk(&argvars[1], buf); 15454 if (p == NULL) 15455 { 15456 fclose(fd); 15457 goto done; /* type error; errmsg already given */ 15458 } 15459 if (fwrite(p, STRLEN(p), 1, fd) != 1) 15460 err = TRUE; 15461 if (fclose(fd) != 0) 15462 err = TRUE; 15463 if (err) 15464 { 15465 EMSG(_("E677: Error writing temp file")); 15466 goto done; 15467 } 15468 } 15469 15470 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 15471 SHELL_SILENT | SHELL_COOKED); 15472 15473 #ifdef USE_CR 15474 /* translate <CR> into <NL> */ 15475 if (res != NULL) 15476 { 15477 char_u *s; 15478 15479 for (s = res; *s; ++s) 15480 { 15481 if (*s == CAR) 15482 *s = NL; 15483 } 15484 } 15485 #else 15486 # ifdef USE_CRNL 15487 /* translate <CR><NL> into <NL> */ 15488 if (res != NULL) 15489 { 15490 char_u *s, *d; 15491 15492 d = res; 15493 for (s = res; *s; ++s) 15494 { 15495 if (s[0] == CAR && s[1] == NL) 15496 ++s; 15497 *d++ = *s; 15498 } 15499 *d = NUL; 15500 } 15501 # endif 15502 #endif 15503 15504 done: 15505 if (infile != NULL) 15506 { 15507 mch_remove(infile); 15508 vim_free(infile); 15509 } 15510 rettv->v_type = VAR_STRING; 15511 rettv->vval.v_string = res; 15512 } 15513 15514 /* 15515 * "tabpagebuflist()" function 15516 */ 15517 /* ARGSUSED */ 15518 static void 15519 f_tabpagebuflist(argvars, rettv) 15520 typval_T *argvars; 15521 typval_T *rettv; 15522 { 15523 #ifndef FEAT_WINDOWS 15524 rettv->vval.v_number = 0; 15525 #else 15526 tabpage_T *tp; 15527 win_T *wp = NULL; 15528 15529 if (argvars[0].v_type == VAR_UNKNOWN) 15530 wp = firstwin; 15531 else 15532 { 15533 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15534 if (tp != NULL) 15535 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15536 } 15537 if (wp == NULL) 15538 rettv->vval.v_number = 0; 15539 else 15540 { 15541 if (rettv_list_alloc(rettv) == FAIL) 15542 rettv->vval.v_number = 0; 15543 else 15544 { 15545 for (; wp != NULL; wp = wp->w_next) 15546 if (list_append_number(rettv->vval.v_list, 15547 wp->w_buffer->b_fnum) == FAIL) 15548 break; 15549 } 15550 } 15551 #endif 15552 } 15553 15554 15555 /* 15556 * "tabpagenr()" function 15557 */ 15558 /* ARGSUSED */ 15559 static void 15560 f_tabpagenr(argvars, rettv) 15561 typval_T *argvars; 15562 typval_T *rettv; 15563 { 15564 int nr = 1; 15565 #ifdef FEAT_WINDOWS 15566 char_u *arg; 15567 15568 if (argvars[0].v_type != VAR_UNKNOWN) 15569 { 15570 arg = get_tv_string_chk(&argvars[0]); 15571 nr = 0; 15572 if (arg != NULL) 15573 { 15574 if (STRCMP(arg, "$") == 0) 15575 nr = tabpage_index(NULL) - 1; 15576 else 15577 EMSG2(_(e_invexpr2), arg); 15578 } 15579 } 15580 else 15581 nr = tabpage_index(curtab); 15582 #endif 15583 rettv->vval.v_number = nr; 15584 } 15585 15586 15587 #ifdef FEAT_WINDOWS 15588 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 15589 15590 /* 15591 * Common code for tabpagewinnr() and winnr(). 15592 */ 15593 static int 15594 get_winnr(tp, argvar) 15595 tabpage_T *tp; 15596 typval_T *argvar; 15597 { 15598 win_T *twin; 15599 int nr = 1; 15600 win_T *wp; 15601 char_u *arg; 15602 15603 twin = (tp == curtab) ? curwin : tp->tp_curwin; 15604 if (argvar->v_type != VAR_UNKNOWN) 15605 { 15606 arg = get_tv_string_chk(argvar); 15607 if (arg == NULL) 15608 nr = 0; /* type error; errmsg already given */ 15609 else if (STRCMP(arg, "$") == 0) 15610 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 15611 else if (STRCMP(arg, "#") == 0) 15612 { 15613 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 15614 if (twin == NULL) 15615 nr = 0; 15616 } 15617 else 15618 { 15619 EMSG2(_(e_invexpr2), arg); 15620 nr = 0; 15621 } 15622 } 15623 15624 if (nr > 0) 15625 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15626 wp != twin; wp = wp->w_next) 15627 ++nr; 15628 return nr; 15629 } 15630 #endif 15631 15632 /* 15633 * "tabpagewinnr()" function 15634 */ 15635 /* ARGSUSED */ 15636 static void 15637 f_tabpagewinnr(argvars, rettv) 15638 typval_T *argvars; 15639 typval_T *rettv; 15640 { 15641 int nr = 1; 15642 #ifdef FEAT_WINDOWS 15643 tabpage_T *tp; 15644 15645 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15646 if (tp == NULL) 15647 nr = 0; 15648 else 15649 nr = get_winnr(tp, &argvars[1]); 15650 #endif 15651 rettv->vval.v_number = nr; 15652 } 15653 15654 15655 /* 15656 * "tagfiles()" function 15657 */ 15658 /*ARGSUSED*/ 15659 static void 15660 f_tagfiles(argvars, rettv) 15661 typval_T *argvars; 15662 typval_T *rettv; 15663 { 15664 char_u fname[MAXPATHL + 1]; 15665 tagname_T tn; 15666 int first; 15667 15668 if (rettv_list_alloc(rettv) == FAIL) 15669 { 15670 rettv->vval.v_number = 0; 15671 return; 15672 } 15673 15674 for (first = TRUE; ; first = FALSE) 15675 if (get_tagfname(&tn, first, fname) == FAIL 15676 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 15677 break; 15678 tagname_free(&tn); 15679 } 15680 15681 /* 15682 * "taglist()" function 15683 */ 15684 static void 15685 f_taglist(argvars, rettv) 15686 typval_T *argvars; 15687 typval_T *rettv; 15688 { 15689 char_u *tag_pattern; 15690 15691 tag_pattern = get_tv_string(&argvars[0]); 15692 15693 rettv->vval.v_number = FALSE; 15694 if (*tag_pattern == NUL) 15695 return; 15696 15697 if (rettv_list_alloc(rettv) == OK) 15698 (void)get_tags(rettv->vval.v_list, tag_pattern); 15699 } 15700 15701 /* 15702 * "tempname()" function 15703 */ 15704 /*ARGSUSED*/ 15705 static void 15706 f_tempname(argvars, rettv) 15707 typval_T *argvars; 15708 typval_T *rettv; 15709 { 15710 static int x = 'A'; 15711 15712 rettv->v_type = VAR_STRING; 15713 rettv->vval.v_string = vim_tempname(x); 15714 15715 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 15716 * names. Skip 'I' and 'O', they are used for shell redirection. */ 15717 do 15718 { 15719 if (x == 'Z') 15720 x = '0'; 15721 else if (x == '9') 15722 x = 'A'; 15723 else 15724 { 15725 #ifdef EBCDIC 15726 if (x == 'I') 15727 x = 'J'; 15728 else if (x == 'R') 15729 x = 'S'; 15730 else 15731 #endif 15732 ++x; 15733 } 15734 } while (x == 'I' || x == 'O'); 15735 } 15736 15737 /* 15738 * "test(list)" function: Just checking the walls... 15739 */ 15740 /*ARGSUSED*/ 15741 static void 15742 f_test(argvars, rettv) 15743 typval_T *argvars; 15744 typval_T *rettv; 15745 { 15746 /* Used for unit testing. Change the code below to your liking. */ 15747 #if 0 15748 listitem_T *li; 15749 list_T *l; 15750 char_u *bad, *good; 15751 15752 if (argvars[0].v_type != VAR_LIST) 15753 return; 15754 l = argvars[0].vval.v_list; 15755 if (l == NULL) 15756 return; 15757 li = l->lv_first; 15758 if (li == NULL) 15759 return; 15760 bad = get_tv_string(&li->li_tv); 15761 li = li->li_next; 15762 if (li == NULL) 15763 return; 15764 good = get_tv_string(&li->li_tv); 15765 rettv->vval.v_number = test_edit_score(bad, good); 15766 #endif 15767 } 15768 15769 /* 15770 * "tolower(string)" function 15771 */ 15772 static void 15773 f_tolower(argvars, rettv) 15774 typval_T *argvars; 15775 typval_T *rettv; 15776 { 15777 char_u *p; 15778 15779 p = vim_strsave(get_tv_string(&argvars[0])); 15780 rettv->v_type = VAR_STRING; 15781 rettv->vval.v_string = p; 15782 15783 if (p != NULL) 15784 while (*p != NUL) 15785 { 15786 #ifdef FEAT_MBYTE 15787 int l; 15788 15789 if (enc_utf8) 15790 { 15791 int c, lc; 15792 15793 c = utf_ptr2char(p); 15794 lc = utf_tolower(c); 15795 l = utf_ptr2len(p); 15796 /* TODO: reallocate string when byte count changes. */ 15797 if (utf_char2len(lc) == l) 15798 utf_char2bytes(lc, p); 15799 p += l; 15800 } 15801 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 15802 p += l; /* skip multi-byte character */ 15803 else 15804 #endif 15805 { 15806 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 15807 ++p; 15808 } 15809 } 15810 } 15811 15812 /* 15813 * "toupper(string)" function 15814 */ 15815 static void 15816 f_toupper(argvars, rettv) 15817 typval_T *argvars; 15818 typval_T *rettv; 15819 { 15820 rettv->v_type = VAR_STRING; 15821 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 15822 } 15823 15824 /* 15825 * "tr(string, fromstr, tostr)" function 15826 */ 15827 static void 15828 f_tr(argvars, rettv) 15829 typval_T *argvars; 15830 typval_T *rettv; 15831 { 15832 char_u *instr; 15833 char_u *fromstr; 15834 char_u *tostr; 15835 char_u *p; 15836 #ifdef FEAT_MBYTE 15837 int inlen; 15838 int fromlen; 15839 int tolen; 15840 int idx; 15841 char_u *cpstr; 15842 int cplen; 15843 int first = TRUE; 15844 #endif 15845 char_u buf[NUMBUFLEN]; 15846 char_u buf2[NUMBUFLEN]; 15847 garray_T ga; 15848 15849 instr = get_tv_string(&argvars[0]); 15850 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 15851 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 15852 15853 /* Default return value: empty string. */ 15854 rettv->v_type = VAR_STRING; 15855 rettv->vval.v_string = NULL; 15856 if (fromstr == NULL || tostr == NULL) 15857 return; /* type error; errmsg already given */ 15858 ga_init2(&ga, (int)sizeof(char), 80); 15859 15860 #ifdef FEAT_MBYTE 15861 if (!has_mbyte) 15862 #endif 15863 /* not multi-byte: fromstr and tostr must be the same length */ 15864 if (STRLEN(fromstr) != STRLEN(tostr)) 15865 { 15866 #ifdef FEAT_MBYTE 15867 error: 15868 #endif 15869 EMSG2(_(e_invarg2), fromstr); 15870 ga_clear(&ga); 15871 return; 15872 } 15873 15874 /* fromstr and tostr have to contain the same number of chars */ 15875 while (*instr != NUL) 15876 { 15877 #ifdef FEAT_MBYTE 15878 if (has_mbyte) 15879 { 15880 inlen = (*mb_ptr2len)(instr); 15881 cpstr = instr; 15882 cplen = inlen; 15883 idx = 0; 15884 for (p = fromstr; *p != NUL; p += fromlen) 15885 { 15886 fromlen = (*mb_ptr2len)(p); 15887 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 15888 { 15889 for (p = tostr; *p != NUL; p += tolen) 15890 { 15891 tolen = (*mb_ptr2len)(p); 15892 if (idx-- == 0) 15893 { 15894 cplen = tolen; 15895 cpstr = p; 15896 break; 15897 } 15898 } 15899 if (*p == NUL) /* tostr is shorter than fromstr */ 15900 goto error; 15901 break; 15902 } 15903 ++idx; 15904 } 15905 15906 if (first && cpstr == instr) 15907 { 15908 /* Check that fromstr and tostr have the same number of 15909 * (multi-byte) characters. Done only once when a character 15910 * of instr doesn't appear in fromstr. */ 15911 first = FALSE; 15912 for (p = tostr; *p != NUL; p += tolen) 15913 { 15914 tolen = (*mb_ptr2len)(p); 15915 --idx; 15916 } 15917 if (idx != 0) 15918 goto error; 15919 } 15920 15921 ga_grow(&ga, cplen); 15922 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 15923 ga.ga_len += cplen; 15924 15925 instr += inlen; 15926 } 15927 else 15928 #endif 15929 { 15930 /* When not using multi-byte chars we can do it faster. */ 15931 p = vim_strchr(fromstr, *instr); 15932 if (p != NULL) 15933 ga_append(&ga, tostr[p - fromstr]); 15934 else 15935 ga_append(&ga, *instr); 15936 ++instr; 15937 } 15938 } 15939 15940 rettv->vval.v_string = ga.ga_data; 15941 } 15942 15943 /* 15944 * "type(expr)" function 15945 */ 15946 static void 15947 f_type(argvars, rettv) 15948 typval_T *argvars; 15949 typval_T *rettv; 15950 { 15951 int n; 15952 15953 switch (argvars[0].v_type) 15954 { 15955 case VAR_NUMBER: n = 0; break; 15956 case VAR_STRING: n = 1; break; 15957 case VAR_FUNC: n = 2; break; 15958 case VAR_LIST: n = 3; break; 15959 case VAR_DICT: n = 4; break; 15960 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 15961 } 15962 rettv->vval.v_number = n; 15963 } 15964 15965 /* 15966 * "values(dict)" function 15967 */ 15968 static void 15969 f_values(argvars, rettv) 15970 typval_T *argvars; 15971 typval_T *rettv; 15972 { 15973 dict_list(argvars, rettv, 1); 15974 } 15975 15976 /* 15977 * "virtcol(string)" function 15978 */ 15979 static void 15980 f_virtcol(argvars, rettv) 15981 typval_T *argvars; 15982 typval_T *rettv; 15983 { 15984 colnr_T vcol = 0; 15985 pos_T *fp; 15986 int fnum = curbuf->b_fnum; 15987 15988 fp = var2fpos(&argvars[0], FALSE, &fnum); 15989 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 15990 && fnum == curbuf->b_fnum) 15991 { 15992 getvvcol(curwin, fp, NULL, NULL, &vcol); 15993 ++vcol; 15994 } 15995 15996 rettv->vval.v_number = vcol; 15997 } 15998 15999 /* 16000 * "visualmode()" function 16001 */ 16002 /*ARGSUSED*/ 16003 static void 16004 f_visualmode(argvars, rettv) 16005 typval_T *argvars; 16006 typval_T *rettv; 16007 { 16008 #ifdef FEAT_VISUAL 16009 char_u str[2]; 16010 16011 rettv->v_type = VAR_STRING; 16012 str[0] = curbuf->b_visual_mode_eval; 16013 str[1] = NUL; 16014 rettv->vval.v_string = vim_strsave(str); 16015 16016 /* A non-zero number or non-empty string argument: reset mode. */ 16017 if ((argvars[0].v_type == VAR_NUMBER 16018 && argvars[0].vval.v_number != 0) 16019 || (argvars[0].v_type == VAR_STRING 16020 && *get_tv_string(&argvars[0]) != NUL)) 16021 curbuf->b_visual_mode_eval = NUL; 16022 #else 16023 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 16024 #endif 16025 } 16026 16027 /* 16028 * "winbufnr(nr)" function 16029 */ 16030 static void 16031 f_winbufnr(argvars, rettv) 16032 typval_T *argvars; 16033 typval_T *rettv; 16034 { 16035 win_T *wp; 16036 16037 wp = find_win_by_nr(&argvars[0], NULL); 16038 if (wp == NULL) 16039 rettv->vval.v_number = -1; 16040 else 16041 rettv->vval.v_number = wp->w_buffer->b_fnum; 16042 } 16043 16044 /* 16045 * "wincol()" function 16046 */ 16047 /*ARGSUSED*/ 16048 static void 16049 f_wincol(argvars, rettv) 16050 typval_T *argvars; 16051 typval_T *rettv; 16052 { 16053 validate_cursor(); 16054 rettv->vval.v_number = curwin->w_wcol + 1; 16055 } 16056 16057 /* 16058 * "winheight(nr)" function 16059 */ 16060 static void 16061 f_winheight(argvars, rettv) 16062 typval_T *argvars; 16063 typval_T *rettv; 16064 { 16065 win_T *wp; 16066 16067 wp = find_win_by_nr(&argvars[0], NULL); 16068 if (wp == NULL) 16069 rettv->vval.v_number = -1; 16070 else 16071 rettv->vval.v_number = wp->w_height; 16072 } 16073 16074 /* 16075 * "winline()" function 16076 */ 16077 /*ARGSUSED*/ 16078 static void 16079 f_winline(argvars, rettv) 16080 typval_T *argvars; 16081 typval_T *rettv; 16082 { 16083 validate_cursor(); 16084 rettv->vval.v_number = curwin->w_wrow + 1; 16085 } 16086 16087 /* 16088 * "winnr()" function 16089 */ 16090 /* ARGSUSED */ 16091 static void 16092 f_winnr(argvars, rettv) 16093 typval_T *argvars; 16094 typval_T *rettv; 16095 { 16096 int nr = 1; 16097 16098 #ifdef FEAT_WINDOWS 16099 nr = get_winnr(curtab, &argvars[0]); 16100 #endif 16101 rettv->vval.v_number = nr; 16102 } 16103 16104 /* 16105 * "winrestcmd()" function 16106 */ 16107 /* ARGSUSED */ 16108 static void 16109 f_winrestcmd(argvars, rettv) 16110 typval_T *argvars; 16111 typval_T *rettv; 16112 { 16113 #ifdef FEAT_WINDOWS 16114 win_T *wp; 16115 int winnr = 1; 16116 garray_T ga; 16117 char_u buf[50]; 16118 16119 ga_init2(&ga, (int)sizeof(char), 70); 16120 for (wp = firstwin; wp != NULL; wp = wp->w_next) 16121 { 16122 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 16123 ga_concat(&ga, buf); 16124 # ifdef FEAT_VERTSPLIT 16125 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 16126 ga_concat(&ga, buf); 16127 # endif 16128 ++winnr; 16129 } 16130 ga_append(&ga, NUL); 16131 16132 rettv->vval.v_string = ga.ga_data; 16133 #else 16134 rettv->vval.v_string = NULL; 16135 #endif 16136 rettv->v_type = VAR_STRING; 16137 } 16138 16139 /* 16140 * "winrestview()" function 16141 */ 16142 /* ARGSUSED */ 16143 static void 16144 f_winrestview(argvars, rettv) 16145 typval_T *argvars; 16146 typval_T *rettv; 16147 { 16148 dict_T *dict; 16149 16150 if (argvars[0].v_type != VAR_DICT 16151 || (dict = argvars[0].vval.v_dict) == NULL) 16152 EMSG(_(e_invarg)); 16153 else 16154 { 16155 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 16156 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 16157 #ifdef FEAT_VIRTUALEDIT 16158 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 16159 #endif 16160 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 16161 curwin->w_set_curswant = FALSE; 16162 16163 curwin->w_topline = get_dict_number(dict, (char_u *)"topline"); 16164 #ifdef FEAT_DIFF 16165 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 16166 #endif 16167 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 16168 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 16169 16170 check_cursor(); 16171 changed_cline_bef_curs(); 16172 invalidate_botline(); 16173 redraw_later(VALID); 16174 16175 if (curwin->w_topline == 0) 16176 curwin->w_topline = 1; 16177 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 16178 curwin->w_topline = curbuf->b_ml.ml_line_count; 16179 #ifdef FEAT_DIFF 16180 check_topfill(curwin, TRUE); 16181 #endif 16182 } 16183 } 16184 16185 /* 16186 * "winsaveview()" function 16187 */ 16188 /* ARGSUSED */ 16189 static void 16190 f_winsaveview(argvars, rettv) 16191 typval_T *argvars; 16192 typval_T *rettv; 16193 { 16194 dict_T *dict; 16195 16196 dict = dict_alloc(); 16197 if (dict == NULL) 16198 return; 16199 rettv->v_type = VAR_DICT; 16200 rettv->vval.v_dict = dict; 16201 ++dict->dv_refcount; 16202 16203 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 16204 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 16205 #ifdef FEAT_VIRTUALEDIT 16206 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 16207 #endif 16208 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 16209 16210 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 16211 #ifdef FEAT_DIFF 16212 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 16213 #endif 16214 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 16215 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 16216 } 16217 16218 /* 16219 * "winwidth(nr)" function 16220 */ 16221 static void 16222 f_winwidth(argvars, rettv) 16223 typval_T *argvars; 16224 typval_T *rettv; 16225 { 16226 win_T *wp; 16227 16228 wp = find_win_by_nr(&argvars[0], NULL); 16229 if (wp == NULL) 16230 rettv->vval.v_number = -1; 16231 else 16232 #ifdef FEAT_VERTSPLIT 16233 rettv->vval.v_number = wp->w_width; 16234 #else 16235 rettv->vval.v_number = Columns; 16236 #endif 16237 } 16238 16239 /* 16240 * "writefile()" function 16241 */ 16242 static void 16243 f_writefile(argvars, rettv) 16244 typval_T *argvars; 16245 typval_T *rettv; 16246 { 16247 int binary = FALSE; 16248 char_u *fname; 16249 FILE *fd; 16250 listitem_T *li; 16251 char_u *s; 16252 int ret = 0; 16253 int c; 16254 16255 if (argvars[0].v_type != VAR_LIST) 16256 { 16257 EMSG2(_(e_listarg), "writefile()"); 16258 return; 16259 } 16260 if (argvars[0].vval.v_list == NULL) 16261 return; 16262 16263 if (argvars[2].v_type != VAR_UNKNOWN 16264 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 16265 binary = TRUE; 16266 16267 /* Always open the file in binary mode, library functions have a mind of 16268 * their own about CR-LF conversion. */ 16269 fname = get_tv_string(&argvars[1]); 16270 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 16271 { 16272 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 16273 ret = -1; 16274 } 16275 else 16276 { 16277 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 16278 li = li->li_next) 16279 { 16280 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 16281 { 16282 if (*s == '\n') 16283 c = putc(NUL, fd); 16284 else 16285 c = putc(*s, fd); 16286 if (c == EOF) 16287 { 16288 ret = -1; 16289 break; 16290 } 16291 } 16292 if (!binary || li->li_next != NULL) 16293 if (putc('\n', fd) == EOF) 16294 { 16295 ret = -1; 16296 break; 16297 } 16298 if (ret < 0) 16299 { 16300 EMSG(_(e_write)); 16301 break; 16302 } 16303 } 16304 fclose(fd); 16305 } 16306 16307 rettv->vval.v_number = ret; 16308 } 16309 16310 /* 16311 * Translate a String variable into a position. 16312 * Returns NULL when there is an error. 16313 */ 16314 static pos_T * 16315 var2fpos(varp, lnum, fnum) 16316 typval_T *varp; 16317 int lnum; /* TRUE when $ is last line */ 16318 int *fnum; /* set to fnum for '0, 'A, etc. */ 16319 { 16320 char_u *name; 16321 static pos_T pos; 16322 pos_T *pp; 16323 16324 /* Argument can be [lnum, col, coladd]. */ 16325 if (varp->v_type == VAR_LIST) 16326 { 16327 list_T *l; 16328 int len; 16329 int error = FALSE; 16330 16331 l = varp->vval.v_list; 16332 if (l == NULL) 16333 return NULL; 16334 16335 /* Get the line number */ 16336 pos.lnum = list_find_nr(l, 0L, &error); 16337 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 16338 return NULL; /* invalid line number */ 16339 16340 /* Get the column number */ 16341 pos.col = list_find_nr(l, 1L, &error); 16342 if (error) 16343 return NULL; 16344 len = (long)STRLEN(ml_get(pos.lnum)); 16345 /* Accept a position up to the NUL after the line. */ 16346 if (pos.col == 0 || (int)pos.col > len + 1) 16347 return NULL; /* invalid column number */ 16348 --pos.col; 16349 16350 #ifdef FEAT_VIRTUALEDIT 16351 /* Get the virtual offset. Defaults to zero. */ 16352 pos.coladd = list_find_nr(l, 2L, &error); 16353 if (error) 16354 pos.coladd = 0; 16355 #endif 16356 16357 return &pos; 16358 } 16359 16360 name = get_tv_string_chk(varp); 16361 if (name == NULL) 16362 return NULL; 16363 if (name[0] == '.') /* cursor */ 16364 return &curwin->w_cursor; 16365 if (name[0] == '\'') /* mark */ 16366 { 16367 pp = getmark_fnum(name[1], FALSE, fnum); 16368 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 16369 return NULL; 16370 return pp; 16371 } 16372 16373 #ifdef FEAT_VIRTUALEDIT 16374 pos.coladd = 0; 16375 #endif 16376 16377 if (name[0] == 'w' && lnum) 16378 { 16379 pos.col = 0; 16380 if (name[1] == '0') /* "w0": first visible line */ 16381 { 16382 update_topline(); 16383 pos.lnum = curwin->w_topline; 16384 return &pos; 16385 } 16386 else if (name[1] == '$') /* "w$": last visible line */ 16387 { 16388 validate_botline(); 16389 pos.lnum = curwin->w_botline - 1; 16390 return &pos; 16391 } 16392 } 16393 else if (name[0] == '$') /* last column or line */ 16394 { 16395 if (lnum) 16396 { 16397 pos.lnum = curbuf->b_ml.ml_line_count; 16398 pos.col = 0; 16399 } 16400 else 16401 { 16402 pos.lnum = curwin->w_cursor.lnum; 16403 pos.col = (colnr_T)STRLEN(ml_get_curline()); 16404 } 16405 return &pos; 16406 } 16407 return NULL; 16408 } 16409 16410 /* 16411 * Convert list in "arg" into a position and optional file number. 16412 * When "fnump" is NULL there is no file number, only 3 items. 16413 * Note that the column is passed on as-is, the caller may want to decrement 16414 * it to use 1 for the first column. 16415 * Return FAIL when conversion is not possible, doesn't check the position for 16416 * validity. 16417 */ 16418 static int 16419 list2fpos(arg, posp, fnump) 16420 typval_T *arg; 16421 pos_T *posp; 16422 int *fnump; 16423 { 16424 list_T *l = arg->vval.v_list; 16425 long i = 0; 16426 long n; 16427 16428 /* List must be: [fnum, lnum, col, coladd] */ 16429 if (arg->v_type != VAR_LIST || l == NULL 16430 || l->lv_len != (fnump == NULL ? 3 : 4)) 16431 return FAIL; 16432 16433 if (fnump != NULL) 16434 { 16435 n = list_find_nr(l, i++, NULL); /* fnum */ 16436 if (n < 0) 16437 return FAIL; 16438 if (n == 0) 16439 n = curbuf->b_fnum; /* current buffer */ 16440 *fnump = n; 16441 } 16442 16443 n = list_find_nr(l, i++, NULL); /* lnum */ 16444 if (n < 0) 16445 return FAIL; 16446 posp->lnum = n; 16447 16448 n = list_find_nr(l, i++, NULL); /* col */ 16449 if (n < 0) 16450 return FAIL; 16451 posp->col = n; 16452 16453 #ifdef FEAT_VIRTUALEDIT 16454 n = list_find_nr(l, i, NULL); 16455 if (n < 0) 16456 return FAIL; 16457 posp->coladd = n; 16458 #endif 16459 16460 return OK; 16461 } 16462 16463 /* 16464 * Get the length of an environment variable name. 16465 * Advance "arg" to the first character after the name. 16466 * Return 0 for error. 16467 */ 16468 static int 16469 get_env_len(arg) 16470 char_u **arg; 16471 { 16472 char_u *p; 16473 int len; 16474 16475 for (p = *arg; vim_isIDc(*p); ++p) 16476 ; 16477 if (p == *arg) /* no name found */ 16478 return 0; 16479 16480 len = (int)(p - *arg); 16481 *arg = p; 16482 return len; 16483 } 16484 16485 /* 16486 * Get the length of the name of a function or internal variable. 16487 * "arg" is advanced to the first non-white character after the name. 16488 * Return 0 if something is wrong. 16489 */ 16490 static int 16491 get_id_len(arg) 16492 char_u **arg; 16493 { 16494 char_u *p; 16495 int len; 16496 16497 /* Find the end of the name. */ 16498 for (p = *arg; eval_isnamec(*p); ++p) 16499 ; 16500 if (p == *arg) /* no name found */ 16501 return 0; 16502 16503 len = (int)(p - *arg); 16504 *arg = skipwhite(p); 16505 16506 return len; 16507 } 16508 16509 /* 16510 * Get the length of the name of a variable or function. 16511 * Only the name is recognized, does not handle ".key" or "[idx]". 16512 * "arg" is advanced to the first non-white character after the name. 16513 * Return -1 if curly braces expansion failed. 16514 * Return 0 if something else is wrong. 16515 * If the name contains 'magic' {}'s, expand them and return the 16516 * expanded name in an allocated string via 'alias' - caller must free. 16517 */ 16518 static int 16519 get_name_len(arg, alias, evaluate, verbose) 16520 char_u **arg; 16521 char_u **alias; 16522 int evaluate; 16523 int verbose; 16524 { 16525 int len; 16526 char_u *p; 16527 char_u *expr_start; 16528 char_u *expr_end; 16529 16530 *alias = NULL; /* default to no alias */ 16531 16532 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 16533 && (*arg)[2] == (int)KE_SNR) 16534 { 16535 /* hard coded <SNR>, already translated */ 16536 *arg += 3; 16537 return get_id_len(arg) + 3; 16538 } 16539 len = eval_fname_script(*arg); 16540 if (len > 0) 16541 { 16542 /* literal "<SID>", "s:" or "<SNR>" */ 16543 *arg += len; 16544 } 16545 16546 /* 16547 * Find the end of the name; check for {} construction. 16548 */ 16549 p = find_name_end(*arg, &expr_start, &expr_end, 16550 len > 0 ? 0 : FNE_CHECK_START); 16551 if (expr_start != NULL) 16552 { 16553 char_u *temp_string; 16554 16555 if (!evaluate) 16556 { 16557 len += (int)(p - *arg); 16558 *arg = skipwhite(p); 16559 return len; 16560 } 16561 16562 /* 16563 * Include any <SID> etc in the expanded string: 16564 * Thus the -len here. 16565 */ 16566 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 16567 if (temp_string == NULL) 16568 return -1; 16569 *alias = temp_string; 16570 *arg = skipwhite(p); 16571 return (int)STRLEN(temp_string); 16572 } 16573 16574 len += get_id_len(arg); 16575 if (len == 0 && verbose) 16576 EMSG2(_(e_invexpr2), *arg); 16577 16578 return len; 16579 } 16580 16581 /* 16582 * Find the end of a variable or function name, taking care of magic braces. 16583 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 16584 * start and end of the first magic braces item. 16585 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 16586 * Return a pointer to just after the name. Equal to "arg" if there is no 16587 * valid name. 16588 */ 16589 static char_u * 16590 find_name_end(arg, expr_start, expr_end, flags) 16591 char_u *arg; 16592 char_u **expr_start; 16593 char_u **expr_end; 16594 int flags; 16595 { 16596 int mb_nest = 0; 16597 int br_nest = 0; 16598 char_u *p; 16599 16600 if (expr_start != NULL) 16601 { 16602 *expr_start = NULL; 16603 *expr_end = NULL; 16604 } 16605 16606 /* Quick check for valid starting character. */ 16607 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 16608 return arg; 16609 16610 for (p = arg; *p != NUL 16611 && (eval_isnamec(*p) 16612 || *p == '{' 16613 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 16614 || mb_nest != 0 16615 || br_nest != 0); mb_ptr_adv(p)) 16616 { 16617 if (*p == '\'') 16618 { 16619 /* skip over 'string' to avoid counting [ and ] inside it. */ 16620 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 16621 ; 16622 if (*p == NUL) 16623 break; 16624 } 16625 else if (*p == '"') 16626 { 16627 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 16628 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 16629 if (*p == '\\' && p[1] != NUL) 16630 ++p; 16631 if (*p == NUL) 16632 break; 16633 } 16634 16635 if (mb_nest == 0) 16636 { 16637 if (*p == '[') 16638 ++br_nest; 16639 else if (*p == ']') 16640 --br_nest; 16641 } 16642 16643 if (br_nest == 0) 16644 { 16645 if (*p == '{') 16646 { 16647 mb_nest++; 16648 if (expr_start != NULL && *expr_start == NULL) 16649 *expr_start = p; 16650 } 16651 else if (*p == '}') 16652 { 16653 mb_nest--; 16654 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 16655 *expr_end = p; 16656 } 16657 } 16658 } 16659 16660 return p; 16661 } 16662 16663 /* 16664 * Expands out the 'magic' {}'s in a variable/function name. 16665 * Note that this can call itself recursively, to deal with 16666 * constructs like foo{bar}{baz}{bam} 16667 * The four pointer arguments point to "foo{expre}ss{ion}bar" 16668 * "in_start" ^ 16669 * "expr_start" ^ 16670 * "expr_end" ^ 16671 * "in_end" ^ 16672 * 16673 * Returns a new allocated string, which the caller must free. 16674 * Returns NULL for failure. 16675 */ 16676 static char_u * 16677 make_expanded_name(in_start, expr_start, expr_end, in_end) 16678 char_u *in_start; 16679 char_u *expr_start; 16680 char_u *expr_end; 16681 char_u *in_end; 16682 { 16683 char_u c1; 16684 char_u *retval = NULL; 16685 char_u *temp_result; 16686 char_u *nextcmd = NULL; 16687 16688 if (expr_end == NULL || in_end == NULL) 16689 return NULL; 16690 *expr_start = NUL; 16691 *expr_end = NUL; 16692 c1 = *in_end; 16693 *in_end = NUL; 16694 16695 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 16696 if (temp_result != NULL && nextcmd == NULL) 16697 { 16698 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 16699 + (in_end - expr_end) + 1)); 16700 if (retval != NULL) 16701 { 16702 STRCPY(retval, in_start); 16703 STRCAT(retval, temp_result); 16704 STRCAT(retval, expr_end + 1); 16705 } 16706 } 16707 vim_free(temp_result); 16708 16709 *in_end = c1; /* put char back for error messages */ 16710 *expr_start = '{'; 16711 *expr_end = '}'; 16712 16713 if (retval != NULL) 16714 { 16715 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 16716 if (expr_start != NULL) 16717 { 16718 /* Further expansion! */ 16719 temp_result = make_expanded_name(retval, expr_start, 16720 expr_end, temp_result); 16721 vim_free(retval); 16722 retval = temp_result; 16723 } 16724 } 16725 16726 return retval; 16727 } 16728 16729 /* 16730 * Return TRUE if character "c" can be used in a variable or function name. 16731 * Does not include '{' or '}' for magic braces. 16732 */ 16733 static int 16734 eval_isnamec(c) 16735 int c; 16736 { 16737 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 16738 } 16739 16740 /* 16741 * Return TRUE if character "c" can be used as the first character in a 16742 * variable or function name (excluding '{' and '}'). 16743 */ 16744 static int 16745 eval_isnamec1(c) 16746 int c; 16747 { 16748 return (ASCII_ISALPHA(c) || c == '_'); 16749 } 16750 16751 /* 16752 * Set number v: variable to "val". 16753 */ 16754 void 16755 set_vim_var_nr(idx, val) 16756 int idx; 16757 long val; 16758 { 16759 vimvars[idx].vv_nr = val; 16760 } 16761 16762 /* 16763 * Get number v: variable value. 16764 */ 16765 long 16766 get_vim_var_nr(idx) 16767 int idx; 16768 { 16769 return vimvars[idx].vv_nr; 16770 } 16771 16772 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16773 /* 16774 * Get string v: variable value. Uses a static buffer, can only be used once. 16775 */ 16776 char_u * 16777 get_vim_var_str(idx) 16778 int idx; 16779 { 16780 return get_tv_string(&vimvars[idx].vv_tv); 16781 } 16782 #endif 16783 16784 /* 16785 * Set v:count, v:count1 and v:prevcount. 16786 */ 16787 void 16788 set_vcount(count, count1) 16789 long count; 16790 long count1; 16791 { 16792 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 16793 vimvars[VV_COUNT].vv_nr = count; 16794 vimvars[VV_COUNT1].vv_nr = count1; 16795 } 16796 16797 /* 16798 * Set string v: variable to a copy of "val". 16799 */ 16800 void 16801 set_vim_var_string(idx, val, len) 16802 int idx; 16803 char_u *val; 16804 int len; /* length of "val" to use or -1 (whole string) */ 16805 { 16806 /* Need to do this (at least) once, since we can't initialize a union. 16807 * Will always be invoked when "v:progname" is set. */ 16808 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 16809 16810 vim_free(vimvars[idx].vv_str); 16811 if (val == NULL) 16812 vimvars[idx].vv_str = NULL; 16813 else if (len == -1) 16814 vimvars[idx].vv_str = vim_strsave(val); 16815 else 16816 vimvars[idx].vv_str = vim_strnsave(val, len); 16817 } 16818 16819 /* 16820 * Set v:register if needed. 16821 */ 16822 void 16823 set_reg_var(c) 16824 int c; 16825 { 16826 char_u regname; 16827 16828 if (c == 0 || c == ' ') 16829 regname = '"'; 16830 else 16831 regname = c; 16832 /* Avoid free/alloc when the value is already right. */ 16833 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 16834 set_vim_var_string(VV_REG, ®name, 1); 16835 } 16836 16837 /* 16838 * Get or set v:exception. If "oldval" == NULL, return the current value. 16839 * Otherwise, restore the value to "oldval" and return NULL. 16840 * Must always be called in pairs to save and restore v:exception! Does not 16841 * take care of memory allocations. 16842 */ 16843 char_u * 16844 v_exception(oldval) 16845 char_u *oldval; 16846 { 16847 if (oldval == NULL) 16848 return vimvars[VV_EXCEPTION].vv_str; 16849 16850 vimvars[VV_EXCEPTION].vv_str = oldval; 16851 return NULL; 16852 } 16853 16854 /* 16855 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 16856 * Otherwise, restore the value to "oldval" and return NULL. 16857 * Must always be called in pairs to save and restore v:throwpoint! Does not 16858 * take care of memory allocations. 16859 */ 16860 char_u * 16861 v_throwpoint(oldval) 16862 char_u *oldval; 16863 { 16864 if (oldval == NULL) 16865 return vimvars[VV_THROWPOINT].vv_str; 16866 16867 vimvars[VV_THROWPOINT].vv_str = oldval; 16868 return NULL; 16869 } 16870 16871 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16872 /* 16873 * Set v:cmdarg. 16874 * If "eap" != NULL, use "eap" to generate the value and return the old value. 16875 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 16876 * Must always be called in pairs! 16877 */ 16878 char_u * 16879 set_cmdarg(eap, oldarg) 16880 exarg_T *eap; 16881 char_u *oldarg; 16882 { 16883 char_u *oldval; 16884 char_u *newval; 16885 unsigned len; 16886 16887 oldval = vimvars[VV_CMDARG].vv_str; 16888 if (eap == NULL) 16889 { 16890 vim_free(oldval); 16891 vimvars[VV_CMDARG].vv_str = oldarg; 16892 return NULL; 16893 } 16894 16895 if (eap->force_bin == FORCE_BIN) 16896 len = 6; 16897 else if (eap->force_bin == FORCE_NOBIN) 16898 len = 8; 16899 else 16900 len = 0; 16901 16902 if (eap->read_edit) 16903 len += 7; 16904 16905 if (eap->force_ff != 0) 16906 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 16907 # ifdef FEAT_MBYTE 16908 if (eap->force_enc != 0) 16909 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 16910 if (eap->bad_char != 0) 16911 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 16912 # endif 16913 16914 newval = alloc(len + 1); 16915 if (newval == NULL) 16916 return NULL; 16917 16918 if (eap->force_bin == FORCE_BIN) 16919 sprintf((char *)newval, " ++bin"); 16920 else if (eap->force_bin == FORCE_NOBIN) 16921 sprintf((char *)newval, " ++nobin"); 16922 else 16923 *newval = NUL; 16924 16925 if (eap->read_edit) 16926 STRCAT(newval, " ++edit"); 16927 16928 if (eap->force_ff != 0) 16929 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 16930 eap->cmd + eap->force_ff); 16931 # ifdef FEAT_MBYTE 16932 if (eap->force_enc != 0) 16933 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 16934 eap->cmd + eap->force_enc); 16935 if (eap->bad_char != 0) 16936 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 16937 eap->cmd + eap->bad_char); 16938 # endif 16939 vimvars[VV_CMDARG].vv_str = newval; 16940 return oldval; 16941 } 16942 #endif 16943 16944 /* 16945 * Get the value of internal variable "name". 16946 * Return OK or FAIL. 16947 */ 16948 static int 16949 get_var_tv(name, len, rettv, verbose) 16950 char_u *name; 16951 int len; /* length of "name" */ 16952 typval_T *rettv; /* NULL when only checking existence */ 16953 int verbose; /* may give error message */ 16954 { 16955 int ret = OK; 16956 typval_T *tv = NULL; 16957 typval_T atv; 16958 dictitem_T *v; 16959 int cc; 16960 16961 /* truncate the name, so that we can use strcmp() */ 16962 cc = name[len]; 16963 name[len] = NUL; 16964 16965 /* 16966 * Check for "b:changedtick". 16967 */ 16968 if (STRCMP(name, "b:changedtick") == 0) 16969 { 16970 atv.v_type = VAR_NUMBER; 16971 atv.vval.v_number = curbuf->b_changedtick; 16972 tv = &atv; 16973 } 16974 16975 /* 16976 * Check for user-defined variables. 16977 */ 16978 else 16979 { 16980 v = find_var(name, NULL); 16981 if (v != NULL) 16982 tv = &v->di_tv; 16983 } 16984 16985 if (tv == NULL) 16986 { 16987 if (rettv != NULL && verbose) 16988 EMSG2(_(e_undefvar), name); 16989 ret = FAIL; 16990 } 16991 else if (rettv != NULL) 16992 copy_tv(tv, rettv); 16993 16994 name[len] = cc; 16995 16996 return ret; 16997 } 16998 16999 /* 17000 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 17001 * Also handle function call with Funcref variable: func(expr) 17002 * Can all be combined: dict.func(expr)[idx]['func'](expr) 17003 */ 17004 static int 17005 handle_subscript(arg, rettv, evaluate, verbose) 17006 char_u **arg; 17007 typval_T *rettv; 17008 int evaluate; /* do more than finding the end */ 17009 int verbose; /* give error messages */ 17010 { 17011 int ret = OK; 17012 dict_T *selfdict = NULL; 17013 char_u *s; 17014 int len; 17015 typval_T functv; 17016 17017 while (ret == OK 17018 && (**arg == '[' 17019 || (**arg == '.' && rettv->v_type == VAR_DICT) 17020 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 17021 && !vim_iswhite(*(*arg - 1))) 17022 { 17023 if (**arg == '(') 17024 { 17025 /* need to copy the funcref so that we can clear rettv */ 17026 functv = *rettv; 17027 rettv->v_type = VAR_UNKNOWN; 17028 17029 /* Invoke the function. Recursive! */ 17030 s = functv.vval.v_string; 17031 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 17032 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 17033 &len, evaluate, selfdict); 17034 17035 /* Clear the funcref afterwards, so that deleting it while 17036 * evaluating the arguments is possible (see test55). */ 17037 clear_tv(&functv); 17038 17039 /* Stop the expression evaluation when immediately aborting on 17040 * error, or when an interrupt occurred or an exception was thrown 17041 * but not caught. */ 17042 if (aborting()) 17043 { 17044 if (ret == OK) 17045 clear_tv(rettv); 17046 ret = FAIL; 17047 } 17048 dict_unref(selfdict); 17049 selfdict = NULL; 17050 } 17051 else /* **arg == '[' || **arg == '.' */ 17052 { 17053 dict_unref(selfdict); 17054 if (rettv->v_type == VAR_DICT) 17055 { 17056 selfdict = rettv->vval.v_dict; 17057 if (selfdict != NULL) 17058 ++selfdict->dv_refcount; 17059 } 17060 else 17061 selfdict = NULL; 17062 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 17063 { 17064 clear_tv(rettv); 17065 ret = FAIL; 17066 } 17067 } 17068 } 17069 dict_unref(selfdict); 17070 return ret; 17071 } 17072 17073 /* 17074 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 17075 * value). 17076 */ 17077 static typval_T * 17078 alloc_tv() 17079 { 17080 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 17081 } 17082 17083 /* 17084 * Allocate memory for a variable type-value, and assign a string to it. 17085 * The string "s" must have been allocated, it is consumed. 17086 * Return NULL for out of memory, the variable otherwise. 17087 */ 17088 static typval_T * 17089 alloc_string_tv(s) 17090 char_u *s; 17091 { 17092 typval_T *rettv; 17093 17094 rettv = alloc_tv(); 17095 if (rettv != NULL) 17096 { 17097 rettv->v_type = VAR_STRING; 17098 rettv->vval.v_string = s; 17099 } 17100 else 17101 vim_free(s); 17102 return rettv; 17103 } 17104 17105 /* 17106 * Free the memory for a variable type-value. 17107 */ 17108 void 17109 free_tv(varp) 17110 typval_T *varp; 17111 { 17112 if (varp != NULL) 17113 { 17114 switch (varp->v_type) 17115 { 17116 case VAR_FUNC: 17117 func_unref(varp->vval.v_string); 17118 /*FALLTHROUGH*/ 17119 case VAR_STRING: 17120 vim_free(varp->vval.v_string); 17121 break; 17122 case VAR_LIST: 17123 list_unref(varp->vval.v_list); 17124 break; 17125 case VAR_DICT: 17126 dict_unref(varp->vval.v_dict); 17127 break; 17128 case VAR_NUMBER: 17129 case VAR_UNKNOWN: 17130 break; 17131 default: 17132 EMSG2(_(e_intern2), "free_tv()"); 17133 break; 17134 } 17135 vim_free(varp); 17136 } 17137 } 17138 17139 /* 17140 * Free the memory for a variable value and set the value to NULL or 0. 17141 */ 17142 void 17143 clear_tv(varp) 17144 typval_T *varp; 17145 { 17146 if (varp != NULL) 17147 { 17148 switch (varp->v_type) 17149 { 17150 case VAR_FUNC: 17151 func_unref(varp->vval.v_string); 17152 /*FALLTHROUGH*/ 17153 case VAR_STRING: 17154 vim_free(varp->vval.v_string); 17155 varp->vval.v_string = NULL; 17156 break; 17157 case VAR_LIST: 17158 list_unref(varp->vval.v_list); 17159 varp->vval.v_list = NULL; 17160 break; 17161 case VAR_DICT: 17162 dict_unref(varp->vval.v_dict); 17163 varp->vval.v_dict = NULL; 17164 break; 17165 case VAR_NUMBER: 17166 varp->vval.v_number = 0; 17167 break; 17168 case VAR_UNKNOWN: 17169 break; 17170 default: 17171 EMSG2(_(e_intern2), "clear_tv()"); 17172 } 17173 varp->v_lock = 0; 17174 } 17175 } 17176 17177 /* 17178 * Set the value of a variable to NULL without freeing items. 17179 */ 17180 static void 17181 init_tv(varp) 17182 typval_T *varp; 17183 { 17184 if (varp != NULL) 17185 vim_memset(varp, 0, sizeof(typval_T)); 17186 } 17187 17188 /* 17189 * Get the number value of a variable. 17190 * If it is a String variable, uses vim_str2nr(). 17191 * For incompatible types, return 0. 17192 * get_tv_number_chk() is similar to get_tv_number(), but informs the 17193 * caller of incompatible types: it sets *denote to TRUE if "denote" 17194 * is not NULL or returns -1 otherwise. 17195 */ 17196 static long 17197 get_tv_number(varp) 17198 typval_T *varp; 17199 { 17200 int error = FALSE; 17201 17202 return get_tv_number_chk(varp, &error); /* return 0L on error */ 17203 } 17204 17205 long 17206 get_tv_number_chk(varp, denote) 17207 typval_T *varp; 17208 int *denote; 17209 { 17210 long n = 0L; 17211 17212 switch (varp->v_type) 17213 { 17214 case VAR_NUMBER: 17215 return (long)(varp->vval.v_number); 17216 case VAR_FUNC: 17217 EMSG(_("E703: Using a Funcref as a number")); 17218 break; 17219 case VAR_STRING: 17220 if (varp->vval.v_string != NULL) 17221 vim_str2nr(varp->vval.v_string, NULL, NULL, 17222 TRUE, TRUE, &n, NULL); 17223 return n; 17224 case VAR_LIST: 17225 EMSG(_("E745: Using a List as a number")); 17226 break; 17227 case VAR_DICT: 17228 EMSG(_("E728: Using a Dictionary as a number")); 17229 break; 17230 default: 17231 EMSG2(_(e_intern2), "get_tv_number()"); 17232 break; 17233 } 17234 if (denote == NULL) /* useful for values that must be unsigned */ 17235 n = -1; 17236 else 17237 *denote = TRUE; 17238 return n; 17239 } 17240 17241 /* 17242 * Get the lnum from the first argument. 17243 * Also accepts ".", "$", etc., but that only works for the current buffer. 17244 * Returns -1 on error. 17245 */ 17246 static linenr_T 17247 get_tv_lnum(argvars) 17248 typval_T *argvars; 17249 { 17250 typval_T rettv; 17251 linenr_T lnum; 17252 17253 lnum = get_tv_number_chk(&argvars[0], NULL); 17254 if (lnum == 0) /* no valid number, try using line() */ 17255 { 17256 rettv.v_type = VAR_NUMBER; 17257 f_line(argvars, &rettv); 17258 lnum = rettv.vval.v_number; 17259 clear_tv(&rettv); 17260 } 17261 return lnum; 17262 } 17263 17264 /* 17265 * Get the lnum from the first argument. 17266 * Also accepts "$", then "buf" is used. 17267 * Returns 0 on error. 17268 */ 17269 static linenr_T 17270 get_tv_lnum_buf(argvars, buf) 17271 typval_T *argvars; 17272 buf_T *buf; 17273 { 17274 if (argvars[0].v_type == VAR_STRING 17275 && argvars[0].vval.v_string != NULL 17276 && argvars[0].vval.v_string[0] == '$' 17277 && buf != NULL) 17278 return buf->b_ml.ml_line_count; 17279 return get_tv_number_chk(&argvars[0], NULL); 17280 } 17281 17282 /* 17283 * Get the string value of a variable. 17284 * If it is a Number variable, the number is converted into a string. 17285 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 17286 * get_tv_string_buf() uses a given buffer. 17287 * If the String variable has never been set, return an empty string. 17288 * Never returns NULL; 17289 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 17290 * NULL on error. 17291 */ 17292 static char_u * 17293 get_tv_string(varp) 17294 typval_T *varp; 17295 { 17296 static char_u mybuf[NUMBUFLEN]; 17297 17298 return get_tv_string_buf(varp, mybuf); 17299 } 17300 17301 static char_u * 17302 get_tv_string_buf(varp, buf) 17303 typval_T *varp; 17304 char_u *buf; 17305 { 17306 char_u *res = get_tv_string_buf_chk(varp, buf); 17307 17308 return res != NULL ? res : (char_u *)""; 17309 } 17310 17311 char_u * 17312 get_tv_string_chk(varp) 17313 typval_T *varp; 17314 { 17315 static char_u mybuf[NUMBUFLEN]; 17316 17317 return get_tv_string_buf_chk(varp, mybuf); 17318 } 17319 17320 static char_u * 17321 get_tv_string_buf_chk(varp, buf) 17322 typval_T *varp; 17323 char_u *buf; 17324 { 17325 switch (varp->v_type) 17326 { 17327 case VAR_NUMBER: 17328 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 17329 return buf; 17330 case VAR_FUNC: 17331 EMSG(_("E729: using Funcref as a String")); 17332 break; 17333 case VAR_LIST: 17334 EMSG(_("E730: using List as a String")); 17335 break; 17336 case VAR_DICT: 17337 EMSG(_("E731: using Dictionary as a String")); 17338 break; 17339 case VAR_STRING: 17340 if (varp->vval.v_string != NULL) 17341 return varp->vval.v_string; 17342 return (char_u *)""; 17343 default: 17344 EMSG2(_(e_intern2), "get_tv_string_buf()"); 17345 break; 17346 } 17347 return NULL; 17348 } 17349 17350 /* 17351 * Find variable "name" in the list of variables. 17352 * Return a pointer to it if found, NULL if not found. 17353 * Careful: "a:0" variables don't have a name. 17354 * When "htp" is not NULL we are writing to the variable, set "htp" to the 17355 * hashtab_T used. 17356 */ 17357 static dictitem_T * 17358 find_var(name, htp) 17359 char_u *name; 17360 hashtab_T **htp; 17361 { 17362 char_u *varname; 17363 hashtab_T *ht; 17364 17365 ht = find_var_ht(name, &varname); 17366 if (htp != NULL) 17367 *htp = ht; 17368 if (ht == NULL) 17369 return NULL; 17370 return find_var_in_ht(ht, varname, htp != NULL); 17371 } 17372 17373 /* 17374 * Find variable "varname" in hashtab "ht". 17375 * Returns NULL if not found. 17376 */ 17377 static dictitem_T * 17378 find_var_in_ht(ht, varname, writing) 17379 hashtab_T *ht; 17380 char_u *varname; 17381 int writing; 17382 { 17383 hashitem_T *hi; 17384 17385 if (*varname == NUL) 17386 { 17387 /* Must be something like "s:", otherwise "ht" would be NULL. */ 17388 switch (varname[-2]) 17389 { 17390 case 's': return &SCRIPT_SV(current_SID).sv_var; 17391 case 'g': return &globvars_var; 17392 case 'v': return &vimvars_var; 17393 case 'b': return &curbuf->b_bufvar; 17394 case 'w': return &curwin->w_winvar; 17395 #ifdef FEAT_WINDOWS 17396 case 't': return &curtab->tp_winvar; 17397 #endif 17398 case 'l': return current_funccal == NULL 17399 ? NULL : ¤t_funccal->l_vars_var; 17400 case 'a': return current_funccal == NULL 17401 ? NULL : ¤t_funccal->l_avars_var; 17402 } 17403 return NULL; 17404 } 17405 17406 hi = hash_find(ht, varname); 17407 if (HASHITEM_EMPTY(hi)) 17408 { 17409 /* For global variables we may try auto-loading the script. If it 17410 * worked find the variable again. Don't auto-load a script if it was 17411 * loaded already, otherwise it would be loaded every time when 17412 * checking if a function name is a Funcref variable. */ 17413 if (ht == &globvarht && !writing 17414 && script_autoload(varname, FALSE) && !aborting()) 17415 hi = hash_find(ht, varname); 17416 if (HASHITEM_EMPTY(hi)) 17417 return NULL; 17418 } 17419 return HI2DI(hi); 17420 } 17421 17422 /* 17423 * Find the hashtab used for a variable name. 17424 * Set "varname" to the start of name without ':'. 17425 */ 17426 static hashtab_T * 17427 find_var_ht(name, varname) 17428 char_u *name; 17429 char_u **varname; 17430 { 17431 hashitem_T *hi; 17432 17433 if (name[1] != ':') 17434 { 17435 /* The name must not start with a colon or #. */ 17436 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 17437 return NULL; 17438 *varname = name; 17439 17440 /* "version" is "v:version" in all scopes */ 17441 hi = hash_find(&compat_hashtab, name); 17442 if (!HASHITEM_EMPTY(hi)) 17443 return &compat_hashtab; 17444 17445 if (current_funccal == NULL) 17446 return &globvarht; /* global variable */ 17447 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 17448 } 17449 *varname = name + 2; 17450 if (*name == 'g') /* global variable */ 17451 return &globvarht; 17452 /* There must be no ':' or '#' in the rest of the name, unless g: is used 17453 */ 17454 if (vim_strchr(name + 2, ':') != NULL 17455 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 17456 return NULL; 17457 if (*name == 'b') /* buffer variable */ 17458 return &curbuf->b_vars.dv_hashtab; 17459 if (*name == 'w') /* window variable */ 17460 return &curwin->w_vars.dv_hashtab; 17461 #ifdef FEAT_WINDOWS 17462 if (*name == 't') /* tab page variable */ 17463 return &curtab->tp_vars.dv_hashtab; 17464 #endif 17465 if (*name == 'v') /* v: variable */ 17466 return &vimvarht; 17467 if (*name == 'a' && current_funccal != NULL) /* function argument */ 17468 return ¤t_funccal->l_avars.dv_hashtab; 17469 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 17470 return ¤t_funccal->l_vars.dv_hashtab; 17471 if (*name == 's' /* script variable */ 17472 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 17473 return &SCRIPT_VARS(current_SID); 17474 return NULL; 17475 } 17476 17477 /* 17478 * Get the string value of a (global/local) variable. 17479 * Returns NULL when it doesn't exist. 17480 */ 17481 char_u * 17482 get_var_value(name) 17483 char_u *name; 17484 { 17485 dictitem_T *v; 17486 17487 v = find_var(name, NULL); 17488 if (v == NULL) 17489 return NULL; 17490 return get_tv_string(&v->di_tv); 17491 } 17492 17493 /* 17494 * Allocate a new hashtab for a sourced script. It will be used while 17495 * sourcing this script and when executing functions defined in the script. 17496 */ 17497 void 17498 new_script_vars(id) 17499 scid_T id; 17500 { 17501 int i; 17502 hashtab_T *ht; 17503 scriptvar_T *sv; 17504 17505 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 17506 { 17507 /* Re-allocating ga_data means that an ht_array pointing to 17508 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 17509 * at its init value. Also reset "v_dict", it's always the same. */ 17510 for (i = 1; i <= ga_scripts.ga_len; ++i) 17511 { 17512 ht = &SCRIPT_VARS(i); 17513 if (ht->ht_mask == HT_INIT_SIZE - 1) 17514 ht->ht_array = ht->ht_smallarray; 17515 sv = &SCRIPT_SV(i); 17516 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 17517 } 17518 17519 while (ga_scripts.ga_len < id) 17520 { 17521 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 17522 init_var_dict(&sv->sv_dict, &sv->sv_var); 17523 ++ga_scripts.ga_len; 17524 } 17525 } 17526 } 17527 17528 /* 17529 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 17530 * point to it. 17531 */ 17532 void 17533 init_var_dict(dict, dict_var) 17534 dict_T *dict; 17535 dictitem_T *dict_var; 17536 { 17537 hash_init(&dict->dv_hashtab); 17538 dict->dv_refcount = 99999; 17539 dict_var->di_tv.vval.v_dict = dict; 17540 dict_var->di_tv.v_type = VAR_DICT; 17541 dict_var->di_tv.v_lock = VAR_FIXED; 17542 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17543 dict_var->di_key[0] = NUL; 17544 } 17545 17546 /* 17547 * Clean up a list of internal variables. 17548 * Frees all allocated variables and the value they contain. 17549 * Clears hashtab "ht", does not free it. 17550 */ 17551 void 17552 vars_clear(ht) 17553 hashtab_T *ht; 17554 { 17555 vars_clear_ext(ht, TRUE); 17556 } 17557 17558 /* 17559 * Like vars_clear(), but only free the value if "free_val" is TRUE. 17560 */ 17561 static void 17562 vars_clear_ext(ht, free_val) 17563 hashtab_T *ht; 17564 int free_val; 17565 { 17566 int todo; 17567 hashitem_T *hi; 17568 dictitem_T *v; 17569 17570 hash_lock(ht); 17571 todo = (int)ht->ht_used; 17572 for (hi = ht->ht_array; todo > 0; ++hi) 17573 { 17574 if (!HASHITEM_EMPTY(hi)) 17575 { 17576 --todo; 17577 17578 /* Free the variable. Don't remove it from the hashtab, 17579 * ht_array might change then. hash_clear() takes care of it 17580 * later. */ 17581 v = HI2DI(hi); 17582 if (free_val) 17583 clear_tv(&v->di_tv); 17584 if ((v->di_flags & DI_FLAGS_FIX) == 0) 17585 vim_free(v); 17586 } 17587 } 17588 hash_clear(ht); 17589 ht->ht_used = 0; 17590 } 17591 17592 /* 17593 * Delete a variable from hashtab "ht" at item "hi". 17594 * Clear the variable value and free the dictitem. 17595 */ 17596 static void 17597 delete_var(ht, hi) 17598 hashtab_T *ht; 17599 hashitem_T *hi; 17600 { 17601 dictitem_T *di = HI2DI(hi); 17602 17603 hash_remove(ht, hi); 17604 clear_tv(&di->di_tv); 17605 vim_free(di); 17606 } 17607 17608 /* 17609 * List the value of one internal variable. 17610 */ 17611 static void 17612 list_one_var(v, prefix) 17613 dictitem_T *v; 17614 char_u *prefix; 17615 { 17616 char_u *tofree; 17617 char_u *s; 17618 char_u numbuf[NUMBUFLEN]; 17619 17620 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID); 17621 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 17622 s == NULL ? (char_u *)"" : s); 17623 vim_free(tofree); 17624 } 17625 17626 static void 17627 list_one_var_a(prefix, name, type, string) 17628 char_u *prefix; 17629 char_u *name; 17630 int type; 17631 char_u *string; 17632 { 17633 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 17634 if (name != NULL) /* "a:" vars don't have a name stored */ 17635 msg_puts(name); 17636 msg_putchar(' '); 17637 msg_advance(22); 17638 if (type == VAR_NUMBER) 17639 msg_putchar('#'); 17640 else if (type == VAR_FUNC) 17641 msg_putchar('*'); 17642 else if (type == VAR_LIST) 17643 { 17644 msg_putchar('['); 17645 if (*string == '[') 17646 ++string; 17647 } 17648 else if (type == VAR_DICT) 17649 { 17650 msg_putchar('{'); 17651 if (*string == '{') 17652 ++string; 17653 } 17654 else 17655 msg_putchar(' '); 17656 17657 msg_outtrans(string); 17658 17659 if (type == VAR_FUNC) 17660 msg_puts((char_u *)"()"); 17661 } 17662 17663 /* 17664 * Set variable "name" to value in "tv". 17665 * If the variable already exists, the value is updated. 17666 * Otherwise the variable is created. 17667 */ 17668 static void 17669 set_var(name, tv, copy) 17670 char_u *name; 17671 typval_T *tv; 17672 int copy; /* make copy of value in "tv" */ 17673 { 17674 dictitem_T *v; 17675 char_u *varname; 17676 hashtab_T *ht; 17677 char_u *p; 17678 17679 if (tv->v_type == VAR_FUNC) 17680 { 17681 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 17682 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 17683 ? name[2] : name[0])) 17684 { 17685 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 17686 return; 17687 } 17688 if (function_exists(name)) 17689 { 17690 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 17691 name); 17692 return; 17693 } 17694 } 17695 17696 ht = find_var_ht(name, &varname); 17697 if (ht == NULL || *varname == NUL) 17698 { 17699 EMSG2(_(e_illvar), name); 17700 return; 17701 } 17702 17703 v = find_var_in_ht(ht, varname, TRUE); 17704 if (v != NULL) 17705 { 17706 /* existing variable, need to clear the value */ 17707 if (var_check_ro(v->di_flags, name) 17708 || tv_check_lock(v->di_tv.v_lock, name)) 17709 return; 17710 if (v->di_tv.v_type != tv->v_type 17711 && !((v->di_tv.v_type == VAR_STRING 17712 || v->di_tv.v_type == VAR_NUMBER) 17713 && (tv->v_type == VAR_STRING 17714 || tv->v_type == VAR_NUMBER))) 17715 { 17716 EMSG2(_("E706: Variable type mismatch for: %s"), name); 17717 return; 17718 } 17719 17720 /* 17721 * Handle setting internal v: variables separately: we don't change 17722 * the type. 17723 */ 17724 if (ht == &vimvarht) 17725 { 17726 if (v->di_tv.v_type == VAR_STRING) 17727 { 17728 vim_free(v->di_tv.vval.v_string); 17729 if (copy || tv->v_type != VAR_STRING) 17730 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 17731 else 17732 { 17733 /* Take over the string to avoid an extra alloc/free. */ 17734 v->di_tv.vval.v_string = tv->vval.v_string; 17735 tv->vval.v_string = NULL; 17736 } 17737 } 17738 else if (v->di_tv.v_type != VAR_NUMBER) 17739 EMSG2(_(e_intern2), "set_var()"); 17740 else 17741 v->di_tv.vval.v_number = get_tv_number(tv); 17742 return; 17743 } 17744 17745 clear_tv(&v->di_tv); 17746 } 17747 else /* add a new variable */ 17748 { 17749 /* Make sure the variable name is valid. */ 17750 for (p = varname; *p != NUL; ++p) 17751 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 17752 && *p != AUTOLOAD_CHAR) 17753 { 17754 EMSG2(_(e_illvar), varname); 17755 return; 17756 } 17757 17758 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 17759 + STRLEN(varname))); 17760 if (v == NULL) 17761 return; 17762 STRCPY(v->di_key, varname); 17763 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 17764 { 17765 vim_free(v); 17766 return; 17767 } 17768 v->di_flags = 0; 17769 } 17770 17771 if (copy || tv->v_type == VAR_NUMBER) 17772 copy_tv(tv, &v->di_tv); 17773 else 17774 { 17775 v->di_tv = *tv; 17776 v->di_tv.v_lock = 0; 17777 init_tv(tv); 17778 } 17779 } 17780 17781 /* 17782 * Return TRUE if di_flags "flags" indicate read-only variable "name". 17783 * Also give an error message. 17784 */ 17785 static int 17786 var_check_ro(flags, name) 17787 int flags; 17788 char_u *name; 17789 { 17790 if (flags & DI_FLAGS_RO) 17791 { 17792 EMSG2(_(e_readonlyvar), name); 17793 return TRUE; 17794 } 17795 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 17796 { 17797 EMSG2(_(e_readonlysbx), name); 17798 return TRUE; 17799 } 17800 return FALSE; 17801 } 17802 17803 /* 17804 * Return TRUE if typeval "tv" is set to be locked (immutable). 17805 * Also give an error message, using "name". 17806 */ 17807 static int 17808 tv_check_lock(lock, name) 17809 int lock; 17810 char_u *name; 17811 { 17812 if (lock & VAR_LOCKED) 17813 { 17814 EMSG2(_("E741: Value is locked: %s"), 17815 name == NULL ? (char_u *)_("Unknown") : name); 17816 return TRUE; 17817 } 17818 if (lock & VAR_FIXED) 17819 { 17820 EMSG2(_("E742: Cannot change value of %s"), 17821 name == NULL ? (char_u *)_("Unknown") : name); 17822 return TRUE; 17823 } 17824 return FALSE; 17825 } 17826 17827 /* 17828 * Copy the values from typval_T "from" to typval_T "to". 17829 * When needed allocates string or increases reference count. 17830 * Does not make a copy of a list or dict but copies the reference! 17831 */ 17832 static void 17833 copy_tv(from, to) 17834 typval_T *from; 17835 typval_T *to; 17836 { 17837 to->v_type = from->v_type; 17838 to->v_lock = 0; 17839 switch (from->v_type) 17840 { 17841 case VAR_NUMBER: 17842 to->vval.v_number = from->vval.v_number; 17843 break; 17844 case VAR_STRING: 17845 case VAR_FUNC: 17846 if (from->vval.v_string == NULL) 17847 to->vval.v_string = NULL; 17848 else 17849 { 17850 to->vval.v_string = vim_strsave(from->vval.v_string); 17851 if (from->v_type == VAR_FUNC) 17852 func_ref(to->vval.v_string); 17853 } 17854 break; 17855 case VAR_LIST: 17856 if (from->vval.v_list == NULL) 17857 to->vval.v_list = NULL; 17858 else 17859 { 17860 to->vval.v_list = from->vval.v_list; 17861 ++to->vval.v_list->lv_refcount; 17862 } 17863 break; 17864 case VAR_DICT: 17865 if (from->vval.v_dict == NULL) 17866 to->vval.v_dict = NULL; 17867 else 17868 { 17869 to->vval.v_dict = from->vval.v_dict; 17870 ++to->vval.v_dict->dv_refcount; 17871 } 17872 break; 17873 default: 17874 EMSG2(_(e_intern2), "copy_tv()"); 17875 break; 17876 } 17877 } 17878 17879 /* 17880 * Make a copy of an item. 17881 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 17882 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 17883 * reference to an already copied list/dict can be used. 17884 * Returns FAIL or OK. 17885 */ 17886 static int 17887 item_copy(from, to, deep, copyID) 17888 typval_T *from; 17889 typval_T *to; 17890 int deep; 17891 int copyID; 17892 { 17893 static int recurse = 0; 17894 int ret = OK; 17895 17896 if (recurse >= DICT_MAXNEST) 17897 { 17898 EMSG(_("E698: variable nested too deep for making a copy")); 17899 return FAIL; 17900 } 17901 ++recurse; 17902 17903 switch (from->v_type) 17904 { 17905 case VAR_NUMBER: 17906 case VAR_STRING: 17907 case VAR_FUNC: 17908 copy_tv(from, to); 17909 break; 17910 case VAR_LIST: 17911 to->v_type = VAR_LIST; 17912 to->v_lock = 0; 17913 if (from->vval.v_list == NULL) 17914 to->vval.v_list = NULL; 17915 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 17916 { 17917 /* use the copy made earlier */ 17918 to->vval.v_list = from->vval.v_list->lv_copylist; 17919 ++to->vval.v_list->lv_refcount; 17920 } 17921 else 17922 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 17923 if (to->vval.v_list == NULL) 17924 ret = FAIL; 17925 break; 17926 case VAR_DICT: 17927 to->v_type = VAR_DICT; 17928 to->v_lock = 0; 17929 if (from->vval.v_dict == NULL) 17930 to->vval.v_dict = NULL; 17931 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 17932 { 17933 /* use the copy made earlier */ 17934 to->vval.v_dict = from->vval.v_dict->dv_copydict; 17935 ++to->vval.v_dict->dv_refcount; 17936 } 17937 else 17938 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 17939 if (to->vval.v_dict == NULL) 17940 ret = FAIL; 17941 break; 17942 default: 17943 EMSG2(_(e_intern2), "item_copy()"); 17944 ret = FAIL; 17945 } 17946 --recurse; 17947 return ret; 17948 } 17949 17950 /* 17951 * ":echo expr1 ..." print each argument separated with a space, add a 17952 * newline at the end. 17953 * ":echon expr1 ..." print each argument plain. 17954 */ 17955 void 17956 ex_echo(eap) 17957 exarg_T *eap; 17958 { 17959 char_u *arg = eap->arg; 17960 typval_T rettv; 17961 char_u *tofree; 17962 char_u *p; 17963 int needclr = TRUE; 17964 int atstart = TRUE; 17965 char_u numbuf[NUMBUFLEN]; 17966 17967 if (eap->skip) 17968 ++emsg_skip; 17969 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 17970 { 17971 p = arg; 17972 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 17973 { 17974 /* 17975 * Report the invalid expression unless the expression evaluation 17976 * has been cancelled due to an aborting error, an interrupt, or an 17977 * exception. 17978 */ 17979 if (!aborting()) 17980 EMSG2(_(e_invexpr2), p); 17981 break; 17982 } 17983 if (!eap->skip) 17984 { 17985 if (atstart) 17986 { 17987 atstart = FALSE; 17988 /* Call msg_start() after eval1(), evaluating the expression 17989 * may cause a message to appear. */ 17990 if (eap->cmdidx == CMD_echo) 17991 msg_start(); 17992 } 17993 else if (eap->cmdidx == CMD_echo) 17994 msg_puts_attr((char_u *)" ", echo_attr); 17995 p = echo_string(&rettv, &tofree, numbuf, ++current_copyID); 17996 if (p != NULL) 17997 for ( ; *p != NUL && !got_int; ++p) 17998 { 17999 if (*p == '\n' || *p == '\r' || *p == TAB) 18000 { 18001 if (*p != TAB && needclr) 18002 { 18003 /* remove any text still there from the command */ 18004 msg_clr_eos(); 18005 needclr = FALSE; 18006 } 18007 msg_putchar_attr(*p, echo_attr); 18008 } 18009 else 18010 { 18011 #ifdef FEAT_MBYTE 18012 if (has_mbyte) 18013 { 18014 int i = (*mb_ptr2len)(p); 18015 18016 (void)msg_outtrans_len_attr(p, i, echo_attr); 18017 p += i - 1; 18018 } 18019 else 18020 #endif 18021 (void)msg_outtrans_len_attr(p, 1, echo_attr); 18022 } 18023 } 18024 vim_free(tofree); 18025 } 18026 clear_tv(&rettv); 18027 arg = skipwhite(arg); 18028 } 18029 eap->nextcmd = check_nextcmd(arg); 18030 18031 if (eap->skip) 18032 --emsg_skip; 18033 else 18034 { 18035 /* remove text that may still be there from the command */ 18036 if (needclr) 18037 msg_clr_eos(); 18038 if (eap->cmdidx == CMD_echo) 18039 msg_end(); 18040 } 18041 } 18042 18043 /* 18044 * ":echohl {name}". 18045 */ 18046 void 18047 ex_echohl(eap) 18048 exarg_T *eap; 18049 { 18050 int id; 18051 18052 id = syn_name2id(eap->arg); 18053 if (id == 0) 18054 echo_attr = 0; 18055 else 18056 echo_attr = syn_id2attr(id); 18057 } 18058 18059 /* 18060 * ":execute expr1 ..." execute the result of an expression. 18061 * ":echomsg expr1 ..." Print a message 18062 * ":echoerr expr1 ..." Print an error 18063 * Each gets spaces around each argument and a newline at the end for 18064 * echo commands 18065 */ 18066 void 18067 ex_execute(eap) 18068 exarg_T *eap; 18069 { 18070 char_u *arg = eap->arg; 18071 typval_T rettv; 18072 int ret = OK; 18073 char_u *p; 18074 garray_T ga; 18075 int len; 18076 int save_did_emsg; 18077 18078 ga_init2(&ga, 1, 80); 18079 18080 if (eap->skip) 18081 ++emsg_skip; 18082 while (*arg != NUL && *arg != '|' && *arg != '\n') 18083 { 18084 p = arg; 18085 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 18086 { 18087 /* 18088 * Report the invalid expression unless the expression evaluation 18089 * has been cancelled due to an aborting error, an interrupt, or an 18090 * exception. 18091 */ 18092 if (!aborting()) 18093 EMSG2(_(e_invexpr2), p); 18094 ret = FAIL; 18095 break; 18096 } 18097 18098 if (!eap->skip) 18099 { 18100 p = get_tv_string(&rettv); 18101 len = (int)STRLEN(p); 18102 if (ga_grow(&ga, len + 2) == FAIL) 18103 { 18104 clear_tv(&rettv); 18105 ret = FAIL; 18106 break; 18107 } 18108 if (ga.ga_len) 18109 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 18110 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 18111 ga.ga_len += len; 18112 } 18113 18114 clear_tv(&rettv); 18115 arg = skipwhite(arg); 18116 } 18117 18118 if (ret != FAIL && ga.ga_data != NULL) 18119 { 18120 if (eap->cmdidx == CMD_echomsg) 18121 { 18122 MSG_ATTR(ga.ga_data, echo_attr); 18123 out_flush(); 18124 } 18125 else if (eap->cmdidx == CMD_echoerr) 18126 { 18127 /* We don't want to abort following commands, restore did_emsg. */ 18128 save_did_emsg = did_emsg; 18129 EMSG((char_u *)ga.ga_data); 18130 if (!force_abort) 18131 did_emsg = save_did_emsg; 18132 } 18133 else if (eap->cmdidx == CMD_execute) 18134 do_cmdline((char_u *)ga.ga_data, 18135 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 18136 } 18137 18138 ga_clear(&ga); 18139 18140 if (eap->skip) 18141 --emsg_skip; 18142 18143 eap->nextcmd = check_nextcmd(arg); 18144 } 18145 18146 /* 18147 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 18148 * "arg" points to the "&" or '+' when called, to "option" when returning. 18149 * Returns NULL when no option name found. Otherwise pointer to the char 18150 * after the option name. 18151 */ 18152 static char_u * 18153 find_option_end(arg, opt_flags) 18154 char_u **arg; 18155 int *opt_flags; 18156 { 18157 char_u *p = *arg; 18158 18159 ++p; 18160 if (*p == 'g' && p[1] == ':') 18161 { 18162 *opt_flags = OPT_GLOBAL; 18163 p += 2; 18164 } 18165 else if (*p == 'l' && p[1] == ':') 18166 { 18167 *opt_flags = OPT_LOCAL; 18168 p += 2; 18169 } 18170 else 18171 *opt_flags = 0; 18172 18173 if (!ASCII_ISALPHA(*p)) 18174 return NULL; 18175 *arg = p; 18176 18177 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 18178 p += 4; /* termcap option */ 18179 else 18180 while (ASCII_ISALPHA(*p)) 18181 ++p; 18182 return p; 18183 } 18184 18185 /* 18186 * ":function" 18187 */ 18188 void 18189 ex_function(eap) 18190 exarg_T *eap; 18191 { 18192 char_u *theline; 18193 int j; 18194 int c; 18195 int saved_did_emsg; 18196 char_u *name = NULL; 18197 char_u *p; 18198 char_u *arg; 18199 char_u *line_arg = NULL; 18200 garray_T newargs; 18201 garray_T newlines; 18202 int varargs = FALSE; 18203 int mustend = FALSE; 18204 int flags = 0; 18205 ufunc_T *fp; 18206 int indent; 18207 int nesting; 18208 char_u *skip_until = NULL; 18209 dictitem_T *v; 18210 funcdict_T fudi; 18211 static int func_nr = 0; /* number for nameless function */ 18212 int paren; 18213 hashtab_T *ht; 18214 int todo; 18215 hashitem_T *hi; 18216 int sourcing_lnum_off; 18217 18218 /* 18219 * ":function" without argument: list functions. 18220 */ 18221 if (ends_excmd(*eap->arg)) 18222 { 18223 if (!eap->skip) 18224 { 18225 todo = (int)func_hashtab.ht_used; 18226 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18227 { 18228 if (!HASHITEM_EMPTY(hi)) 18229 { 18230 --todo; 18231 fp = HI2UF(hi); 18232 if (!isdigit(*fp->uf_name)) 18233 list_func_head(fp, FALSE); 18234 } 18235 } 18236 } 18237 eap->nextcmd = check_nextcmd(eap->arg); 18238 return; 18239 } 18240 18241 /* 18242 * ":function /pat": list functions matching pattern. 18243 */ 18244 if (*eap->arg == '/') 18245 { 18246 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 18247 if (!eap->skip) 18248 { 18249 regmatch_T regmatch; 18250 18251 c = *p; 18252 *p = NUL; 18253 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 18254 *p = c; 18255 if (regmatch.regprog != NULL) 18256 { 18257 regmatch.rm_ic = p_ic; 18258 18259 todo = (int)func_hashtab.ht_used; 18260 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18261 { 18262 if (!HASHITEM_EMPTY(hi)) 18263 { 18264 --todo; 18265 fp = HI2UF(hi); 18266 if (!isdigit(*fp->uf_name) 18267 && vim_regexec(®match, fp->uf_name, 0)) 18268 list_func_head(fp, FALSE); 18269 } 18270 } 18271 } 18272 } 18273 if (*p == '/') 18274 ++p; 18275 eap->nextcmd = check_nextcmd(p); 18276 return; 18277 } 18278 18279 /* 18280 * Get the function name. There are these situations: 18281 * func normal function name 18282 * "name" == func, "fudi.fd_dict" == NULL 18283 * dict.func new dictionary entry 18284 * "name" == NULL, "fudi.fd_dict" set, 18285 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 18286 * dict.func existing dict entry with a Funcref 18287 * "name" == func, "fudi.fd_dict" set, 18288 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18289 * dict.func existing dict entry that's not a Funcref 18290 * "name" == NULL, "fudi.fd_dict" set, 18291 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18292 */ 18293 p = eap->arg; 18294 name = trans_function_name(&p, eap->skip, 0, &fudi); 18295 paren = (vim_strchr(p, '(') != NULL); 18296 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 18297 { 18298 /* 18299 * Return on an invalid expression in braces, unless the expression 18300 * evaluation has been cancelled due to an aborting error, an 18301 * interrupt, or an exception. 18302 */ 18303 if (!aborting()) 18304 { 18305 if (!eap->skip && fudi.fd_newkey != NULL) 18306 EMSG2(_(e_dictkey), fudi.fd_newkey); 18307 vim_free(fudi.fd_newkey); 18308 return; 18309 } 18310 else 18311 eap->skip = TRUE; 18312 } 18313 18314 /* An error in a function call during evaluation of an expression in magic 18315 * braces should not cause the function not to be defined. */ 18316 saved_did_emsg = did_emsg; 18317 did_emsg = FALSE; 18318 18319 /* 18320 * ":function func" with only function name: list function. 18321 */ 18322 if (!paren) 18323 { 18324 if (!ends_excmd(*skipwhite(p))) 18325 { 18326 EMSG(_(e_trailing)); 18327 goto ret_free; 18328 } 18329 eap->nextcmd = check_nextcmd(p); 18330 if (eap->nextcmd != NULL) 18331 *p = NUL; 18332 if (!eap->skip && !got_int) 18333 { 18334 fp = find_func(name); 18335 if (fp != NULL) 18336 { 18337 list_func_head(fp, TRUE); 18338 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 18339 { 18340 if (FUNCLINE(fp, j) == NULL) 18341 continue; 18342 msg_putchar('\n'); 18343 msg_outnum((long)(j + 1)); 18344 if (j < 9) 18345 msg_putchar(' '); 18346 if (j < 99) 18347 msg_putchar(' '); 18348 msg_prt_line(FUNCLINE(fp, j), FALSE); 18349 out_flush(); /* show a line at a time */ 18350 ui_breakcheck(); 18351 } 18352 if (!got_int) 18353 { 18354 msg_putchar('\n'); 18355 msg_puts((char_u *)" endfunction"); 18356 } 18357 } 18358 else 18359 emsg_funcname("E123: Undefined function: %s", name); 18360 } 18361 goto ret_free; 18362 } 18363 18364 /* 18365 * ":function name(arg1, arg2)" Define function. 18366 */ 18367 p = skipwhite(p); 18368 if (*p != '(') 18369 { 18370 if (!eap->skip) 18371 { 18372 EMSG2(_("E124: Missing '(': %s"), eap->arg); 18373 goto ret_free; 18374 } 18375 /* attempt to continue by skipping some text */ 18376 if (vim_strchr(p, '(') != NULL) 18377 p = vim_strchr(p, '('); 18378 } 18379 p = skipwhite(p + 1); 18380 18381 ga_init2(&newargs, (int)sizeof(char_u *), 3); 18382 ga_init2(&newlines, (int)sizeof(char_u *), 3); 18383 18384 if (!eap->skip) 18385 { 18386 /* Check the name of the function. */ 18387 if (name != NULL) 18388 arg = name; 18389 else 18390 arg = fudi.fd_newkey; 18391 if (arg != NULL) 18392 { 18393 if (*arg == K_SPECIAL) 18394 j = 3; 18395 else 18396 j = 0; 18397 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 18398 : eval_isnamec(arg[j]))) 18399 ++j; 18400 if (arg[j] != NUL) 18401 emsg_funcname(_(e_invarg2), arg); 18402 } 18403 } 18404 18405 /* 18406 * Isolate the arguments: "arg1, arg2, ...)" 18407 */ 18408 while (*p != ')') 18409 { 18410 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 18411 { 18412 varargs = TRUE; 18413 p += 3; 18414 mustend = TRUE; 18415 } 18416 else 18417 { 18418 arg = p; 18419 while (ASCII_ISALNUM(*p) || *p == '_') 18420 ++p; 18421 if (arg == p || isdigit(*arg) 18422 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 18423 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 18424 { 18425 if (!eap->skip) 18426 EMSG2(_("E125: Illegal argument: %s"), arg); 18427 break; 18428 } 18429 if (ga_grow(&newargs, 1) == FAIL) 18430 goto erret; 18431 c = *p; 18432 *p = NUL; 18433 arg = vim_strsave(arg); 18434 if (arg == NULL) 18435 goto erret; 18436 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 18437 *p = c; 18438 newargs.ga_len++; 18439 if (*p == ',') 18440 ++p; 18441 else 18442 mustend = TRUE; 18443 } 18444 p = skipwhite(p); 18445 if (mustend && *p != ')') 18446 { 18447 if (!eap->skip) 18448 EMSG2(_(e_invarg2), eap->arg); 18449 break; 18450 } 18451 } 18452 ++p; /* skip the ')' */ 18453 18454 /* find extra arguments "range", "dict" and "abort" */ 18455 for (;;) 18456 { 18457 p = skipwhite(p); 18458 if (STRNCMP(p, "range", 5) == 0) 18459 { 18460 flags |= FC_RANGE; 18461 p += 5; 18462 } 18463 else if (STRNCMP(p, "dict", 4) == 0) 18464 { 18465 flags |= FC_DICT; 18466 p += 4; 18467 } 18468 else if (STRNCMP(p, "abort", 5) == 0) 18469 { 18470 flags |= FC_ABORT; 18471 p += 5; 18472 } 18473 else 18474 break; 18475 } 18476 18477 /* When there is a line break use what follows for the function body. 18478 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 18479 if (*p == '\n') 18480 line_arg = p + 1; 18481 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 18482 EMSG(_(e_trailing)); 18483 18484 /* 18485 * Read the body of the function, until ":endfunction" is found. 18486 */ 18487 if (KeyTyped) 18488 { 18489 /* Check if the function already exists, don't let the user type the 18490 * whole function before telling him it doesn't work! For a script we 18491 * need to skip the body to be able to find what follows. */ 18492 if (!eap->skip && !eap->forceit) 18493 { 18494 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 18495 EMSG(_(e_funcdict)); 18496 else if (name != NULL && find_func(name) != NULL) 18497 emsg_funcname(e_funcexts, name); 18498 } 18499 18500 if (!eap->skip && did_emsg) 18501 goto erret; 18502 18503 msg_putchar('\n'); /* don't overwrite the function name */ 18504 cmdline_row = msg_row; 18505 } 18506 18507 indent = 2; 18508 nesting = 0; 18509 for (;;) 18510 { 18511 msg_scroll = TRUE; 18512 need_wait_return = FALSE; 18513 sourcing_lnum_off = sourcing_lnum; 18514 18515 if (line_arg != NULL) 18516 { 18517 /* Use eap->arg, split up in parts by line breaks. */ 18518 theline = line_arg; 18519 p = vim_strchr(theline, '\n'); 18520 if (p == NULL) 18521 line_arg += STRLEN(line_arg); 18522 else 18523 { 18524 *p = NUL; 18525 line_arg = p + 1; 18526 } 18527 } 18528 else if (eap->getline == NULL) 18529 theline = getcmdline(':', 0L, indent); 18530 else 18531 theline = eap->getline(':', eap->cookie, indent); 18532 if (KeyTyped) 18533 lines_left = Rows - 1; 18534 if (theline == NULL) 18535 { 18536 EMSG(_("E126: Missing :endfunction")); 18537 goto erret; 18538 } 18539 18540 /* Detect line continuation: sourcing_lnum increased more than one. */ 18541 if (sourcing_lnum > sourcing_lnum_off + 1) 18542 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 18543 else 18544 sourcing_lnum_off = 0; 18545 18546 if (skip_until != NULL) 18547 { 18548 /* between ":append" and "." and between ":python <<EOF" and "EOF" 18549 * don't check for ":endfunc". */ 18550 if (STRCMP(theline, skip_until) == 0) 18551 { 18552 vim_free(skip_until); 18553 skip_until = NULL; 18554 } 18555 } 18556 else 18557 { 18558 /* skip ':' and blanks*/ 18559 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 18560 ; 18561 18562 /* Check for "endfunction". */ 18563 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 18564 { 18565 if (line_arg == NULL) 18566 vim_free(theline); 18567 break; 18568 } 18569 18570 /* Increase indent inside "if", "while", "for" and "try", decrease 18571 * at "end". */ 18572 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 18573 indent -= 2; 18574 else if (STRNCMP(p, "if", 2) == 0 18575 || STRNCMP(p, "wh", 2) == 0 18576 || STRNCMP(p, "for", 3) == 0 18577 || STRNCMP(p, "try", 3) == 0) 18578 indent += 2; 18579 18580 /* Check for defining a function inside this function. */ 18581 if (checkforcmd(&p, "function", 2)) 18582 { 18583 if (*p == '!') 18584 p = skipwhite(p + 1); 18585 p += eval_fname_script(p); 18586 if (ASCII_ISALPHA(*p)) 18587 { 18588 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 18589 if (*skipwhite(p) == '(') 18590 { 18591 ++nesting; 18592 indent += 2; 18593 } 18594 } 18595 } 18596 18597 /* Check for ":append" or ":insert". */ 18598 p = skip_range(p, NULL); 18599 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 18600 || (p[0] == 'i' 18601 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 18602 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 18603 skip_until = vim_strsave((char_u *)"."); 18604 18605 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 18606 arg = skipwhite(skiptowhite(p)); 18607 if (arg[0] == '<' && arg[1] =='<' 18608 && ((p[0] == 'p' && p[1] == 'y' 18609 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 18610 || (p[0] == 'p' && p[1] == 'e' 18611 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 18612 || (p[0] == 't' && p[1] == 'c' 18613 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 18614 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 18615 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 18616 || (p[0] == 'm' && p[1] == 'z' 18617 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 18618 )) 18619 { 18620 /* ":python <<" continues until a dot, like ":append" */ 18621 p = skipwhite(arg + 2); 18622 if (*p == NUL) 18623 skip_until = vim_strsave((char_u *)"."); 18624 else 18625 skip_until = vim_strsave(p); 18626 } 18627 } 18628 18629 /* Add the line to the function. */ 18630 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 18631 { 18632 if (line_arg == NULL) 18633 vim_free(theline); 18634 goto erret; 18635 } 18636 18637 /* Copy the line to newly allocated memory. get_one_sourceline() 18638 * allocates 250 bytes per line, this saves 80% on average. The cost 18639 * is an extra alloc/free. */ 18640 p = vim_strsave(theline); 18641 if (p != NULL) 18642 { 18643 if (line_arg == NULL) 18644 vim_free(theline); 18645 theline = p; 18646 } 18647 18648 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 18649 18650 /* Add NULL lines for continuation lines, so that the line count is 18651 * equal to the index in the growarray. */ 18652 while (sourcing_lnum_off-- > 0) 18653 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 18654 18655 /* Check for end of eap->arg. */ 18656 if (line_arg != NULL && *line_arg == NUL) 18657 line_arg = NULL; 18658 } 18659 18660 /* Don't define the function when skipping commands or when an error was 18661 * detected. */ 18662 if (eap->skip || did_emsg) 18663 goto erret; 18664 18665 /* 18666 * If there are no errors, add the function 18667 */ 18668 if (fudi.fd_dict == NULL) 18669 { 18670 v = find_var(name, &ht); 18671 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 18672 { 18673 emsg_funcname("E707: Function name conflicts with variable: %s", 18674 name); 18675 goto erret; 18676 } 18677 18678 fp = find_func(name); 18679 if (fp != NULL) 18680 { 18681 if (!eap->forceit) 18682 { 18683 emsg_funcname(e_funcexts, name); 18684 goto erret; 18685 } 18686 if (fp->uf_calls > 0) 18687 { 18688 emsg_funcname("E127: Cannot redefine function %s: It is in use", 18689 name); 18690 goto erret; 18691 } 18692 /* redefine existing function */ 18693 ga_clear_strings(&(fp->uf_args)); 18694 ga_clear_strings(&(fp->uf_lines)); 18695 vim_free(name); 18696 name = NULL; 18697 } 18698 } 18699 else 18700 { 18701 char numbuf[20]; 18702 18703 fp = NULL; 18704 if (fudi.fd_newkey == NULL && !eap->forceit) 18705 { 18706 EMSG(_(e_funcdict)); 18707 goto erret; 18708 } 18709 if (fudi.fd_di == NULL) 18710 { 18711 /* Can't add a function to a locked dictionary */ 18712 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 18713 goto erret; 18714 } 18715 /* Can't change an existing function if it is locked */ 18716 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 18717 goto erret; 18718 18719 /* Give the function a sequential number. Can only be used with a 18720 * Funcref! */ 18721 vim_free(name); 18722 sprintf(numbuf, "%d", ++func_nr); 18723 name = vim_strsave((char_u *)numbuf); 18724 if (name == NULL) 18725 goto erret; 18726 } 18727 18728 if (fp == NULL) 18729 { 18730 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 18731 { 18732 int slen, plen; 18733 char_u *scriptname; 18734 18735 /* Check that the autoload name matches the script name. */ 18736 j = FAIL; 18737 if (sourcing_name != NULL) 18738 { 18739 scriptname = autoload_name(name); 18740 if (scriptname != NULL) 18741 { 18742 p = vim_strchr(scriptname, '/'); 18743 plen = (int)STRLEN(p); 18744 slen = (int)STRLEN(sourcing_name); 18745 if (slen > plen && fnamecmp(p, 18746 sourcing_name + slen - plen) == 0) 18747 j = OK; 18748 vim_free(scriptname); 18749 } 18750 } 18751 if (j == FAIL) 18752 { 18753 EMSG2(_("E746: Function name does not match script file name: %s"), name); 18754 goto erret; 18755 } 18756 } 18757 18758 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 18759 if (fp == NULL) 18760 goto erret; 18761 18762 if (fudi.fd_dict != NULL) 18763 { 18764 if (fudi.fd_di == NULL) 18765 { 18766 /* add new dict entry */ 18767 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 18768 if (fudi.fd_di == NULL) 18769 { 18770 vim_free(fp); 18771 goto erret; 18772 } 18773 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 18774 { 18775 vim_free(fudi.fd_di); 18776 goto erret; 18777 } 18778 } 18779 else 18780 /* overwrite existing dict entry */ 18781 clear_tv(&fudi.fd_di->di_tv); 18782 fudi.fd_di->di_tv.v_type = VAR_FUNC; 18783 fudi.fd_di->di_tv.v_lock = 0; 18784 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 18785 fp->uf_refcount = 1; 18786 18787 /* behave like "dict" was used */ 18788 flags |= FC_DICT; 18789 } 18790 18791 /* insert the new function in the function list */ 18792 STRCPY(fp->uf_name, name); 18793 hash_add(&func_hashtab, UF2HIKEY(fp)); 18794 } 18795 fp->uf_args = newargs; 18796 fp->uf_lines = newlines; 18797 #ifdef FEAT_PROFILE 18798 fp->uf_tml_count = NULL; 18799 fp->uf_tml_total = NULL; 18800 fp->uf_tml_self = NULL; 18801 fp->uf_profiling = FALSE; 18802 if (prof_def_func()) 18803 func_do_profile(fp); 18804 #endif 18805 fp->uf_varargs = varargs; 18806 fp->uf_flags = flags; 18807 fp->uf_calls = 0; 18808 fp->uf_script_ID = current_SID; 18809 goto ret_free; 18810 18811 erret: 18812 ga_clear_strings(&newargs); 18813 ga_clear_strings(&newlines); 18814 ret_free: 18815 vim_free(skip_until); 18816 vim_free(fudi.fd_newkey); 18817 vim_free(name); 18818 did_emsg |= saved_did_emsg; 18819 } 18820 18821 /* 18822 * Get a function name, translating "<SID>" and "<SNR>". 18823 * Also handles a Funcref in a List or Dictionary. 18824 * Returns the function name in allocated memory, or NULL for failure. 18825 * flags: 18826 * TFN_INT: internal function name OK 18827 * TFN_QUIET: be quiet 18828 * Advances "pp" to just after the function name (if no error). 18829 */ 18830 static char_u * 18831 trans_function_name(pp, skip, flags, fdp) 18832 char_u **pp; 18833 int skip; /* only find the end, don't evaluate */ 18834 int flags; 18835 funcdict_T *fdp; /* return: info about dictionary used */ 18836 { 18837 char_u *name = NULL; 18838 char_u *start; 18839 char_u *end; 18840 int lead; 18841 char_u sid_buf[20]; 18842 int len; 18843 lval_T lv; 18844 18845 if (fdp != NULL) 18846 vim_memset(fdp, 0, sizeof(funcdict_T)); 18847 start = *pp; 18848 18849 /* Check for hard coded <SNR>: already translated function ID (from a user 18850 * command). */ 18851 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 18852 && (*pp)[2] == (int)KE_SNR) 18853 { 18854 *pp += 3; 18855 len = get_id_len(pp) + 3; 18856 return vim_strnsave(start, len); 18857 } 18858 18859 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 18860 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 18861 lead = eval_fname_script(start); 18862 if (lead > 2) 18863 start += lead; 18864 18865 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 18866 lead > 2 ? 0 : FNE_CHECK_START); 18867 if (end == start) 18868 { 18869 if (!skip) 18870 EMSG(_("E129: Function name required")); 18871 goto theend; 18872 } 18873 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 18874 { 18875 /* 18876 * Report an invalid expression in braces, unless the expression 18877 * evaluation has been cancelled due to an aborting error, an 18878 * interrupt, or an exception. 18879 */ 18880 if (!aborting()) 18881 { 18882 if (end != NULL) 18883 EMSG2(_(e_invarg2), start); 18884 } 18885 else 18886 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 18887 goto theend; 18888 } 18889 18890 if (lv.ll_tv != NULL) 18891 { 18892 if (fdp != NULL) 18893 { 18894 fdp->fd_dict = lv.ll_dict; 18895 fdp->fd_newkey = lv.ll_newkey; 18896 lv.ll_newkey = NULL; 18897 fdp->fd_di = lv.ll_di; 18898 } 18899 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 18900 { 18901 name = vim_strsave(lv.ll_tv->vval.v_string); 18902 *pp = end; 18903 } 18904 else 18905 { 18906 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 18907 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 18908 EMSG(_(e_funcref)); 18909 else 18910 *pp = end; 18911 name = NULL; 18912 } 18913 goto theend; 18914 } 18915 18916 if (lv.ll_name == NULL) 18917 { 18918 /* Error found, but continue after the function name. */ 18919 *pp = end; 18920 goto theend; 18921 } 18922 18923 if (lv.ll_exp_name != NULL) 18924 { 18925 len = (int)STRLEN(lv.ll_exp_name); 18926 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 18927 && STRNCMP(lv.ll_name, "s:", 2) == 0) 18928 { 18929 /* When there was "s:" already or the name expanded to get a 18930 * leading "s:" then remove it. */ 18931 lv.ll_name += 2; 18932 len -= 2; 18933 lead = 2; 18934 } 18935 } 18936 else 18937 { 18938 if (lead == 2) /* skip over "s:" */ 18939 lv.ll_name += 2; 18940 len = (int)(end - lv.ll_name); 18941 } 18942 18943 /* 18944 * Copy the function name to allocated memory. 18945 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 18946 * Accept <SNR>123_name() outside a script. 18947 */ 18948 if (skip) 18949 lead = 0; /* do nothing */ 18950 else if (lead > 0) 18951 { 18952 lead = 3; 18953 if (eval_fname_sid(lv.ll_exp_name != NULL ? lv.ll_exp_name : *pp)) 18954 { 18955 /* It's "s:" or "<SID>" */ 18956 if (current_SID <= 0) 18957 { 18958 EMSG(_(e_usingsid)); 18959 goto theend; 18960 } 18961 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 18962 lead += (int)STRLEN(sid_buf); 18963 } 18964 } 18965 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 18966 { 18967 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 18968 goto theend; 18969 } 18970 name = alloc((unsigned)(len + lead + 1)); 18971 if (name != NULL) 18972 { 18973 if (lead > 0) 18974 { 18975 name[0] = K_SPECIAL; 18976 name[1] = KS_EXTRA; 18977 name[2] = (int)KE_SNR; 18978 if (lead > 3) /* If it's "<SID>" */ 18979 STRCPY(name + 3, sid_buf); 18980 } 18981 mch_memmove(name + lead, lv.ll_name, (size_t)len); 18982 name[len + lead] = NUL; 18983 } 18984 *pp = end; 18985 18986 theend: 18987 clear_lval(&lv); 18988 return name; 18989 } 18990 18991 /* 18992 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 18993 * Return 2 if "p" starts with "s:". 18994 * Return 0 otherwise. 18995 */ 18996 static int 18997 eval_fname_script(p) 18998 char_u *p; 18999 { 19000 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 19001 || STRNICMP(p + 1, "SNR>", 4) == 0)) 19002 return 5; 19003 if (p[0] == 's' && p[1] == ':') 19004 return 2; 19005 return 0; 19006 } 19007 19008 /* 19009 * Return TRUE if "p" starts with "<SID>" or "s:". 19010 * Only works if eval_fname_script() returned non-zero for "p"! 19011 */ 19012 static int 19013 eval_fname_sid(p) 19014 char_u *p; 19015 { 19016 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 19017 } 19018 19019 /* 19020 * List the head of the function: "name(arg1, arg2)". 19021 */ 19022 static void 19023 list_func_head(fp, indent) 19024 ufunc_T *fp; 19025 int indent; 19026 { 19027 int j; 19028 19029 msg_start(); 19030 if (indent) 19031 MSG_PUTS(" "); 19032 MSG_PUTS("function "); 19033 if (fp->uf_name[0] == K_SPECIAL) 19034 { 19035 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 19036 msg_puts(fp->uf_name + 3); 19037 } 19038 else 19039 msg_puts(fp->uf_name); 19040 msg_putchar('('); 19041 for (j = 0; j < fp->uf_args.ga_len; ++j) 19042 { 19043 if (j) 19044 MSG_PUTS(", "); 19045 msg_puts(FUNCARG(fp, j)); 19046 } 19047 if (fp->uf_varargs) 19048 { 19049 if (j) 19050 MSG_PUTS(", "); 19051 MSG_PUTS("..."); 19052 } 19053 msg_putchar(')'); 19054 msg_clr_eos(); 19055 if (p_verbose > 0) 19056 last_set_msg(fp->uf_script_ID); 19057 } 19058 19059 /* 19060 * Find a function by name, return pointer to it in ufuncs. 19061 * Return NULL for unknown function. 19062 */ 19063 static ufunc_T * 19064 find_func(name) 19065 char_u *name; 19066 { 19067 hashitem_T *hi; 19068 19069 hi = hash_find(&func_hashtab, name); 19070 if (!HASHITEM_EMPTY(hi)) 19071 return HI2UF(hi); 19072 return NULL; 19073 } 19074 19075 #if defined(EXITFREE) || defined(PROTO) 19076 void 19077 free_all_functions() 19078 { 19079 hashitem_T *hi; 19080 19081 /* Need to start all over every time, because func_free() may change the 19082 * hash table. */ 19083 while (func_hashtab.ht_used > 0) 19084 for (hi = func_hashtab.ht_array; ; ++hi) 19085 if (!HASHITEM_EMPTY(hi)) 19086 { 19087 func_free(HI2UF(hi)); 19088 break; 19089 } 19090 } 19091 #endif 19092 19093 /* 19094 * Return TRUE if a function "name" exists. 19095 */ 19096 static int 19097 function_exists(name) 19098 char_u *name; 19099 { 19100 char_u *p = name; 19101 int n = FALSE; 19102 19103 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 19104 if (p != NULL) 19105 { 19106 if (builtin_function(p)) 19107 n = (find_internal_func(p) >= 0); 19108 else 19109 n = (find_func(p) != NULL); 19110 vim_free(p); 19111 } 19112 return n; 19113 } 19114 19115 /* 19116 * Return TRUE if "name" looks like a builtin function name: starts with a 19117 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 19118 */ 19119 static int 19120 builtin_function(name) 19121 char_u *name; 19122 { 19123 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 19124 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 19125 } 19126 19127 #if defined(FEAT_PROFILE) || defined(PROTO) 19128 /* 19129 * Start profiling function "fp". 19130 */ 19131 static void 19132 func_do_profile(fp) 19133 ufunc_T *fp; 19134 { 19135 fp->uf_tm_count = 0; 19136 profile_zero(&fp->uf_tm_self); 19137 profile_zero(&fp->uf_tm_total); 19138 if (fp->uf_tml_count == NULL) 19139 fp->uf_tml_count = (int *)alloc_clear((unsigned) 19140 (sizeof(int) * fp->uf_lines.ga_len)); 19141 if (fp->uf_tml_total == NULL) 19142 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 19143 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19144 if (fp->uf_tml_self == NULL) 19145 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 19146 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19147 fp->uf_tml_idx = -1; 19148 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 19149 || fp->uf_tml_self == NULL) 19150 return; /* out of memory */ 19151 19152 fp->uf_profiling = TRUE; 19153 } 19154 19155 /* 19156 * Dump the profiling results for all functions in file "fd". 19157 */ 19158 void 19159 func_dump_profile(fd) 19160 FILE *fd; 19161 { 19162 hashitem_T *hi; 19163 int todo; 19164 ufunc_T *fp; 19165 int i; 19166 ufunc_T **sorttab; 19167 int st_len = 0; 19168 19169 todo = (int)func_hashtab.ht_used; 19170 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 19171 19172 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 19173 { 19174 if (!HASHITEM_EMPTY(hi)) 19175 { 19176 --todo; 19177 fp = HI2UF(hi); 19178 if (fp->uf_profiling) 19179 { 19180 if (sorttab != NULL) 19181 sorttab[st_len++] = fp; 19182 19183 if (fp->uf_name[0] == K_SPECIAL) 19184 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 19185 else 19186 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 19187 if (fp->uf_tm_count == 1) 19188 fprintf(fd, "Called 1 time\n"); 19189 else 19190 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 19191 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 19192 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 19193 fprintf(fd, "\n"); 19194 fprintf(fd, "count total (s) self (s)\n"); 19195 19196 for (i = 0; i < fp->uf_lines.ga_len; ++i) 19197 { 19198 if (FUNCLINE(fp, i) == NULL) 19199 continue; 19200 prof_func_line(fd, fp->uf_tml_count[i], 19201 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 19202 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 19203 } 19204 fprintf(fd, "\n"); 19205 } 19206 } 19207 } 19208 19209 if (sorttab != NULL && st_len > 0) 19210 { 19211 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19212 prof_total_cmp); 19213 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 19214 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19215 prof_self_cmp); 19216 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 19217 } 19218 } 19219 19220 static void 19221 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 19222 FILE *fd; 19223 ufunc_T **sorttab; 19224 int st_len; 19225 char *title; 19226 int prefer_self; /* when equal print only self time */ 19227 { 19228 int i; 19229 ufunc_T *fp; 19230 19231 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 19232 fprintf(fd, "count total (s) self (s) function\n"); 19233 for (i = 0; i < 20 && i < st_len; ++i) 19234 { 19235 fp = sorttab[i]; 19236 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 19237 prefer_self); 19238 if (fp->uf_name[0] == K_SPECIAL) 19239 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 19240 else 19241 fprintf(fd, " %s()\n", fp->uf_name); 19242 } 19243 fprintf(fd, "\n"); 19244 } 19245 19246 /* 19247 * Print the count and times for one function or function line. 19248 */ 19249 static void 19250 prof_func_line(fd, count, total, self, prefer_self) 19251 FILE *fd; 19252 int count; 19253 proftime_T *total; 19254 proftime_T *self; 19255 int prefer_self; /* when equal print only self time */ 19256 { 19257 if (count > 0) 19258 { 19259 fprintf(fd, "%5d ", count); 19260 if (prefer_self && profile_equal(total, self)) 19261 fprintf(fd, " "); 19262 else 19263 fprintf(fd, "%s ", profile_msg(total)); 19264 if (!prefer_self && profile_equal(total, self)) 19265 fprintf(fd, " "); 19266 else 19267 fprintf(fd, "%s ", profile_msg(self)); 19268 } 19269 else 19270 fprintf(fd, " "); 19271 } 19272 19273 /* 19274 * Compare function for total time sorting. 19275 */ 19276 static int 19277 #ifdef __BORLANDC__ 19278 _RTLENTRYF 19279 #endif 19280 prof_total_cmp(s1, s2) 19281 const void *s1; 19282 const void *s2; 19283 { 19284 ufunc_T *p1, *p2; 19285 19286 p1 = *(ufunc_T **)s1; 19287 p2 = *(ufunc_T **)s2; 19288 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 19289 } 19290 19291 /* 19292 * Compare function for self time sorting. 19293 */ 19294 static int 19295 #ifdef __BORLANDC__ 19296 _RTLENTRYF 19297 #endif 19298 prof_self_cmp(s1, s2) 19299 const void *s1; 19300 const void *s2; 19301 { 19302 ufunc_T *p1, *p2; 19303 19304 p1 = *(ufunc_T **)s1; 19305 p2 = *(ufunc_T **)s2; 19306 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 19307 } 19308 19309 #endif 19310 19311 /* The names of packages that once were loaded is remembered. */ 19312 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 19313 19314 /* 19315 * If "name" has a package name try autoloading the script for it. 19316 * Return TRUE if a package was loaded. 19317 */ 19318 static int 19319 script_autoload(name, reload) 19320 char_u *name; 19321 int reload; /* load script again when already loaded */ 19322 { 19323 char_u *p; 19324 char_u *scriptname, *tofree; 19325 int ret = FALSE; 19326 int i; 19327 19328 /* If there is no '#' after name[0] there is no package name. */ 19329 p = vim_strchr(name, AUTOLOAD_CHAR); 19330 if (p == NULL || p == name) 19331 return FALSE; 19332 19333 tofree = scriptname = autoload_name(name); 19334 19335 /* Find the name in the list of previously loaded package names. Skip 19336 * "autoload/", it's always the same. */ 19337 for (i = 0; i < ga_loaded.ga_len; ++i) 19338 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 19339 break; 19340 if (!reload && i < ga_loaded.ga_len) 19341 ret = FALSE; /* was loaded already */ 19342 else 19343 { 19344 /* Remember the name if it wasn't loaded already. */ 19345 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 19346 { 19347 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 19348 tofree = NULL; 19349 } 19350 19351 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 19352 if (source_runtime(scriptname, FALSE) == OK) 19353 ret = TRUE; 19354 } 19355 19356 vim_free(tofree); 19357 return ret; 19358 } 19359 19360 /* 19361 * Return the autoload script name for a function or variable name. 19362 * Returns NULL when out of memory. 19363 */ 19364 static char_u * 19365 autoload_name(name) 19366 char_u *name; 19367 { 19368 char_u *p; 19369 char_u *scriptname; 19370 19371 /* Get the script file name: replace '#' with '/', append ".vim". */ 19372 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 19373 if (scriptname == NULL) 19374 return FALSE; 19375 STRCPY(scriptname, "autoload/"); 19376 STRCAT(scriptname, name); 19377 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 19378 STRCAT(scriptname, ".vim"); 19379 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 19380 *p = '/'; 19381 return scriptname; 19382 } 19383 19384 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 19385 19386 /* 19387 * Function given to ExpandGeneric() to obtain the list of user defined 19388 * function names. 19389 */ 19390 char_u * 19391 get_user_func_name(xp, idx) 19392 expand_T *xp; 19393 int idx; 19394 { 19395 static long_u done; 19396 static hashitem_T *hi; 19397 ufunc_T *fp; 19398 19399 if (idx == 0) 19400 { 19401 done = 0; 19402 hi = func_hashtab.ht_array; 19403 } 19404 if (done < func_hashtab.ht_used) 19405 { 19406 if (done++ > 0) 19407 ++hi; 19408 while (HASHITEM_EMPTY(hi)) 19409 ++hi; 19410 fp = HI2UF(hi); 19411 19412 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 19413 return fp->uf_name; /* prevents overflow */ 19414 19415 cat_func_name(IObuff, fp); 19416 if (xp->xp_context != EXPAND_USER_FUNC) 19417 { 19418 STRCAT(IObuff, "("); 19419 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 19420 STRCAT(IObuff, ")"); 19421 } 19422 return IObuff; 19423 } 19424 return NULL; 19425 } 19426 19427 #endif /* FEAT_CMDL_COMPL */ 19428 19429 /* 19430 * Copy the function name of "fp" to buffer "buf". 19431 * "buf" must be able to hold the function name plus three bytes. 19432 * Takes care of script-local function names. 19433 */ 19434 static void 19435 cat_func_name(buf, fp) 19436 char_u *buf; 19437 ufunc_T *fp; 19438 { 19439 if (fp->uf_name[0] == K_SPECIAL) 19440 { 19441 STRCPY(buf, "<SNR>"); 19442 STRCAT(buf, fp->uf_name + 3); 19443 } 19444 else 19445 STRCPY(buf, fp->uf_name); 19446 } 19447 19448 /* 19449 * ":delfunction {name}" 19450 */ 19451 void 19452 ex_delfunction(eap) 19453 exarg_T *eap; 19454 { 19455 ufunc_T *fp = NULL; 19456 char_u *p; 19457 char_u *name; 19458 funcdict_T fudi; 19459 19460 p = eap->arg; 19461 name = trans_function_name(&p, eap->skip, 0, &fudi); 19462 vim_free(fudi.fd_newkey); 19463 if (name == NULL) 19464 { 19465 if (fudi.fd_dict != NULL && !eap->skip) 19466 EMSG(_(e_funcref)); 19467 return; 19468 } 19469 if (!ends_excmd(*skipwhite(p))) 19470 { 19471 vim_free(name); 19472 EMSG(_(e_trailing)); 19473 return; 19474 } 19475 eap->nextcmd = check_nextcmd(p); 19476 if (eap->nextcmd != NULL) 19477 *p = NUL; 19478 19479 if (!eap->skip) 19480 fp = find_func(name); 19481 vim_free(name); 19482 19483 if (!eap->skip) 19484 { 19485 if (fp == NULL) 19486 { 19487 EMSG2(_(e_nofunc), eap->arg); 19488 return; 19489 } 19490 if (fp->uf_calls > 0) 19491 { 19492 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 19493 return; 19494 } 19495 19496 if (fudi.fd_dict != NULL) 19497 { 19498 /* Delete the dict item that refers to the function, it will 19499 * invoke func_unref() and possibly delete the function. */ 19500 dictitem_remove(fudi.fd_dict, fudi.fd_di); 19501 } 19502 else 19503 func_free(fp); 19504 } 19505 } 19506 19507 /* 19508 * Free a function and remove it from the list of functions. 19509 */ 19510 static void 19511 func_free(fp) 19512 ufunc_T *fp; 19513 { 19514 hashitem_T *hi; 19515 19516 /* clear this function */ 19517 ga_clear_strings(&(fp->uf_args)); 19518 ga_clear_strings(&(fp->uf_lines)); 19519 #ifdef FEAT_PROFILE 19520 vim_free(fp->uf_tml_count); 19521 vim_free(fp->uf_tml_total); 19522 vim_free(fp->uf_tml_self); 19523 #endif 19524 19525 /* remove the function from the function hashtable */ 19526 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 19527 if (HASHITEM_EMPTY(hi)) 19528 EMSG2(_(e_intern2), "func_free()"); 19529 else 19530 hash_remove(&func_hashtab, hi); 19531 19532 vim_free(fp); 19533 } 19534 19535 /* 19536 * Unreference a Function: decrement the reference count and free it when it 19537 * becomes zero. Only for numbered functions. 19538 */ 19539 static void 19540 func_unref(name) 19541 char_u *name; 19542 { 19543 ufunc_T *fp; 19544 19545 if (name != NULL && isdigit(*name)) 19546 { 19547 fp = find_func(name); 19548 if (fp == NULL) 19549 EMSG2(_(e_intern2), "func_unref()"); 19550 else if (--fp->uf_refcount <= 0) 19551 { 19552 /* Only delete it when it's not being used. Otherwise it's done 19553 * when "uf_calls" becomes zero. */ 19554 if (fp->uf_calls == 0) 19555 func_free(fp); 19556 } 19557 } 19558 } 19559 19560 /* 19561 * Count a reference to a Function. 19562 */ 19563 static void 19564 func_ref(name) 19565 char_u *name; 19566 { 19567 ufunc_T *fp; 19568 19569 if (name != NULL && isdigit(*name)) 19570 { 19571 fp = find_func(name); 19572 if (fp == NULL) 19573 EMSG2(_(e_intern2), "func_ref()"); 19574 else 19575 ++fp->uf_refcount; 19576 } 19577 } 19578 19579 /* 19580 * Call a user function. 19581 */ 19582 static void 19583 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 19584 ufunc_T *fp; /* pointer to function */ 19585 int argcount; /* nr of args */ 19586 typval_T *argvars; /* arguments */ 19587 typval_T *rettv; /* return value */ 19588 linenr_T firstline; /* first line of range */ 19589 linenr_T lastline; /* last line of range */ 19590 dict_T *selfdict; /* Dictionary for "self" */ 19591 { 19592 char_u *save_sourcing_name; 19593 linenr_T save_sourcing_lnum; 19594 scid_T save_current_SID; 19595 funccall_T fc; 19596 int save_did_emsg; 19597 static int depth = 0; 19598 dictitem_T *v; 19599 int fixvar_idx = 0; /* index in fixvar[] */ 19600 int i; 19601 int ai; 19602 char_u numbuf[NUMBUFLEN]; 19603 char_u *name; 19604 #ifdef FEAT_PROFILE 19605 proftime_T wait_start; 19606 #endif 19607 19608 /* If depth of calling is getting too high, don't execute the function */ 19609 if (depth >= p_mfd) 19610 { 19611 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 19612 rettv->v_type = VAR_NUMBER; 19613 rettv->vval.v_number = -1; 19614 return; 19615 } 19616 ++depth; 19617 19618 line_breakcheck(); /* check for CTRL-C hit */ 19619 19620 fc.caller = current_funccal; 19621 current_funccal = &fc; 19622 fc.func = fp; 19623 fc.rettv = rettv; 19624 rettv->vval.v_number = 0; 19625 fc.linenr = 0; 19626 fc.returned = FALSE; 19627 fc.level = ex_nesting_level; 19628 /* Check if this function has a breakpoint. */ 19629 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 19630 fc.dbg_tick = debug_tick; 19631 19632 /* 19633 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 19634 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 19635 * each argument variable and saves a lot of time. 19636 */ 19637 /* 19638 * Init l: variables. 19639 */ 19640 init_var_dict(&fc.l_vars, &fc.l_vars_var); 19641 if (selfdict != NULL) 19642 { 19643 /* Set l:self to "selfdict". Use "name" to avoid a warning from 19644 * some compiler that checks the destination size. */ 19645 v = &fc.fixvar[fixvar_idx++].var; 19646 name = v->di_key; 19647 STRCPY(name, "self"); 19648 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 19649 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 19650 v->di_tv.v_type = VAR_DICT; 19651 v->di_tv.v_lock = 0; 19652 v->di_tv.vval.v_dict = selfdict; 19653 ++selfdict->dv_refcount; 19654 } 19655 19656 /* 19657 * Init a: variables. 19658 * Set a:0 to "argcount". 19659 * Set a:000 to a list with room for the "..." arguments. 19660 */ 19661 init_var_dict(&fc.l_avars, &fc.l_avars_var); 19662 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 19663 (varnumber_T)(argcount - fp->uf_args.ga_len)); 19664 v = &fc.fixvar[fixvar_idx++].var; 19665 STRCPY(v->di_key, "000"); 19666 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19667 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19668 v->di_tv.v_type = VAR_LIST; 19669 v->di_tv.v_lock = VAR_FIXED; 19670 v->di_tv.vval.v_list = &fc.l_varlist; 19671 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 19672 fc.l_varlist.lv_refcount = 99999; 19673 19674 /* 19675 * Set a:firstline to "firstline" and a:lastline to "lastline". 19676 * Set a:name to named arguments. 19677 * Set a:N to the "..." arguments. 19678 */ 19679 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 19680 (varnumber_T)firstline); 19681 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 19682 (varnumber_T)lastline); 19683 for (i = 0; i < argcount; ++i) 19684 { 19685 ai = i - fp->uf_args.ga_len; 19686 if (ai < 0) 19687 /* named argument a:name */ 19688 name = FUNCARG(fp, i); 19689 else 19690 { 19691 /* "..." argument a:1, a:2, etc. */ 19692 sprintf((char *)numbuf, "%d", ai + 1); 19693 name = numbuf; 19694 } 19695 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 19696 { 19697 v = &fc.fixvar[fixvar_idx++].var; 19698 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19699 } 19700 else 19701 { 19702 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19703 + STRLEN(name))); 19704 if (v == NULL) 19705 break; 19706 v->di_flags = DI_FLAGS_RO; 19707 } 19708 STRCPY(v->di_key, name); 19709 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19710 19711 /* Note: the values are copied directly to avoid alloc/free. 19712 * "argvars" must have VAR_FIXED for v_lock. */ 19713 v->di_tv = argvars[i]; 19714 v->di_tv.v_lock = VAR_FIXED; 19715 19716 if (ai >= 0 && ai < MAX_FUNC_ARGS) 19717 { 19718 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 19719 fc.l_listitems[ai].li_tv = argvars[i]; 19720 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 19721 } 19722 } 19723 19724 /* Don't redraw while executing the function. */ 19725 ++RedrawingDisabled; 19726 save_sourcing_name = sourcing_name; 19727 save_sourcing_lnum = sourcing_lnum; 19728 sourcing_lnum = 1; 19729 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 19730 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 19731 if (sourcing_name != NULL) 19732 { 19733 if (save_sourcing_name != NULL 19734 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 19735 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 19736 else 19737 STRCPY(sourcing_name, "function "); 19738 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 19739 19740 if (p_verbose >= 12) 19741 { 19742 ++no_wait_return; 19743 verbose_enter_scroll(); 19744 19745 smsg((char_u *)_("calling %s"), sourcing_name); 19746 if (p_verbose >= 14) 19747 { 19748 char_u buf[MSG_BUF_LEN]; 19749 char_u numbuf[NUMBUFLEN]; 19750 char_u *tofree; 19751 19752 msg_puts((char_u *)"("); 19753 for (i = 0; i < argcount; ++i) 19754 { 19755 if (i > 0) 19756 msg_puts((char_u *)", "); 19757 if (argvars[i].v_type == VAR_NUMBER) 19758 msg_outnum((long)argvars[i].vval.v_number); 19759 else 19760 { 19761 trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0), 19762 buf, MSG_BUF_CLEN); 19763 msg_puts(buf); 19764 vim_free(tofree); 19765 } 19766 } 19767 msg_puts((char_u *)")"); 19768 } 19769 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19770 19771 verbose_leave_scroll(); 19772 --no_wait_return; 19773 } 19774 } 19775 #ifdef FEAT_PROFILE 19776 if (do_profiling == PROF_YES) 19777 { 19778 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 19779 func_do_profile(fp); 19780 if (fp->uf_profiling 19781 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 19782 { 19783 ++fp->uf_tm_count; 19784 profile_start(&fp->uf_tm_start); 19785 profile_zero(&fp->uf_tm_children); 19786 } 19787 script_prof_save(&wait_start); 19788 } 19789 #endif 19790 19791 save_current_SID = current_SID; 19792 current_SID = fp->uf_script_ID; 19793 save_did_emsg = did_emsg; 19794 did_emsg = FALSE; 19795 19796 /* call do_cmdline() to execute the lines */ 19797 do_cmdline(NULL, get_func_line, (void *)&fc, 19798 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 19799 19800 --RedrawingDisabled; 19801 19802 /* when the function was aborted because of an error, return -1 */ 19803 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 19804 { 19805 clear_tv(rettv); 19806 rettv->v_type = VAR_NUMBER; 19807 rettv->vval.v_number = -1; 19808 } 19809 19810 #ifdef FEAT_PROFILE 19811 if (do_profiling == PROF_YES && (fp->uf_profiling 19812 || (fc.caller != NULL && &fc.caller->func->uf_profiling))) 19813 { 19814 profile_end(&fp->uf_tm_start); 19815 profile_sub_wait(&wait_start, &fp->uf_tm_start); 19816 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 19817 profile_self(&fp->uf_tm_self, &fp->uf_tm_start, &fp->uf_tm_children); 19818 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 19819 { 19820 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 19821 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 19822 } 19823 } 19824 #endif 19825 19826 /* when being verbose, mention the return value */ 19827 if (p_verbose >= 12) 19828 { 19829 ++no_wait_return; 19830 verbose_enter_scroll(); 19831 19832 if (aborting()) 19833 smsg((char_u *)_("%s aborted"), sourcing_name); 19834 else if (fc.rettv->v_type == VAR_NUMBER) 19835 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 19836 (long)fc.rettv->vval.v_number); 19837 else 19838 { 19839 char_u buf[MSG_BUF_LEN]; 19840 char_u numbuf[NUMBUFLEN]; 19841 char_u *tofree; 19842 19843 /* The value may be very long. Skip the middle part, so that we 19844 * have some idea how it starts and ends. smsg() would always 19845 * truncate it at the end. */ 19846 trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0), 19847 buf, MSG_BUF_CLEN); 19848 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 19849 vim_free(tofree); 19850 } 19851 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19852 19853 verbose_leave_scroll(); 19854 --no_wait_return; 19855 } 19856 19857 vim_free(sourcing_name); 19858 sourcing_name = save_sourcing_name; 19859 sourcing_lnum = save_sourcing_lnum; 19860 current_SID = save_current_SID; 19861 #ifdef FEAT_PROFILE 19862 if (do_profiling == PROF_YES) 19863 script_prof_restore(&wait_start); 19864 #endif 19865 19866 if (p_verbose >= 12 && sourcing_name != NULL) 19867 { 19868 ++no_wait_return; 19869 verbose_enter_scroll(); 19870 19871 smsg((char_u *)_("continuing in %s"), sourcing_name); 19872 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19873 19874 verbose_leave_scroll(); 19875 --no_wait_return; 19876 } 19877 19878 did_emsg |= save_did_emsg; 19879 current_funccal = fc.caller; 19880 19881 /* The a: variables typevals were not alloced, only free the allocated 19882 * variables. */ 19883 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 19884 19885 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 19886 --depth; 19887 } 19888 19889 /* 19890 * Add a number variable "name" to dict "dp" with value "nr". 19891 */ 19892 static void 19893 add_nr_var(dp, v, name, nr) 19894 dict_T *dp; 19895 dictitem_T *v; 19896 char *name; 19897 varnumber_T nr; 19898 { 19899 STRCPY(v->di_key, name); 19900 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19901 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 19902 v->di_tv.v_type = VAR_NUMBER; 19903 v->di_tv.v_lock = VAR_FIXED; 19904 v->di_tv.vval.v_number = nr; 19905 } 19906 19907 /* 19908 * ":return [expr]" 19909 */ 19910 void 19911 ex_return(eap) 19912 exarg_T *eap; 19913 { 19914 char_u *arg = eap->arg; 19915 typval_T rettv; 19916 int returning = FALSE; 19917 19918 if (current_funccal == NULL) 19919 { 19920 EMSG(_("E133: :return not inside a function")); 19921 return; 19922 } 19923 19924 if (eap->skip) 19925 ++emsg_skip; 19926 19927 eap->nextcmd = NULL; 19928 if ((*arg != NUL && *arg != '|' && *arg != '\n') 19929 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 19930 { 19931 if (!eap->skip) 19932 returning = do_return(eap, FALSE, TRUE, &rettv); 19933 else 19934 clear_tv(&rettv); 19935 } 19936 /* It's safer to return also on error. */ 19937 else if (!eap->skip) 19938 { 19939 /* 19940 * Return unless the expression evaluation has been cancelled due to an 19941 * aborting error, an interrupt, or an exception. 19942 */ 19943 if (!aborting()) 19944 returning = do_return(eap, FALSE, TRUE, NULL); 19945 } 19946 19947 /* When skipping or the return gets pending, advance to the next command 19948 * in this line (!returning). Otherwise, ignore the rest of the line. 19949 * Following lines will be ignored by get_func_line(). */ 19950 if (returning) 19951 eap->nextcmd = NULL; 19952 else if (eap->nextcmd == NULL) /* no argument */ 19953 eap->nextcmd = check_nextcmd(arg); 19954 19955 if (eap->skip) 19956 --emsg_skip; 19957 } 19958 19959 /* 19960 * Return from a function. Possibly makes the return pending. Also called 19961 * for a pending return at the ":endtry" or after returning from an extra 19962 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 19963 * when called due to a ":return" command. "rettv" may point to a typval_T 19964 * with the return rettv. Returns TRUE when the return can be carried out, 19965 * FALSE when the return gets pending. 19966 */ 19967 int 19968 do_return(eap, reanimate, is_cmd, rettv) 19969 exarg_T *eap; 19970 int reanimate; 19971 int is_cmd; 19972 void *rettv; 19973 { 19974 int idx; 19975 struct condstack *cstack = eap->cstack; 19976 19977 if (reanimate) 19978 /* Undo the return. */ 19979 current_funccal->returned = FALSE; 19980 19981 /* 19982 * Cleanup (and inactivate) conditionals, but stop when a try conditional 19983 * not in its finally clause (which then is to be executed next) is found. 19984 * In this case, make the ":return" pending for execution at the ":endtry". 19985 * Otherwise, return normally. 19986 */ 19987 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 19988 if (idx >= 0) 19989 { 19990 cstack->cs_pending[idx] = CSTP_RETURN; 19991 19992 if (!is_cmd && !reanimate) 19993 /* A pending return again gets pending. "rettv" points to an 19994 * allocated variable with the rettv of the original ":return"'s 19995 * argument if present or is NULL else. */ 19996 cstack->cs_rettv[idx] = rettv; 19997 else 19998 { 19999 /* When undoing a return in order to make it pending, get the stored 20000 * return rettv. */ 20001 if (reanimate) 20002 rettv = current_funccal->rettv; 20003 20004 if (rettv != NULL) 20005 { 20006 /* Store the value of the pending return. */ 20007 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 20008 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 20009 else 20010 EMSG(_(e_outofmem)); 20011 } 20012 else 20013 cstack->cs_rettv[idx] = NULL; 20014 20015 if (reanimate) 20016 { 20017 /* The pending return value could be overwritten by a ":return" 20018 * without argument in a finally clause; reset the default 20019 * return value. */ 20020 current_funccal->rettv->v_type = VAR_NUMBER; 20021 current_funccal->rettv->vval.v_number = 0; 20022 } 20023 } 20024 report_make_pending(CSTP_RETURN, rettv); 20025 } 20026 else 20027 { 20028 current_funccal->returned = TRUE; 20029 20030 /* If the return is carried out now, store the return value. For 20031 * a return immediately after reanimation, the value is already 20032 * there. */ 20033 if (!reanimate && rettv != NULL) 20034 { 20035 clear_tv(current_funccal->rettv); 20036 *current_funccal->rettv = *(typval_T *)rettv; 20037 if (!is_cmd) 20038 vim_free(rettv); 20039 } 20040 } 20041 20042 return idx < 0; 20043 } 20044 20045 /* 20046 * Free the variable with a pending return value. 20047 */ 20048 void 20049 discard_pending_return(rettv) 20050 void *rettv; 20051 { 20052 free_tv((typval_T *)rettv); 20053 } 20054 20055 /* 20056 * Generate a return command for producing the value of "rettv". The result 20057 * is an allocated string. Used by report_pending() for verbose messages. 20058 */ 20059 char_u * 20060 get_return_cmd(rettv) 20061 void *rettv; 20062 { 20063 char_u *s = NULL; 20064 char_u *tofree = NULL; 20065 char_u numbuf[NUMBUFLEN]; 20066 20067 if (rettv != NULL) 20068 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 20069 if (s == NULL) 20070 s = (char_u *)""; 20071 20072 STRCPY(IObuff, ":return "); 20073 STRNCPY(IObuff + 8, s, IOSIZE - 8); 20074 if (STRLEN(s) + 8 >= IOSIZE) 20075 STRCPY(IObuff + IOSIZE - 4, "..."); 20076 vim_free(tofree); 20077 return vim_strsave(IObuff); 20078 } 20079 20080 /* 20081 * Get next function line. 20082 * Called by do_cmdline() to get the next line. 20083 * Returns allocated string, or NULL for end of function. 20084 */ 20085 /* ARGSUSED */ 20086 char_u * 20087 get_func_line(c, cookie, indent) 20088 int c; /* not used */ 20089 void *cookie; 20090 int indent; /* not used */ 20091 { 20092 funccall_T *fcp = (funccall_T *)cookie; 20093 ufunc_T *fp = fcp->func; 20094 char_u *retval; 20095 garray_T *gap; /* growarray with function lines */ 20096 20097 /* If breakpoints have been added/deleted need to check for it. */ 20098 if (fcp->dbg_tick != debug_tick) 20099 { 20100 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20101 sourcing_lnum); 20102 fcp->dbg_tick = debug_tick; 20103 } 20104 #ifdef FEAT_PROFILE 20105 if (do_profiling == PROF_YES) 20106 func_line_end(cookie); 20107 #endif 20108 20109 gap = &fp->uf_lines; 20110 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20111 || fcp->returned) 20112 retval = NULL; 20113 else 20114 { 20115 /* Skip NULL lines (continuation lines). */ 20116 while (fcp->linenr < gap->ga_len 20117 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 20118 ++fcp->linenr; 20119 if (fcp->linenr >= gap->ga_len) 20120 retval = NULL; 20121 else 20122 { 20123 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 20124 sourcing_lnum = fcp->linenr; 20125 #ifdef FEAT_PROFILE 20126 if (do_profiling == PROF_YES) 20127 func_line_start(cookie); 20128 #endif 20129 } 20130 } 20131 20132 /* Did we encounter a breakpoint? */ 20133 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 20134 { 20135 dbg_breakpoint(fp->uf_name, sourcing_lnum); 20136 /* Find next breakpoint. */ 20137 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20138 sourcing_lnum); 20139 fcp->dbg_tick = debug_tick; 20140 } 20141 20142 return retval; 20143 } 20144 20145 #if defined(FEAT_PROFILE) || defined(PROTO) 20146 /* 20147 * Called when starting to read a function line. 20148 * "sourcing_lnum" must be correct! 20149 * When skipping lines it may not actually be executed, but we won't find out 20150 * until later and we need to store the time now. 20151 */ 20152 void 20153 func_line_start(cookie) 20154 void *cookie; 20155 { 20156 funccall_T *fcp = (funccall_T *)cookie; 20157 ufunc_T *fp = fcp->func; 20158 20159 if (fp->uf_profiling && sourcing_lnum >= 1 20160 && sourcing_lnum <= fp->uf_lines.ga_len) 20161 { 20162 fp->uf_tml_idx = sourcing_lnum - 1; 20163 /* Skip continuation lines. */ 20164 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 20165 --fp->uf_tml_idx; 20166 fp->uf_tml_execed = FALSE; 20167 profile_start(&fp->uf_tml_start); 20168 profile_zero(&fp->uf_tml_children); 20169 profile_get_wait(&fp->uf_tml_wait); 20170 } 20171 } 20172 20173 /* 20174 * Called when actually executing a function line. 20175 */ 20176 void 20177 func_line_exec(cookie) 20178 void *cookie; 20179 { 20180 funccall_T *fcp = (funccall_T *)cookie; 20181 ufunc_T *fp = fcp->func; 20182 20183 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20184 fp->uf_tml_execed = TRUE; 20185 } 20186 20187 /* 20188 * Called when done with a function line. 20189 */ 20190 void 20191 func_line_end(cookie) 20192 void *cookie; 20193 { 20194 funccall_T *fcp = (funccall_T *)cookie; 20195 ufunc_T *fp = fcp->func; 20196 20197 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20198 { 20199 if (fp->uf_tml_execed) 20200 { 20201 ++fp->uf_tml_count[fp->uf_tml_idx]; 20202 profile_end(&fp->uf_tml_start); 20203 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 20204 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 20205 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 20206 &fp->uf_tml_children); 20207 } 20208 fp->uf_tml_idx = -1; 20209 } 20210 } 20211 #endif 20212 20213 /* 20214 * Return TRUE if the currently active function should be ended, because a 20215 * return was encountered or an error occured. Used inside a ":while". 20216 */ 20217 int 20218 func_has_ended(cookie) 20219 void *cookie; 20220 { 20221 funccall_T *fcp = (funccall_T *)cookie; 20222 20223 /* Ignore the "abort" flag if the abortion behavior has been changed due to 20224 * an error inside a try conditional. */ 20225 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20226 || fcp->returned); 20227 } 20228 20229 /* 20230 * return TRUE if cookie indicates a function which "abort"s on errors. 20231 */ 20232 int 20233 func_has_abort(cookie) 20234 void *cookie; 20235 { 20236 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 20237 } 20238 20239 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 20240 typedef enum 20241 { 20242 VAR_FLAVOUR_DEFAULT, 20243 VAR_FLAVOUR_SESSION, 20244 VAR_FLAVOUR_VIMINFO 20245 } var_flavour_T; 20246 20247 static var_flavour_T var_flavour __ARGS((char_u *varname)); 20248 20249 static var_flavour_T 20250 var_flavour(varname) 20251 char_u *varname; 20252 { 20253 char_u *p = varname; 20254 20255 if (ASCII_ISUPPER(*p)) 20256 { 20257 while (*(++p)) 20258 if (ASCII_ISLOWER(*p)) 20259 return VAR_FLAVOUR_SESSION; 20260 return VAR_FLAVOUR_VIMINFO; 20261 } 20262 else 20263 return VAR_FLAVOUR_DEFAULT; 20264 } 20265 #endif 20266 20267 #if defined(FEAT_VIMINFO) || defined(PROTO) 20268 /* 20269 * Restore global vars that start with a capital from the viminfo file 20270 */ 20271 int 20272 read_viminfo_varlist(virp, writing) 20273 vir_T *virp; 20274 int writing; 20275 { 20276 char_u *tab; 20277 int is_string = FALSE; 20278 typval_T tv; 20279 20280 if (!writing && (find_viminfo_parameter('!') != NULL)) 20281 { 20282 tab = vim_strchr(virp->vir_line + 1, '\t'); 20283 if (tab != NULL) 20284 { 20285 *tab++ = '\0'; /* isolate the variable name */ 20286 if (*tab == 'S') /* string var */ 20287 is_string = TRUE; 20288 20289 tab = vim_strchr(tab, '\t'); 20290 if (tab != NULL) 20291 { 20292 if (is_string) 20293 { 20294 tv.v_type = VAR_STRING; 20295 tv.vval.v_string = viminfo_readstring(virp, 20296 (int)(tab - virp->vir_line + 1), TRUE); 20297 } 20298 else 20299 { 20300 tv.v_type = VAR_NUMBER; 20301 tv.vval.v_number = atol((char *)tab + 1); 20302 } 20303 set_var(virp->vir_line + 1, &tv, FALSE); 20304 if (is_string) 20305 vim_free(tv.vval.v_string); 20306 } 20307 } 20308 } 20309 20310 return viminfo_readline(virp); 20311 } 20312 20313 /* 20314 * Write global vars that start with a capital to the viminfo file 20315 */ 20316 void 20317 write_viminfo_varlist(fp) 20318 FILE *fp; 20319 { 20320 hashitem_T *hi; 20321 dictitem_T *this_var; 20322 int todo; 20323 char *s; 20324 char_u *p; 20325 char_u *tofree; 20326 char_u numbuf[NUMBUFLEN]; 20327 20328 if (find_viminfo_parameter('!') == NULL) 20329 return; 20330 20331 fprintf(fp, _("\n# global variables:\n")); 20332 20333 todo = (int)globvarht.ht_used; 20334 for (hi = globvarht.ht_array; todo > 0; ++hi) 20335 { 20336 if (!HASHITEM_EMPTY(hi)) 20337 { 20338 --todo; 20339 this_var = HI2DI(hi); 20340 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 20341 { 20342 switch (this_var->di_tv.v_type) 20343 { 20344 case VAR_STRING: s = "STR"; break; 20345 case VAR_NUMBER: s = "NUM"; break; 20346 default: continue; 20347 } 20348 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 20349 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 20350 if (p != NULL) 20351 viminfo_writestring(fp, p); 20352 vim_free(tofree); 20353 } 20354 } 20355 } 20356 } 20357 #endif 20358 20359 #if defined(FEAT_SESSION) || defined(PROTO) 20360 int 20361 store_session_globals(fd) 20362 FILE *fd; 20363 { 20364 hashitem_T *hi; 20365 dictitem_T *this_var; 20366 int todo; 20367 char_u *p, *t; 20368 20369 todo = (int)globvarht.ht_used; 20370 for (hi = globvarht.ht_array; todo > 0; ++hi) 20371 { 20372 if (!HASHITEM_EMPTY(hi)) 20373 { 20374 --todo; 20375 this_var = HI2DI(hi); 20376 if ((this_var->di_tv.v_type == VAR_NUMBER 20377 || this_var->di_tv.v_type == VAR_STRING) 20378 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 20379 { 20380 /* Escape special characters with a backslash. Turn a LF and 20381 * CR into \n and \r. */ 20382 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 20383 (char_u *)"\\\"\n\r"); 20384 if (p == NULL) /* out of memory */ 20385 break; 20386 for (t = p; *t != NUL; ++t) 20387 if (*t == '\n') 20388 *t = 'n'; 20389 else if (*t == '\r') 20390 *t = 'r'; 20391 if ((fprintf(fd, "let %s = %c%s%c", 20392 this_var->di_key, 20393 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20394 : ' ', 20395 p, 20396 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20397 : ' ') < 0) 20398 || put_eol(fd) == FAIL) 20399 { 20400 vim_free(p); 20401 return FAIL; 20402 } 20403 vim_free(p); 20404 } 20405 } 20406 } 20407 return OK; 20408 } 20409 #endif 20410 20411 /* 20412 * Display script name where an item was last set. 20413 * Should only be invoked when 'verbose' is non-zero. 20414 */ 20415 void 20416 last_set_msg(scriptID) 20417 scid_T scriptID; 20418 { 20419 char_u *p; 20420 20421 if (scriptID != 0) 20422 { 20423 p = home_replace_save(NULL, get_scriptname(scriptID)); 20424 if (p != NULL) 20425 { 20426 verbose_enter(); 20427 MSG_PUTS(_("\n\tLast set from ")); 20428 MSG_PUTS(p); 20429 vim_free(p); 20430 verbose_leave(); 20431 } 20432 } 20433 } 20434 20435 #endif /* FEAT_EVAL */ 20436 20437 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 20438 20439 20440 #ifdef WIN3264 20441 /* 20442 * Functions for ":8" filename modifier: get 8.3 version of a filename. 20443 */ 20444 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20445 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 20446 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20447 20448 /* 20449 * Get the short pathname of a file. 20450 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 20451 */ 20452 static int 20453 get_short_pathname(fnamep, bufp, fnamelen) 20454 char_u **fnamep; 20455 char_u **bufp; 20456 int *fnamelen; 20457 { 20458 int l,len; 20459 char_u *newbuf; 20460 20461 len = *fnamelen; 20462 20463 l = GetShortPathName(*fnamep, *fnamep, len); 20464 if (l > len - 1) 20465 { 20466 /* If that doesn't work (not enough space), then save the string 20467 * and try again with a new buffer big enough 20468 */ 20469 newbuf = vim_strnsave(*fnamep, l); 20470 if (newbuf == NULL) 20471 return 0; 20472 20473 vim_free(*bufp); 20474 *fnamep = *bufp = newbuf; 20475 20476 l = GetShortPathName(*fnamep,*fnamep,l+1); 20477 20478 /* Really should always succeed, as the buffer is big enough */ 20479 } 20480 20481 *fnamelen = l; 20482 return 1; 20483 } 20484 20485 /* 20486 * Create a short path name. Returns the length of the buffer it needs. 20487 * Doesn't copy over the end of the buffer passed in. 20488 */ 20489 static int 20490 shortpath_for_invalid_fname(fname, bufp, fnamelen) 20491 char_u **fname; 20492 char_u **bufp; 20493 int *fnamelen; 20494 { 20495 char_u *s, *p, *pbuf2, *pbuf3; 20496 char_u ch; 20497 int len, len2, plen, slen; 20498 20499 /* Make a copy */ 20500 len2 = *fnamelen; 20501 pbuf2 = vim_strnsave(*fname, len2); 20502 pbuf3 = NULL; 20503 20504 s = pbuf2 + len2 - 1; /* Find the end */ 20505 slen = 1; 20506 plen = len2; 20507 20508 if (after_pathsep(pbuf2, s + 1)) 20509 { 20510 --s; 20511 ++slen; 20512 --plen; 20513 } 20514 20515 do 20516 { 20517 /* Go back one path-seperator */ 20518 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 20519 { 20520 --s; 20521 ++slen; 20522 --plen; 20523 } 20524 if (s <= pbuf2) 20525 break; 20526 20527 /* Remeber the character that is about to be blatted */ 20528 ch = *s; 20529 *s = 0; /* get_short_pathname requires a null-terminated string */ 20530 20531 /* Try it in situ */ 20532 p = pbuf2; 20533 if (!get_short_pathname(&p, &pbuf3, &plen)) 20534 { 20535 vim_free(pbuf2); 20536 return -1; 20537 } 20538 *s = ch; /* Preserve the string */ 20539 } while (plen == 0); 20540 20541 if (plen > 0) 20542 { 20543 /* Remeber the length of the new string. */ 20544 *fnamelen = len = plen + slen; 20545 vim_free(*bufp); 20546 if (len > len2) 20547 { 20548 /* If there's not enough space in the currently allocated string, 20549 * then copy it to a buffer big enough. 20550 */ 20551 *fname= *bufp = vim_strnsave(p, len); 20552 if (*fname == NULL) 20553 return -1; 20554 } 20555 else 20556 { 20557 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 20558 *fname = *bufp = pbuf2; 20559 if (p != pbuf2) 20560 strncpy(*fname, p, plen); 20561 pbuf2 = NULL; 20562 } 20563 /* Concat the next bit */ 20564 strncpy(*fname + plen, s, slen); 20565 (*fname)[len] = '\0'; 20566 } 20567 vim_free(pbuf3); 20568 vim_free(pbuf2); 20569 return 0; 20570 } 20571 20572 /* 20573 * Get a pathname for a partial path. 20574 */ 20575 static int 20576 shortpath_for_partial(fnamep, bufp, fnamelen) 20577 char_u **fnamep; 20578 char_u **bufp; 20579 int *fnamelen; 20580 { 20581 int sepcount, len, tflen; 20582 char_u *p; 20583 char_u *pbuf, *tfname; 20584 int hasTilde; 20585 20586 /* Count up the path seperators from the RHS.. so we know which part 20587 * of the path to return. 20588 */ 20589 sepcount = 0; 20590 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 20591 if (vim_ispathsep(*p)) 20592 ++sepcount; 20593 20594 /* Need full path first (use expand_env() to remove a "~/") */ 20595 hasTilde = (**fnamep == '~'); 20596 if (hasTilde) 20597 pbuf = tfname = expand_env_save(*fnamep); 20598 else 20599 pbuf = tfname = FullName_save(*fnamep, FALSE); 20600 20601 len = tflen = (int)STRLEN(tfname); 20602 20603 if (!get_short_pathname(&tfname, &pbuf, &len)) 20604 return -1; 20605 20606 if (len == 0) 20607 { 20608 /* Don't have a valid filename, so shorten the rest of the 20609 * path if we can. This CAN give us invalid 8.3 filenames, but 20610 * there's not a lot of point in guessing what it might be. 20611 */ 20612 len = tflen; 20613 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 20614 return -1; 20615 } 20616 20617 /* Count the paths backward to find the beginning of the desired string. */ 20618 for (p = tfname + len - 1; p >= tfname; --p) 20619 { 20620 #ifdef FEAT_MBYTE 20621 if (has_mbyte) 20622 p -= mb_head_off(tfname, p); 20623 #endif 20624 if (vim_ispathsep(*p)) 20625 { 20626 if (sepcount == 0 || (hasTilde && sepcount == 1)) 20627 break; 20628 else 20629 sepcount --; 20630 } 20631 } 20632 if (hasTilde) 20633 { 20634 --p; 20635 if (p >= tfname) 20636 *p = '~'; 20637 else 20638 return -1; 20639 } 20640 else 20641 ++p; 20642 20643 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 20644 vim_free(*bufp); 20645 *fnamelen = (int)STRLEN(p); 20646 *bufp = pbuf; 20647 *fnamep = p; 20648 20649 return 0; 20650 } 20651 #endif /* WIN3264 */ 20652 20653 /* 20654 * Adjust a filename, according to a string of modifiers. 20655 * *fnamep must be NUL terminated when called. When returning, the length is 20656 * determined by *fnamelen. 20657 * Returns valid flags. 20658 * When there is an error, *fnamep is set to NULL. 20659 */ 20660 int 20661 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 20662 char_u *src; /* string with modifiers */ 20663 int *usedlen; /* characters after src that are used */ 20664 char_u **fnamep; /* file name so far */ 20665 char_u **bufp; /* buffer for allocated file name or NULL */ 20666 int *fnamelen; /* length of fnamep */ 20667 { 20668 int valid = 0; 20669 char_u *tail; 20670 char_u *s, *p, *pbuf; 20671 char_u dirname[MAXPATHL]; 20672 int c; 20673 int has_fullname = 0; 20674 #ifdef WIN3264 20675 int has_shortname = 0; 20676 #endif 20677 20678 repeat: 20679 /* ":p" - full path/file_name */ 20680 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 20681 { 20682 has_fullname = 1; 20683 20684 valid |= VALID_PATH; 20685 *usedlen += 2; 20686 20687 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 20688 if ((*fnamep)[0] == '~' 20689 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 20690 && ((*fnamep)[1] == '/' 20691 # ifdef BACKSLASH_IN_FILENAME 20692 || (*fnamep)[1] == '\\' 20693 # endif 20694 || (*fnamep)[1] == NUL) 20695 20696 #endif 20697 ) 20698 { 20699 *fnamep = expand_env_save(*fnamep); 20700 vim_free(*bufp); /* free any allocated file name */ 20701 *bufp = *fnamep; 20702 if (*fnamep == NULL) 20703 return -1; 20704 } 20705 20706 /* When "/." or "/.." is used: force expansion to get rid of it. */ 20707 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 20708 { 20709 if (vim_ispathsep(*p) 20710 && p[1] == '.' 20711 && (p[2] == NUL 20712 || vim_ispathsep(p[2]) 20713 || (p[2] == '.' 20714 && (p[3] == NUL || vim_ispathsep(p[3]))))) 20715 break; 20716 } 20717 20718 /* FullName_save() is slow, don't use it when not needed. */ 20719 if (*p != NUL || !vim_isAbsName(*fnamep)) 20720 { 20721 *fnamep = FullName_save(*fnamep, *p != NUL); 20722 vim_free(*bufp); /* free any allocated file name */ 20723 *bufp = *fnamep; 20724 if (*fnamep == NULL) 20725 return -1; 20726 } 20727 20728 /* Append a path separator to a directory. */ 20729 if (mch_isdir(*fnamep)) 20730 { 20731 /* Make room for one or two extra characters. */ 20732 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 20733 vim_free(*bufp); /* free any allocated file name */ 20734 *bufp = *fnamep; 20735 if (*fnamep == NULL) 20736 return -1; 20737 add_pathsep(*fnamep); 20738 } 20739 } 20740 20741 /* ":." - path relative to the current directory */ 20742 /* ":~" - path relative to the home directory */ 20743 /* ":8" - shortname path - postponed till after */ 20744 while (src[*usedlen] == ':' 20745 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 20746 { 20747 *usedlen += 2; 20748 if (c == '8') 20749 { 20750 #ifdef WIN3264 20751 has_shortname = 1; /* Postpone this. */ 20752 #endif 20753 continue; 20754 } 20755 pbuf = NULL; 20756 /* Need full path first (use expand_env() to remove a "~/") */ 20757 if (!has_fullname) 20758 { 20759 if (c == '.' && **fnamep == '~') 20760 p = pbuf = expand_env_save(*fnamep); 20761 else 20762 p = pbuf = FullName_save(*fnamep, FALSE); 20763 } 20764 else 20765 p = *fnamep; 20766 20767 has_fullname = 0; 20768 20769 if (p != NULL) 20770 { 20771 if (c == '.') 20772 { 20773 mch_dirname(dirname, MAXPATHL); 20774 s = shorten_fname(p, dirname); 20775 if (s != NULL) 20776 { 20777 *fnamep = s; 20778 if (pbuf != NULL) 20779 { 20780 vim_free(*bufp); /* free any allocated file name */ 20781 *bufp = pbuf; 20782 pbuf = NULL; 20783 } 20784 } 20785 } 20786 else 20787 { 20788 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 20789 /* Only replace it when it starts with '~' */ 20790 if (*dirname == '~') 20791 { 20792 s = vim_strsave(dirname); 20793 if (s != NULL) 20794 { 20795 *fnamep = s; 20796 vim_free(*bufp); 20797 *bufp = s; 20798 } 20799 } 20800 } 20801 vim_free(pbuf); 20802 } 20803 } 20804 20805 tail = gettail(*fnamep); 20806 *fnamelen = (int)STRLEN(*fnamep); 20807 20808 /* ":h" - head, remove "/file_name", can be repeated */ 20809 /* Don't remove the first "/" or "c:\" */ 20810 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 20811 { 20812 valid |= VALID_HEAD; 20813 *usedlen += 2; 20814 s = get_past_head(*fnamep); 20815 while (tail > s && after_pathsep(s, tail)) 20816 --tail; 20817 *fnamelen = (int)(tail - *fnamep); 20818 #ifdef VMS 20819 if (*fnamelen > 0) 20820 *fnamelen += 1; /* the path separator is part of the path */ 20821 #endif 20822 while (tail > s && !after_pathsep(s, tail)) 20823 mb_ptr_back(*fnamep, tail); 20824 } 20825 20826 /* ":8" - shortname */ 20827 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 20828 { 20829 *usedlen += 2; 20830 #ifdef WIN3264 20831 has_shortname = 1; 20832 #endif 20833 } 20834 20835 #ifdef WIN3264 20836 /* Check shortname after we have done 'heads' and before we do 'tails' 20837 */ 20838 if (has_shortname) 20839 { 20840 pbuf = NULL; 20841 /* Copy the string if it is shortened by :h */ 20842 if (*fnamelen < (int)STRLEN(*fnamep)) 20843 { 20844 p = vim_strnsave(*fnamep, *fnamelen); 20845 if (p == 0) 20846 return -1; 20847 vim_free(*bufp); 20848 *bufp = *fnamep = p; 20849 } 20850 20851 /* Split into two implementations - makes it easier. First is where 20852 * there isn't a full name already, second is where there is. 20853 */ 20854 if (!has_fullname && !vim_isAbsName(*fnamep)) 20855 { 20856 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 20857 return -1; 20858 } 20859 else 20860 { 20861 int l; 20862 20863 /* Simple case, already have the full-name 20864 * Nearly always shorter, so try first time. */ 20865 l = *fnamelen; 20866 if (!get_short_pathname(fnamep, bufp, &l)) 20867 return -1; 20868 20869 if (l == 0) 20870 { 20871 /* Couldn't find the filename.. search the paths. 20872 */ 20873 l = *fnamelen; 20874 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 20875 return -1; 20876 } 20877 *fnamelen = l; 20878 } 20879 } 20880 #endif /* WIN3264 */ 20881 20882 /* ":t" - tail, just the basename */ 20883 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 20884 { 20885 *usedlen += 2; 20886 *fnamelen -= (int)(tail - *fnamep); 20887 *fnamep = tail; 20888 } 20889 20890 /* ":e" - extension, can be repeated */ 20891 /* ":r" - root, without extension, can be repeated */ 20892 while (src[*usedlen] == ':' 20893 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 20894 { 20895 /* find a '.' in the tail: 20896 * - for second :e: before the current fname 20897 * - otherwise: The last '.' 20898 */ 20899 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 20900 s = *fnamep - 2; 20901 else 20902 s = *fnamep + *fnamelen - 1; 20903 for ( ; s > tail; --s) 20904 if (s[0] == '.') 20905 break; 20906 if (src[*usedlen + 1] == 'e') /* :e */ 20907 { 20908 if (s > tail) 20909 { 20910 *fnamelen += (int)(*fnamep - (s + 1)); 20911 *fnamep = s + 1; 20912 #ifdef VMS 20913 /* cut version from the extension */ 20914 s = *fnamep + *fnamelen - 1; 20915 for ( ; s > *fnamep; --s) 20916 if (s[0] == ';') 20917 break; 20918 if (s > *fnamep) 20919 *fnamelen = s - *fnamep; 20920 #endif 20921 } 20922 else if (*fnamep <= tail) 20923 *fnamelen = 0; 20924 } 20925 else /* :r */ 20926 { 20927 if (s > tail) /* remove one extension */ 20928 *fnamelen = (int)(s - *fnamep); 20929 } 20930 *usedlen += 2; 20931 } 20932 20933 /* ":s?pat?foo?" - substitute */ 20934 /* ":gs?pat?foo?" - global substitute */ 20935 if (src[*usedlen] == ':' 20936 && (src[*usedlen + 1] == 's' 20937 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 20938 { 20939 char_u *str; 20940 char_u *pat; 20941 char_u *sub; 20942 int sep; 20943 char_u *flags; 20944 int didit = FALSE; 20945 20946 flags = (char_u *)""; 20947 s = src + *usedlen + 2; 20948 if (src[*usedlen + 1] == 'g') 20949 { 20950 flags = (char_u *)"g"; 20951 ++s; 20952 } 20953 20954 sep = *s++; 20955 if (sep) 20956 { 20957 /* find end of pattern */ 20958 p = vim_strchr(s, sep); 20959 if (p != NULL) 20960 { 20961 pat = vim_strnsave(s, (int)(p - s)); 20962 if (pat != NULL) 20963 { 20964 s = p + 1; 20965 /* find end of substitution */ 20966 p = vim_strchr(s, sep); 20967 if (p != NULL) 20968 { 20969 sub = vim_strnsave(s, (int)(p - s)); 20970 str = vim_strnsave(*fnamep, *fnamelen); 20971 if (sub != NULL && str != NULL) 20972 { 20973 *usedlen = (int)(p + 1 - src); 20974 s = do_string_sub(str, pat, sub, flags); 20975 if (s != NULL) 20976 { 20977 *fnamep = s; 20978 *fnamelen = (int)STRLEN(s); 20979 vim_free(*bufp); 20980 *bufp = s; 20981 didit = TRUE; 20982 } 20983 } 20984 vim_free(sub); 20985 vim_free(str); 20986 } 20987 vim_free(pat); 20988 } 20989 } 20990 /* after using ":s", repeat all the modifiers */ 20991 if (didit) 20992 goto repeat; 20993 } 20994 } 20995 20996 return valid; 20997 } 20998 20999 /* 21000 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 21001 * "flags" can be "g" to do a global substitute. 21002 * Returns an allocated string, NULL for error. 21003 */ 21004 char_u * 21005 do_string_sub(str, pat, sub, flags) 21006 char_u *str; 21007 char_u *pat; 21008 char_u *sub; 21009 char_u *flags; 21010 { 21011 int sublen; 21012 regmatch_T regmatch; 21013 int i; 21014 int do_all; 21015 char_u *tail; 21016 garray_T ga; 21017 char_u *ret; 21018 char_u *save_cpo; 21019 21020 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 21021 save_cpo = p_cpo; 21022 p_cpo = (char_u *)""; 21023 21024 ga_init2(&ga, 1, 200); 21025 21026 do_all = (flags[0] == 'g'); 21027 21028 regmatch.rm_ic = p_ic; 21029 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 21030 if (regmatch.regprog != NULL) 21031 { 21032 tail = str; 21033 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 21034 { 21035 /* 21036 * Get some space for a temporary buffer to do the substitution 21037 * into. It will contain: 21038 * - The text up to where the match is. 21039 * - The substituted text. 21040 * - The text after the match. 21041 */ 21042 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 21043 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 21044 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 21045 { 21046 ga_clear(&ga); 21047 break; 21048 } 21049 21050 /* copy the text up to where the match is */ 21051 i = (int)(regmatch.startp[0] - tail); 21052 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 21053 /* add the substituted text */ 21054 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 21055 + ga.ga_len + i, TRUE, TRUE, FALSE); 21056 ga.ga_len += i + sublen - 1; 21057 /* avoid getting stuck on a match with an empty string */ 21058 if (tail == regmatch.endp[0]) 21059 { 21060 if (*tail == NUL) 21061 break; 21062 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 21063 ++ga.ga_len; 21064 } 21065 else 21066 { 21067 tail = regmatch.endp[0]; 21068 if (*tail == NUL) 21069 break; 21070 } 21071 if (!do_all) 21072 break; 21073 } 21074 21075 if (ga.ga_data != NULL) 21076 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 21077 21078 vim_free(regmatch.regprog); 21079 } 21080 21081 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 21082 ga_clear(&ga); 21083 p_cpo = save_cpo; 21084 21085 return ret; 21086 } 21087 21088 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 21089