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_children; /* time spent in children this call */ 170 /* profiling the function per line */ 171 int *uf_tml_count; /* nr of times line was executed */ 172 proftime_T *uf_tml_total; /* time spend in a line + children */ 173 proftime_T *uf_tml_self; /* time spend in a line itself */ 174 proftime_T uf_tml_start; /* start time for current line */ 175 proftime_T uf_tml_children; /* time spent in children for this line */ 176 proftime_T uf_tml_wait; /* start wait time for current line */ 177 int uf_tml_idx; /* index of line being timed; -1 if none */ 178 int uf_tml_execed; /* line being timed was executed */ 179 #endif 180 scid_T uf_script_ID; /* ID of script where function was defined, 181 used for s: variables */ 182 int uf_refcount; /* for numbered function: reference count */ 183 char_u uf_name[1]; /* name of function (actually longer); can 184 start with <SNR>123_ (<SNR> is K_SPECIAL 185 KS_EXTRA KE_SNR) */ 186 }; 187 188 /* function flags */ 189 #define FC_ABORT 1 /* abort function on error */ 190 #define FC_RANGE 2 /* function accepts range */ 191 #define FC_DICT 4 /* Dict function, uses "self" */ 192 193 /* 194 * All user-defined functions are found in this hashtable. 195 */ 196 static hashtab_T func_hashtab; 197 198 /* The names of packages that once were loaded are remembered. */ 199 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 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 {VV_NAME("mouse_win", VAR_NUMBER), 0}, 346 {VV_NAME("mouse_lnum", VAR_NUMBER), 0}, 347 {VV_NAME("mouse_col", VAR_NUMBER), 0}, 348 }; 349 350 /* shorthand */ 351 #define vv_type vv_di.di_tv.v_type 352 #define vv_nr vv_di.di_tv.vval.v_number 353 #define vv_str vv_di.di_tv.vval.v_string 354 #define vv_tv vv_di.di_tv 355 356 /* 357 * The v: variables are stored in dictionary "vimvardict". 358 * "vimvars_var" is the variable that is used for the "l:" scope. 359 */ 360 static dict_T vimvardict; 361 static dictitem_T vimvars_var; 362 #define vimvarht vimvardict.dv_hashtab 363 364 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 365 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 366 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 367 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 368 #endif 369 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 370 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 371 static char_u *skip_var_one __ARGS((char_u *arg)); 372 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 373 static void list_glob_vars __ARGS((void)); 374 static void list_buf_vars __ARGS((void)); 375 static void list_win_vars __ARGS((void)); 376 #ifdef FEAT_WINDOWS 377 static void list_tab_vars __ARGS((void)); 378 #endif 379 static void list_vim_vars __ARGS((void)); 380 static void list_script_vars __ARGS((void)); 381 static void list_func_vars __ARGS((void)); 382 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 383 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 384 static int check_changedtick __ARGS((char_u *arg)); 385 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 386 static void clear_lval __ARGS((lval_T *lp)); 387 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 388 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 389 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 390 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 391 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 392 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 393 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 394 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 395 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 396 static int tv_islocked __ARGS((typval_T *tv)); 397 398 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 399 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 400 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 401 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 402 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 403 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 404 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 405 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 406 407 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 408 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 409 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 410 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 411 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 412 static int rettv_list_alloc __ARGS((typval_T *rettv)); 413 static listitem_T *listitem_alloc __ARGS((void)); 414 static void listitem_free __ARGS((listitem_T *item)); 415 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 416 static long list_len __ARGS((list_T *l)); 417 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 418 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 419 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 420 static listitem_T *list_find __ARGS((list_T *l, long n)); 421 static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); 422 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 423 static void list_append __ARGS((list_T *l, listitem_T *item)); 424 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 425 static int list_append_string __ARGS((list_T *l, char_u *str, int len)); 426 static int list_append_number __ARGS((list_T *l, varnumber_T n)); 427 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 428 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 429 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 430 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 431 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 432 static char_u *list2string __ARGS((typval_T *tv, int copyID)); 433 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); 434 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 435 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 436 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 437 static void dict_unref __ARGS((dict_T *d)); 438 static void dict_free __ARGS((dict_T *d, int recurse)); 439 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 440 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 441 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 442 static void dictitem_free __ARGS((dictitem_T *item)); 443 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 444 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 445 static long dict_len __ARGS((dict_T *d)); 446 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 447 static char_u *dict2string __ARGS((typval_T *tv, int copyID)); 448 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 449 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 450 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)); 451 static char_u *string_quote __ARGS((char_u *str, int function)); 452 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 453 static int find_internal_func __ARGS((char_u *name)); 454 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 455 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)); 456 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)); 457 static void emsg_funcname __ARGS((char *ermsg, char_u *name)); 458 459 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 464 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 465 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 467 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 468 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 473 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 479 #if defined(FEAT_INS_EXPAND) 480 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 483 #endif 484 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 489 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_feedkeys __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_gettabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_haslocaldir __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 565 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 586 #ifdef vim_mkdir 587 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 588 #endif 589 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_reltimestr __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_searchpairpos __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_searchpos __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_str2nr __ARGS((typval_T *argvars, typval_T *rettv)); 634 #ifdef HAVE_STRFTIME 635 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 636 #endif 637 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 638 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 639 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 640 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 641 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 642 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 643 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 644 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 645 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 646 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 647 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 648 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 649 static void f_tabpagebuflist __ARGS((typval_T *argvars, typval_T *rettv)); 650 static void f_tabpagenr __ARGS((typval_T *argvars, typval_T *rettv)); 651 static void f_tabpagewinnr __ARGS((typval_T *argvars, typval_T *rettv)); 652 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 653 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 654 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 655 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 656 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 657 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 658 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 659 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 660 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 661 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 662 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 663 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 664 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 665 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 666 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 667 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 668 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 669 static void f_winrestview __ARGS((typval_T *argvars, typval_T *rettv)); 670 static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); 671 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 672 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 673 674 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); 675 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum)); 676 static int get_env_len __ARGS((char_u **arg)); 677 static int get_id_len __ARGS((char_u **arg)); 678 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 679 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 680 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 681 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 682 valid character */ 683 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 684 static int eval_isnamec __ARGS((int c)); 685 static int eval_isnamec1 __ARGS((int c)); 686 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 687 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 688 static typval_T *alloc_tv __ARGS((void)); 689 static typval_T *alloc_string_tv __ARGS((char_u *string)); 690 static void init_tv __ARGS((typval_T *varp)); 691 static long get_tv_number __ARGS((typval_T *varp)); 692 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 693 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 694 static char_u *get_tv_string __ARGS((typval_T *varp)); 695 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 696 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 697 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 698 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 699 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 700 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 701 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 702 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 703 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 704 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 705 static int var_check_ro __ARGS((int flags, char_u *name)); 706 static int var_check_fixed __ARGS((int flags, char_u *name)); 707 static int tv_check_lock __ARGS((int lock, char_u *name)); 708 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 709 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 710 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 711 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 712 static int eval_fname_script __ARGS((char_u *p)); 713 static int eval_fname_sid __ARGS((char_u *p)); 714 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 715 static ufunc_T *find_func __ARGS((char_u *name)); 716 static int function_exists __ARGS((char_u *name)); 717 static int builtin_function __ARGS((char_u *name)); 718 #ifdef FEAT_PROFILE 719 static void func_do_profile __ARGS((ufunc_T *fp)); 720 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 721 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 722 static int 723 # ifdef __BORLANDC__ 724 _RTLENTRYF 725 # endif 726 prof_total_cmp __ARGS((const void *s1, const void *s2)); 727 static int 728 # ifdef __BORLANDC__ 729 _RTLENTRYF 730 # endif 731 prof_self_cmp __ARGS((const void *s1, const void *s2)); 732 #endif 733 static int script_autoload __ARGS((char_u *name, int reload)); 734 static char_u *autoload_name __ARGS((char_u *name)); 735 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 736 static void func_free __ARGS((ufunc_T *fp)); 737 static void func_unref __ARGS((char_u *name)); 738 static void func_ref __ARGS((char_u *name)); 739 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)); 740 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 741 static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); 742 static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 743 static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos)); 744 static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp)); 745 static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); 746 747 /* Character used as separated in autoload function/variable names. */ 748 #define AUTOLOAD_CHAR '#' 749 750 /* 751 * Initialize the global and v: variables. 752 */ 753 void 754 eval_init() 755 { 756 int i; 757 struct vimvar *p; 758 759 init_var_dict(&globvardict, &globvars_var); 760 init_var_dict(&vimvardict, &vimvars_var); 761 hash_init(&compat_hashtab); 762 hash_init(&func_hashtab); 763 764 for (i = 0; i < VV_LEN; ++i) 765 { 766 p = &vimvars[i]; 767 STRCPY(p->vv_di.di_key, p->vv_name); 768 if (p->vv_flags & VV_RO) 769 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 770 else if (p->vv_flags & VV_RO_SBX) 771 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 772 else 773 p->vv_di.di_flags = DI_FLAGS_FIX; 774 775 /* add to v: scope dict, unless the value is not always available */ 776 if (p->vv_type != VAR_UNKNOWN) 777 hash_add(&vimvarht, p->vv_di.di_key); 778 if (p->vv_flags & VV_COMPAT) 779 /* add to compat scope dict */ 780 hash_add(&compat_hashtab, p->vv_di.di_key); 781 } 782 } 783 784 #if defined(EXITFREE) || defined(PROTO) 785 void 786 eval_clear() 787 { 788 int i; 789 struct vimvar *p; 790 791 for (i = 0; i < VV_LEN; ++i) 792 { 793 p = &vimvars[i]; 794 if (p->vv_di.di_tv.v_type == VAR_STRING) 795 { 796 vim_free(p->vv_di.di_tv.vval.v_string); 797 p->vv_di.di_tv.vval.v_string = NULL; 798 } 799 } 800 hash_clear(&vimvarht); 801 hash_clear(&compat_hashtab); 802 803 /* script-local variables */ 804 for (i = 1; i <= ga_scripts.ga_len; ++i) 805 vars_clear(&SCRIPT_VARS(i)); 806 ga_clear(&ga_scripts); 807 free_scriptnames(); 808 809 /* global variables */ 810 vars_clear(&globvarht); 811 812 /* functions */ 813 free_all_functions(); 814 hash_clear(&func_hashtab); 815 816 /* autoloaded script names */ 817 ga_clear_strings(&ga_loaded); 818 819 /* unreferenced lists and dicts */ 820 (void)garbage_collect(); 821 } 822 #endif 823 824 /* 825 * Return the name of the executed function. 826 */ 827 char_u * 828 func_name(cookie) 829 void *cookie; 830 { 831 return ((funccall_T *)cookie)->func->uf_name; 832 } 833 834 /* 835 * Return the address holding the next breakpoint line for a funccall cookie. 836 */ 837 linenr_T * 838 func_breakpoint(cookie) 839 void *cookie; 840 { 841 return &((funccall_T *)cookie)->breakpoint; 842 } 843 844 /* 845 * Return the address holding the debug tick for a funccall cookie. 846 */ 847 int * 848 func_dbg_tick(cookie) 849 void *cookie; 850 { 851 return &((funccall_T *)cookie)->dbg_tick; 852 } 853 854 /* 855 * Return the nesting level for a funccall cookie. 856 */ 857 int 858 func_level(cookie) 859 void *cookie; 860 { 861 return ((funccall_T *)cookie)->level; 862 } 863 864 /* pointer to funccal for currently active function */ 865 funccall_T *current_funccal = NULL; 866 867 /* 868 * Return TRUE when a function was ended by a ":return" command. 869 */ 870 int 871 current_func_returned() 872 { 873 return current_funccal->returned; 874 } 875 876 877 /* 878 * Set an internal variable to a string value. Creates the variable if it does 879 * not already exist. 880 */ 881 void 882 set_internal_string_var(name, value) 883 char_u *name; 884 char_u *value; 885 { 886 char_u *val; 887 typval_T *tvp; 888 889 val = vim_strsave(value); 890 if (val != NULL) 891 { 892 tvp = alloc_string_tv(val); 893 if (tvp != NULL) 894 { 895 set_var(name, tvp, FALSE); 896 free_tv(tvp); 897 } 898 } 899 } 900 901 static lval_T *redir_lval = NULL; 902 static garray_T redir_ga; /* only valid when redir_lval is not NULL */ 903 static char_u *redir_endp = NULL; 904 static char_u *redir_varname = NULL; 905 906 /* 907 * Start recording command output to a variable 908 * Returns OK if successfully completed the setup. FAIL otherwise. 909 */ 910 int 911 var_redir_start(name, append) 912 char_u *name; 913 int append; /* append to an existing variable */ 914 { 915 int save_emsg; 916 int err; 917 typval_T tv; 918 919 /* Make sure a valid variable name is specified */ 920 if (!eval_isnamec1(*name)) 921 { 922 EMSG(_(e_invarg)); 923 return FAIL; 924 } 925 926 redir_varname = vim_strsave(name); 927 if (redir_varname == NULL) 928 return FAIL; 929 930 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 931 if (redir_lval == NULL) 932 { 933 var_redir_stop(); 934 return FAIL; 935 } 936 937 /* The output is stored in growarray "redir_ga" until redirection ends. */ 938 ga_init2(&redir_ga, (int)sizeof(char), 500); 939 940 /* Parse the variable name (can be a dict or list entry). */ 941 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 942 FNE_CHECK_START); 943 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 944 { 945 if (redir_endp != NULL && *redir_endp != NUL) 946 /* Trailing characters are present after the variable name */ 947 EMSG(_(e_trailing)); 948 else 949 EMSG(_(e_invarg)); 950 var_redir_stop(); 951 return FAIL; 952 } 953 954 /* check if we can write to the variable: set it to or append an empty 955 * string */ 956 save_emsg = did_emsg; 957 did_emsg = FALSE; 958 tv.v_type = VAR_STRING; 959 tv.vval.v_string = (char_u *)""; 960 if (append) 961 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 962 else 963 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 964 err = did_emsg; 965 did_emsg |= save_emsg; 966 if (err) 967 { 968 var_redir_stop(); 969 return FAIL; 970 } 971 if (redir_lval->ll_newkey != NULL) 972 { 973 /* Dictionary item was created, don't do it again. */ 974 vim_free(redir_lval->ll_newkey); 975 redir_lval->ll_newkey = NULL; 976 } 977 978 return OK; 979 } 980 981 /* 982 * Append "value[value_len]" to the variable set by var_redir_start(). 983 * The actual appending is postponed until redirection ends, because the value 984 * appended may in fact be the string we write to, changing it may cause freed 985 * memory to be used: 986 * :redir => foo 987 * :let foo 988 * :redir END 989 */ 990 void 991 var_redir_str(value, value_len) 992 char_u *value; 993 int value_len; 994 { 995 size_t len; 996 997 if (redir_lval == NULL) 998 return; 999 1000 if (value_len == -1) 1001 len = STRLEN(value); /* Append the entire string */ 1002 else 1003 len = value_len; /* Append only "value_len" characters */ 1004 1005 if (ga_grow(&redir_ga, (int)len) == OK) 1006 { 1007 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); 1008 redir_ga.ga_len += (int)len; 1009 } 1010 else 1011 var_redir_stop(); 1012 } 1013 1014 /* 1015 * Stop redirecting command output to a variable. 1016 */ 1017 void 1018 var_redir_stop() 1019 { 1020 typval_T tv; 1021 1022 if (redir_lval != NULL) 1023 { 1024 /* Append the trailing NUL. */ 1025 ga_append(&redir_ga, NUL); 1026 1027 /* Assign the text to the variable. */ 1028 tv.v_type = VAR_STRING; 1029 tv.vval.v_string = redir_ga.ga_data; 1030 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 1031 vim_free(tv.vval.v_string); 1032 1033 clear_lval(redir_lval); 1034 vim_free(redir_lval); 1035 redir_lval = NULL; 1036 } 1037 vim_free(redir_varname); 1038 redir_varname = NULL; 1039 } 1040 1041 # if defined(FEAT_MBYTE) || defined(PROTO) 1042 int 1043 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 1044 char_u *enc_from; 1045 char_u *enc_to; 1046 char_u *fname_from; 1047 char_u *fname_to; 1048 { 1049 int err = FALSE; 1050 1051 set_vim_var_string(VV_CC_FROM, enc_from, -1); 1052 set_vim_var_string(VV_CC_TO, enc_to, -1); 1053 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 1054 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1055 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1056 err = TRUE; 1057 set_vim_var_string(VV_CC_FROM, NULL, -1); 1058 set_vim_var_string(VV_CC_TO, NULL, -1); 1059 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1060 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1061 1062 if (err) 1063 return FAIL; 1064 return OK; 1065 } 1066 # endif 1067 1068 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1069 int 1070 eval_printexpr(fname, args) 1071 char_u *fname; 1072 char_u *args; 1073 { 1074 int err = FALSE; 1075 1076 set_vim_var_string(VV_FNAME_IN, fname, -1); 1077 set_vim_var_string(VV_CMDARG, args, -1); 1078 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1079 err = TRUE; 1080 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1081 set_vim_var_string(VV_CMDARG, NULL, -1); 1082 1083 if (err) 1084 { 1085 mch_remove(fname); 1086 return FAIL; 1087 } 1088 return OK; 1089 } 1090 # endif 1091 1092 # if defined(FEAT_DIFF) || defined(PROTO) 1093 void 1094 eval_diff(origfile, newfile, outfile) 1095 char_u *origfile; 1096 char_u *newfile; 1097 char_u *outfile; 1098 { 1099 int err = FALSE; 1100 1101 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1102 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1103 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1104 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1105 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1106 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1107 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1108 } 1109 1110 void 1111 eval_patch(origfile, difffile, outfile) 1112 char_u *origfile; 1113 char_u *difffile; 1114 char_u *outfile; 1115 { 1116 int err; 1117 1118 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1119 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1120 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1121 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1122 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1123 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1124 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1125 } 1126 # endif 1127 1128 /* 1129 * Top level evaluation function, returning a boolean. 1130 * Sets "error" to TRUE if there was an error. 1131 * Return TRUE or FALSE. 1132 */ 1133 int 1134 eval_to_bool(arg, error, nextcmd, skip) 1135 char_u *arg; 1136 int *error; 1137 char_u **nextcmd; 1138 int skip; /* only parse, don't execute */ 1139 { 1140 typval_T tv; 1141 int retval = FALSE; 1142 1143 if (skip) 1144 ++emsg_skip; 1145 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1146 *error = TRUE; 1147 else 1148 { 1149 *error = FALSE; 1150 if (!skip) 1151 { 1152 retval = (get_tv_number_chk(&tv, error) != 0); 1153 clear_tv(&tv); 1154 } 1155 } 1156 if (skip) 1157 --emsg_skip; 1158 1159 return retval; 1160 } 1161 1162 /* 1163 * Top level evaluation function, returning a string. If "skip" is TRUE, 1164 * only parsing to "nextcmd" is done, without reporting errors. Return 1165 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1166 */ 1167 char_u * 1168 eval_to_string_skip(arg, nextcmd, skip) 1169 char_u *arg; 1170 char_u **nextcmd; 1171 int skip; /* only parse, don't execute */ 1172 { 1173 typval_T tv; 1174 char_u *retval; 1175 1176 if (skip) 1177 ++emsg_skip; 1178 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1179 retval = NULL; 1180 else 1181 { 1182 retval = vim_strsave(get_tv_string(&tv)); 1183 clear_tv(&tv); 1184 } 1185 if (skip) 1186 --emsg_skip; 1187 1188 return retval; 1189 } 1190 1191 /* 1192 * Skip over an expression at "*pp". 1193 * Return FAIL for an error, OK otherwise. 1194 */ 1195 int 1196 skip_expr(pp) 1197 char_u **pp; 1198 { 1199 typval_T rettv; 1200 1201 *pp = skipwhite(*pp); 1202 return eval1(pp, &rettv, FALSE); 1203 } 1204 1205 /* 1206 * Top level evaluation function, returning a string. 1207 * Return pointer to allocated memory, or NULL for failure. 1208 */ 1209 char_u * 1210 eval_to_string(arg, nextcmd, dolist) 1211 char_u *arg; 1212 char_u **nextcmd; 1213 int dolist; /* turn List into sequence of lines */ 1214 { 1215 typval_T tv; 1216 char_u *retval; 1217 garray_T ga; 1218 1219 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1220 retval = NULL; 1221 else 1222 { 1223 if (dolist && tv.v_type == VAR_LIST) 1224 { 1225 ga_init2(&ga, (int)sizeof(char), 80); 1226 list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0); 1227 ga_append(&ga, NUL); 1228 retval = (char_u *)ga.ga_data; 1229 } 1230 else 1231 retval = vim_strsave(get_tv_string(&tv)); 1232 clear_tv(&tv); 1233 } 1234 1235 return retval; 1236 } 1237 1238 /* 1239 * Call eval_to_string() without using current local variables and using 1240 * textlock. When "use_sandbox" is TRUE use the sandbox. 1241 */ 1242 char_u * 1243 eval_to_string_safe(arg, nextcmd, use_sandbox) 1244 char_u *arg; 1245 char_u **nextcmd; 1246 int use_sandbox; 1247 { 1248 char_u *retval; 1249 void *save_funccalp; 1250 1251 save_funccalp = save_funccal(); 1252 if (use_sandbox) 1253 ++sandbox; 1254 ++textlock; 1255 retval = eval_to_string(arg, nextcmd, FALSE); 1256 if (use_sandbox) 1257 --sandbox; 1258 --textlock; 1259 restore_funccal(save_funccalp); 1260 return retval; 1261 } 1262 1263 /* 1264 * Top level evaluation function, returning a number. 1265 * Evaluates "expr" silently. 1266 * Returns -1 for an error. 1267 */ 1268 int 1269 eval_to_number(expr) 1270 char_u *expr; 1271 { 1272 typval_T rettv; 1273 int retval; 1274 char_u *p = skipwhite(expr); 1275 1276 ++emsg_off; 1277 1278 if (eval1(&p, &rettv, TRUE) == FAIL) 1279 retval = -1; 1280 else 1281 { 1282 retval = get_tv_number_chk(&rettv, NULL); 1283 clear_tv(&rettv); 1284 } 1285 --emsg_off; 1286 1287 return retval; 1288 } 1289 1290 /* 1291 * Prepare v: variable "idx" to be used. 1292 * Save the current typeval in "save_tv". 1293 * When not used yet add the variable to the v: hashtable. 1294 */ 1295 static void 1296 prepare_vimvar(idx, save_tv) 1297 int idx; 1298 typval_T *save_tv; 1299 { 1300 *save_tv = vimvars[idx].vv_tv; 1301 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1302 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1303 } 1304 1305 /* 1306 * Restore v: variable "idx" to typeval "save_tv". 1307 * When no longer defined, remove the variable from the v: hashtable. 1308 */ 1309 static void 1310 restore_vimvar(idx, save_tv) 1311 int idx; 1312 typval_T *save_tv; 1313 { 1314 hashitem_T *hi; 1315 1316 clear_tv(&vimvars[idx].vv_tv); 1317 vimvars[idx].vv_tv = *save_tv; 1318 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1319 { 1320 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1321 if (HASHITEM_EMPTY(hi)) 1322 EMSG2(_(e_intern2), "restore_vimvar()"); 1323 else 1324 hash_remove(&vimvarht, hi); 1325 } 1326 } 1327 1328 #if defined(FEAT_SPELL) || defined(PROTO) 1329 /* 1330 * Evaluate an expression to a list with suggestions. 1331 * For the "expr:" part of 'spellsuggest'. 1332 */ 1333 list_T * 1334 eval_spell_expr(badword, expr) 1335 char_u *badword; 1336 char_u *expr; 1337 { 1338 typval_T save_val; 1339 typval_T rettv; 1340 list_T *list = NULL; 1341 char_u *p = skipwhite(expr); 1342 1343 /* Set "v:val" to the bad word. */ 1344 prepare_vimvar(VV_VAL, &save_val); 1345 vimvars[VV_VAL].vv_type = VAR_STRING; 1346 vimvars[VV_VAL].vv_str = badword; 1347 if (p_verbose == 0) 1348 ++emsg_off; 1349 1350 if (eval1(&p, &rettv, TRUE) == OK) 1351 { 1352 if (rettv.v_type != VAR_LIST) 1353 clear_tv(&rettv); 1354 else 1355 list = rettv.vval.v_list; 1356 } 1357 1358 if (p_verbose == 0) 1359 --emsg_off; 1360 vimvars[VV_VAL].vv_str = NULL; 1361 restore_vimvar(VV_VAL, &save_val); 1362 1363 return list; 1364 } 1365 1366 /* 1367 * "list" is supposed to contain two items: a word and a number. Return the 1368 * word in "pp" and the number as the return value. 1369 * Return -1 if anything isn't right. 1370 * Used to get the good word and score from the eval_spell_expr() result. 1371 */ 1372 int 1373 get_spellword(list, pp) 1374 list_T *list; 1375 char_u **pp; 1376 { 1377 listitem_T *li; 1378 1379 li = list->lv_first; 1380 if (li == NULL) 1381 return -1; 1382 *pp = get_tv_string(&li->li_tv); 1383 1384 li = li->li_next; 1385 if (li == NULL) 1386 return -1; 1387 return get_tv_number(&li->li_tv); 1388 } 1389 #endif 1390 1391 /* 1392 * Top level evaluation function. 1393 * Returns an allocated typval_T with the result. 1394 * Returns NULL when there is an error. 1395 */ 1396 typval_T * 1397 eval_expr(arg, nextcmd) 1398 char_u *arg; 1399 char_u **nextcmd; 1400 { 1401 typval_T *tv; 1402 1403 tv = (typval_T *)alloc(sizeof(typval_T)); 1404 if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL) 1405 { 1406 vim_free(tv); 1407 tv = NULL; 1408 } 1409 1410 return tv; 1411 } 1412 1413 1414 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1415 /* 1416 * Call some vimL function and return the result in "*rettv". 1417 * Uses argv[argc] for the function arguments. 1418 * Returns OK or FAIL. 1419 */ 1420 static int 1421 call_vim_function(func, argc, argv, safe, rettv) 1422 char_u *func; 1423 int argc; 1424 char_u **argv; 1425 int safe; /* use the sandbox */ 1426 typval_T *rettv; 1427 { 1428 typval_T *argvars; 1429 long n; 1430 int len; 1431 int i; 1432 int doesrange; 1433 void *save_funccalp = NULL; 1434 int ret; 1435 1436 argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T))); 1437 if (argvars == NULL) 1438 return FAIL; 1439 1440 for (i = 0; i < argc; i++) 1441 { 1442 /* Pass a NULL or empty argument as an empty string */ 1443 if (argv[i] == NULL || *argv[i] == NUL) 1444 { 1445 argvars[i].v_type = VAR_STRING; 1446 argvars[i].vval.v_string = (char_u *)""; 1447 continue; 1448 } 1449 1450 /* Recognize a number argument, the others must be strings. */ 1451 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1452 if (len != 0 && len == (int)STRLEN(argv[i])) 1453 { 1454 argvars[i].v_type = VAR_NUMBER; 1455 argvars[i].vval.v_number = n; 1456 } 1457 else 1458 { 1459 argvars[i].v_type = VAR_STRING; 1460 argvars[i].vval.v_string = argv[i]; 1461 } 1462 } 1463 1464 if (safe) 1465 { 1466 save_funccalp = save_funccal(); 1467 ++sandbox; 1468 } 1469 1470 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1471 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1472 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1473 &doesrange, TRUE, NULL); 1474 if (safe) 1475 { 1476 --sandbox; 1477 restore_funccal(save_funccalp); 1478 } 1479 vim_free(argvars); 1480 1481 if (ret == FAIL) 1482 clear_tv(rettv); 1483 1484 return ret; 1485 } 1486 1487 /* 1488 * Call vimL function "func" and return the result as a string. 1489 * Returns NULL when calling the function fails. 1490 * Uses argv[argc] for the function arguments. 1491 */ 1492 void * 1493 call_func_retstr(func, argc, argv, safe) 1494 char_u *func; 1495 int argc; 1496 char_u **argv; 1497 int safe; /* use the sandbox */ 1498 { 1499 typval_T rettv; 1500 char_u *retval; 1501 1502 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1503 return NULL; 1504 1505 retval = vim_strsave(get_tv_string(&rettv)); 1506 clear_tv(&rettv); 1507 return retval; 1508 } 1509 1510 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1511 /* 1512 * Call vimL function "func" and return the result as a number. 1513 * Returns -1 when calling the function fails. 1514 * Uses argv[argc] for the function arguments. 1515 */ 1516 long 1517 call_func_retnr(func, argc, argv, safe) 1518 char_u *func; 1519 int argc; 1520 char_u **argv; 1521 int safe; /* use the sandbox */ 1522 { 1523 typval_T rettv; 1524 long retval; 1525 1526 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1527 return -1; 1528 1529 retval = get_tv_number_chk(&rettv, NULL); 1530 clear_tv(&rettv); 1531 return retval; 1532 } 1533 #endif 1534 1535 /* 1536 * Call vimL function "func" and return the result as a list 1537 * Uses argv[argc] for the function arguments. 1538 */ 1539 void * 1540 call_func_retlist(func, argc, argv, safe) 1541 char_u *func; 1542 int argc; 1543 char_u **argv; 1544 int safe; /* use the sandbox */ 1545 { 1546 typval_T rettv; 1547 1548 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1549 return NULL; 1550 1551 if (rettv.v_type != VAR_LIST) 1552 { 1553 clear_tv(&rettv); 1554 return NULL; 1555 } 1556 1557 return rettv.vval.v_list; 1558 } 1559 1560 #endif 1561 1562 /* 1563 * Save the current function call pointer, and set it to NULL. 1564 * Used when executing autocommands and for ":source". 1565 */ 1566 void * 1567 save_funccal() 1568 { 1569 funccall_T *fc = current_funccal; 1570 1571 current_funccal = NULL; 1572 return (void *)fc; 1573 } 1574 1575 void 1576 restore_funccal(vfc) 1577 void *vfc; 1578 { 1579 funccall_T *fc = (funccall_T *)vfc; 1580 1581 current_funccal = fc; 1582 } 1583 1584 #if defined(FEAT_PROFILE) || defined(PROTO) 1585 /* 1586 * Prepare profiling for entering a child or something else that is not 1587 * counted for the script/function itself. 1588 * Should always be called in pair with prof_child_exit(). 1589 */ 1590 void 1591 prof_child_enter(tm) 1592 proftime_T *tm; /* place to store waittime */ 1593 { 1594 funccall_T *fc = current_funccal; 1595 1596 if (fc != NULL && fc->func->uf_profiling) 1597 profile_start(&fc->prof_child); 1598 script_prof_save(tm); 1599 } 1600 1601 /* 1602 * Take care of time spent in a child. 1603 * Should always be called after prof_child_enter(). 1604 */ 1605 void 1606 prof_child_exit(tm) 1607 proftime_T *tm; /* where waittime was stored */ 1608 { 1609 funccall_T *fc = current_funccal; 1610 1611 if (fc != NULL && fc->func->uf_profiling) 1612 { 1613 profile_end(&fc->prof_child); 1614 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1615 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1616 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1617 } 1618 script_prof_restore(tm); 1619 } 1620 #endif 1621 1622 1623 #ifdef FEAT_FOLDING 1624 /* 1625 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1626 * it in "*cp". Doesn't give error messages. 1627 */ 1628 int 1629 eval_foldexpr(arg, cp) 1630 char_u *arg; 1631 int *cp; 1632 { 1633 typval_T tv; 1634 int retval; 1635 char_u *s; 1636 int use_sandbox = was_set_insecurely((char_u *)"foldexpr", 1637 OPT_LOCAL); 1638 1639 ++emsg_off; 1640 if (use_sandbox) 1641 ++sandbox; 1642 ++textlock; 1643 *cp = NUL; 1644 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1645 retval = 0; 1646 else 1647 { 1648 /* If the result is a number, just return the number. */ 1649 if (tv.v_type == VAR_NUMBER) 1650 retval = tv.vval.v_number; 1651 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1652 retval = 0; 1653 else 1654 { 1655 /* If the result is a string, check if there is a non-digit before 1656 * the number. */ 1657 s = tv.vval.v_string; 1658 if (!VIM_ISDIGIT(*s) && *s != '-') 1659 *cp = *s++; 1660 retval = atol((char *)s); 1661 } 1662 clear_tv(&tv); 1663 } 1664 --emsg_off; 1665 if (use_sandbox) 1666 --sandbox; 1667 --textlock; 1668 1669 return retval; 1670 } 1671 #endif 1672 1673 /* 1674 * ":let" list all variable values 1675 * ":let var1 var2" list variable values 1676 * ":let var = expr" assignment command. 1677 * ":let var += expr" assignment command. 1678 * ":let var -= expr" assignment command. 1679 * ":let var .= expr" assignment command. 1680 * ":let [var1, var2] = expr" unpack list. 1681 */ 1682 void 1683 ex_let(eap) 1684 exarg_T *eap; 1685 { 1686 char_u *arg = eap->arg; 1687 char_u *expr = NULL; 1688 typval_T rettv; 1689 int i; 1690 int var_count = 0; 1691 int semicolon = 0; 1692 char_u op[2]; 1693 char_u *argend; 1694 1695 argend = skip_var_list(arg, &var_count, &semicolon); 1696 if (argend == NULL) 1697 return; 1698 if (argend > arg && argend[-1] == '.') /* for var.='str' */ 1699 --argend; 1700 expr = vim_strchr(argend, '='); 1701 if (expr == NULL) 1702 { 1703 /* 1704 * ":let" without "=": list variables 1705 */ 1706 if (*arg == '[') 1707 EMSG(_(e_invarg)); 1708 else if (!ends_excmd(*arg)) 1709 /* ":let var1 var2" */ 1710 arg = list_arg_vars(eap, arg); 1711 else if (!eap->skip) 1712 { 1713 /* ":let" */ 1714 list_glob_vars(); 1715 list_buf_vars(); 1716 list_win_vars(); 1717 #ifdef FEAT_WINDOWS 1718 list_tab_vars(); 1719 #endif 1720 list_script_vars(); 1721 list_func_vars(); 1722 list_vim_vars(); 1723 } 1724 eap->nextcmd = check_nextcmd(arg); 1725 } 1726 else 1727 { 1728 op[0] = '='; 1729 op[1] = NUL; 1730 if (expr > argend) 1731 { 1732 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1733 op[0] = expr[-1]; /* +=, -= or .= */ 1734 } 1735 expr = skipwhite(expr + 1); 1736 1737 if (eap->skip) 1738 ++emsg_skip; 1739 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1740 if (eap->skip) 1741 { 1742 if (i != FAIL) 1743 clear_tv(&rettv); 1744 --emsg_skip; 1745 } 1746 else if (i != FAIL) 1747 { 1748 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1749 op); 1750 clear_tv(&rettv); 1751 } 1752 } 1753 } 1754 1755 /* 1756 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1757 * Handles both "var" with any type and "[var, var; var]" with a list type. 1758 * When "nextchars" is not NULL it points to a string with characters that 1759 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1760 * or concatenate. 1761 * Returns OK or FAIL; 1762 */ 1763 static int 1764 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1765 char_u *arg_start; 1766 typval_T *tv; 1767 int copy; /* copy values from "tv", don't move */ 1768 int semicolon; /* from skip_var_list() */ 1769 int var_count; /* from skip_var_list() */ 1770 char_u *nextchars; 1771 { 1772 char_u *arg = arg_start; 1773 list_T *l; 1774 int i; 1775 listitem_T *item; 1776 typval_T ltv; 1777 1778 if (*arg != '[') 1779 { 1780 /* 1781 * ":let var = expr" or ":for var in list" 1782 */ 1783 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1784 return FAIL; 1785 return OK; 1786 } 1787 1788 /* 1789 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1790 */ 1791 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1792 { 1793 EMSG(_(e_listreq)); 1794 return FAIL; 1795 } 1796 1797 i = list_len(l); 1798 if (semicolon == 0 && var_count < i) 1799 { 1800 EMSG(_("E687: Less targets than List items")); 1801 return FAIL; 1802 } 1803 if (var_count - semicolon > i) 1804 { 1805 EMSG(_("E688: More targets than List items")); 1806 return FAIL; 1807 } 1808 1809 item = l->lv_first; 1810 while (*arg != ']') 1811 { 1812 arg = skipwhite(arg + 1); 1813 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1814 item = item->li_next; 1815 if (arg == NULL) 1816 return FAIL; 1817 1818 arg = skipwhite(arg); 1819 if (*arg == ';') 1820 { 1821 /* Put the rest of the list (may be empty) in the var after ';'. 1822 * Create a new list for this. */ 1823 l = list_alloc(); 1824 if (l == NULL) 1825 return FAIL; 1826 while (item != NULL) 1827 { 1828 list_append_tv(l, &item->li_tv); 1829 item = item->li_next; 1830 } 1831 1832 ltv.v_type = VAR_LIST; 1833 ltv.v_lock = 0; 1834 ltv.vval.v_list = l; 1835 l->lv_refcount = 1; 1836 1837 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1838 (char_u *)"]", nextchars); 1839 clear_tv(<v); 1840 if (arg == NULL) 1841 return FAIL; 1842 break; 1843 } 1844 else if (*arg != ',' && *arg != ']') 1845 { 1846 EMSG2(_(e_intern2), "ex_let_vars()"); 1847 return FAIL; 1848 } 1849 } 1850 1851 return OK; 1852 } 1853 1854 /* 1855 * Skip over assignable variable "var" or list of variables "[var, var]". 1856 * Used for ":let varvar = expr" and ":for varvar in expr". 1857 * For "[var, var]" increment "*var_count" for each variable. 1858 * for "[var, var; var]" set "semicolon". 1859 * Return NULL for an error. 1860 */ 1861 static char_u * 1862 skip_var_list(arg, var_count, semicolon) 1863 char_u *arg; 1864 int *var_count; 1865 int *semicolon; 1866 { 1867 char_u *p, *s; 1868 1869 if (*arg == '[') 1870 { 1871 /* "[var, var]": find the matching ']'. */ 1872 p = arg; 1873 for (;;) 1874 { 1875 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1876 s = skip_var_one(p); 1877 if (s == p) 1878 { 1879 EMSG2(_(e_invarg2), p); 1880 return NULL; 1881 } 1882 ++*var_count; 1883 1884 p = skipwhite(s); 1885 if (*p == ']') 1886 break; 1887 else if (*p == ';') 1888 { 1889 if (*semicolon == 1) 1890 { 1891 EMSG(_("Double ; in list of variables")); 1892 return NULL; 1893 } 1894 *semicolon = 1; 1895 } 1896 else if (*p != ',') 1897 { 1898 EMSG2(_(e_invarg2), p); 1899 return NULL; 1900 } 1901 } 1902 return p + 1; 1903 } 1904 else 1905 return skip_var_one(arg); 1906 } 1907 1908 /* 1909 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1910 * l[idx]. 1911 */ 1912 static char_u * 1913 skip_var_one(arg) 1914 char_u *arg; 1915 { 1916 if (*arg == '@' && arg[1] != NUL) 1917 return arg + 2; 1918 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1919 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1920 } 1921 1922 /* 1923 * List variables for hashtab "ht" with prefix "prefix". 1924 * If "empty" is TRUE also list NULL strings as empty strings. 1925 */ 1926 static void 1927 list_hashtable_vars(ht, prefix, empty) 1928 hashtab_T *ht; 1929 char_u *prefix; 1930 int empty; 1931 { 1932 hashitem_T *hi; 1933 dictitem_T *di; 1934 int todo; 1935 1936 todo = (int)ht->ht_used; 1937 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1938 { 1939 if (!HASHITEM_EMPTY(hi)) 1940 { 1941 --todo; 1942 di = HI2DI(hi); 1943 if (empty || di->di_tv.v_type != VAR_STRING 1944 || di->di_tv.vval.v_string != NULL) 1945 list_one_var(di, prefix); 1946 } 1947 } 1948 } 1949 1950 /* 1951 * List global variables. 1952 */ 1953 static void 1954 list_glob_vars() 1955 { 1956 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1957 } 1958 1959 /* 1960 * List buffer variables. 1961 */ 1962 static void 1963 list_buf_vars() 1964 { 1965 char_u numbuf[NUMBUFLEN]; 1966 1967 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1968 1969 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1970 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1971 } 1972 1973 /* 1974 * List window variables. 1975 */ 1976 static void 1977 list_win_vars() 1978 { 1979 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1980 } 1981 1982 #ifdef FEAT_WINDOWS 1983 /* 1984 * List tab page variables. 1985 */ 1986 static void 1987 list_tab_vars() 1988 { 1989 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE); 1990 } 1991 #endif 1992 1993 /* 1994 * List Vim variables. 1995 */ 1996 static void 1997 list_vim_vars() 1998 { 1999 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 2000 } 2001 2002 /* 2003 * List script-local variables, if there is a script. 2004 */ 2005 static void 2006 list_script_vars() 2007 { 2008 if (current_SID > 0 && current_SID <= ga_scripts.ga_len) 2009 list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE); 2010 } 2011 2012 /* 2013 * List function variables, if there is a function. 2014 */ 2015 static void 2016 list_func_vars() 2017 { 2018 if (current_funccal != NULL) 2019 list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, 2020 (char_u *)"l:", FALSE); 2021 } 2022 2023 /* 2024 * List variables in "arg". 2025 */ 2026 static char_u * 2027 list_arg_vars(eap, arg) 2028 exarg_T *eap; 2029 char_u *arg; 2030 { 2031 int error = FALSE; 2032 int len; 2033 char_u *name; 2034 char_u *name_start; 2035 char_u *arg_subsc; 2036 char_u *tofree; 2037 typval_T tv; 2038 2039 while (!ends_excmd(*arg) && !got_int) 2040 { 2041 if (error || eap->skip) 2042 { 2043 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 2044 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 2045 { 2046 emsg_severe = TRUE; 2047 EMSG(_(e_trailing)); 2048 break; 2049 } 2050 } 2051 else 2052 { 2053 /* get_name_len() takes care of expanding curly braces */ 2054 name_start = name = arg; 2055 len = get_name_len(&arg, &tofree, TRUE, TRUE); 2056 if (len <= 0) 2057 { 2058 /* This is mainly to keep test 49 working: when expanding 2059 * curly braces fails overrule the exception error message. */ 2060 if (len < 0 && !aborting()) 2061 { 2062 emsg_severe = TRUE; 2063 EMSG2(_(e_invarg2), arg); 2064 break; 2065 } 2066 error = TRUE; 2067 } 2068 else 2069 { 2070 if (tofree != NULL) 2071 name = tofree; 2072 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 2073 error = TRUE; 2074 else 2075 { 2076 /* handle d.key, l[idx], f(expr) */ 2077 arg_subsc = arg; 2078 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 2079 error = TRUE; 2080 else 2081 { 2082 if (arg == arg_subsc && len == 2 && name[1] == ':') 2083 { 2084 switch (*name) 2085 { 2086 case 'g': list_glob_vars(); break; 2087 case 'b': list_buf_vars(); break; 2088 case 'w': list_win_vars(); break; 2089 #ifdef FEAT_WINDOWS 2090 case 't': list_tab_vars(); break; 2091 #endif 2092 case 'v': list_vim_vars(); break; 2093 case 's': list_script_vars(); break; 2094 case 'l': list_func_vars(); break; 2095 default: 2096 EMSG2(_("E738: Can't list variables for %s"), name); 2097 } 2098 } 2099 else 2100 { 2101 char_u numbuf[NUMBUFLEN]; 2102 char_u *tf; 2103 int c; 2104 char_u *s; 2105 2106 s = echo_string(&tv, &tf, numbuf, 0); 2107 c = *arg; 2108 *arg = NUL; 2109 list_one_var_a((char_u *)"", 2110 arg == arg_subsc ? name : name_start, 2111 tv.v_type, s == NULL ? (char_u *)"" : s); 2112 *arg = c; 2113 vim_free(tf); 2114 } 2115 clear_tv(&tv); 2116 } 2117 } 2118 } 2119 2120 vim_free(tofree); 2121 } 2122 2123 arg = skipwhite(arg); 2124 } 2125 2126 return arg; 2127 } 2128 2129 /* 2130 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2131 * Returns a pointer to the char just after the var name. 2132 * Returns NULL if there is an error. 2133 */ 2134 static char_u * 2135 ex_let_one(arg, tv, copy, endchars, op) 2136 char_u *arg; /* points to variable name */ 2137 typval_T *tv; /* value to assign to variable */ 2138 int copy; /* copy value from "tv" */ 2139 char_u *endchars; /* valid chars after variable name or NULL */ 2140 char_u *op; /* "+", "-", "." or NULL*/ 2141 { 2142 int c1; 2143 char_u *name; 2144 char_u *p; 2145 char_u *arg_end = NULL; 2146 int len; 2147 int opt_flags; 2148 char_u *tofree = NULL; 2149 2150 /* 2151 * ":let $VAR = expr": Set environment variable. 2152 */ 2153 if (*arg == '$') 2154 { 2155 /* Find the end of the name. */ 2156 ++arg; 2157 name = arg; 2158 len = get_env_len(&arg); 2159 if (len == 0) 2160 EMSG2(_(e_invarg2), name - 1); 2161 else 2162 { 2163 if (op != NULL && (*op == '+' || *op == '-')) 2164 EMSG2(_(e_letwrong), op); 2165 else if (endchars != NULL 2166 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2167 EMSG(_(e_letunexp)); 2168 else 2169 { 2170 c1 = name[len]; 2171 name[len] = NUL; 2172 p = get_tv_string_chk(tv); 2173 if (p != NULL && op != NULL && *op == '.') 2174 { 2175 int mustfree = FALSE; 2176 char_u *s = vim_getenv(name, &mustfree); 2177 2178 if (s != NULL) 2179 { 2180 p = tofree = concat_str(s, p); 2181 if (mustfree) 2182 vim_free(s); 2183 } 2184 } 2185 if (p != NULL) 2186 { 2187 vim_setenv(name, p); 2188 if (STRICMP(name, "HOME") == 0) 2189 init_homedir(); 2190 else if (didset_vim && STRICMP(name, "VIM") == 0) 2191 didset_vim = FALSE; 2192 else if (didset_vimruntime 2193 && STRICMP(name, "VIMRUNTIME") == 0) 2194 didset_vimruntime = FALSE; 2195 arg_end = arg; 2196 } 2197 name[len] = c1; 2198 vim_free(tofree); 2199 } 2200 } 2201 } 2202 2203 /* 2204 * ":let &option = expr": Set option value. 2205 * ":let &l:option = expr": Set local option value. 2206 * ":let &g:option = expr": Set global option value. 2207 */ 2208 else if (*arg == '&') 2209 { 2210 /* Find the end of the name. */ 2211 p = find_option_end(&arg, &opt_flags); 2212 if (p == NULL || (endchars != NULL 2213 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2214 EMSG(_(e_letunexp)); 2215 else 2216 { 2217 long n; 2218 int opt_type; 2219 long numval; 2220 char_u *stringval = NULL; 2221 char_u *s; 2222 2223 c1 = *p; 2224 *p = NUL; 2225 2226 n = get_tv_number(tv); 2227 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2228 if (s != NULL && op != NULL && *op != '=') 2229 { 2230 opt_type = get_option_value(arg, &numval, 2231 &stringval, opt_flags); 2232 if ((opt_type == 1 && *op == '.') 2233 || (opt_type == 0 && *op != '.')) 2234 EMSG2(_(e_letwrong), op); 2235 else 2236 { 2237 if (opt_type == 1) /* number */ 2238 { 2239 if (*op == '+') 2240 n = numval + n; 2241 else 2242 n = numval - n; 2243 } 2244 else if (opt_type == 0 && stringval != NULL) /* string */ 2245 { 2246 s = concat_str(stringval, s); 2247 vim_free(stringval); 2248 stringval = s; 2249 } 2250 } 2251 } 2252 if (s != NULL) 2253 { 2254 set_option_value(arg, n, s, opt_flags); 2255 arg_end = p; 2256 } 2257 *p = c1; 2258 vim_free(stringval); 2259 } 2260 } 2261 2262 /* 2263 * ":let @r = expr": Set register contents. 2264 */ 2265 else if (*arg == '@') 2266 { 2267 ++arg; 2268 if (op != NULL && (*op == '+' || *op == '-')) 2269 EMSG2(_(e_letwrong), op); 2270 else if (endchars != NULL 2271 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2272 EMSG(_(e_letunexp)); 2273 else 2274 { 2275 char_u *ptofree = NULL; 2276 char_u *s; 2277 2278 p = get_tv_string_chk(tv); 2279 if (p != NULL && op != NULL && *op == '.') 2280 { 2281 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2282 if (s != NULL) 2283 { 2284 p = ptofree = concat_str(s, p); 2285 vim_free(s); 2286 } 2287 } 2288 if (p != NULL) 2289 { 2290 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2291 arg_end = arg + 1; 2292 } 2293 vim_free(ptofree); 2294 } 2295 } 2296 2297 /* 2298 * ":let var = expr": Set internal variable. 2299 * ":let {expr} = expr": Idem, name made with curly braces 2300 */ 2301 else if (eval_isnamec1(*arg) || *arg == '{') 2302 { 2303 lval_T lv; 2304 2305 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2306 if (p != NULL && lv.ll_name != NULL) 2307 { 2308 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2309 EMSG(_(e_letunexp)); 2310 else 2311 { 2312 set_var_lval(&lv, p, tv, copy, op); 2313 arg_end = p; 2314 } 2315 } 2316 clear_lval(&lv); 2317 } 2318 2319 else 2320 EMSG2(_(e_invarg2), arg); 2321 2322 return arg_end; 2323 } 2324 2325 /* 2326 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2327 */ 2328 static int 2329 check_changedtick(arg) 2330 char_u *arg; 2331 { 2332 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2333 { 2334 EMSG2(_(e_readonlyvar), arg); 2335 return TRUE; 2336 } 2337 return FALSE; 2338 } 2339 2340 /* 2341 * Get an lval: variable, Dict item or List item that can be assigned a value 2342 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2343 * "name.key", "name.key[expr]" etc. 2344 * Indexing only works if "name" is an existing List or Dictionary. 2345 * "name" points to the start of the name. 2346 * If "rettv" is not NULL it points to the value to be assigned. 2347 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2348 * wrong; must end in space or cmd separator. 2349 * 2350 * Returns a pointer to just after the name, including indexes. 2351 * When an evaluation error occurs "lp->ll_name" is NULL; 2352 * Returns NULL for a parsing error. Still need to free items in "lp"! 2353 */ 2354 static char_u * 2355 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2356 char_u *name; 2357 typval_T *rettv; 2358 lval_T *lp; 2359 int unlet; 2360 int skip; 2361 int quiet; /* don't give error messages */ 2362 int fne_flags; /* flags for find_name_end() */ 2363 { 2364 char_u *p; 2365 char_u *expr_start, *expr_end; 2366 int cc; 2367 dictitem_T *v; 2368 typval_T var1; 2369 typval_T var2; 2370 int empty1 = FALSE; 2371 listitem_T *ni; 2372 char_u *key = NULL; 2373 int len; 2374 hashtab_T *ht; 2375 2376 /* Clear everything in "lp". */ 2377 vim_memset(lp, 0, sizeof(lval_T)); 2378 2379 if (skip) 2380 { 2381 /* When skipping just find the end of the name. */ 2382 lp->ll_name = name; 2383 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2384 } 2385 2386 /* Find the end of the name. */ 2387 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2388 if (expr_start != NULL) 2389 { 2390 /* Don't expand the name when we already know there is an error. */ 2391 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2392 && *p != '[' && *p != '.') 2393 { 2394 EMSG(_(e_trailing)); 2395 return NULL; 2396 } 2397 2398 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2399 if (lp->ll_exp_name == NULL) 2400 { 2401 /* Report an invalid expression in braces, unless the 2402 * expression evaluation has been cancelled due to an 2403 * aborting error, an interrupt, or an exception. */ 2404 if (!aborting() && !quiet) 2405 { 2406 emsg_severe = TRUE; 2407 EMSG2(_(e_invarg2), name); 2408 return NULL; 2409 } 2410 } 2411 lp->ll_name = lp->ll_exp_name; 2412 } 2413 else 2414 lp->ll_name = name; 2415 2416 /* Without [idx] or .key we are done. */ 2417 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2418 return p; 2419 2420 cc = *p; 2421 *p = NUL; 2422 v = find_var(lp->ll_name, &ht); 2423 if (v == NULL && !quiet) 2424 EMSG2(_(e_undefvar), lp->ll_name); 2425 *p = cc; 2426 if (v == NULL) 2427 return NULL; 2428 2429 /* 2430 * Loop until no more [idx] or .key is following. 2431 */ 2432 lp->ll_tv = &v->di_tv; 2433 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2434 { 2435 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2436 && !(lp->ll_tv->v_type == VAR_DICT 2437 && lp->ll_tv->vval.v_dict != NULL)) 2438 { 2439 if (!quiet) 2440 EMSG(_("E689: Can only index a List or Dictionary")); 2441 return NULL; 2442 } 2443 if (lp->ll_range) 2444 { 2445 if (!quiet) 2446 EMSG(_("E708: [:] must come last")); 2447 return NULL; 2448 } 2449 2450 len = -1; 2451 if (*p == '.') 2452 { 2453 key = p + 1; 2454 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2455 ; 2456 if (len == 0) 2457 { 2458 if (!quiet) 2459 EMSG(_(e_emptykey)); 2460 return NULL; 2461 } 2462 p = key + len; 2463 } 2464 else 2465 { 2466 /* Get the index [expr] or the first index [expr: ]. */ 2467 p = skipwhite(p + 1); 2468 if (*p == ':') 2469 empty1 = TRUE; 2470 else 2471 { 2472 empty1 = FALSE; 2473 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2474 return NULL; 2475 if (get_tv_string_chk(&var1) == NULL) 2476 { 2477 /* not a number or string */ 2478 clear_tv(&var1); 2479 return NULL; 2480 } 2481 } 2482 2483 /* Optionally get the second index [ :expr]. */ 2484 if (*p == ':') 2485 { 2486 if (lp->ll_tv->v_type == VAR_DICT) 2487 { 2488 if (!quiet) 2489 EMSG(_(e_dictrange)); 2490 if (!empty1) 2491 clear_tv(&var1); 2492 return NULL; 2493 } 2494 if (rettv != NULL && (rettv->v_type != VAR_LIST 2495 || rettv->vval.v_list == NULL)) 2496 { 2497 if (!quiet) 2498 EMSG(_("E709: [:] requires a List value")); 2499 if (!empty1) 2500 clear_tv(&var1); 2501 return NULL; 2502 } 2503 p = skipwhite(p + 1); 2504 if (*p == ']') 2505 lp->ll_empty2 = TRUE; 2506 else 2507 { 2508 lp->ll_empty2 = FALSE; 2509 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2510 { 2511 if (!empty1) 2512 clear_tv(&var1); 2513 return NULL; 2514 } 2515 if (get_tv_string_chk(&var2) == NULL) 2516 { 2517 /* not a number or string */ 2518 if (!empty1) 2519 clear_tv(&var1); 2520 clear_tv(&var2); 2521 return NULL; 2522 } 2523 } 2524 lp->ll_range = TRUE; 2525 } 2526 else 2527 lp->ll_range = FALSE; 2528 2529 if (*p != ']') 2530 { 2531 if (!quiet) 2532 EMSG(_(e_missbrac)); 2533 if (!empty1) 2534 clear_tv(&var1); 2535 if (lp->ll_range && !lp->ll_empty2) 2536 clear_tv(&var2); 2537 return NULL; 2538 } 2539 2540 /* Skip to past ']'. */ 2541 ++p; 2542 } 2543 2544 if (lp->ll_tv->v_type == VAR_DICT) 2545 { 2546 if (len == -1) 2547 { 2548 /* "[key]": get key from "var1" */ 2549 key = get_tv_string(&var1); /* is number or string */ 2550 if (*key == NUL) 2551 { 2552 if (!quiet) 2553 EMSG(_(e_emptykey)); 2554 clear_tv(&var1); 2555 return NULL; 2556 } 2557 } 2558 lp->ll_list = NULL; 2559 lp->ll_dict = lp->ll_tv->vval.v_dict; 2560 lp->ll_di = dict_find(lp->ll_dict, key, len); 2561 if (lp->ll_di == NULL) 2562 { 2563 /* Key does not exist in dict: may need to add it. */ 2564 if (*p == '[' || *p == '.' || unlet) 2565 { 2566 if (!quiet) 2567 EMSG2(_(e_dictkey), key); 2568 if (len == -1) 2569 clear_tv(&var1); 2570 return NULL; 2571 } 2572 if (len == -1) 2573 lp->ll_newkey = vim_strsave(key); 2574 else 2575 lp->ll_newkey = vim_strnsave(key, len); 2576 if (len == -1) 2577 clear_tv(&var1); 2578 if (lp->ll_newkey == NULL) 2579 p = NULL; 2580 break; 2581 } 2582 if (len == -1) 2583 clear_tv(&var1); 2584 lp->ll_tv = &lp->ll_di->di_tv; 2585 } 2586 else 2587 { 2588 /* 2589 * Get the number and item for the only or first index of the List. 2590 */ 2591 if (empty1) 2592 lp->ll_n1 = 0; 2593 else 2594 { 2595 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2596 clear_tv(&var1); 2597 } 2598 lp->ll_dict = NULL; 2599 lp->ll_list = lp->ll_tv->vval.v_list; 2600 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2601 if (lp->ll_li == NULL) 2602 { 2603 if (lp->ll_n1 < 0) 2604 { 2605 lp->ll_n1 = 0; 2606 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2607 } 2608 } 2609 if (lp->ll_li == NULL) 2610 { 2611 if (lp->ll_range && !lp->ll_empty2) 2612 clear_tv(&var2); 2613 return NULL; 2614 } 2615 2616 /* 2617 * May need to find the item or absolute index for the second 2618 * index of a range. 2619 * When no index given: "lp->ll_empty2" is TRUE. 2620 * Otherwise "lp->ll_n2" is set to the second index. 2621 */ 2622 if (lp->ll_range && !lp->ll_empty2) 2623 { 2624 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2625 clear_tv(&var2); 2626 if (lp->ll_n2 < 0) 2627 { 2628 ni = list_find(lp->ll_list, lp->ll_n2); 2629 if (ni == NULL) 2630 return NULL; 2631 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2632 } 2633 2634 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2635 if (lp->ll_n1 < 0) 2636 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2637 if (lp->ll_n2 < lp->ll_n1) 2638 return NULL; 2639 } 2640 2641 lp->ll_tv = &lp->ll_li->li_tv; 2642 } 2643 } 2644 2645 return p; 2646 } 2647 2648 /* 2649 * Clear lval "lp" that was filled by get_lval(). 2650 */ 2651 static void 2652 clear_lval(lp) 2653 lval_T *lp; 2654 { 2655 vim_free(lp->ll_exp_name); 2656 vim_free(lp->ll_newkey); 2657 } 2658 2659 /* 2660 * Set a variable that was parsed by get_lval() to "rettv". 2661 * "endp" points to just after the parsed name. 2662 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2663 */ 2664 static void 2665 set_var_lval(lp, endp, rettv, copy, op) 2666 lval_T *lp; 2667 char_u *endp; 2668 typval_T *rettv; 2669 int copy; 2670 char_u *op; 2671 { 2672 int cc; 2673 listitem_T *ri; 2674 dictitem_T *di; 2675 2676 if (lp->ll_tv == NULL) 2677 { 2678 if (!check_changedtick(lp->ll_name)) 2679 { 2680 cc = *endp; 2681 *endp = NUL; 2682 if (op != NULL && *op != '=') 2683 { 2684 typval_T tv; 2685 2686 /* handle +=, -= and .= */ 2687 if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), 2688 &tv, TRUE) == OK) 2689 { 2690 if (tv_op(&tv, rettv, op) == OK) 2691 set_var(lp->ll_name, &tv, FALSE); 2692 clear_tv(&tv); 2693 } 2694 } 2695 else 2696 set_var(lp->ll_name, rettv, copy); 2697 *endp = cc; 2698 } 2699 } 2700 else if (tv_check_lock(lp->ll_newkey == NULL 2701 ? lp->ll_tv->v_lock 2702 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2703 ; 2704 else if (lp->ll_range) 2705 { 2706 /* 2707 * Assign the List values to the list items. 2708 */ 2709 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2710 { 2711 if (op != NULL && *op != '=') 2712 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2713 else 2714 { 2715 clear_tv(&lp->ll_li->li_tv); 2716 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2717 } 2718 ri = ri->li_next; 2719 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2720 break; 2721 if (lp->ll_li->li_next == NULL) 2722 { 2723 /* Need to add an empty item. */ 2724 if (list_append_number(lp->ll_list, 0) == FAIL) 2725 { 2726 ri = NULL; 2727 break; 2728 } 2729 } 2730 lp->ll_li = lp->ll_li->li_next; 2731 ++lp->ll_n1; 2732 } 2733 if (ri != NULL) 2734 EMSG(_("E710: List value has more items than target")); 2735 else if (lp->ll_empty2 2736 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2737 : lp->ll_n1 != lp->ll_n2) 2738 EMSG(_("E711: List value has not enough items")); 2739 } 2740 else 2741 { 2742 /* 2743 * Assign to a List or Dictionary item. 2744 */ 2745 if (lp->ll_newkey != NULL) 2746 { 2747 if (op != NULL && *op != '=') 2748 { 2749 EMSG2(_(e_letwrong), op); 2750 return; 2751 } 2752 2753 /* Need to add an item to the Dictionary. */ 2754 di = dictitem_alloc(lp->ll_newkey); 2755 if (di == NULL) 2756 return; 2757 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2758 { 2759 vim_free(di); 2760 return; 2761 } 2762 lp->ll_tv = &di->di_tv; 2763 } 2764 else if (op != NULL && *op != '=') 2765 { 2766 tv_op(lp->ll_tv, rettv, op); 2767 return; 2768 } 2769 else 2770 clear_tv(lp->ll_tv); 2771 2772 /* 2773 * Assign the value to the variable or list item. 2774 */ 2775 if (copy) 2776 copy_tv(rettv, lp->ll_tv); 2777 else 2778 { 2779 *lp->ll_tv = *rettv; 2780 lp->ll_tv->v_lock = 0; 2781 init_tv(rettv); 2782 } 2783 } 2784 } 2785 2786 /* 2787 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2788 * Returns OK or FAIL. 2789 */ 2790 static int 2791 tv_op(tv1, tv2, op) 2792 typval_T *tv1; 2793 typval_T *tv2; 2794 char_u *op; 2795 { 2796 long n; 2797 char_u numbuf[NUMBUFLEN]; 2798 char_u *s; 2799 2800 /* Can't do anything with a Funcref or a Dict on the right. */ 2801 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2802 { 2803 switch (tv1->v_type) 2804 { 2805 case VAR_DICT: 2806 case VAR_FUNC: 2807 break; 2808 2809 case VAR_LIST: 2810 if (*op != '+' || tv2->v_type != VAR_LIST) 2811 break; 2812 /* List += List */ 2813 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2814 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2815 return OK; 2816 2817 case VAR_NUMBER: 2818 case VAR_STRING: 2819 if (tv2->v_type == VAR_LIST) 2820 break; 2821 if (*op == '+' || *op == '-') 2822 { 2823 /* nr += nr or nr -= nr*/ 2824 n = get_tv_number(tv1); 2825 if (*op == '+') 2826 n += get_tv_number(tv2); 2827 else 2828 n -= get_tv_number(tv2); 2829 clear_tv(tv1); 2830 tv1->v_type = VAR_NUMBER; 2831 tv1->vval.v_number = n; 2832 } 2833 else 2834 { 2835 /* str .= str */ 2836 s = get_tv_string(tv1); 2837 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2838 clear_tv(tv1); 2839 tv1->v_type = VAR_STRING; 2840 tv1->vval.v_string = s; 2841 } 2842 return OK; 2843 } 2844 } 2845 2846 EMSG2(_(e_letwrong), op); 2847 return FAIL; 2848 } 2849 2850 /* 2851 * Add a watcher to a list. 2852 */ 2853 static void 2854 list_add_watch(l, lw) 2855 list_T *l; 2856 listwatch_T *lw; 2857 { 2858 lw->lw_next = l->lv_watch; 2859 l->lv_watch = lw; 2860 } 2861 2862 /* 2863 * Remove a watcher from a list. 2864 * No warning when it isn't found... 2865 */ 2866 static void 2867 list_rem_watch(l, lwrem) 2868 list_T *l; 2869 listwatch_T *lwrem; 2870 { 2871 listwatch_T *lw, **lwp; 2872 2873 lwp = &l->lv_watch; 2874 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2875 { 2876 if (lw == lwrem) 2877 { 2878 *lwp = lw->lw_next; 2879 break; 2880 } 2881 lwp = &lw->lw_next; 2882 } 2883 } 2884 2885 /* 2886 * Just before removing an item from a list: advance watchers to the next 2887 * item. 2888 */ 2889 static void 2890 list_fix_watch(l, item) 2891 list_T *l; 2892 listitem_T *item; 2893 { 2894 listwatch_T *lw; 2895 2896 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2897 if (lw->lw_item == item) 2898 lw->lw_item = item->li_next; 2899 } 2900 2901 /* 2902 * Evaluate the expression used in a ":for var in expr" command. 2903 * "arg" points to "var". 2904 * Set "*errp" to TRUE for an error, FALSE otherwise; 2905 * Return a pointer that holds the info. Null when there is an error. 2906 */ 2907 void * 2908 eval_for_line(arg, errp, nextcmdp, skip) 2909 char_u *arg; 2910 int *errp; 2911 char_u **nextcmdp; 2912 int skip; 2913 { 2914 forinfo_T *fi; 2915 char_u *expr; 2916 typval_T tv; 2917 list_T *l; 2918 2919 *errp = TRUE; /* default: there is an error */ 2920 2921 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2922 if (fi == NULL) 2923 return NULL; 2924 2925 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2926 if (expr == NULL) 2927 return fi; 2928 2929 expr = skipwhite(expr); 2930 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2931 { 2932 EMSG(_("E690: Missing \"in\" after :for")); 2933 return fi; 2934 } 2935 2936 if (skip) 2937 ++emsg_skip; 2938 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2939 { 2940 *errp = FALSE; 2941 if (!skip) 2942 { 2943 l = tv.vval.v_list; 2944 if (tv.v_type != VAR_LIST || l == NULL) 2945 { 2946 EMSG(_(e_listreq)); 2947 clear_tv(&tv); 2948 } 2949 else 2950 { 2951 /* No need to increment the refcount, it's already set for the 2952 * list being used in "tv". */ 2953 fi->fi_list = l; 2954 list_add_watch(l, &fi->fi_lw); 2955 fi->fi_lw.lw_item = l->lv_first; 2956 } 2957 } 2958 } 2959 if (skip) 2960 --emsg_skip; 2961 2962 return fi; 2963 } 2964 2965 /* 2966 * Use the first item in a ":for" list. Advance to the next. 2967 * Assign the values to the variable (list). "arg" points to the first one. 2968 * Return TRUE when a valid item was found, FALSE when at end of list or 2969 * something wrong. 2970 */ 2971 int 2972 next_for_item(fi_void, arg) 2973 void *fi_void; 2974 char_u *arg; 2975 { 2976 forinfo_T *fi = (forinfo_T *)fi_void; 2977 int result; 2978 listitem_T *item; 2979 2980 item = fi->fi_lw.lw_item; 2981 if (item == NULL) 2982 result = FALSE; 2983 else 2984 { 2985 fi->fi_lw.lw_item = item->li_next; 2986 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2987 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2988 } 2989 return result; 2990 } 2991 2992 /* 2993 * Free the structure used to store info used by ":for". 2994 */ 2995 void 2996 free_for_info(fi_void) 2997 void *fi_void; 2998 { 2999 forinfo_T *fi = (forinfo_T *)fi_void; 3000 3001 if (fi != NULL && fi->fi_list != NULL) 3002 { 3003 list_rem_watch(fi->fi_list, &fi->fi_lw); 3004 list_unref(fi->fi_list); 3005 } 3006 vim_free(fi); 3007 } 3008 3009 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3010 3011 void 3012 set_context_for_expression(xp, arg, cmdidx) 3013 expand_T *xp; 3014 char_u *arg; 3015 cmdidx_T cmdidx; 3016 { 3017 int got_eq = FALSE; 3018 int c; 3019 char_u *p; 3020 3021 if (cmdidx == CMD_let) 3022 { 3023 xp->xp_context = EXPAND_USER_VARS; 3024 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 3025 { 3026 /* ":let var1 var2 ...": find last space. */ 3027 for (p = arg + STRLEN(arg); p >= arg; ) 3028 { 3029 xp->xp_pattern = p; 3030 mb_ptr_back(arg, p); 3031 if (vim_iswhite(*p)) 3032 break; 3033 } 3034 return; 3035 } 3036 } 3037 else 3038 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 3039 : EXPAND_EXPRESSION; 3040 while ((xp->xp_pattern = vim_strpbrk(arg, 3041 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 3042 { 3043 c = *xp->xp_pattern; 3044 if (c == '&') 3045 { 3046 c = xp->xp_pattern[1]; 3047 if (c == '&') 3048 { 3049 ++xp->xp_pattern; 3050 xp->xp_context = cmdidx != CMD_let || got_eq 3051 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 3052 } 3053 else if (c != ' ') 3054 { 3055 xp->xp_context = EXPAND_SETTINGS; 3056 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 3057 xp->xp_pattern += 2; 3058 3059 } 3060 } 3061 else if (c == '$') 3062 { 3063 /* environment variable */ 3064 xp->xp_context = EXPAND_ENV_VARS; 3065 } 3066 else if (c == '=') 3067 { 3068 got_eq = TRUE; 3069 xp->xp_context = EXPAND_EXPRESSION; 3070 } 3071 else if (c == '<' 3072 && xp->xp_context == EXPAND_FUNCTIONS 3073 && vim_strchr(xp->xp_pattern, '(') == NULL) 3074 { 3075 /* Function name can start with "<SNR>" */ 3076 break; 3077 } 3078 else if (cmdidx != CMD_let || got_eq) 3079 { 3080 if (c == '"') /* string */ 3081 { 3082 while ((c = *++xp->xp_pattern) != NUL && c != '"') 3083 if (c == '\\' && xp->xp_pattern[1] != NUL) 3084 ++xp->xp_pattern; 3085 xp->xp_context = EXPAND_NOTHING; 3086 } 3087 else if (c == '\'') /* literal string */ 3088 { 3089 /* Trick: '' is like stopping and starting a literal string. */ 3090 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 3091 /* skip */ ; 3092 xp->xp_context = EXPAND_NOTHING; 3093 } 3094 else if (c == '|') 3095 { 3096 if (xp->xp_pattern[1] == '|') 3097 { 3098 ++xp->xp_pattern; 3099 xp->xp_context = EXPAND_EXPRESSION; 3100 } 3101 else 3102 xp->xp_context = EXPAND_COMMANDS; 3103 } 3104 else 3105 xp->xp_context = EXPAND_EXPRESSION; 3106 } 3107 else 3108 /* Doesn't look like something valid, expand as an expression 3109 * anyway. */ 3110 xp->xp_context = EXPAND_EXPRESSION; 3111 arg = xp->xp_pattern; 3112 if (*arg != NUL) 3113 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3114 /* skip */ ; 3115 } 3116 xp->xp_pattern = arg; 3117 } 3118 3119 #endif /* FEAT_CMDL_COMPL */ 3120 3121 /* 3122 * ":1,25call func(arg1, arg2)" function call. 3123 */ 3124 void 3125 ex_call(eap) 3126 exarg_T *eap; 3127 { 3128 char_u *arg = eap->arg; 3129 char_u *startarg; 3130 char_u *name; 3131 char_u *tofree; 3132 int len; 3133 typval_T rettv; 3134 linenr_T lnum; 3135 int doesrange; 3136 int failed = FALSE; 3137 funcdict_T fudi; 3138 3139 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3140 if (fudi.fd_newkey != NULL) 3141 { 3142 /* Still need to give an error message for missing key. */ 3143 EMSG2(_(e_dictkey), fudi.fd_newkey); 3144 vim_free(fudi.fd_newkey); 3145 } 3146 if (tofree == NULL) 3147 return; 3148 3149 /* Increase refcount on dictionary, it could get deleted when evaluating 3150 * the arguments. */ 3151 if (fudi.fd_dict != NULL) 3152 ++fudi.fd_dict->dv_refcount; 3153 3154 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3155 len = (int)STRLEN(tofree); 3156 name = deref_func_name(tofree, &len); 3157 3158 /* Skip white space to allow ":call func ()". Not good, but required for 3159 * backward compatibility. */ 3160 startarg = skipwhite(arg); 3161 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3162 3163 if (*startarg != '(') 3164 { 3165 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3166 goto end; 3167 } 3168 3169 /* 3170 * When skipping, evaluate the function once, to find the end of the 3171 * arguments. 3172 * When the function takes a range, this is discovered after the first 3173 * call, and the loop is broken. 3174 */ 3175 if (eap->skip) 3176 { 3177 ++emsg_skip; 3178 lnum = eap->line2; /* do it once, also with an invalid range */ 3179 } 3180 else 3181 lnum = eap->line1; 3182 for ( ; lnum <= eap->line2; ++lnum) 3183 { 3184 if (!eap->skip && eap->addr_count > 0) 3185 { 3186 curwin->w_cursor.lnum = lnum; 3187 curwin->w_cursor.col = 0; 3188 } 3189 arg = startarg; 3190 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, 3191 eap->line1, eap->line2, &doesrange, 3192 !eap->skip, fudi.fd_dict) == FAIL) 3193 { 3194 failed = TRUE; 3195 break; 3196 } 3197 3198 /* Handle a function returning a Funcref, Dictionary or List. */ 3199 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) 3200 { 3201 failed = TRUE; 3202 break; 3203 } 3204 3205 clear_tv(&rettv); 3206 if (doesrange || eap->skip) 3207 break; 3208 3209 /* Stop when immediately aborting on error, or when an interrupt 3210 * occurred or an exception was thrown but not caught. 3211 * get_func_tv() returned OK, so that the check for trailing 3212 * characters below is executed. */ 3213 if (aborting()) 3214 break; 3215 } 3216 if (eap->skip) 3217 --emsg_skip; 3218 3219 if (!failed) 3220 { 3221 /* Check for trailing illegal characters and a following command. */ 3222 if (!ends_excmd(*arg)) 3223 { 3224 emsg_severe = TRUE; 3225 EMSG(_(e_trailing)); 3226 } 3227 else 3228 eap->nextcmd = check_nextcmd(arg); 3229 } 3230 3231 end: 3232 dict_unref(fudi.fd_dict); 3233 vim_free(tofree); 3234 } 3235 3236 /* 3237 * ":unlet[!] var1 ... " command. 3238 */ 3239 void 3240 ex_unlet(eap) 3241 exarg_T *eap; 3242 { 3243 ex_unletlock(eap, eap->arg, 0); 3244 } 3245 3246 /* 3247 * ":lockvar" and ":unlockvar" commands 3248 */ 3249 void 3250 ex_lockvar(eap) 3251 exarg_T *eap; 3252 { 3253 char_u *arg = eap->arg; 3254 int deep = 2; 3255 3256 if (eap->forceit) 3257 deep = -1; 3258 else if (vim_isdigit(*arg)) 3259 { 3260 deep = getdigits(&arg); 3261 arg = skipwhite(arg); 3262 } 3263 3264 ex_unletlock(eap, arg, deep); 3265 } 3266 3267 /* 3268 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3269 */ 3270 static void 3271 ex_unletlock(eap, argstart, deep) 3272 exarg_T *eap; 3273 char_u *argstart; 3274 int deep; 3275 { 3276 char_u *arg = argstart; 3277 char_u *name_end; 3278 int error = FALSE; 3279 lval_T lv; 3280 3281 do 3282 { 3283 /* Parse the name and find the end. */ 3284 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3285 FNE_CHECK_START); 3286 if (lv.ll_name == NULL) 3287 error = TRUE; /* error but continue parsing */ 3288 if (name_end == NULL || (!vim_iswhite(*name_end) 3289 && !ends_excmd(*name_end))) 3290 { 3291 if (name_end != NULL) 3292 { 3293 emsg_severe = TRUE; 3294 EMSG(_(e_trailing)); 3295 } 3296 if (!(eap->skip || error)) 3297 clear_lval(&lv); 3298 break; 3299 } 3300 3301 if (!error && !eap->skip) 3302 { 3303 if (eap->cmdidx == CMD_unlet) 3304 { 3305 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3306 error = TRUE; 3307 } 3308 else 3309 { 3310 if (do_lock_var(&lv, name_end, deep, 3311 eap->cmdidx == CMD_lockvar) == FAIL) 3312 error = TRUE; 3313 } 3314 } 3315 3316 if (!eap->skip) 3317 clear_lval(&lv); 3318 3319 arg = skipwhite(name_end); 3320 } while (!ends_excmd(*arg)); 3321 3322 eap->nextcmd = check_nextcmd(arg); 3323 } 3324 3325 static int 3326 do_unlet_var(lp, name_end, forceit) 3327 lval_T *lp; 3328 char_u *name_end; 3329 int forceit; 3330 { 3331 int ret = OK; 3332 int cc; 3333 3334 if (lp->ll_tv == NULL) 3335 { 3336 cc = *name_end; 3337 *name_end = NUL; 3338 3339 /* Normal name or expanded name. */ 3340 if (check_changedtick(lp->ll_name)) 3341 ret = FAIL; 3342 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3343 ret = FAIL; 3344 *name_end = cc; 3345 } 3346 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3347 return FAIL; 3348 else if (lp->ll_range) 3349 { 3350 listitem_T *li; 3351 3352 /* Delete a range of List items. */ 3353 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3354 { 3355 li = lp->ll_li->li_next; 3356 listitem_remove(lp->ll_list, lp->ll_li); 3357 lp->ll_li = li; 3358 ++lp->ll_n1; 3359 } 3360 } 3361 else 3362 { 3363 if (lp->ll_list != NULL) 3364 /* unlet a List item. */ 3365 listitem_remove(lp->ll_list, lp->ll_li); 3366 else 3367 /* unlet a Dictionary item. */ 3368 dictitem_remove(lp->ll_dict, lp->ll_di); 3369 } 3370 3371 return ret; 3372 } 3373 3374 /* 3375 * "unlet" a variable. Return OK if it existed, FAIL if not. 3376 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3377 */ 3378 int 3379 do_unlet(name, forceit) 3380 char_u *name; 3381 int forceit; 3382 { 3383 hashtab_T *ht; 3384 hashitem_T *hi; 3385 char_u *varname; 3386 3387 ht = find_var_ht(name, &varname); 3388 if (ht != NULL && *varname != NUL) 3389 { 3390 hi = hash_find(ht, varname); 3391 if (!HASHITEM_EMPTY(hi)) 3392 { 3393 if (var_check_fixed(HI2DI(hi)->di_flags, name)) 3394 return FAIL; 3395 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3396 return FAIL; 3397 delete_var(ht, hi); 3398 return OK; 3399 } 3400 } 3401 if (forceit) 3402 return OK; 3403 EMSG2(_("E108: No such variable: \"%s\""), name); 3404 return FAIL; 3405 } 3406 3407 /* 3408 * Lock or unlock variable indicated by "lp". 3409 * "deep" is the levels to go (-1 for unlimited); 3410 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3411 */ 3412 static int 3413 do_lock_var(lp, name_end, deep, lock) 3414 lval_T *lp; 3415 char_u *name_end; 3416 int deep; 3417 int lock; 3418 { 3419 int ret = OK; 3420 int cc; 3421 dictitem_T *di; 3422 3423 if (deep == 0) /* nothing to do */ 3424 return OK; 3425 3426 if (lp->ll_tv == NULL) 3427 { 3428 cc = *name_end; 3429 *name_end = NUL; 3430 3431 /* Normal name or expanded name. */ 3432 if (check_changedtick(lp->ll_name)) 3433 ret = FAIL; 3434 else 3435 { 3436 di = find_var(lp->ll_name, NULL); 3437 if (di == NULL) 3438 ret = FAIL; 3439 else 3440 { 3441 if (lock) 3442 di->di_flags |= DI_FLAGS_LOCK; 3443 else 3444 di->di_flags &= ~DI_FLAGS_LOCK; 3445 item_lock(&di->di_tv, deep, lock); 3446 } 3447 } 3448 *name_end = cc; 3449 } 3450 else if (lp->ll_range) 3451 { 3452 listitem_T *li = lp->ll_li; 3453 3454 /* (un)lock a range of List items. */ 3455 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3456 { 3457 item_lock(&li->li_tv, deep, lock); 3458 li = li->li_next; 3459 ++lp->ll_n1; 3460 } 3461 } 3462 else if (lp->ll_list != NULL) 3463 /* (un)lock a List item. */ 3464 item_lock(&lp->ll_li->li_tv, deep, lock); 3465 else 3466 /* un(lock) a Dictionary item. */ 3467 item_lock(&lp->ll_di->di_tv, deep, lock); 3468 3469 return ret; 3470 } 3471 3472 /* 3473 * Lock or unlock an item. "deep" is nr of levels to go. 3474 */ 3475 static void 3476 item_lock(tv, deep, lock) 3477 typval_T *tv; 3478 int deep; 3479 int lock; 3480 { 3481 static int recurse = 0; 3482 list_T *l; 3483 listitem_T *li; 3484 dict_T *d; 3485 hashitem_T *hi; 3486 int todo; 3487 3488 if (recurse >= DICT_MAXNEST) 3489 { 3490 EMSG(_("E743: variable nested too deep for (un)lock")); 3491 return; 3492 } 3493 if (deep == 0) 3494 return; 3495 ++recurse; 3496 3497 /* lock/unlock the item itself */ 3498 if (lock) 3499 tv->v_lock |= VAR_LOCKED; 3500 else 3501 tv->v_lock &= ~VAR_LOCKED; 3502 3503 switch (tv->v_type) 3504 { 3505 case VAR_LIST: 3506 if ((l = tv->vval.v_list) != NULL) 3507 { 3508 if (lock) 3509 l->lv_lock |= VAR_LOCKED; 3510 else 3511 l->lv_lock &= ~VAR_LOCKED; 3512 if (deep < 0 || deep > 1) 3513 /* recursive: lock/unlock the items the List contains */ 3514 for (li = l->lv_first; li != NULL; li = li->li_next) 3515 item_lock(&li->li_tv, deep - 1, lock); 3516 } 3517 break; 3518 case VAR_DICT: 3519 if ((d = tv->vval.v_dict) != NULL) 3520 { 3521 if (lock) 3522 d->dv_lock |= VAR_LOCKED; 3523 else 3524 d->dv_lock &= ~VAR_LOCKED; 3525 if (deep < 0 || deep > 1) 3526 { 3527 /* recursive: lock/unlock the items the List contains */ 3528 todo = (int)d->dv_hashtab.ht_used; 3529 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3530 { 3531 if (!HASHITEM_EMPTY(hi)) 3532 { 3533 --todo; 3534 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3535 } 3536 } 3537 } 3538 } 3539 } 3540 --recurse; 3541 } 3542 3543 /* 3544 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3545 * it refers to a List or Dictionary that is locked. 3546 */ 3547 static int 3548 tv_islocked(tv) 3549 typval_T *tv; 3550 { 3551 return (tv->v_lock & VAR_LOCKED) 3552 || (tv->v_type == VAR_LIST 3553 && tv->vval.v_list != NULL 3554 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3555 || (tv->v_type == VAR_DICT 3556 && tv->vval.v_dict != NULL 3557 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3558 } 3559 3560 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3561 /* 3562 * Delete all "menutrans_" variables. 3563 */ 3564 void 3565 del_menutrans_vars() 3566 { 3567 hashitem_T *hi; 3568 int todo; 3569 3570 hash_lock(&globvarht); 3571 todo = (int)globvarht.ht_used; 3572 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3573 { 3574 if (!HASHITEM_EMPTY(hi)) 3575 { 3576 --todo; 3577 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3578 delete_var(&globvarht, hi); 3579 } 3580 } 3581 hash_unlock(&globvarht); 3582 } 3583 #endif 3584 3585 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3586 3587 /* 3588 * Local string buffer for the next two functions to store a variable name 3589 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3590 * get_user_var_name(). 3591 */ 3592 3593 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3594 3595 static char_u *varnamebuf = NULL; 3596 static int varnamebuflen = 0; 3597 3598 /* 3599 * Function to concatenate a prefix and a variable name. 3600 */ 3601 static char_u * 3602 cat_prefix_varname(prefix, name) 3603 int prefix; 3604 char_u *name; 3605 { 3606 int len; 3607 3608 len = (int)STRLEN(name) + 3; 3609 if (len > varnamebuflen) 3610 { 3611 vim_free(varnamebuf); 3612 len += 10; /* some additional space */ 3613 varnamebuf = alloc(len); 3614 if (varnamebuf == NULL) 3615 { 3616 varnamebuflen = 0; 3617 return NULL; 3618 } 3619 varnamebuflen = len; 3620 } 3621 *varnamebuf = prefix; 3622 varnamebuf[1] = ':'; 3623 STRCPY(varnamebuf + 2, name); 3624 return varnamebuf; 3625 } 3626 3627 /* 3628 * Function given to ExpandGeneric() to obtain the list of user defined 3629 * (global/buffer/window/built-in) variable names. 3630 */ 3631 /*ARGSUSED*/ 3632 char_u * 3633 get_user_var_name(xp, idx) 3634 expand_T *xp; 3635 int idx; 3636 { 3637 static long_u gdone; 3638 static long_u bdone; 3639 static long_u wdone; 3640 #ifdef FEAT_WINDOWS 3641 static long_u tdone; 3642 #endif 3643 static int vidx; 3644 static hashitem_T *hi; 3645 hashtab_T *ht; 3646 3647 if (idx == 0) 3648 { 3649 gdone = bdone = wdone = vidx = 0; 3650 #ifdef FEAT_WINDOWS 3651 tdone = 0; 3652 #endif 3653 } 3654 3655 /* Global variables */ 3656 if (gdone < globvarht.ht_used) 3657 { 3658 if (gdone++ == 0) 3659 hi = globvarht.ht_array; 3660 else 3661 ++hi; 3662 while (HASHITEM_EMPTY(hi)) 3663 ++hi; 3664 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3665 return cat_prefix_varname('g', hi->hi_key); 3666 return hi->hi_key; 3667 } 3668 3669 /* b: variables */ 3670 ht = &curbuf->b_vars.dv_hashtab; 3671 if (bdone < ht->ht_used) 3672 { 3673 if (bdone++ == 0) 3674 hi = ht->ht_array; 3675 else 3676 ++hi; 3677 while (HASHITEM_EMPTY(hi)) 3678 ++hi; 3679 return cat_prefix_varname('b', hi->hi_key); 3680 } 3681 if (bdone == ht->ht_used) 3682 { 3683 ++bdone; 3684 return (char_u *)"b:changedtick"; 3685 } 3686 3687 /* w: variables */ 3688 ht = &curwin->w_vars.dv_hashtab; 3689 if (wdone < ht->ht_used) 3690 { 3691 if (wdone++ == 0) 3692 hi = ht->ht_array; 3693 else 3694 ++hi; 3695 while (HASHITEM_EMPTY(hi)) 3696 ++hi; 3697 return cat_prefix_varname('w', hi->hi_key); 3698 } 3699 3700 #ifdef FEAT_WINDOWS 3701 /* t: variables */ 3702 ht = &curtab->tp_vars.dv_hashtab; 3703 if (tdone < ht->ht_used) 3704 { 3705 if (tdone++ == 0) 3706 hi = ht->ht_array; 3707 else 3708 ++hi; 3709 while (HASHITEM_EMPTY(hi)) 3710 ++hi; 3711 return cat_prefix_varname('t', hi->hi_key); 3712 } 3713 #endif 3714 3715 /* v: variables */ 3716 if (vidx < VV_LEN) 3717 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3718 3719 vim_free(varnamebuf); 3720 varnamebuf = NULL; 3721 varnamebuflen = 0; 3722 return NULL; 3723 } 3724 3725 #endif /* FEAT_CMDL_COMPL */ 3726 3727 /* 3728 * types for expressions. 3729 */ 3730 typedef enum 3731 { 3732 TYPE_UNKNOWN = 0 3733 , TYPE_EQUAL /* == */ 3734 , TYPE_NEQUAL /* != */ 3735 , TYPE_GREATER /* > */ 3736 , TYPE_GEQUAL /* >= */ 3737 , TYPE_SMALLER /* < */ 3738 , TYPE_SEQUAL /* <= */ 3739 , TYPE_MATCH /* =~ */ 3740 , TYPE_NOMATCH /* !~ */ 3741 } exptype_T; 3742 3743 /* 3744 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3745 * executed. The function may return OK, but the rettv will be of type 3746 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3747 */ 3748 3749 /* 3750 * Handle zero level expression. 3751 * This calls eval1() and handles error message and nextcmd. 3752 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3753 * Note: "rettv.v_lock" is not set. 3754 * Return OK or FAIL. 3755 */ 3756 static int 3757 eval0(arg, rettv, nextcmd, evaluate) 3758 char_u *arg; 3759 typval_T *rettv; 3760 char_u **nextcmd; 3761 int evaluate; 3762 { 3763 int ret; 3764 char_u *p; 3765 3766 p = skipwhite(arg); 3767 ret = eval1(&p, rettv, evaluate); 3768 if (ret == FAIL || !ends_excmd(*p)) 3769 { 3770 if (ret != FAIL) 3771 clear_tv(rettv); 3772 /* 3773 * Report the invalid expression unless the expression evaluation has 3774 * been cancelled due to an aborting error, an interrupt, or an 3775 * exception. 3776 */ 3777 if (!aborting()) 3778 EMSG2(_(e_invexpr2), arg); 3779 ret = FAIL; 3780 } 3781 if (nextcmd != NULL) 3782 *nextcmd = check_nextcmd(p); 3783 3784 return ret; 3785 } 3786 3787 /* 3788 * Handle top level expression: 3789 * expr1 ? expr0 : expr0 3790 * 3791 * "arg" must point to the first non-white of the expression. 3792 * "arg" is advanced to the next non-white after the recognized expression. 3793 * 3794 * Note: "rettv.v_lock" is not set. 3795 * 3796 * Return OK or FAIL. 3797 */ 3798 static int 3799 eval1(arg, rettv, evaluate) 3800 char_u **arg; 3801 typval_T *rettv; 3802 int evaluate; 3803 { 3804 int result; 3805 typval_T var2; 3806 3807 /* 3808 * Get the first variable. 3809 */ 3810 if (eval2(arg, rettv, evaluate) == FAIL) 3811 return FAIL; 3812 3813 if ((*arg)[0] == '?') 3814 { 3815 result = FALSE; 3816 if (evaluate) 3817 { 3818 int error = FALSE; 3819 3820 if (get_tv_number_chk(rettv, &error) != 0) 3821 result = TRUE; 3822 clear_tv(rettv); 3823 if (error) 3824 return FAIL; 3825 } 3826 3827 /* 3828 * Get the second variable. 3829 */ 3830 *arg = skipwhite(*arg + 1); 3831 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3832 return FAIL; 3833 3834 /* 3835 * Check for the ":". 3836 */ 3837 if ((*arg)[0] != ':') 3838 { 3839 EMSG(_("E109: Missing ':' after '?'")); 3840 if (evaluate && result) 3841 clear_tv(rettv); 3842 return FAIL; 3843 } 3844 3845 /* 3846 * Get the third variable. 3847 */ 3848 *arg = skipwhite(*arg + 1); 3849 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3850 { 3851 if (evaluate && result) 3852 clear_tv(rettv); 3853 return FAIL; 3854 } 3855 if (evaluate && !result) 3856 *rettv = var2; 3857 } 3858 3859 return OK; 3860 } 3861 3862 /* 3863 * Handle first level expression: 3864 * expr2 || expr2 || expr2 logical OR 3865 * 3866 * "arg" must point to the first non-white of the expression. 3867 * "arg" is advanced to the next non-white after the recognized expression. 3868 * 3869 * Return OK or FAIL. 3870 */ 3871 static int 3872 eval2(arg, rettv, evaluate) 3873 char_u **arg; 3874 typval_T *rettv; 3875 int evaluate; 3876 { 3877 typval_T var2; 3878 long result; 3879 int first; 3880 int error = FALSE; 3881 3882 /* 3883 * Get the first variable. 3884 */ 3885 if (eval3(arg, rettv, evaluate) == FAIL) 3886 return FAIL; 3887 3888 /* 3889 * Repeat until there is no following "||". 3890 */ 3891 first = TRUE; 3892 result = FALSE; 3893 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3894 { 3895 if (evaluate && first) 3896 { 3897 if (get_tv_number_chk(rettv, &error) != 0) 3898 result = TRUE; 3899 clear_tv(rettv); 3900 if (error) 3901 return FAIL; 3902 first = FALSE; 3903 } 3904 3905 /* 3906 * Get the second variable. 3907 */ 3908 *arg = skipwhite(*arg + 2); 3909 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3910 return FAIL; 3911 3912 /* 3913 * Compute the result. 3914 */ 3915 if (evaluate && !result) 3916 { 3917 if (get_tv_number_chk(&var2, &error) != 0) 3918 result = TRUE; 3919 clear_tv(&var2); 3920 if (error) 3921 return FAIL; 3922 } 3923 if (evaluate) 3924 { 3925 rettv->v_type = VAR_NUMBER; 3926 rettv->vval.v_number = result; 3927 } 3928 } 3929 3930 return OK; 3931 } 3932 3933 /* 3934 * Handle second level expression: 3935 * expr3 && expr3 && expr3 logical AND 3936 * 3937 * "arg" must point to the first non-white of the expression. 3938 * "arg" is advanced to the next non-white after the recognized expression. 3939 * 3940 * Return OK or FAIL. 3941 */ 3942 static int 3943 eval3(arg, rettv, evaluate) 3944 char_u **arg; 3945 typval_T *rettv; 3946 int evaluate; 3947 { 3948 typval_T var2; 3949 long result; 3950 int first; 3951 int error = FALSE; 3952 3953 /* 3954 * Get the first variable. 3955 */ 3956 if (eval4(arg, rettv, evaluate) == FAIL) 3957 return FAIL; 3958 3959 /* 3960 * Repeat until there is no following "&&". 3961 */ 3962 first = TRUE; 3963 result = TRUE; 3964 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3965 { 3966 if (evaluate && first) 3967 { 3968 if (get_tv_number_chk(rettv, &error) == 0) 3969 result = FALSE; 3970 clear_tv(rettv); 3971 if (error) 3972 return FAIL; 3973 first = FALSE; 3974 } 3975 3976 /* 3977 * Get the second variable. 3978 */ 3979 *arg = skipwhite(*arg + 2); 3980 if (eval4(arg, &var2, evaluate && result) == FAIL) 3981 return FAIL; 3982 3983 /* 3984 * Compute the result. 3985 */ 3986 if (evaluate && result) 3987 { 3988 if (get_tv_number_chk(&var2, &error) == 0) 3989 result = FALSE; 3990 clear_tv(&var2); 3991 if (error) 3992 return FAIL; 3993 } 3994 if (evaluate) 3995 { 3996 rettv->v_type = VAR_NUMBER; 3997 rettv->vval.v_number = result; 3998 } 3999 } 4000 4001 return OK; 4002 } 4003 4004 /* 4005 * Handle third level expression: 4006 * var1 == var2 4007 * var1 =~ var2 4008 * var1 != var2 4009 * var1 !~ var2 4010 * var1 > var2 4011 * var1 >= var2 4012 * var1 < var2 4013 * var1 <= var2 4014 * var1 is var2 4015 * var1 isnot var2 4016 * 4017 * "arg" must point to the first non-white of the expression. 4018 * "arg" is advanced to the next non-white after the recognized expression. 4019 * 4020 * Return OK or FAIL. 4021 */ 4022 static int 4023 eval4(arg, rettv, evaluate) 4024 char_u **arg; 4025 typval_T *rettv; 4026 int evaluate; 4027 { 4028 typval_T var2; 4029 char_u *p; 4030 int i; 4031 exptype_T type = TYPE_UNKNOWN; 4032 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 4033 int len = 2; 4034 long n1, n2; 4035 char_u *s1, *s2; 4036 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4037 regmatch_T regmatch; 4038 int ic; 4039 char_u *save_cpo; 4040 4041 /* 4042 * Get the first variable. 4043 */ 4044 if (eval5(arg, rettv, evaluate) == FAIL) 4045 return FAIL; 4046 4047 p = *arg; 4048 switch (p[0]) 4049 { 4050 case '=': if (p[1] == '=') 4051 type = TYPE_EQUAL; 4052 else if (p[1] == '~') 4053 type = TYPE_MATCH; 4054 break; 4055 case '!': if (p[1] == '=') 4056 type = TYPE_NEQUAL; 4057 else if (p[1] == '~') 4058 type = TYPE_NOMATCH; 4059 break; 4060 case '>': if (p[1] != '=') 4061 { 4062 type = TYPE_GREATER; 4063 len = 1; 4064 } 4065 else 4066 type = TYPE_GEQUAL; 4067 break; 4068 case '<': if (p[1] != '=') 4069 { 4070 type = TYPE_SMALLER; 4071 len = 1; 4072 } 4073 else 4074 type = TYPE_SEQUAL; 4075 break; 4076 case 'i': if (p[1] == 's') 4077 { 4078 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 4079 len = 5; 4080 if (!vim_isIDc(p[len])) 4081 { 4082 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 4083 type_is = TRUE; 4084 } 4085 } 4086 break; 4087 } 4088 4089 /* 4090 * If there is a comparitive operator, use it. 4091 */ 4092 if (type != TYPE_UNKNOWN) 4093 { 4094 /* extra question mark appended: ignore case */ 4095 if (p[len] == '?') 4096 { 4097 ic = TRUE; 4098 ++len; 4099 } 4100 /* extra '#' appended: match case */ 4101 else if (p[len] == '#') 4102 { 4103 ic = FALSE; 4104 ++len; 4105 } 4106 /* nothing appened: use 'ignorecase' */ 4107 else 4108 ic = p_ic; 4109 4110 /* 4111 * Get the second variable. 4112 */ 4113 *arg = skipwhite(p + len); 4114 if (eval5(arg, &var2, evaluate) == FAIL) 4115 { 4116 clear_tv(rettv); 4117 return FAIL; 4118 } 4119 4120 if (evaluate) 4121 { 4122 if (type_is && rettv->v_type != var2.v_type) 4123 { 4124 /* For "is" a different type always means FALSE, for "notis" 4125 * it means TRUE. */ 4126 n1 = (type == TYPE_NEQUAL); 4127 } 4128 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 4129 { 4130 if (type_is) 4131 { 4132 n1 = (rettv->v_type == var2.v_type 4133 && rettv->vval.v_list == var2.vval.v_list); 4134 if (type == TYPE_NEQUAL) 4135 n1 = !n1; 4136 } 4137 else if (rettv->v_type != var2.v_type 4138 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4139 { 4140 if (rettv->v_type != var2.v_type) 4141 EMSG(_("E691: Can only compare List with List")); 4142 else 4143 EMSG(_("E692: Invalid operation for Lists")); 4144 clear_tv(rettv); 4145 clear_tv(&var2); 4146 return FAIL; 4147 } 4148 else 4149 { 4150 /* Compare two Lists for being equal or unequal. */ 4151 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 4152 if (type == TYPE_NEQUAL) 4153 n1 = !n1; 4154 } 4155 } 4156 4157 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4158 { 4159 if (type_is) 4160 { 4161 n1 = (rettv->v_type == var2.v_type 4162 && rettv->vval.v_dict == var2.vval.v_dict); 4163 if (type == TYPE_NEQUAL) 4164 n1 = !n1; 4165 } 4166 else if (rettv->v_type != var2.v_type 4167 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4168 { 4169 if (rettv->v_type != var2.v_type) 4170 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4171 else 4172 EMSG(_("E736: Invalid operation for Dictionary")); 4173 clear_tv(rettv); 4174 clear_tv(&var2); 4175 return FAIL; 4176 } 4177 else 4178 { 4179 /* Compare two Dictionaries for being equal or unequal. */ 4180 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4181 if (type == TYPE_NEQUAL) 4182 n1 = !n1; 4183 } 4184 } 4185 4186 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4187 { 4188 if (rettv->v_type != var2.v_type 4189 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4190 { 4191 if (rettv->v_type != var2.v_type) 4192 EMSG(_("E693: Can only compare Funcref with Funcref")); 4193 else 4194 EMSG(_("E694: Invalid operation for Funcrefs")); 4195 clear_tv(rettv); 4196 clear_tv(&var2); 4197 return FAIL; 4198 } 4199 else 4200 { 4201 /* Compare two Funcrefs for being equal or unequal. */ 4202 if (rettv->vval.v_string == NULL 4203 || var2.vval.v_string == NULL) 4204 n1 = FALSE; 4205 else 4206 n1 = STRCMP(rettv->vval.v_string, 4207 var2.vval.v_string) == 0; 4208 if (type == TYPE_NEQUAL) 4209 n1 = !n1; 4210 } 4211 } 4212 4213 /* 4214 * If one of the two variables is a number, compare as a number. 4215 * When using "=~" or "!~", always compare as string. 4216 */ 4217 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4218 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4219 { 4220 n1 = get_tv_number(rettv); 4221 n2 = get_tv_number(&var2); 4222 switch (type) 4223 { 4224 case TYPE_EQUAL: n1 = (n1 == n2); break; 4225 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4226 case TYPE_GREATER: n1 = (n1 > n2); break; 4227 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4228 case TYPE_SMALLER: n1 = (n1 < n2); break; 4229 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4230 case TYPE_UNKNOWN: 4231 case TYPE_MATCH: 4232 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4233 } 4234 } 4235 else 4236 { 4237 s1 = get_tv_string_buf(rettv, buf1); 4238 s2 = get_tv_string_buf(&var2, buf2); 4239 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4240 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4241 else 4242 i = 0; 4243 n1 = FALSE; 4244 switch (type) 4245 { 4246 case TYPE_EQUAL: n1 = (i == 0); break; 4247 case TYPE_NEQUAL: n1 = (i != 0); break; 4248 case TYPE_GREATER: n1 = (i > 0); break; 4249 case TYPE_GEQUAL: n1 = (i >= 0); break; 4250 case TYPE_SMALLER: n1 = (i < 0); break; 4251 case TYPE_SEQUAL: n1 = (i <= 0); break; 4252 4253 case TYPE_MATCH: 4254 case TYPE_NOMATCH: 4255 /* avoid 'l' flag in 'cpoptions' */ 4256 save_cpo = p_cpo; 4257 p_cpo = (char_u *)""; 4258 regmatch.regprog = vim_regcomp(s2, 4259 RE_MAGIC + RE_STRING); 4260 regmatch.rm_ic = ic; 4261 if (regmatch.regprog != NULL) 4262 { 4263 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4264 vim_free(regmatch.regprog); 4265 if (type == TYPE_NOMATCH) 4266 n1 = !n1; 4267 } 4268 p_cpo = save_cpo; 4269 break; 4270 4271 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4272 } 4273 } 4274 clear_tv(rettv); 4275 clear_tv(&var2); 4276 rettv->v_type = VAR_NUMBER; 4277 rettv->vval.v_number = n1; 4278 } 4279 } 4280 4281 return OK; 4282 } 4283 4284 /* 4285 * Handle fourth level expression: 4286 * + number addition 4287 * - number subtraction 4288 * . string concatenation 4289 * 4290 * "arg" must point to the first non-white of the expression. 4291 * "arg" is advanced to the next non-white after the recognized expression. 4292 * 4293 * Return OK or FAIL. 4294 */ 4295 static int 4296 eval5(arg, rettv, evaluate) 4297 char_u **arg; 4298 typval_T *rettv; 4299 int evaluate; 4300 { 4301 typval_T var2; 4302 typval_T var3; 4303 int op; 4304 long n1, n2; 4305 char_u *s1, *s2; 4306 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4307 char_u *p; 4308 4309 /* 4310 * Get the first variable. 4311 */ 4312 if (eval6(arg, rettv, evaluate) == FAIL) 4313 return FAIL; 4314 4315 /* 4316 * Repeat computing, until no '+', '-' or '.' is following. 4317 */ 4318 for (;;) 4319 { 4320 op = **arg; 4321 if (op != '+' && op != '-' && op != '.') 4322 break; 4323 4324 if (op != '+' || rettv->v_type != VAR_LIST) 4325 { 4326 /* For "list + ...", an illegal use of the first operand as 4327 * a number cannot be determined before evaluating the 2nd 4328 * operand: if this is also a list, all is ok. 4329 * For "something . ...", "something - ..." or "non-list + ...", 4330 * we know that the first operand needs to be a string or number 4331 * without evaluating the 2nd operand. So check before to avoid 4332 * side effects after an error. */ 4333 if (evaluate && get_tv_string_chk(rettv) == NULL) 4334 { 4335 clear_tv(rettv); 4336 return FAIL; 4337 } 4338 } 4339 4340 /* 4341 * Get the second variable. 4342 */ 4343 *arg = skipwhite(*arg + 1); 4344 if (eval6(arg, &var2, evaluate) == FAIL) 4345 { 4346 clear_tv(rettv); 4347 return FAIL; 4348 } 4349 4350 if (evaluate) 4351 { 4352 /* 4353 * Compute the result. 4354 */ 4355 if (op == '.') 4356 { 4357 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4358 s2 = get_tv_string_buf_chk(&var2, buf2); 4359 if (s2 == NULL) /* type error ? */ 4360 { 4361 clear_tv(rettv); 4362 clear_tv(&var2); 4363 return FAIL; 4364 } 4365 p = concat_str(s1, s2); 4366 clear_tv(rettv); 4367 rettv->v_type = VAR_STRING; 4368 rettv->vval.v_string = p; 4369 } 4370 else if (op == '+' && rettv->v_type == VAR_LIST 4371 && var2.v_type == VAR_LIST) 4372 { 4373 /* concatenate Lists */ 4374 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4375 &var3) == FAIL) 4376 { 4377 clear_tv(rettv); 4378 clear_tv(&var2); 4379 return FAIL; 4380 } 4381 clear_tv(rettv); 4382 *rettv = var3; 4383 } 4384 else 4385 { 4386 int error = FALSE; 4387 4388 n1 = get_tv_number_chk(rettv, &error); 4389 if (error) 4390 { 4391 /* This can only happen for "list + non-list". 4392 * For "non-list + ..." or "something - ...", we returned 4393 * before evaluating the 2nd operand. */ 4394 clear_tv(rettv); 4395 return FAIL; 4396 } 4397 n2 = get_tv_number_chk(&var2, &error); 4398 if (error) 4399 { 4400 clear_tv(rettv); 4401 clear_tv(&var2); 4402 return FAIL; 4403 } 4404 clear_tv(rettv); 4405 if (op == '+') 4406 n1 = n1 + n2; 4407 else 4408 n1 = n1 - n2; 4409 rettv->v_type = VAR_NUMBER; 4410 rettv->vval.v_number = n1; 4411 } 4412 clear_tv(&var2); 4413 } 4414 } 4415 return OK; 4416 } 4417 4418 /* 4419 * Handle fifth level expression: 4420 * * number multiplication 4421 * / number division 4422 * % number modulo 4423 * 4424 * "arg" must point to the first non-white of the expression. 4425 * "arg" is advanced to the next non-white after the recognized expression. 4426 * 4427 * Return OK or FAIL. 4428 */ 4429 static int 4430 eval6(arg, rettv, evaluate) 4431 char_u **arg; 4432 typval_T *rettv; 4433 int evaluate; 4434 { 4435 typval_T var2; 4436 int op; 4437 long n1, n2; 4438 int error = FALSE; 4439 4440 /* 4441 * Get the first variable. 4442 */ 4443 if (eval7(arg, rettv, evaluate) == FAIL) 4444 return FAIL; 4445 4446 /* 4447 * Repeat computing, until no '*', '/' or '%' is following. 4448 */ 4449 for (;;) 4450 { 4451 op = **arg; 4452 if (op != '*' && op != '/' && op != '%') 4453 break; 4454 4455 if (evaluate) 4456 { 4457 n1 = get_tv_number_chk(rettv, &error); 4458 clear_tv(rettv); 4459 if (error) 4460 return FAIL; 4461 } 4462 else 4463 n1 = 0; 4464 4465 /* 4466 * Get the second variable. 4467 */ 4468 *arg = skipwhite(*arg + 1); 4469 if (eval7(arg, &var2, evaluate) == FAIL) 4470 return FAIL; 4471 4472 if (evaluate) 4473 { 4474 n2 = get_tv_number_chk(&var2, &error); 4475 clear_tv(&var2); 4476 if (error) 4477 return FAIL; 4478 4479 /* 4480 * Compute the result. 4481 */ 4482 if (op == '*') 4483 n1 = n1 * n2; 4484 else if (op == '/') 4485 { 4486 if (n2 == 0) /* give an error message? */ 4487 n1 = 0x7fffffffL; 4488 else 4489 n1 = n1 / n2; 4490 } 4491 else 4492 { 4493 if (n2 == 0) /* give an error message? */ 4494 n1 = 0; 4495 else 4496 n1 = n1 % n2; 4497 } 4498 rettv->v_type = VAR_NUMBER; 4499 rettv->vval.v_number = n1; 4500 } 4501 } 4502 4503 return OK; 4504 } 4505 4506 /* 4507 * Handle sixth level expression: 4508 * number number constant 4509 * "string" string contstant 4510 * 'string' literal string contstant 4511 * &option-name option value 4512 * @r register contents 4513 * identifier variable value 4514 * function() function call 4515 * $VAR environment variable 4516 * (expression) nested expression 4517 * [expr, expr] List 4518 * {key: val, key: val} Dictionary 4519 * 4520 * Also handle: 4521 * ! in front logical NOT 4522 * - in front unary minus 4523 * + in front unary plus (ignored) 4524 * trailing [] subscript in String or List 4525 * trailing .name entry in Dictionary 4526 * 4527 * "arg" must point to the first non-white of the expression. 4528 * "arg" is advanced to the next non-white after the recognized expression. 4529 * 4530 * Return OK or FAIL. 4531 */ 4532 static int 4533 eval7(arg, rettv, evaluate) 4534 char_u **arg; 4535 typval_T *rettv; 4536 int evaluate; 4537 { 4538 long n; 4539 int len; 4540 char_u *s; 4541 int val; 4542 char_u *start_leader, *end_leader; 4543 int ret = OK; 4544 char_u *alias; 4545 4546 /* 4547 * Initialise variable so that clear_tv() can't mistake this for a 4548 * string and free a string that isn't there. 4549 */ 4550 rettv->v_type = VAR_UNKNOWN; 4551 4552 /* 4553 * Skip '!' and '-' characters. They are handled later. 4554 */ 4555 start_leader = *arg; 4556 while (**arg == '!' || **arg == '-' || **arg == '+') 4557 *arg = skipwhite(*arg + 1); 4558 end_leader = *arg; 4559 4560 switch (**arg) 4561 { 4562 /* 4563 * Number constant. 4564 */ 4565 case '0': 4566 case '1': 4567 case '2': 4568 case '3': 4569 case '4': 4570 case '5': 4571 case '6': 4572 case '7': 4573 case '8': 4574 case '9': 4575 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4576 *arg += len; 4577 if (evaluate) 4578 { 4579 rettv->v_type = VAR_NUMBER; 4580 rettv->vval.v_number = n; 4581 } 4582 break; 4583 4584 /* 4585 * String constant: "string". 4586 */ 4587 case '"': ret = get_string_tv(arg, rettv, evaluate); 4588 break; 4589 4590 /* 4591 * Literal string constant: 'str''ing'. 4592 */ 4593 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4594 break; 4595 4596 /* 4597 * List: [expr, expr] 4598 */ 4599 case '[': ret = get_list_tv(arg, rettv, evaluate); 4600 break; 4601 4602 /* 4603 * Dictionary: {key: val, key: val} 4604 */ 4605 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4606 break; 4607 4608 /* 4609 * Option value: &name 4610 */ 4611 case '&': ret = get_option_tv(arg, rettv, evaluate); 4612 break; 4613 4614 /* 4615 * Environment variable: $VAR. 4616 */ 4617 case '$': ret = get_env_tv(arg, rettv, evaluate); 4618 break; 4619 4620 /* 4621 * Register contents: @r. 4622 */ 4623 case '@': ++*arg; 4624 if (evaluate) 4625 { 4626 rettv->v_type = VAR_STRING; 4627 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4628 } 4629 if (**arg != NUL) 4630 ++*arg; 4631 break; 4632 4633 /* 4634 * nested expression: (expression). 4635 */ 4636 case '(': *arg = skipwhite(*arg + 1); 4637 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4638 if (**arg == ')') 4639 ++*arg; 4640 else if (ret == OK) 4641 { 4642 EMSG(_("E110: Missing ')'")); 4643 clear_tv(rettv); 4644 ret = FAIL; 4645 } 4646 break; 4647 4648 default: ret = NOTDONE; 4649 break; 4650 } 4651 4652 if (ret == NOTDONE) 4653 { 4654 /* 4655 * Must be a variable or function name. 4656 * Can also be a curly-braces kind of name: {expr}. 4657 */ 4658 s = *arg; 4659 len = get_name_len(arg, &alias, evaluate, TRUE); 4660 if (alias != NULL) 4661 s = alias; 4662 4663 if (len <= 0) 4664 ret = FAIL; 4665 else 4666 { 4667 if (**arg == '(') /* recursive! */ 4668 { 4669 /* If "s" is the name of a variable of type VAR_FUNC 4670 * use its contents. */ 4671 s = deref_func_name(s, &len); 4672 4673 /* Invoke the function. */ 4674 ret = get_func_tv(s, len, rettv, arg, 4675 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4676 &len, evaluate, NULL); 4677 /* Stop the expression evaluation when immediately 4678 * aborting on error, or when an interrupt occurred or 4679 * an exception was thrown but not caught. */ 4680 if (aborting()) 4681 { 4682 if (ret == OK) 4683 clear_tv(rettv); 4684 ret = FAIL; 4685 } 4686 } 4687 else if (evaluate) 4688 ret = get_var_tv(s, len, rettv, TRUE); 4689 else 4690 ret = OK; 4691 } 4692 4693 if (alias != NULL) 4694 vim_free(alias); 4695 } 4696 4697 *arg = skipwhite(*arg); 4698 4699 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4700 * expr(expr). */ 4701 if (ret == OK) 4702 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4703 4704 /* 4705 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4706 */ 4707 if (ret == OK && evaluate && end_leader > start_leader) 4708 { 4709 int error = FALSE; 4710 4711 val = get_tv_number_chk(rettv, &error); 4712 if (error) 4713 { 4714 clear_tv(rettv); 4715 ret = FAIL; 4716 } 4717 else 4718 { 4719 while (end_leader > start_leader) 4720 { 4721 --end_leader; 4722 if (*end_leader == '!') 4723 val = !val; 4724 else if (*end_leader == '-') 4725 val = -val; 4726 } 4727 clear_tv(rettv); 4728 rettv->v_type = VAR_NUMBER; 4729 rettv->vval.v_number = val; 4730 } 4731 } 4732 4733 return ret; 4734 } 4735 4736 /* 4737 * Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key". 4738 * "*arg" points to the '[' or '.'. 4739 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4740 */ 4741 static int 4742 eval_index(arg, rettv, evaluate, verbose) 4743 char_u **arg; 4744 typval_T *rettv; 4745 int evaluate; 4746 int verbose; /* give error messages */ 4747 { 4748 int empty1 = FALSE, empty2 = FALSE; 4749 typval_T var1, var2; 4750 long n1, n2 = 0; 4751 long len = -1; 4752 int range = FALSE; 4753 char_u *s; 4754 char_u *key = NULL; 4755 4756 if (rettv->v_type == VAR_FUNC) 4757 { 4758 if (verbose) 4759 EMSG(_("E695: Cannot index a Funcref")); 4760 return FAIL; 4761 } 4762 4763 if (**arg == '.') 4764 { 4765 /* 4766 * dict.name 4767 */ 4768 key = *arg + 1; 4769 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4770 ; 4771 if (len == 0) 4772 return FAIL; 4773 *arg = skipwhite(key + len); 4774 } 4775 else 4776 { 4777 /* 4778 * something[idx] 4779 * 4780 * Get the (first) variable from inside the []. 4781 */ 4782 *arg = skipwhite(*arg + 1); 4783 if (**arg == ':') 4784 empty1 = TRUE; 4785 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4786 return FAIL; 4787 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4788 { 4789 /* not a number or string */ 4790 clear_tv(&var1); 4791 return FAIL; 4792 } 4793 4794 /* 4795 * Get the second variable from inside the [:]. 4796 */ 4797 if (**arg == ':') 4798 { 4799 range = TRUE; 4800 *arg = skipwhite(*arg + 1); 4801 if (**arg == ']') 4802 empty2 = TRUE; 4803 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4804 { 4805 if (!empty1) 4806 clear_tv(&var1); 4807 return FAIL; 4808 } 4809 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4810 { 4811 /* not a number or string */ 4812 if (!empty1) 4813 clear_tv(&var1); 4814 clear_tv(&var2); 4815 return FAIL; 4816 } 4817 } 4818 4819 /* Check for the ']'. */ 4820 if (**arg != ']') 4821 { 4822 if (verbose) 4823 EMSG(_(e_missbrac)); 4824 clear_tv(&var1); 4825 if (range) 4826 clear_tv(&var2); 4827 return FAIL; 4828 } 4829 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4830 } 4831 4832 if (evaluate) 4833 { 4834 n1 = 0; 4835 if (!empty1 && rettv->v_type != VAR_DICT) 4836 { 4837 n1 = get_tv_number(&var1); 4838 clear_tv(&var1); 4839 } 4840 if (range) 4841 { 4842 if (empty2) 4843 n2 = -1; 4844 else 4845 { 4846 n2 = get_tv_number(&var2); 4847 clear_tv(&var2); 4848 } 4849 } 4850 4851 switch (rettv->v_type) 4852 { 4853 case VAR_NUMBER: 4854 case VAR_STRING: 4855 s = get_tv_string(rettv); 4856 len = (long)STRLEN(s); 4857 if (range) 4858 { 4859 /* The resulting variable is a substring. If the indexes 4860 * are out of range the result is empty. */ 4861 if (n1 < 0) 4862 { 4863 n1 = len + n1; 4864 if (n1 < 0) 4865 n1 = 0; 4866 } 4867 if (n2 < 0) 4868 n2 = len + n2; 4869 else if (n2 >= len) 4870 n2 = len; 4871 if (n1 >= len || n2 < 0 || n1 > n2) 4872 s = NULL; 4873 else 4874 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4875 } 4876 else 4877 { 4878 /* The resulting variable is a string of a single 4879 * character. If the index is too big or negative the 4880 * result is empty. */ 4881 if (n1 >= len || n1 < 0) 4882 s = NULL; 4883 else 4884 s = vim_strnsave(s + n1, 1); 4885 } 4886 clear_tv(rettv); 4887 rettv->v_type = VAR_STRING; 4888 rettv->vval.v_string = s; 4889 break; 4890 4891 case VAR_LIST: 4892 len = list_len(rettv->vval.v_list); 4893 if (n1 < 0) 4894 n1 = len + n1; 4895 if (!empty1 && (n1 < 0 || n1 >= len)) 4896 { 4897 /* For a range we allow invalid values and return an empty 4898 * list. A list index out of range is an error. */ 4899 if (!range) 4900 { 4901 if (verbose) 4902 EMSGN(_(e_listidx), n1); 4903 return FAIL; 4904 } 4905 n1 = len; 4906 } 4907 if (range) 4908 { 4909 list_T *l; 4910 listitem_T *item; 4911 4912 if (n2 < 0) 4913 n2 = len + n2; 4914 else if (n2 >= len) 4915 n2 = len - 1; 4916 if (!empty2 && (n2 < 0 || n2 + 1 < n1)) 4917 n2 = -1; 4918 l = list_alloc(); 4919 if (l == NULL) 4920 return FAIL; 4921 for (item = list_find(rettv->vval.v_list, n1); 4922 n1 <= n2; ++n1) 4923 { 4924 if (list_append_tv(l, &item->li_tv) == FAIL) 4925 { 4926 list_free(l, TRUE); 4927 return FAIL; 4928 } 4929 item = item->li_next; 4930 } 4931 clear_tv(rettv); 4932 rettv->v_type = VAR_LIST; 4933 rettv->vval.v_list = l; 4934 ++l->lv_refcount; 4935 } 4936 else 4937 { 4938 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1); 4939 clear_tv(rettv); 4940 *rettv = var1; 4941 } 4942 break; 4943 4944 case VAR_DICT: 4945 if (range) 4946 { 4947 if (verbose) 4948 EMSG(_(e_dictrange)); 4949 if (len == -1) 4950 clear_tv(&var1); 4951 return FAIL; 4952 } 4953 { 4954 dictitem_T *item; 4955 4956 if (len == -1) 4957 { 4958 key = get_tv_string(&var1); 4959 if (*key == NUL) 4960 { 4961 if (verbose) 4962 EMSG(_(e_emptykey)); 4963 clear_tv(&var1); 4964 return FAIL; 4965 } 4966 } 4967 4968 item = dict_find(rettv->vval.v_dict, key, (int)len); 4969 4970 if (item == NULL && verbose) 4971 EMSG2(_(e_dictkey), key); 4972 if (len == -1) 4973 clear_tv(&var1); 4974 if (item == NULL) 4975 return FAIL; 4976 4977 copy_tv(&item->di_tv, &var1); 4978 clear_tv(rettv); 4979 *rettv = var1; 4980 } 4981 break; 4982 } 4983 } 4984 4985 return OK; 4986 } 4987 4988 /* 4989 * Get an option value. 4990 * "arg" points to the '&' or '+' before the option name. 4991 * "arg" is advanced to character after the option name. 4992 * Return OK or FAIL. 4993 */ 4994 static int 4995 get_option_tv(arg, rettv, evaluate) 4996 char_u **arg; 4997 typval_T *rettv; /* when NULL, only check if option exists */ 4998 int evaluate; 4999 { 5000 char_u *option_end; 5001 long numval; 5002 char_u *stringval; 5003 int opt_type; 5004 int c; 5005 int working = (**arg == '+'); /* has("+option") */ 5006 int ret = OK; 5007 int opt_flags; 5008 5009 /* 5010 * Isolate the option name and find its value. 5011 */ 5012 option_end = find_option_end(arg, &opt_flags); 5013 if (option_end == NULL) 5014 { 5015 if (rettv != NULL) 5016 EMSG2(_("E112: Option name missing: %s"), *arg); 5017 return FAIL; 5018 } 5019 5020 if (!evaluate) 5021 { 5022 *arg = option_end; 5023 return OK; 5024 } 5025 5026 c = *option_end; 5027 *option_end = NUL; 5028 opt_type = get_option_value(*arg, &numval, 5029 rettv == NULL ? NULL : &stringval, opt_flags); 5030 5031 if (opt_type == -3) /* invalid name */ 5032 { 5033 if (rettv != NULL) 5034 EMSG2(_("E113: Unknown option: %s"), *arg); 5035 ret = FAIL; 5036 } 5037 else if (rettv != NULL) 5038 { 5039 if (opt_type == -2) /* hidden string option */ 5040 { 5041 rettv->v_type = VAR_STRING; 5042 rettv->vval.v_string = NULL; 5043 } 5044 else if (opt_type == -1) /* hidden number option */ 5045 { 5046 rettv->v_type = VAR_NUMBER; 5047 rettv->vval.v_number = 0; 5048 } 5049 else if (opt_type == 1) /* number option */ 5050 { 5051 rettv->v_type = VAR_NUMBER; 5052 rettv->vval.v_number = numval; 5053 } 5054 else /* string option */ 5055 { 5056 rettv->v_type = VAR_STRING; 5057 rettv->vval.v_string = stringval; 5058 } 5059 } 5060 else if (working && (opt_type == -2 || opt_type == -1)) 5061 ret = FAIL; 5062 5063 *option_end = c; /* put back for error messages */ 5064 *arg = option_end; 5065 5066 return ret; 5067 } 5068 5069 /* 5070 * Allocate a variable for a string constant. 5071 * Return OK or FAIL. 5072 */ 5073 static int 5074 get_string_tv(arg, rettv, evaluate) 5075 char_u **arg; 5076 typval_T *rettv; 5077 int evaluate; 5078 { 5079 char_u *p; 5080 char_u *name; 5081 int extra = 0; 5082 5083 /* 5084 * Find the end of the string, skipping backslashed characters. 5085 */ 5086 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 5087 { 5088 if (*p == '\\' && p[1] != NUL) 5089 { 5090 ++p; 5091 /* A "\<x>" form occupies at least 4 characters, and produces up 5092 * to 6 characters: reserve space for 2 extra */ 5093 if (*p == '<') 5094 extra += 2; 5095 } 5096 } 5097 5098 if (*p != '"') 5099 { 5100 EMSG2(_("E114: Missing quote: %s"), *arg); 5101 return FAIL; 5102 } 5103 5104 /* If only parsing, set *arg and return here */ 5105 if (!evaluate) 5106 { 5107 *arg = p + 1; 5108 return OK; 5109 } 5110 5111 /* 5112 * Copy the string into allocated memory, handling backslashed 5113 * characters. 5114 */ 5115 name = alloc((unsigned)(p - *arg + extra)); 5116 if (name == NULL) 5117 return FAIL; 5118 rettv->v_type = VAR_STRING; 5119 rettv->vval.v_string = name; 5120 5121 for (p = *arg + 1; *p != NUL && *p != '"'; ) 5122 { 5123 if (*p == '\\') 5124 { 5125 switch (*++p) 5126 { 5127 case 'b': *name++ = BS; ++p; break; 5128 case 'e': *name++ = ESC; ++p; break; 5129 case 'f': *name++ = FF; ++p; break; 5130 case 'n': *name++ = NL; ++p; break; 5131 case 'r': *name++ = CAR; ++p; break; 5132 case 't': *name++ = TAB; ++p; break; 5133 5134 case 'X': /* hex: "\x1", "\x12" */ 5135 case 'x': 5136 case 'u': /* Unicode: "\u0023" */ 5137 case 'U': 5138 if (vim_isxdigit(p[1])) 5139 { 5140 int n, nr; 5141 int c = toupper(*p); 5142 5143 if (c == 'X') 5144 n = 2; 5145 else 5146 n = 4; 5147 nr = 0; 5148 while (--n >= 0 && vim_isxdigit(p[1])) 5149 { 5150 ++p; 5151 nr = (nr << 4) + hex2nr(*p); 5152 } 5153 ++p; 5154 #ifdef FEAT_MBYTE 5155 /* For "\u" store the number according to 5156 * 'encoding'. */ 5157 if (c != 'X') 5158 name += (*mb_char2bytes)(nr, name); 5159 else 5160 #endif 5161 *name++ = nr; 5162 } 5163 break; 5164 5165 /* octal: "\1", "\12", "\123" */ 5166 case '0': 5167 case '1': 5168 case '2': 5169 case '3': 5170 case '4': 5171 case '5': 5172 case '6': 5173 case '7': *name = *p++ - '0'; 5174 if (*p >= '0' && *p <= '7') 5175 { 5176 *name = (*name << 3) + *p++ - '0'; 5177 if (*p >= '0' && *p <= '7') 5178 *name = (*name << 3) + *p++ - '0'; 5179 } 5180 ++name; 5181 break; 5182 5183 /* Special key, e.g.: "\<C-W>" */ 5184 case '<': extra = trans_special(&p, name, TRUE); 5185 if (extra != 0) 5186 { 5187 name += extra; 5188 break; 5189 } 5190 /* FALLTHROUGH */ 5191 5192 default: MB_COPY_CHAR(p, name); 5193 break; 5194 } 5195 } 5196 else 5197 MB_COPY_CHAR(p, name); 5198 5199 } 5200 *name = NUL; 5201 *arg = p + 1; 5202 5203 return OK; 5204 } 5205 5206 /* 5207 * Allocate a variable for a 'str''ing' constant. 5208 * Return OK or FAIL. 5209 */ 5210 static int 5211 get_lit_string_tv(arg, rettv, evaluate) 5212 char_u **arg; 5213 typval_T *rettv; 5214 int evaluate; 5215 { 5216 char_u *p; 5217 char_u *str; 5218 int reduce = 0; 5219 5220 /* 5221 * Find the end of the string, skipping ''. 5222 */ 5223 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5224 { 5225 if (*p == '\'') 5226 { 5227 if (p[1] != '\'') 5228 break; 5229 ++reduce; 5230 ++p; 5231 } 5232 } 5233 5234 if (*p != '\'') 5235 { 5236 EMSG2(_("E115: Missing quote: %s"), *arg); 5237 return FAIL; 5238 } 5239 5240 /* If only parsing return after setting "*arg" */ 5241 if (!evaluate) 5242 { 5243 *arg = p + 1; 5244 return OK; 5245 } 5246 5247 /* 5248 * Copy the string into allocated memory, handling '' to ' reduction. 5249 */ 5250 str = alloc((unsigned)((p - *arg) - reduce)); 5251 if (str == NULL) 5252 return FAIL; 5253 rettv->v_type = VAR_STRING; 5254 rettv->vval.v_string = str; 5255 5256 for (p = *arg + 1; *p != NUL; ) 5257 { 5258 if (*p == '\'') 5259 { 5260 if (p[1] != '\'') 5261 break; 5262 ++p; 5263 } 5264 MB_COPY_CHAR(p, str); 5265 } 5266 *str = NUL; 5267 *arg = p + 1; 5268 5269 return OK; 5270 } 5271 5272 /* 5273 * Allocate a variable for a List and fill it from "*arg". 5274 * Return OK or FAIL. 5275 */ 5276 static int 5277 get_list_tv(arg, rettv, evaluate) 5278 char_u **arg; 5279 typval_T *rettv; 5280 int evaluate; 5281 { 5282 list_T *l = NULL; 5283 typval_T tv; 5284 listitem_T *item; 5285 5286 if (evaluate) 5287 { 5288 l = list_alloc(); 5289 if (l == NULL) 5290 return FAIL; 5291 } 5292 5293 *arg = skipwhite(*arg + 1); 5294 while (**arg != ']' && **arg != NUL) 5295 { 5296 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5297 goto failret; 5298 if (evaluate) 5299 { 5300 item = listitem_alloc(); 5301 if (item != NULL) 5302 { 5303 item->li_tv = tv; 5304 item->li_tv.v_lock = 0; 5305 list_append(l, item); 5306 } 5307 else 5308 clear_tv(&tv); 5309 } 5310 5311 if (**arg == ']') 5312 break; 5313 if (**arg != ',') 5314 { 5315 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5316 goto failret; 5317 } 5318 *arg = skipwhite(*arg + 1); 5319 } 5320 5321 if (**arg != ']') 5322 { 5323 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5324 failret: 5325 if (evaluate) 5326 list_free(l, TRUE); 5327 return FAIL; 5328 } 5329 5330 *arg = skipwhite(*arg + 1); 5331 if (evaluate) 5332 { 5333 rettv->v_type = VAR_LIST; 5334 rettv->vval.v_list = l; 5335 ++l->lv_refcount; 5336 } 5337 5338 return OK; 5339 } 5340 5341 /* 5342 * Allocate an empty header for a list. 5343 * Caller should take care of the reference count. 5344 */ 5345 list_T * 5346 list_alloc() 5347 { 5348 list_T *l; 5349 5350 l = (list_T *)alloc_clear(sizeof(list_T)); 5351 if (l != NULL) 5352 { 5353 /* Prepend the list to the list of lists for garbage collection. */ 5354 if (first_list != NULL) 5355 first_list->lv_used_prev = l; 5356 l->lv_used_prev = NULL; 5357 l->lv_used_next = first_list; 5358 first_list = l; 5359 } 5360 return l; 5361 } 5362 5363 /* 5364 * Allocate an empty list for a return value. 5365 * Returns OK or FAIL. 5366 */ 5367 static int 5368 rettv_list_alloc(rettv) 5369 typval_T *rettv; 5370 { 5371 list_T *l = list_alloc(); 5372 5373 if (l == NULL) 5374 return FAIL; 5375 5376 rettv->vval.v_list = l; 5377 rettv->v_type = VAR_LIST; 5378 ++l->lv_refcount; 5379 return OK; 5380 } 5381 5382 /* 5383 * Unreference a list: decrement the reference count and free it when it 5384 * becomes zero. 5385 */ 5386 void 5387 list_unref(l) 5388 list_T *l; 5389 { 5390 if (l != NULL && --l->lv_refcount <= 0) 5391 list_free(l, TRUE); 5392 } 5393 5394 /* 5395 * Free a list, including all items it points to. 5396 * Ignores the reference count. 5397 */ 5398 void 5399 list_free(l, recurse) 5400 list_T *l; 5401 int recurse; /* Free Lists and Dictionaries recursively. */ 5402 { 5403 listitem_T *item; 5404 5405 /* Remove the list from the list of lists for garbage collection. */ 5406 if (l->lv_used_prev == NULL) 5407 first_list = l->lv_used_next; 5408 else 5409 l->lv_used_prev->lv_used_next = l->lv_used_next; 5410 if (l->lv_used_next != NULL) 5411 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5412 5413 for (item = l->lv_first; item != NULL; item = l->lv_first) 5414 { 5415 /* Remove the item before deleting it. */ 5416 l->lv_first = item->li_next; 5417 if (recurse || (item->li_tv.v_type != VAR_LIST 5418 && item->li_tv.v_type != VAR_DICT)) 5419 clear_tv(&item->li_tv); 5420 vim_free(item); 5421 } 5422 vim_free(l); 5423 } 5424 5425 /* 5426 * Allocate a list item. 5427 */ 5428 static listitem_T * 5429 listitem_alloc() 5430 { 5431 return (listitem_T *)alloc(sizeof(listitem_T)); 5432 } 5433 5434 /* 5435 * Free a list item. Also clears the value. Does not notify watchers. 5436 */ 5437 static void 5438 listitem_free(item) 5439 listitem_T *item; 5440 { 5441 clear_tv(&item->li_tv); 5442 vim_free(item); 5443 } 5444 5445 /* 5446 * Remove a list item from a List and free it. Also clears the value. 5447 */ 5448 static void 5449 listitem_remove(l, item) 5450 list_T *l; 5451 listitem_T *item; 5452 { 5453 list_remove(l, item, item); 5454 listitem_free(item); 5455 } 5456 5457 /* 5458 * Get the number of items in a list. 5459 */ 5460 static long 5461 list_len(l) 5462 list_T *l; 5463 { 5464 if (l == NULL) 5465 return 0L; 5466 return l->lv_len; 5467 } 5468 5469 /* 5470 * Return TRUE when two lists have exactly the same values. 5471 */ 5472 static int 5473 list_equal(l1, l2, ic) 5474 list_T *l1; 5475 list_T *l2; 5476 int ic; /* ignore case for strings */ 5477 { 5478 listitem_T *item1, *item2; 5479 5480 if (l1 == l2) 5481 return TRUE; 5482 if (list_len(l1) != list_len(l2)) 5483 return FALSE; 5484 5485 for (item1 = l1->lv_first, item2 = l2->lv_first; 5486 item1 != NULL && item2 != NULL; 5487 item1 = item1->li_next, item2 = item2->li_next) 5488 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5489 return FALSE; 5490 return item1 == NULL && item2 == NULL; 5491 } 5492 5493 #if defined(FEAT_PYTHON) || defined(PROTO) 5494 /* 5495 * Return the dictitem that an entry in a hashtable points to. 5496 */ 5497 dictitem_T * 5498 dict_lookup(hi) 5499 hashitem_T *hi; 5500 { 5501 return HI2DI(hi); 5502 } 5503 #endif 5504 5505 /* 5506 * Return TRUE when two dictionaries have exactly the same key/values. 5507 */ 5508 static int 5509 dict_equal(d1, d2, ic) 5510 dict_T *d1; 5511 dict_T *d2; 5512 int ic; /* ignore case for strings */ 5513 { 5514 hashitem_T *hi; 5515 dictitem_T *item2; 5516 int todo; 5517 5518 if (d1 == d2) 5519 return TRUE; 5520 if (dict_len(d1) != dict_len(d2)) 5521 return FALSE; 5522 5523 todo = (int)d1->dv_hashtab.ht_used; 5524 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5525 { 5526 if (!HASHITEM_EMPTY(hi)) 5527 { 5528 item2 = dict_find(d2, hi->hi_key, -1); 5529 if (item2 == NULL) 5530 return FALSE; 5531 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5532 return FALSE; 5533 --todo; 5534 } 5535 } 5536 return TRUE; 5537 } 5538 5539 /* 5540 * Return TRUE if "tv1" and "tv2" have the same value. 5541 * Compares the items just like "==" would compare them, but strings and 5542 * numbers are different. 5543 */ 5544 static int 5545 tv_equal(tv1, tv2, ic) 5546 typval_T *tv1; 5547 typval_T *tv2; 5548 int ic; /* ignore case */ 5549 { 5550 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5551 char_u *s1, *s2; 5552 static int recursive = 0; /* cach recursive loops */ 5553 int r; 5554 5555 if (tv1->v_type != tv2->v_type) 5556 return FALSE; 5557 /* Catch lists and dicts that have an endless loop by limiting 5558 * recursiveness to 1000. We guess they are equal then. */ 5559 if (recursive >= 1000) 5560 return TRUE; 5561 5562 switch (tv1->v_type) 5563 { 5564 case VAR_LIST: 5565 ++recursive; 5566 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5567 --recursive; 5568 return r; 5569 5570 case VAR_DICT: 5571 ++recursive; 5572 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5573 --recursive; 5574 return r; 5575 5576 case VAR_FUNC: 5577 return (tv1->vval.v_string != NULL 5578 && tv2->vval.v_string != NULL 5579 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5580 5581 case VAR_NUMBER: 5582 return tv1->vval.v_number == tv2->vval.v_number; 5583 5584 case VAR_STRING: 5585 s1 = get_tv_string_buf(tv1, buf1); 5586 s2 = get_tv_string_buf(tv2, buf2); 5587 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5588 } 5589 5590 EMSG2(_(e_intern2), "tv_equal()"); 5591 return TRUE; 5592 } 5593 5594 /* 5595 * Locate item with index "n" in list "l" and return it. 5596 * A negative index is counted from the end; -1 is the last item. 5597 * Returns NULL when "n" is out of range. 5598 */ 5599 static listitem_T * 5600 list_find(l, n) 5601 list_T *l; 5602 long n; 5603 { 5604 listitem_T *item; 5605 long idx; 5606 5607 if (l == NULL) 5608 return NULL; 5609 5610 /* Negative index is relative to the end. */ 5611 if (n < 0) 5612 n = l->lv_len + n; 5613 5614 /* Check for index out of range. */ 5615 if (n < 0 || n >= l->lv_len) 5616 return NULL; 5617 5618 /* When there is a cached index may start search from there. */ 5619 if (l->lv_idx_item != NULL) 5620 { 5621 if (n < l->lv_idx / 2) 5622 { 5623 /* closest to the start of the list */ 5624 item = l->lv_first; 5625 idx = 0; 5626 } 5627 else if (n > (l->lv_idx + l->lv_len) / 2) 5628 { 5629 /* closest to the end of the list */ 5630 item = l->lv_last; 5631 idx = l->lv_len - 1; 5632 } 5633 else 5634 { 5635 /* closest to the cached index */ 5636 item = l->lv_idx_item; 5637 idx = l->lv_idx; 5638 } 5639 } 5640 else 5641 { 5642 if (n < l->lv_len / 2) 5643 { 5644 /* closest to the start of the list */ 5645 item = l->lv_first; 5646 idx = 0; 5647 } 5648 else 5649 { 5650 /* closest to the end of the list */ 5651 item = l->lv_last; 5652 idx = l->lv_len - 1; 5653 } 5654 } 5655 5656 while (n > idx) 5657 { 5658 /* search forward */ 5659 item = item->li_next; 5660 ++idx; 5661 } 5662 while (n < idx) 5663 { 5664 /* search backward */ 5665 item = item->li_prev; 5666 --idx; 5667 } 5668 5669 /* cache the used index */ 5670 l->lv_idx = idx; 5671 l->lv_idx_item = item; 5672 5673 return item; 5674 } 5675 5676 /* 5677 * Get list item "l[idx]" as a number. 5678 */ 5679 static long 5680 list_find_nr(l, idx, errorp) 5681 list_T *l; 5682 long idx; 5683 int *errorp; /* set to TRUE when something wrong */ 5684 { 5685 listitem_T *li; 5686 5687 li = list_find(l, idx); 5688 if (li == NULL) 5689 { 5690 if (errorp != NULL) 5691 *errorp = TRUE; 5692 return -1L; 5693 } 5694 return get_tv_number_chk(&li->li_tv, errorp); 5695 } 5696 5697 /* 5698 * Locate "item" list "l" and return its index. 5699 * Returns -1 when "item" is not in the list. 5700 */ 5701 static long 5702 list_idx_of_item(l, item) 5703 list_T *l; 5704 listitem_T *item; 5705 { 5706 long idx = 0; 5707 listitem_T *li; 5708 5709 if (l == NULL) 5710 return -1; 5711 idx = 0; 5712 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5713 ++idx; 5714 if (li == NULL) 5715 return -1; 5716 return idx; 5717 } 5718 5719 /* 5720 * Append item "item" to the end of list "l". 5721 */ 5722 static void 5723 list_append(l, item) 5724 list_T *l; 5725 listitem_T *item; 5726 { 5727 if (l->lv_last == NULL) 5728 { 5729 /* empty list */ 5730 l->lv_first = item; 5731 l->lv_last = item; 5732 item->li_prev = NULL; 5733 } 5734 else 5735 { 5736 l->lv_last->li_next = item; 5737 item->li_prev = l->lv_last; 5738 l->lv_last = item; 5739 } 5740 ++l->lv_len; 5741 item->li_next = NULL; 5742 } 5743 5744 /* 5745 * Append typval_T "tv" to the end of list "l". 5746 * Return FAIL when out of memory. 5747 */ 5748 static int 5749 list_append_tv(l, tv) 5750 list_T *l; 5751 typval_T *tv; 5752 { 5753 listitem_T *li = listitem_alloc(); 5754 5755 if (li == NULL) 5756 return FAIL; 5757 copy_tv(tv, &li->li_tv); 5758 list_append(l, li); 5759 return OK; 5760 } 5761 5762 /* 5763 * Add a dictionary to a list. Used by getqflist(). 5764 * Return FAIL when out of memory. 5765 */ 5766 int 5767 list_append_dict(list, dict) 5768 list_T *list; 5769 dict_T *dict; 5770 { 5771 listitem_T *li = listitem_alloc(); 5772 5773 if (li == NULL) 5774 return FAIL; 5775 li->li_tv.v_type = VAR_DICT; 5776 li->li_tv.v_lock = 0; 5777 li->li_tv.vval.v_dict = dict; 5778 list_append(list, li); 5779 ++dict->dv_refcount; 5780 return OK; 5781 } 5782 5783 /* 5784 * Make a copy of "str" and append it as an item to list "l". 5785 * When "len" >= 0 use "str[len]". 5786 * Returns FAIL when out of memory. 5787 */ 5788 static int 5789 list_append_string(l, str, len) 5790 list_T *l; 5791 char_u *str; 5792 int len; 5793 { 5794 listitem_T *li = listitem_alloc(); 5795 5796 if (li == NULL) 5797 return FAIL; 5798 list_append(l, li); 5799 li->li_tv.v_type = VAR_STRING; 5800 li->li_tv.v_lock = 0; 5801 if (str == NULL) 5802 li->li_tv.vval.v_string = NULL; 5803 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 5804 : vim_strsave(str))) == NULL) 5805 return FAIL; 5806 return OK; 5807 } 5808 5809 /* 5810 * Append "n" to list "l". 5811 * Returns FAIL when out of memory. 5812 */ 5813 static int 5814 list_append_number(l, n) 5815 list_T *l; 5816 varnumber_T n; 5817 { 5818 listitem_T *li; 5819 5820 li = listitem_alloc(); 5821 if (li == NULL) 5822 return FAIL; 5823 li->li_tv.v_type = VAR_NUMBER; 5824 li->li_tv.v_lock = 0; 5825 li->li_tv.vval.v_number = n; 5826 list_append(l, li); 5827 return OK; 5828 } 5829 5830 /* 5831 * Insert typval_T "tv" in list "l" before "item". 5832 * If "item" is NULL append at the end. 5833 * Return FAIL when out of memory. 5834 */ 5835 static int 5836 list_insert_tv(l, tv, item) 5837 list_T *l; 5838 typval_T *tv; 5839 listitem_T *item; 5840 { 5841 listitem_T *ni = listitem_alloc(); 5842 5843 if (ni == NULL) 5844 return FAIL; 5845 copy_tv(tv, &ni->li_tv); 5846 if (item == NULL) 5847 /* Append new item at end of list. */ 5848 list_append(l, ni); 5849 else 5850 { 5851 /* Insert new item before existing item. */ 5852 ni->li_prev = item->li_prev; 5853 ni->li_next = item; 5854 if (item->li_prev == NULL) 5855 { 5856 l->lv_first = ni; 5857 ++l->lv_idx; 5858 } 5859 else 5860 { 5861 item->li_prev->li_next = ni; 5862 l->lv_idx_item = NULL; 5863 } 5864 item->li_prev = ni; 5865 ++l->lv_len; 5866 } 5867 return OK; 5868 } 5869 5870 /* 5871 * Extend "l1" with "l2". 5872 * If "bef" is NULL append at the end, otherwise insert before this item. 5873 * Returns FAIL when out of memory. 5874 */ 5875 static int 5876 list_extend(l1, l2, bef) 5877 list_T *l1; 5878 list_T *l2; 5879 listitem_T *bef; 5880 { 5881 listitem_T *item; 5882 5883 for (item = l2->lv_first; item != NULL; item = item->li_next) 5884 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5885 return FAIL; 5886 return OK; 5887 } 5888 5889 /* 5890 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5891 * Return FAIL when out of memory. 5892 */ 5893 static int 5894 list_concat(l1, l2, tv) 5895 list_T *l1; 5896 list_T *l2; 5897 typval_T *tv; 5898 { 5899 list_T *l; 5900 5901 /* make a copy of the first list. */ 5902 l = list_copy(l1, FALSE, 0); 5903 if (l == NULL) 5904 return FAIL; 5905 tv->v_type = VAR_LIST; 5906 tv->vval.v_list = l; 5907 5908 /* append all items from the second list */ 5909 return list_extend(l, l2, NULL); 5910 } 5911 5912 /* 5913 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5914 * The refcount of the new list is set to 1. 5915 * See item_copy() for "copyID". 5916 * Returns NULL when out of memory. 5917 */ 5918 static list_T * 5919 list_copy(orig, deep, copyID) 5920 list_T *orig; 5921 int deep; 5922 int copyID; 5923 { 5924 list_T *copy; 5925 listitem_T *item; 5926 listitem_T *ni; 5927 5928 if (orig == NULL) 5929 return NULL; 5930 5931 copy = list_alloc(); 5932 if (copy != NULL) 5933 { 5934 if (copyID != 0) 5935 { 5936 /* Do this before adding the items, because one of the items may 5937 * refer back to this list. */ 5938 orig->lv_copyID = copyID; 5939 orig->lv_copylist = copy; 5940 } 5941 for (item = orig->lv_first; item != NULL && !got_int; 5942 item = item->li_next) 5943 { 5944 ni = listitem_alloc(); 5945 if (ni == NULL) 5946 break; 5947 if (deep) 5948 { 5949 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5950 { 5951 vim_free(ni); 5952 break; 5953 } 5954 } 5955 else 5956 copy_tv(&item->li_tv, &ni->li_tv); 5957 list_append(copy, ni); 5958 } 5959 ++copy->lv_refcount; 5960 if (item != NULL) 5961 { 5962 list_unref(copy); 5963 copy = NULL; 5964 } 5965 } 5966 5967 return copy; 5968 } 5969 5970 /* 5971 * Remove items "item" to "item2" from list "l". 5972 * Does not free the listitem or the value! 5973 */ 5974 static void 5975 list_remove(l, item, item2) 5976 list_T *l; 5977 listitem_T *item; 5978 listitem_T *item2; 5979 { 5980 listitem_T *ip; 5981 5982 /* notify watchers */ 5983 for (ip = item; ip != NULL; ip = ip->li_next) 5984 { 5985 --l->lv_len; 5986 list_fix_watch(l, ip); 5987 if (ip == item2) 5988 break; 5989 } 5990 5991 if (item2->li_next == NULL) 5992 l->lv_last = item->li_prev; 5993 else 5994 item2->li_next->li_prev = item->li_prev; 5995 if (item->li_prev == NULL) 5996 l->lv_first = item2->li_next; 5997 else 5998 item->li_prev->li_next = item2->li_next; 5999 l->lv_idx_item = NULL; 6000 } 6001 6002 /* 6003 * Return an allocated string with the string representation of a list. 6004 * May return NULL. 6005 */ 6006 static char_u * 6007 list2string(tv, copyID) 6008 typval_T *tv; 6009 int copyID; 6010 { 6011 garray_T ga; 6012 6013 if (tv->vval.v_list == NULL) 6014 return NULL; 6015 ga_init2(&ga, (int)sizeof(char), 80); 6016 ga_append(&ga, '['); 6017 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL) 6018 { 6019 vim_free(ga.ga_data); 6020 return NULL; 6021 } 6022 ga_append(&ga, ']'); 6023 ga_append(&ga, NUL); 6024 return (char_u *)ga.ga_data; 6025 } 6026 6027 /* 6028 * Join list "l" into a string in "*gap", using separator "sep". 6029 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 6030 * Return FAIL or OK. 6031 */ 6032 static int 6033 list_join(gap, l, sep, echo, copyID) 6034 garray_T *gap; 6035 list_T *l; 6036 char_u *sep; 6037 int echo; 6038 int copyID; 6039 { 6040 int first = TRUE; 6041 char_u *tofree; 6042 char_u numbuf[NUMBUFLEN]; 6043 listitem_T *item; 6044 char_u *s; 6045 6046 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 6047 { 6048 if (first) 6049 first = FALSE; 6050 else 6051 ga_concat(gap, sep); 6052 6053 if (echo) 6054 s = echo_string(&item->li_tv, &tofree, numbuf, copyID); 6055 else 6056 s = tv2string(&item->li_tv, &tofree, numbuf, copyID); 6057 if (s != NULL) 6058 ga_concat(gap, s); 6059 vim_free(tofree); 6060 if (s == NULL) 6061 return FAIL; 6062 } 6063 return OK; 6064 } 6065 6066 /* 6067 * Garbage collection for lists and dictionaries. 6068 * 6069 * We use reference counts to be able to free most items right away when they 6070 * are no longer used. But for composite items it's possible that it becomes 6071 * unused while the reference count is > 0: When there is a recursive 6072 * reference. Example: 6073 * :let l = [1, 2, 3] 6074 * :let d = {9: l} 6075 * :let l[1] = d 6076 * 6077 * Since this is quite unusual we handle this with garbage collection: every 6078 * once in a while find out which lists and dicts are not referenced from any 6079 * variable. 6080 * 6081 * Here is a good reference text about garbage collection (refers to Python 6082 * but it applies to all reference-counting mechanisms): 6083 * http://python.ca/nas/python/gc/ 6084 */ 6085 6086 /* 6087 * Do garbage collection for lists and dicts. 6088 * Return TRUE if some memory was freed. 6089 */ 6090 int 6091 garbage_collect() 6092 { 6093 dict_T *dd; 6094 list_T *ll; 6095 int copyID = ++current_copyID; 6096 buf_T *buf; 6097 win_T *wp; 6098 int i; 6099 funccall_T *fc; 6100 int did_free = FALSE; 6101 #ifdef FEAT_WINDOWS 6102 tabpage_T *tp; 6103 #endif 6104 6105 /* Only do this once. */ 6106 want_garbage_collect = FALSE; 6107 may_garbage_collect = FALSE; 6108 6109 /* 6110 * 1. Go through all accessible variables and mark all lists and dicts 6111 * with copyID. 6112 */ 6113 /* script-local variables */ 6114 for (i = 1; i <= ga_scripts.ga_len; ++i) 6115 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 6116 6117 /* buffer-local variables */ 6118 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 6119 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 6120 6121 /* window-local variables */ 6122 FOR_ALL_TAB_WINDOWS(tp, wp) 6123 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 6124 6125 #ifdef FEAT_WINDOWS 6126 /* tabpage-local variables */ 6127 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) 6128 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); 6129 #endif 6130 6131 /* global variables */ 6132 set_ref_in_ht(&globvarht, copyID); 6133 6134 /* function-local variables */ 6135 for (fc = current_funccal; fc != NULL; fc = fc->caller) 6136 { 6137 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 6138 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 6139 } 6140 6141 /* 6142 * 2. Go through the list of dicts and free items without the copyID. 6143 */ 6144 for (dd = first_dict; dd != NULL; ) 6145 if (dd->dv_copyID != copyID) 6146 { 6147 /* Free the Dictionary and ordinary items it contains, but don't 6148 * recurse into Lists and Dictionaries, they will be in the list 6149 * of dicts or list of lists. */ 6150 dict_free(dd, FALSE); 6151 did_free = TRUE; 6152 6153 /* restart, next dict may also have been freed */ 6154 dd = first_dict; 6155 } 6156 else 6157 dd = dd->dv_used_next; 6158 6159 /* 6160 * 3. Go through the list of lists and free items without the copyID. 6161 * But don't free a list that has a watcher (used in a for loop), these 6162 * are not referenced anywhere. 6163 */ 6164 for (ll = first_list; ll != NULL; ) 6165 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 6166 { 6167 /* Free the List and ordinary items it contains, but don't recurse 6168 * into Lists and Dictionaries, they will be in the list of dicts 6169 * or list of lists. */ 6170 list_free(ll, FALSE); 6171 did_free = TRUE; 6172 6173 /* restart, next list may also have been freed */ 6174 ll = first_list; 6175 } 6176 else 6177 ll = ll->lv_used_next; 6178 6179 return did_free; 6180 } 6181 6182 /* 6183 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6184 */ 6185 static void 6186 set_ref_in_ht(ht, copyID) 6187 hashtab_T *ht; 6188 int copyID; 6189 { 6190 int todo; 6191 hashitem_T *hi; 6192 6193 todo = (int)ht->ht_used; 6194 for (hi = ht->ht_array; todo > 0; ++hi) 6195 if (!HASHITEM_EMPTY(hi)) 6196 { 6197 --todo; 6198 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 6199 } 6200 } 6201 6202 /* 6203 * Mark all lists and dicts referenced through list "l" with "copyID". 6204 */ 6205 static void 6206 set_ref_in_list(l, copyID) 6207 list_T *l; 6208 int copyID; 6209 { 6210 listitem_T *li; 6211 6212 for (li = l->lv_first; li != NULL; li = li->li_next) 6213 set_ref_in_item(&li->li_tv, copyID); 6214 } 6215 6216 /* 6217 * Mark all lists and dicts referenced through typval "tv" with "copyID". 6218 */ 6219 static void 6220 set_ref_in_item(tv, copyID) 6221 typval_T *tv; 6222 int copyID; 6223 { 6224 dict_T *dd; 6225 list_T *ll; 6226 6227 switch (tv->v_type) 6228 { 6229 case VAR_DICT: 6230 dd = tv->vval.v_dict; 6231 if (dd->dv_copyID != copyID) 6232 { 6233 /* Didn't see this dict yet. */ 6234 dd->dv_copyID = copyID; 6235 set_ref_in_ht(&dd->dv_hashtab, copyID); 6236 } 6237 break; 6238 6239 case VAR_LIST: 6240 ll = tv->vval.v_list; 6241 if (ll->lv_copyID != copyID) 6242 { 6243 /* Didn't see this list yet. */ 6244 ll->lv_copyID = copyID; 6245 set_ref_in_list(ll, copyID); 6246 } 6247 break; 6248 } 6249 return; 6250 } 6251 6252 /* 6253 * Allocate an empty header for a dictionary. 6254 */ 6255 dict_T * 6256 dict_alloc() 6257 { 6258 dict_T *d; 6259 6260 d = (dict_T *)alloc(sizeof(dict_T)); 6261 if (d != NULL) 6262 { 6263 /* Add the list to the list of dicts for garbage collection. */ 6264 if (first_dict != NULL) 6265 first_dict->dv_used_prev = d; 6266 d->dv_used_next = first_dict; 6267 d->dv_used_prev = NULL; 6268 first_dict = d; 6269 6270 hash_init(&d->dv_hashtab); 6271 d->dv_lock = 0; 6272 d->dv_refcount = 0; 6273 d->dv_copyID = 0; 6274 } 6275 return d; 6276 } 6277 6278 /* 6279 * Unreference a Dictionary: decrement the reference count and free it when it 6280 * becomes zero. 6281 */ 6282 static void 6283 dict_unref(d) 6284 dict_T *d; 6285 { 6286 if (d != NULL && --d->dv_refcount <= 0) 6287 dict_free(d, TRUE); 6288 } 6289 6290 /* 6291 * Free a Dictionary, including all items it contains. 6292 * Ignores the reference count. 6293 */ 6294 static void 6295 dict_free(d, recurse) 6296 dict_T *d; 6297 int recurse; /* Free Lists and Dictionaries recursively. */ 6298 { 6299 int todo; 6300 hashitem_T *hi; 6301 dictitem_T *di; 6302 6303 /* Remove the dict from the list of dicts for garbage collection. */ 6304 if (d->dv_used_prev == NULL) 6305 first_dict = d->dv_used_next; 6306 else 6307 d->dv_used_prev->dv_used_next = d->dv_used_next; 6308 if (d->dv_used_next != NULL) 6309 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6310 6311 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6312 hash_lock(&d->dv_hashtab); 6313 todo = (int)d->dv_hashtab.ht_used; 6314 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6315 { 6316 if (!HASHITEM_EMPTY(hi)) 6317 { 6318 /* Remove the item before deleting it, just in case there is 6319 * something recursive causing trouble. */ 6320 di = HI2DI(hi); 6321 hash_remove(&d->dv_hashtab, hi); 6322 if (recurse || (di->di_tv.v_type != VAR_LIST 6323 && di->di_tv.v_type != VAR_DICT)) 6324 clear_tv(&di->di_tv); 6325 vim_free(di); 6326 --todo; 6327 } 6328 } 6329 hash_clear(&d->dv_hashtab); 6330 vim_free(d); 6331 } 6332 6333 /* 6334 * Allocate a Dictionary item. 6335 * The "key" is copied to the new item. 6336 * Note that the value of the item "di_tv" still needs to be initialized! 6337 * Returns NULL when out of memory. 6338 */ 6339 static dictitem_T * 6340 dictitem_alloc(key) 6341 char_u *key; 6342 { 6343 dictitem_T *di; 6344 6345 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key))); 6346 if (di != NULL) 6347 { 6348 STRCPY(di->di_key, key); 6349 di->di_flags = 0; 6350 } 6351 return di; 6352 } 6353 6354 /* 6355 * Make a copy of a Dictionary item. 6356 */ 6357 static dictitem_T * 6358 dictitem_copy(org) 6359 dictitem_T *org; 6360 { 6361 dictitem_T *di; 6362 6363 di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 6364 + STRLEN(org->di_key))); 6365 if (di != NULL) 6366 { 6367 STRCPY(di->di_key, org->di_key); 6368 di->di_flags = 0; 6369 copy_tv(&org->di_tv, &di->di_tv); 6370 } 6371 return di; 6372 } 6373 6374 /* 6375 * Remove item "item" from Dictionary "dict" and free it. 6376 */ 6377 static void 6378 dictitem_remove(dict, item) 6379 dict_T *dict; 6380 dictitem_T *item; 6381 { 6382 hashitem_T *hi; 6383 6384 hi = hash_find(&dict->dv_hashtab, item->di_key); 6385 if (HASHITEM_EMPTY(hi)) 6386 EMSG2(_(e_intern2), "dictitem_remove()"); 6387 else 6388 hash_remove(&dict->dv_hashtab, hi); 6389 dictitem_free(item); 6390 } 6391 6392 /* 6393 * Free a dict item. Also clears the value. 6394 */ 6395 static void 6396 dictitem_free(item) 6397 dictitem_T *item; 6398 { 6399 clear_tv(&item->di_tv); 6400 vim_free(item); 6401 } 6402 6403 /* 6404 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6405 * The refcount of the new dict is set to 1. 6406 * See item_copy() for "copyID". 6407 * Returns NULL when out of memory. 6408 */ 6409 static dict_T * 6410 dict_copy(orig, deep, copyID) 6411 dict_T *orig; 6412 int deep; 6413 int copyID; 6414 { 6415 dict_T *copy; 6416 dictitem_T *di; 6417 int todo; 6418 hashitem_T *hi; 6419 6420 if (orig == NULL) 6421 return NULL; 6422 6423 copy = dict_alloc(); 6424 if (copy != NULL) 6425 { 6426 if (copyID != 0) 6427 { 6428 orig->dv_copyID = copyID; 6429 orig->dv_copydict = copy; 6430 } 6431 todo = (int)orig->dv_hashtab.ht_used; 6432 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6433 { 6434 if (!HASHITEM_EMPTY(hi)) 6435 { 6436 --todo; 6437 6438 di = dictitem_alloc(hi->hi_key); 6439 if (di == NULL) 6440 break; 6441 if (deep) 6442 { 6443 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6444 copyID) == FAIL) 6445 { 6446 vim_free(di); 6447 break; 6448 } 6449 } 6450 else 6451 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6452 if (dict_add(copy, di) == FAIL) 6453 { 6454 dictitem_free(di); 6455 break; 6456 } 6457 } 6458 } 6459 6460 ++copy->dv_refcount; 6461 if (todo > 0) 6462 { 6463 dict_unref(copy); 6464 copy = NULL; 6465 } 6466 } 6467 6468 return copy; 6469 } 6470 6471 /* 6472 * Add item "item" to Dictionary "d". 6473 * Returns FAIL when out of memory and when key already existed. 6474 */ 6475 static int 6476 dict_add(d, item) 6477 dict_T *d; 6478 dictitem_T *item; 6479 { 6480 return hash_add(&d->dv_hashtab, item->di_key); 6481 } 6482 6483 /* 6484 * Add a number or string entry to dictionary "d". 6485 * When "str" is NULL use number "nr", otherwise use "str". 6486 * Returns FAIL when out of memory and when key already exists. 6487 */ 6488 int 6489 dict_add_nr_str(d, key, nr, str) 6490 dict_T *d; 6491 char *key; 6492 long nr; 6493 char_u *str; 6494 { 6495 dictitem_T *item; 6496 6497 item = dictitem_alloc((char_u *)key); 6498 if (item == NULL) 6499 return FAIL; 6500 item->di_tv.v_lock = 0; 6501 if (str == NULL) 6502 { 6503 item->di_tv.v_type = VAR_NUMBER; 6504 item->di_tv.vval.v_number = nr; 6505 } 6506 else 6507 { 6508 item->di_tv.v_type = VAR_STRING; 6509 item->di_tv.vval.v_string = vim_strsave(str); 6510 } 6511 if (dict_add(d, item) == FAIL) 6512 { 6513 dictitem_free(item); 6514 return FAIL; 6515 } 6516 return OK; 6517 } 6518 6519 /* 6520 * Get the number of items in a Dictionary. 6521 */ 6522 static long 6523 dict_len(d) 6524 dict_T *d; 6525 { 6526 if (d == NULL) 6527 return 0L; 6528 return (long)d->dv_hashtab.ht_used; 6529 } 6530 6531 /* 6532 * Find item "key[len]" in Dictionary "d". 6533 * If "len" is negative use strlen(key). 6534 * Returns NULL when not found. 6535 */ 6536 static dictitem_T * 6537 dict_find(d, key, len) 6538 dict_T *d; 6539 char_u *key; 6540 int len; 6541 { 6542 #define AKEYLEN 200 6543 char_u buf[AKEYLEN]; 6544 char_u *akey; 6545 char_u *tofree = NULL; 6546 hashitem_T *hi; 6547 6548 if (len < 0) 6549 akey = key; 6550 else if (len >= AKEYLEN) 6551 { 6552 tofree = akey = vim_strnsave(key, len); 6553 if (akey == NULL) 6554 return NULL; 6555 } 6556 else 6557 { 6558 /* Avoid a malloc/free by using buf[]. */ 6559 vim_strncpy(buf, key, len); 6560 akey = buf; 6561 } 6562 6563 hi = hash_find(&d->dv_hashtab, akey); 6564 vim_free(tofree); 6565 if (HASHITEM_EMPTY(hi)) 6566 return NULL; 6567 return HI2DI(hi); 6568 } 6569 6570 /* 6571 * Get a string item from a dictionary. 6572 * When "save" is TRUE allocate memory for it. 6573 * Returns NULL if the entry doesn't exist or out of memory. 6574 */ 6575 char_u * 6576 get_dict_string(d, key, save) 6577 dict_T *d; 6578 char_u *key; 6579 int save; 6580 { 6581 dictitem_T *di; 6582 char_u *s; 6583 6584 di = dict_find(d, key, -1); 6585 if (di == NULL) 6586 return NULL; 6587 s = get_tv_string(&di->di_tv); 6588 if (save && s != NULL) 6589 s = vim_strsave(s); 6590 return s; 6591 } 6592 6593 /* 6594 * Get a number item from a dictionary. 6595 * Returns 0 if the entry doesn't exist or out of memory. 6596 */ 6597 long 6598 get_dict_number(d, key) 6599 dict_T *d; 6600 char_u *key; 6601 { 6602 dictitem_T *di; 6603 6604 di = dict_find(d, key, -1); 6605 if (di == NULL) 6606 return 0; 6607 return get_tv_number(&di->di_tv); 6608 } 6609 6610 /* 6611 * Return an allocated string with the string representation of a Dictionary. 6612 * May return NULL. 6613 */ 6614 static char_u * 6615 dict2string(tv, copyID) 6616 typval_T *tv; 6617 int copyID; 6618 { 6619 garray_T ga; 6620 int first = TRUE; 6621 char_u *tofree; 6622 char_u numbuf[NUMBUFLEN]; 6623 hashitem_T *hi; 6624 char_u *s; 6625 dict_T *d; 6626 int todo; 6627 6628 if ((d = tv->vval.v_dict) == NULL) 6629 return NULL; 6630 ga_init2(&ga, (int)sizeof(char), 80); 6631 ga_append(&ga, '{'); 6632 6633 todo = (int)d->dv_hashtab.ht_used; 6634 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6635 { 6636 if (!HASHITEM_EMPTY(hi)) 6637 { 6638 --todo; 6639 6640 if (first) 6641 first = FALSE; 6642 else 6643 ga_concat(&ga, (char_u *)", "); 6644 6645 tofree = string_quote(hi->hi_key, FALSE); 6646 if (tofree != NULL) 6647 { 6648 ga_concat(&ga, tofree); 6649 vim_free(tofree); 6650 } 6651 ga_concat(&ga, (char_u *)": "); 6652 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID); 6653 if (s != NULL) 6654 ga_concat(&ga, s); 6655 vim_free(tofree); 6656 if (s == NULL) 6657 break; 6658 } 6659 } 6660 if (todo > 0) 6661 { 6662 vim_free(ga.ga_data); 6663 return NULL; 6664 } 6665 6666 ga_append(&ga, '}'); 6667 ga_append(&ga, NUL); 6668 return (char_u *)ga.ga_data; 6669 } 6670 6671 /* 6672 * Allocate a variable for a Dictionary and fill it from "*arg". 6673 * Return OK or FAIL. Returns NOTDONE for {expr}. 6674 */ 6675 static int 6676 get_dict_tv(arg, rettv, evaluate) 6677 char_u **arg; 6678 typval_T *rettv; 6679 int evaluate; 6680 { 6681 dict_T *d = NULL; 6682 typval_T tvkey; 6683 typval_T tv; 6684 char_u *key; 6685 dictitem_T *item; 6686 char_u *start = skipwhite(*arg + 1); 6687 char_u buf[NUMBUFLEN]; 6688 6689 /* 6690 * First check if it's not a curly-braces thing: {expr}. 6691 * Must do this without evaluating, otherwise a function may be called 6692 * twice. Unfortunately this means we need to call eval1() twice for the 6693 * first item. 6694 * But {} is an empty Dictionary. 6695 */ 6696 if (*start != '}') 6697 { 6698 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6699 return FAIL; 6700 if (*start == '}') 6701 return NOTDONE; 6702 } 6703 6704 if (evaluate) 6705 { 6706 d = dict_alloc(); 6707 if (d == NULL) 6708 return FAIL; 6709 } 6710 tvkey.v_type = VAR_UNKNOWN; 6711 tv.v_type = VAR_UNKNOWN; 6712 6713 *arg = skipwhite(*arg + 1); 6714 while (**arg != '}' && **arg != NUL) 6715 { 6716 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6717 goto failret; 6718 if (**arg != ':') 6719 { 6720 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6721 clear_tv(&tvkey); 6722 goto failret; 6723 } 6724 key = get_tv_string_buf_chk(&tvkey, buf); 6725 if (key == NULL || *key == NUL) 6726 { 6727 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6728 if (key != NULL) 6729 EMSG(_(e_emptykey)); 6730 clear_tv(&tvkey); 6731 goto failret; 6732 } 6733 6734 *arg = skipwhite(*arg + 1); 6735 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6736 { 6737 clear_tv(&tvkey); 6738 goto failret; 6739 } 6740 if (evaluate) 6741 { 6742 item = dict_find(d, key, -1); 6743 if (item != NULL) 6744 { 6745 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6746 clear_tv(&tvkey); 6747 clear_tv(&tv); 6748 goto failret; 6749 } 6750 item = dictitem_alloc(key); 6751 clear_tv(&tvkey); 6752 if (item != NULL) 6753 { 6754 item->di_tv = tv; 6755 item->di_tv.v_lock = 0; 6756 if (dict_add(d, item) == FAIL) 6757 dictitem_free(item); 6758 } 6759 } 6760 6761 if (**arg == '}') 6762 break; 6763 if (**arg != ',') 6764 { 6765 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6766 goto failret; 6767 } 6768 *arg = skipwhite(*arg + 1); 6769 } 6770 6771 if (**arg != '}') 6772 { 6773 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6774 failret: 6775 if (evaluate) 6776 dict_free(d, TRUE); 6777 return FAIL; 6778 } 6779 6780 *arg = skipwhite(*arg + 1); 6781 if (evaluate) 6782 { 6783 rettv->v_type = VAR_DICT; 6784 rettv->vval.v_dict = d; 6785 ++d->dv_refcount; 6786 } 6787 6788 return OK; 6789 } 6790 6791 /* 6792 * Return a string with the string representation of a variable. 6793 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6794 * "numbuf" is used for a number. 6795 * Does not put quotes around strings, as ":echo" displays values. 6796 * When "copyID" is not NULL replace recursive lists and dicts with "...". 6797 * May return NULL; 6798 */ 6799 static char_u * 6800 echo_string(tv, tofree, numbuf, copyID) 6801 typval_T *tv; 6802 char_u **tofree; 6803 char_u *numbuf; 6804 int copyID; 6805 { 6806 static int recurse = 0; 6807 char_u *r = NULL; 6808 6809 if (recurse >= DICT_MAXNEST) 6810 { 6811 EMSG(_("E724: variable nested too deep for displaying")); 6812 *tofree = NULL; 6813 return NULL; 6814 } 6815 ++recurse; 6816 6817 switch (tv->v_type) 6818 { 6819 case VAR_FUNC: 6820 *tofree = NULL; 6821 r = tv->vval.v_string; 6822 break; 6823 6824 case VAR_LIST: 6825 if (tv->vval.v_list == NULL) 6826 { 6827 *tofree = NULL; 6828 r = NULL; 6829 } 6830 else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID) 6831 { 6832 *tofree = NULL; 6833 r = (char_u *)"[...]"; 6834 } 6835 else 6836 { 6837 tv->vval.v_list->lv_copyID = copyID; 6838 *tofree = list2string(tv, copyID); 6839 r = *tofree; 6840 } 6841 break; 6842 6843 case VAR_DICT: 6844 if (tv->vval.v_dict == NULL) 6845 { 6846 *tofree = NULL; 6847 r = NULL; 6848 } 6849 else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID) 6850 { 6851 *tofree = NULL; 6852 r = (char_u *)"{...}"; 6853 } 6854 else 6855 { 6856 tv->vval.v_dict->dv_copyID = copyID; 6857 *tofree = dict2string(tv, copyID); 6858 r = *tofree; 6859 } 6860 break; 6861 6862 case VAR_STRING: 6863 case VAR_NUMBER: 6864 *tofree = NULL; 6865 r = get_tv_string_buf(tv, numbuf); 6866 break; 6867 6868 default: 6869 EMSG2(_(e_intern2), "echo_string()"); 6870 *tofree = NULL; 6871 } 6872 6873 --recurse; 6874 return r; 6875 } 6876 6877 /* 6878 * Return a string with the string representation of a variable. 6879 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6880 * "numbuf" is used for a number. 6881 * Puts quotes around strings, so that they can be parsed back by eval(). 6882 * May return NULL; 6883 */ 6884 static char_u * 6885 tv2string(tv, tofree, numbuf, copyID) 6886 typval_T *tv; 6887 char_u **tofree; 6888 char_u *numbuf; 6889 int copyID; 6890 { 6891 switch (tv->v_type) 6892 { 6893 case VAR_FUNC: 6894 *tofree = string_quote(tv->vval.v_string, TRUE); 6895 return *tofree; 6896 case VAR_STRING: 6897 *tofree = string_quote(tv->vval.v_string, FALSE); 6898 return *tofree; 6899 case VAR_NUMBER: 6900 case VAR_LIST: 6901 case VAR_DICT: 6902 break; 6903 default: 6904 EMSG2(_(e_intern2), "tv2string()"); 6905 } 6906 return echo_string(tv, tofree, numbuf, copyID); 6907 } 6908 6909 /* 6910 * Return string "str" in ' quotes, doubling ' characters. 6911 * If "str" is NULL an empty string is assumed. 6912 * If "function" is TRUE make it function('string'). 6913 */ 6914 static char_u * 6915 string_quote(str, function) 6916 char_u *str; 6917 int function; 6918 { 6919 unsigned len; 6920 char_u *p, *r, *s; 6921 6922 len = (function ? 13 : 3); 6923 if (str != NULL) 6924 { 6925 len += (unsigned)STRLEN(str); 6926 for (p = str; *p != NUL; mb_ptr_adv(p)) 6927 if (*p == '\'') 6928 ++len; 6929 } 6930 s = r = alloc(len); 6931 if (r != NULL) 6932 { 6933 if (function) 6934 { 6935 STRCPY(r, "function('"); 6936 r += 10; 6937 } 6938 else 6939 *r++ = '\''; 6940 if (str != NULL) 6941 for (p = str; *p != NUL; ) 6942 { 6943 if (*p == '\'') 6944 *r++ = '\''; 6945 MB_COPY_CHAR(p, r); 6946 } 6947 *r++ = '\''; 6948 if (function) 6949 *r++ = ')'; 6950 *r++ = NUL; 6951 } 6952 return s; 6953 } 6954 6955 /* 6956 * Get the value of an environment variable. 6957 * "arg" is pointing to the '$'. It is advanced to after the name. 6958 * If the environment variable was not set, silently assume it is empty. 6959 * Always return OK. 6960 */ 6961 static int 6962 get_env_tv(arg, rettv, evaluate) 6963 char_u **arg; 6964 typval_T *rettv; 6965 int evaluate; 6966 { 6967 char_u *string = NULL; 6968 int len; 6969 int cc; 6970 char_u *name; 6971 int mustfree = FALSE; 6972 6973 ++*arg; 6974 name = *arg; 6975 len = get_env_len(arg); 6976 if (evaluate) 6977 { 6978 if (len != 0) 6979 { 6980 cc = name[len]; 6981 name[len] = NUL; 6982 /* first try vim_getenv(), fast for normal environment vars */ 6983 string = vim_getenv(name, &mustfree); 6984 if (string != NULL && *string != NUL) 6985 { 6986 if (!mustfree) 6987 string = vim_strsave(string); 6988 } 6989 else 6990 { 6991 if (mustfree) 6992 vim_free(string); 6993 6994 /* next try expanding things like $VIM and ${HOME} */ 6995 string = expand_env_save(name - 1); 6996 if (string != NULL && *string == '$') 6997 { 6998 vim_free(string); 6999 string = NULL; 7000 } 7001 } 7002 name[len] = cc; 7003 } 7004 rettv->v_type = VAR_STRING; 7005 rettv->vval.v_string = string; 7006 } 7007 7008 return OK; 7009 } 7010 7011 /* 7012 * Array with names and number of arguments of all internal functions 7013 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 7014 */ 7015 static struct fst 7016 { 7017 char *f_name; /* function name */ 7018 char f_min_argc; /* minimal number of arguments */ 7019 char f_max_argc; /* maximal number of arguments */ 7020 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 7021 /* implemenation of function */ 7022 } functions[] = 7023 { 7024 {"add", 2, 2, f_add}, 7025 {"append", 2, 2, f_append}, 7026 {"argc", 0, 0, f_argc}, 7027 {"argidx", 0, 0, f_argidx}, 7028 {"argv", 0, 1, f_argv}, 7029 {"browse", 4, 4, f_browse}, 7030 {"browsedir", 2, 2, f_browsedir}, 7031 {"bufexists", 1, 1, f_bufexists}, 7032 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 7033 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 7034 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 7035 {"buflisted", 1, 1, f_buflisted}, 7036 {"bufloaded", 1, 1, f_bufloaded}, 7037 {"bufname", 1, 1, f_bufname}, 7038 {"bufnr", 1, 2, f_bufnr}, 7039 {"bufwinnr", 1, 1, f_bufwinnr}, 7040 {"byte2line", 1, 1, f_byte2line}, 7041 {"byteidx", 2, 2, f_byteidx}, 7042 {"call", 2, 3, f_call}, 7043 {"changenr", 0, 0, f_changenr}, 7044 {"char2nr", 1, 1, f_char2nr}, 7045 {"cindent", 1, 1, f_cindent}, 7046 {"col", 1, 1, f_col}, 7047 #if defined(FEAT_INS_EXPAND) 7048 {"complete", 2, 2, f_complete}, 7049 {"complete_add", 1, 1, f_complete_add}, 7050 {"complete_check", 0, 0, f_complete_check}, 7051 #endif 7052 {"confirm", 1, 4, f_confirm}, 7053 {"copy", 1, 1, f_copy}, 7054 {"count", 2, 4, f_count}, 7055 {"cscope_connection",0,3, f_cscope_connection}, 7056 {"cursor", 1, 3, f_cursor}, 7057 {"deepcopy", 1, 2, f_deepcopy}, 7058 {"delete", 1, 1, f_delete}, 7059 {"did_filetype", 0, 0, f_did_filetype}, 7060 {"diff_filler", 1, 1, f_diff_filler}, 7061 {"diff_hlID", 2, 2, f_diff_hlID}, 7062 {"empty", 1, 1, f_empty}, 7063 {"escape", 2, 2, f_escape}, 7064 {"eval", 1, 1, f_eval}, 7065 {"eventhandler", 0, 0, f_eventhandler}, 7066 {"executable", 1, 1, f_executable}, 7067 {"exists", 1, 1, f_exists}, 7068 {"expand", 1, 2, f_expand}, 7069 {"extend", 2, 3, f_extend}, 7070 {"feedkeys", 1, 2, f_feedkeys}, 7071 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 7072 {"filereadable", 1, 1, f_filereadable}, 7073 {"filewritable", 1, 1, f_filewritable}, 7074 {"filter", 2, 2, f_filter}, 7075 {"finddir", 1, 3, f_finddir}, 7076 {"findfile", 1, 3, f_findfile}, 7077 {"fnamemodify", 2, 2, f_fnamemodify}, 7078 {"foldclosed", 1, 1, f_foldclosed}, 7079 {"foldclosedend", 1, 1, f_foldclosedend}, 7080 {"foldlevel", 1, 1, f_foldlevel}, 7081 {"foldtext", 0, 0, f_foldtext}, 7082 {"foldtextresult", 1, 1, f_foldtextresult}, 7083 {"foreground", 0, 0, f_foreground}, 7084 {"function", 1, 1, f_function}, 7085 {"garbagecollect", 0, 0, f_garbagecollect}, 7086 {"get", 2, 3, f_get}, 7087 {"getbufline", 2, 3, f_getbufline}, 7088 {"getbufvar", 2, 2, f_getbufvar}, 7089 {"getchar", 0, 1, f_getchar}, 7090 {"getcharmod", 0, 0, f_getcharmod}, 7091 {"getcmdline", 0, 0, f_getcmdline}, 7092 {"getcmdpos", 0, 0, f_getcmdpos}, 7093 {"getcmdtype", 0, 0, f_getcmdtype}, 7094 {"getcwd", 0, 0, f_getcwd}, 7095 {"getfontname", 0, 1, f_getfontname}, 7096 {"getfperm", 1, 1, f_getfperm}, 7097 {"getfsize", 1, 1, f_getfsize}, 7098 {"getftime", 1, 1, f_getftime}, 7099 {"getftype", 1, 1, f_getftype}, 7100 {"getline", 1, 2, f_getline}, 7101 {"getloclist", 1, 1, f_getqflist}, 7102 {"getpos", 1, 1, f_getpos}, 7103 {"getqflist", 0, 0, f_getqflist}, 7104 {"getreg", 0, 2, f_getreg}, 7105 {"getregtype", 0, 1, f_getregtype}, 7106 {"gettabwinvar", 3, 3, f_gettabwinvar}, 7107 {"getwinposx", 0, 0, f_getwinposx}, 7108 {"getwinposy", 0, 0, f_getwinposy}, 7109 {"getwinvar", 2, 2, f_getwinvar}, 7110 {"glob", 1, 1, f_glob}, 7111 {"globpath", 2, 2, f_globpath}, 7112 {"has", 1, 1, f_has}, 7113 {"has_key", 2, 2, f_has_key}, 7114 {"haslocaldir", 0, 0, f_haslocaldir}, 7115 {"hasmapto", 1, 3, f_hasmapto}, 7116 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 7117 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 7118 {"histadd", 2, 2, f_histadd}, 7119 {"histdel", 1, 2, f_histdel}, 7120 {"histget", 1, 2, f_histget}, 7121 {"histnr", 1, 1, f_histnr}, 7122 {"hlID", 1, 1, f_hlID}, 7123 {"hlexists", 1, 1, f_hlexists}, 7124 {"hostname", 0, 0, f_hostname}, 7125 {"iconv", 3, 3, f_iconv}, 7126 {"indent", 1, 1, f_indent}, 7127 {"index", 2, 4, f_index}, 7128 {"input", 1, 3, f_input}, 7129 {"inputdialog", 1, 3, f_inputdialog}, 7130 {"inputlist", 1, 1, f_inputlist}, 7131 {"inputrestore", 0, 0, f_inputrestore}, 7132 {"inputsave", 0, 0, f_inputsave}, 7133 {"inputsecret", 1, 2, f_inputsecret}, 7134 {"insert", 2, 3, f_insert}, 7135 {"isdirectory", 1, 1, f_isdirectory}, 7136 {"islocked", 1, 1, f_islocked}, 7137 {"items", 1, 1, f_items}, 7138 {"join", 1, 2, f_join}, 7139 {"keys", 1, 1, f_keys}, 7140 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 7141 {"len", 1, 1, f_len}, 7142 {"libcall", 3, 3, f_libcall}, 7143 {"libcallnr", 3, 3, f_libcallnr}, 7144 {"line", 1, 1, f_line}, 7145 {"line2byte", 1, 1, f_line2byte}, 7146 {"lispindent", 1, 1, f_lispindent}, 7147 {"localtime", 0, 0, f_localtime}, 7148 {"map", 2, 2, f_map}, 7149 {"maparg", 1, 3, f_maparg}, 7150 {"mapcheck", 1, 3, f_mapcheck}, 7151 {"match", 2, 4, f_match}, 7152 {"matcharg", 1, 1, f_matcharg}, 7153 {"matchend", 2, 4, f_matchend}, 7154 {"matchlist", 2, 4, f_matchlist}, 7155 {"matchstr", 2, 4, f_matchstr}, 7156 {"max", 1, 1, f_max}, 7157 {"min", 1, 1, f_min}, 7158 #ifdef vim_mkdir 7159 {"mkdir", 1, 3, f_mkdir}, 7160 #endif 7161 {"mode", 0, 0, f_mode}, 7162 {"nextnonblank", 1, 1, f_nextnonblank}, 7163 {"nr2char", 1, 1, f_nr2char}, 7164 {"pathshorten", 1, 1, f_pathshorten}, 7165 {"prevnonblank", 1, 1, f_prevnonblank}, 7166 {"printf", 2, 19, f_printf}, 7167 {"pumvisible", 0, 0, f_pumvisible}, 7168 {"range", 1, 3, f_range}, 7169 {"readfile", 1, 3, f_readfile}, 7170 {"reltime", 0, 2, f_reltime}, 7171 {"reltimestr", 1, 1, f_reltimestr}, 7172 {"remote_expr", 2, 3, f_remote_expr}, 7173 {"remote_foreground", 1, 1, f_remote_foreground}, 7174 {"remote_peek", 1, 2, f_remote_peek}, 7175 {"remote_read", 1, 1, f_remote_read}, 7176 {"remote_send", 2, 3, f_remote_send}, 7177 {"remove", 2, 3, f_remove}, 7178 {"rename", 2, 2, f_rename}, 7179 {"repeat", 2, 2, f_repeat}, 7180 {"resolve", 1, 1, f_resolve}, 7181 {"reverse", 1, 1, f_reverse}, 7182 {"search", 1, 3, f_search}, 7183 {"searchdecl", 1, 3, f_searchdecl}, 7184 {"searchpair", 3, 6, f_searchpair}, 7185 {"searchpairpos", 3, 6, f_searchpairpos}, 7186 {"searchpos", 1, 3, f_searchpos}, 7187 {"server2client", 2, 2, f_server2client}, 7188 {"serverlist", 0, 0, f_serverlist}, 7189 {"setbufvar", 3, 3, f_setbufvar}, 7190 {"setcmdpos", 1, 1, f_setcmdpos}, 7191 {"setline", 2, 2, f_setline}, 7192 {"setloclist", 2, 3, f_setloclist}, 7193 {"setpos", 2, 2, f_setpos}, 7194 {"setqflist", 1, 2, f_setqflist}, 7195 {"setreg", 2, 3, f_setreg}, 7196 {"settabwinvar", 4, 4, f_settabwinvar}, 7197 {"setwinvar", 3, 3, f_setwinvar}, 7198 {"shellescape", 1, 1, f_shellescape}, 7199 {"simplify", 1, 1, f_simplify}, 7200 {"sort", 1, 2, f_sort}, 7201 {"soundfold", 1, 1, f_soundfold}, 7202 {"spellbadword", 0, 1, f_spellbadword}, 7203 {"spellsuggest", 1, 3, f_spellsuggest}, 7204 {"split", 1, 3, f_split}, 7205 {"str2nr", 1, 2, f_str2nr}, 7206 #ifdef HAVE_STRFTIME 7207 {"strftime", 1, 2, f_strftime}, 7208 #endif 7209 {"stridx", 2, 3, f_stridx}, 7210 {"string", 1, 1, f_string}, 7211 {"strlen", 1, 1, f_strlen}, 7212 {"strpart", 2, 3, f_strpart}, 7213 {"strridx", 2, 3, f_strridx}, 7214 {"strtrans", 1, 1, f_strtrans}, 7215 {"submatch", 1, 1, f_submatch}, 7216 {"substitute", 4, 4, f_substitute}, 7217 {"synID", 3, 3, f_synID}, 7218 {"synIDattr", 2, 3, f_synIDattr}, 7219 {"synIDtrans", 1, 1, f_synIDtrans}, 7220 {"system", 1, 2, f_system}, 7221 {"tabpagebuflist", 0, 1, f_tabpagebuflist}, 7222 {"tabpagenr", 0, 1, f_tabpagenr}, 7223 {"tabpagewinnr", 1, 2, f_tabpagewinnr}, 7224 {"tagfiles", 0, 0, f_tagfiles}, 7225 {"taglist", 1, 1, f_taglist}, 7226 {"tempname", 0, 0, f_tempname}, 7227 {"test", 1, 1, f_test}, 7228 {"tolower", 1, 1, f_tolower}, 7229 {"toupper", 1, 1, f_toupper}, 7230 {"tr", 3, 3, f_tr}, 7231 {"type", 1, 1, f_type}, 7232 {"values", 1, 1, f_values}, 7233 {"virtcol", 1, 1, f_virtcol}, 7234 {"visualmode", 0, 1, f_visualmode}, 7235 {"winbufnr", 1, 1, f_winbufnr}, 7236 {"wincol", 0, 0, f_wincol}, 7237 {"winheight", 1, 1, f_winheight}, 7238 {"winline", 0, 0, f_winline}, 7239 {"winnr", 0, 1, f_winnr}, 7240 {"winrestcmd", 0, 0, f_winrestcmd}, 7241 {"winrestview", 1, 1, f_winrestview}, 7242 {"winsaveview", 0, 0, f_winsaveview}, 7243 {"winwidth", 1, 1, f_winwidth}, 7244 {"writefile", 2, 3, f_writefile}, 7245 }; 7246 7247 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 7248 7249 /* 7250 * Function given to ExpandGeneric() to obtain the list of internal 7251 * or user defined function names. 7252 */ 7253 char_u * 7254 get_function_name(xp, idx) 7255 expand_T *xp; 7256 int idx; 7257 { 7258 static int intidx = -1; 7259 char_u *name; 7260 7261 if (idx == 0) 7262 intidx = -1; 7263 if (intidx < 0) 7264 { 7265 name = get_user_func_name(xp, idx); 7266 if (name != NULL) 7267 return name; 7268 } 7269 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 7270 { 7271 STRCPY(IObuff, functions[intidx].f_name); 7272 STRCAT(IObuff, "("); 7273 if (functions[intidx].f_max_argc == 0) 7274 STRCAT(IObuff, ")"); 7275 return IObuff; 7276 } 7277 7278 return NULL; 7279 } 7280 7281 /* 7282 * Function given to ExpandGeneric() to obtain the list of internal or 7283 * user defined variable or function names. 7284 */ 7285 /*ARGSUSED*/ 7286 char_u * 7287 get_expr_name(xp, idx) 7288 expand_T *xp; 7289 int idx; 7290 { 7291 static int intidx = -1; 7292 char_u *name; 7293 7294 if (idx == 0) 7295 intidx = -1; 7296 if (intidx < 0) 7297 { 7298 name = get_function_name(xp, idx); 7299 if (name != NULL) 7300 return name; 7301 } 7302 return get_user_var_name(xp, ++intidx); 7303 } 7304 7305 #endif /* FEAT_CMDL_COMPL */ 7306 7307 /* 7308 * Find internal function in table above. 7309 * Return index, or -1 if not found 7310 */ 7311 static int 7312 find_internal_func(name) 7313 char_u *name; /* name of the function */ 7314 { 7315 int first = 0; 7316 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 7317 int cmp; 7318 int x; 7319 7320 /* 7321 * Find the function name in the table. Binary search. 7322 */ 7323 while (first <= last) 7324 { 7325 x = first + ((unsigned)(last - first) >> 1); 7326 cmp = STRCMP(name, functions[x].f_name); 7327 if (cmp < 0) 7328 last = x - 1; 7329 else if (cmp > 0) 7330 first = x + 1; 7331 else 7332 return x; 7333 } 7334 return -1; 7335 } 7336 7337 /* 7338 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 7339 * name it contains, otherwise return "name". 7340 */ 7341 static char_u * 7342 deref_func_name(name, lenp) 7343 char_u *name; 7344 int *lenp; 7345 { 7346 dictitem_T *v; 7347 int cc; 7348 7349 cc = name[*lenp]; 7350 name[*lenp] = NUL; 7351 v = find_var(name, NULL); 7352 name[*lenp] = cc; 7353 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7354 { 7355 if (v->di_tv.vval.v_string == NULL) 7356 { 7357 *lenp = 0; 7358 return (char_u *)""; /* just in case */ 7359 } 7360 *lenp = (int)STRLEN(v->di_tv.vval.v_string); 7361 return v->di_tv.vval.v_string; 7362 } 7363 7364 return name; 7365 } 7366 7367 /* 7368 * Allocate a variable for the result of a function. 7369 * Return OK or FAIL. 7370 */ 7371 static int 7372 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7373 evaluate, selfdict) 7374 char_u *name; /* name of the function */ 7375 int len; /* length of "name" */ 7376 typval_T *rettv; 7377 char_u **arg; /* argument, pointing to the '(' */ 7378 linenr_T firstline; /* first line of range */ 7379 linenr_T lastline; /* last line of range */ 7380 int *doesrange; /* return: function handled range */ 7381 int evaluate; 7382 dict_T *selfdict; /* Dictionary for "self" */ 7383 { 7384 char_u *argp; 7385 int ret = OK; 7386 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 7387 int argcount = 0; /* number of arguments found */ 7388 7389 /* 7390 * Get the arguments. 7391 */ 7392 argp = *arg; 7393 while (argcount < MAX_FUNC_ARGS) 7394 { 7395 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7396 if (*argp == ')' || *argp == ',' || *argp == NUL) 7397 break; 7398 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7399 { 7400 ret = FAIL; 7401 break; 7402 } 7403 ++argcount; 7404 if (*argp != ',') 7405 break; 7406 } 7407 if (*argp == ')') 7408 ++argp; 7409 else 7410 ret = FAIL; 7411 7412 if (ret == OK) 7413 ret = call_func(name, len, rettv, argcount, argvars, 7414 firstline, lastline, doesrange, evaluate, selfdict); 7415 else if (!aborting()) 7416 { 7417 if (argcount == MAX_FUNC_ARGS) 7418 emsg_funcname("E740: Too many arguments for function %s", name); 7419 else 7420 emsg_funcname("E116: Invalid arguments for function %s", name); 7421 } 7422 7423 while (--argcount >= 0) 7424 clear_tv(&argvars[argcount]); 7425 7426 *arg = skipwhite(argp); 7427 return ret; 7428 } 7429 7430 7431 /* 7432 * Call a function with its resolved parameters 7433 * Return OK when the function can't be called, FAIL otherwise. 7434 * Also returns OK when an error was encountered while executing the function. 7435 */ 7436 static int 7437 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7438 doesrange, evaluate, selfdict) 7439 char_u *name; /* name of the function */ 7440 int len; /* length of "name" */ 7441 typval_T *rettv; /* return value goes here */ 7442 int argcount; /* number of "argvars" */ 7443 typval_T *argvars; /* vars for arguments, must have "argcount" 7444 PLUS ONE elements! */ 7445 linenr_T firstline; /* first line of range */ 7446 linenr_T lastline; /* last line of range */ 7447 int *doesrange; /* return: function handled range */ 7448 int evaluate; 7449 dict_T *selfdict; /* Dictionary for "self" */ 7450 { 7451 int ret = FAIL; 7452 #define ERROR_UNKNOWN 0 7453 #define ERROR_TOOMANY 1 7454 #define ERROR_TOOFEW 2 7455 #define ERROR_SCRIPT 3 7456 #define ERROR_DICT 4 7457 #define ERROR_NONE 5 7458 #define ERROR_OTHER 6 7459 int error = ERROR_NONE; 7460 int i; 7461 int llen; 7462 ufunc_T *fp; 7463 int cc; 7464 #define FLEN_FIXED 40 7465 char_u fname_buf[FLEN_FIXED + 1]; 7466 char_u *fname; 7467 7468 /* 7469 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7470 * Change <SNR>123_name() to K_SNR 123_name(). 7471 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7472 */ 7473 cc = name[len]; 7474 name[len] = NUL; 7475 llen = eval_fname_script(name); 7476 if (llen > 0) 7477 { 7478 fname_buf[0] = K_SPECIAL; 7479 fname_buf[1] = KS_EXTRA; 7480 fname_buf[2] = (int)KE_SNR; 7481 i = 3; 7482 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7483 { 7484 if (current_SID <= 0) 7485 error = ERROR_SCRIPT; 7486 else 7487 { 7488 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7489 i = (int)STRLEN(fname_buf); 7490 } 7491 } 7492 if (i + STRLEN(name + llen) < FLEN_FIXED) 7493 { 7494 STRCPY(fname_buf + i, name + llen); 7495 fname = fname_buf; 7496 } 7497 else 7498 { 7499 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7500 if (fname == NULL) 7501 error = ERROR_OTHER; 7502 else 7503 { 7504 mch_memmove(fname, fname_buf, (size_t)i); 7505 STRCPY(fname + i, name + llen); 7506 } 7507 } 7508 } 7509 else 7510 fname = name; 7511 7512 *doesrange = FALSE; 7513 7514 7515 /* execute the function if no errors detected and executing */ 7516 if (evaluate && error == ERROR_NONE) 7517 { 7518 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7519 error = ERROR_UNKNOWN; 7520 7521 if (!builtin_function(fname)) 7522 { 7523 /* 7524 * User defined function. 7525 */ 7526 fp = find_func(fname); 7527 7528 #ifdef FEAT_AUTOCMD 7529 /* Trigger FuncUndefined event, may load the function. */ 7530 if (fp == NULL 7531 && apply_autocmds(EVENT_FUNCUNDEFINED, 7532 fname, fname, TRUE, NULL) 7533 && !aborting()) 7534 { 7535 /* executed an autocommand, search for the function again */ 7536 fp = find_func(fname); 7537 } 7538 #endif 7539 /* Try loading a package. */ 7540 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7541 { 7542 /* loaded a package, search for the function again */ 7543 fp = find_func(fname); 7544 } 7545 7546 if (fp != NULL) 7547 { 7548 if (fp->uf_flags & FC_RANGE) 7549 *doesrange = TRUE; 7550 if (argcount < fp->uf_args.ga_len) 7551 error = ERROR_TOOFEW; 7552 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7553 error = ERROR_TOOMANY; 7554 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7555 error = ERROR_DICT; 7556 else 7557 { 7558 /* 7559 * Call the user function. 7560 * Save and restore search patterns, script variables and 7561 * redo buffer. 7562 */ 7563 save_search_patterns(); 7564 saveRedobuff(); 7565 ++fp->uf_calls; 7566 call_user_func(fp, argcount, argvars, rettv, 7567 firstline, lastline, 7568 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7569 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7570 && fp->uf_refcount <= 0) 7571 /* Function was unreferenced while being used, free it 7572 * now. */ 7573 func_free(fp); 7574 restoreRedobuff(); 7575 restore_search_patterns(); 7576 error = ERROR_NONE; 7577 } 7578 } 7579 } 7580 else 7581 { 7582 /* 7583 * Find the function name in the table, call its implementation. 7584 */ 7585 i = find_internal_func(fname); 7586 if (i >= 0) 7587 { 7588 if (argcount < functions[i].f_min_argc) 7589 error = ERROR_TOOFEW; 7590 else if (argcount > functions[i].f_max_argc) 7591 error = ERROR_TOOMANY; 7592 else 7593 { 7594 argvars[argcount].v_type = VAR_UNKNOWN; 7595 functions[i].f_func(argvars, rettv); 7596 error = ERROR_NONE; 7597 } 7598 } 7599 } 7600 /* 7601 * The function call (or "FuncUndefined" autocommand sequence) might 7602 * have been aborted by an error, an interrupt, or an explicitly thrown 7603 * exception that has not been caught so far. This situation can be 7604 * tested for by calling aborting(). For an error in an internal 7605 * function or for the "E132" error in call_user_func(), however, the 7606 * throw point at which the "force_abort" flag (temporarily reset by 7607 * emsg()) is normally updated has not been reached yet. We need to 7608 * update that flag first to make aborting() reliable. 7609 */ 7610 update_force_abort(); 7611 } 7612 if (error == ERROR_NONE) 7613 ret = OK; 7614 7615 /* 7616 * Report an error unless the argument evaluation or function call has been 7617 * cancelled due to an aborting error, an interrupt, or an exception. 7618 */ 7619 if (!aborting()) 7620 { 7621 switch (error) 7622 { 7623 case ERROR_UNKNOWN: 7624 emsg_funcname(N_("E117: Unknown function: %s"), name); 7625 break; 7626 case ERROR_TOOMANY: 7627 emsg_funcname(e_toomanyarg, name); 7628 break; 7629 case ERROR_TOOFEW: 7630 emsg_funcname(N_("E119: Not enough arguments for function: %s"), 7631 name); 7632 break; 7633 case ERROR_SCRIPT: 7634 emsg_funcname(N_("E120: Using <SID> not in a script context: %s"), 7635 name); 7636 break; 7637 case ERROR_DICT: 7638 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), 7639 name); 7640 break; 7641 } 7642 } 7643 7644 name[len] = cc; 7645 if (fname != name && fname != fname_buf) 7646 vim_free(fname); 7647 7648 return ret; 7649 } 7650 7651 /* 7652 * Give an error message with a function name. Handle <SNR> things. 7653 */ 7654 static void 7655 emsg_funcname(ermsg, name) 7656 char *ermsg; 7657 char_u *name; 7658 { 7659 char_u *p; 7660 7661 if (*name == K_SPECIAL) 7662 p = concat_str((char_u *)"<SNR>", name + 3); 7663 else 7664 p = name; 7665 EMSG2(_(ermsg), p); 7666 if (p != name) 7667 vim_free(p); 7668 } 7669 7670 /********************************************* 7671 * Implementation of the built-in functions 7672 */ 7673 7674 /* 7675 * "add(list, item)" function 7676 */ 7677 static void 7678 f_add(argvars, rettv) 7679 typval_T *argvars; 7680 typval_T *rettv; 7681 { 7682 list_T *l; 7683 7684 rettv->vval.v_number = 1; /* Default: Failed */ 7685 if (argvars[0].v_type == VAR_LIST) 7686 { 7687 if ((l = argvars[0].vval.v_list) != NULL 7688 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7689 && list_append_tv(l, &argvars[1]) == OK) 7690 copy_tv(&argvars[0], rettv); 7691 } 7692 else 7693 EMSG(_(e_listreq)); 7694 } 7695 7696 /* 7697 * "append(lnum, string/list)" function 7698 */ 7699 static void 7700 f_append(argvars, rettv) 7701 typval_T *argvars; 7702 typval_T *rettv; 7703 { 7704 long lnum; 7705 char_u *line; 7706 list_T *l = NULL; 7707 listitem_T *li = NULL; 7708 typval_T *tv; 7709 long added = 0; 7710 7711 lnum = get_tv_lnum(argvars); 7712 if (lnum >= 0 7713 && lnum <= curbuf->b_ml.ml_line_count 7714 && u_save(lnum, lnum + 1) == OK) 7715 { 7716 if (argvars[1].v_type == VAR_LIST) 7717 { 7718 l = argvars[1].vval.v_list; 7719 if (l == NULL) 7720 return; 7721 li = l->lv_first; 7722 } 7723 rettv->vval.v_number = 0; /* Default: Success */ 7724 for (;;) 7725 { 7726 if (l == NULL) 7727 tv = &argvars[1]; /* append a string */ 7728 else if (li == NULL) 7729 break; /* end of list */ 7730 else 7731 tv = &li->li_tv; /* append item from list */ 7732 line = get_tv_string_chk(tv); 7733 if (line == NULL) /* type error */ 7734 { 7735 rettv->vval.v_number = 1; /* Failed */ 7736 break; 7737 } 7738 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7739 ++added; 7740 if (l == NULL) 7741 break; 7742 li = li->li_next; 7743 } 7744 7745 appended_lines_mark(lnum, added); 7746 if (curwin->w_cursor.lnum > lnum) 7747 curwin->w_cursor.lnum += added; 7748 } 7749 else 7750 rettv->vval.v_number = 1; /* Failed */ 7751 } 7752 7753 /* 7754 * "argc()" function 7755 */ 7756 /* ARGSUSED */ 7757 static void 7758 f_argc(argvars, rettv) 7759 typval_T *argvars; 7760 typval_T *rettv; 7761 { 7762 rettv->vval.v_number = ARGCOUNT; 7763 } 7764 7765 /* 7766 * "argidx()" function 7767 */ 7768 /* ARGSUSED */ 7769 static void 7770 f_argidx(argvars, rettv) 7771 typval_T *argvars; 7772 typval_T *rettv; 7773 { 7774 rettv->vval.v_number = curwin->w_arg_idx; 7775 } 7776 7777 /* 7778 * "argv(nr)" function 7779 */ 7780 static void 7781 f_argv(argvars, rettv) 7782 typval_T *argvars; 7783 typval_T *rettv; 7784 { 7785 int idx; 7786 7787 if (argvars[0].v_type != VAR_UNKNOWN) 7788 { 7789 idx = get_tv_number_chk(&argvars[0], NULL); 7790 if (idx >= 0 && idx < ARGCOUNT) 7791 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7792 else 7793 rettv->vval.v_string = NULL; 7794 rettv->v_type = VAR_STRING; 7795 } 7796 else if (rettv_list_alloc(rettv) == OK) 7797 for (idx = 0; idx < ARGCOUNT; ++idx) 7798 list_append_string(rettv->vval.v_list, 7799 alist_name(&ARGLIST[idx]), -1); 7800 } 7801 7802 /* 7803 * "browse(save, title, initdir, default)" function 7804 */ 7805 /* ARGSUSED */ 7806 static void 7807 f_browse(argvars, rettv) 7808 typval_T *argvars; 7809 typval_T *rettv; 7810 { 7811 #ifdef FEAT_BROWSE 7812 int save; 7813 char_u *title; 7814 char_u *initdir; 7815 char_u *defname; 7816 char_u buf[NUMBUFLEN]; 7817 char_u buf2[NUMBUFLEN]; 7818 int error = FALSE; 7819 7820 save = get_tv_number_chk(&argvars[0], &error); 7821 title = get_tv_string_chk(&argvars[1]); 7822 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7823 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7824 7825 if (error || title == NULL || initdir == NULL || defname == NULL) 7826 rettv->vval.v_string = NULL; 7827 else 7828 rettv->vval.v_string = 7829 do_browse(save ? BROWSE_SAVE : 0, 7830 title, defname, NULL, initdir, NULL, curbuf); 7831 #else 7832 rettv->vval.v_string = NULL; 7833 #endif 7834 rettv->v_type = VAR_STRING; 7835 } 7836 7837 /* 7838 * "browsedir(title, initdir)" function 7839 */ 7840 /* ARGSUSED */ 7841 static void 7842 f_browsedir(argvars, rettv) 7843 typval_T *argvars; 7844 typval_T *rettv; 7845 { 7846 #ifdef FEAT_BROWSE 7847 char_u *title; 7848 char_u *initdir; 7849 char_u buf[NUMBUFLEN]; 7850 7851 title = get_tv_string_chk(&argvars[0]); 7852 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7853 7854 if (title == NULL || initdir == NULL) 7855 rettv->vval.v_string = NULL; 7856 else 7857 rettv->vval.v_string = do_browse(BROWSE_DIR, 7858 title, NULL, NULL, initdir, NULL, curbuf); 7859 #else 7860 rettv->vval.v_string = NULL; 7861 #endif 7862 rettv->v_type = VAR_STRING; 7863 } 7864 7865 static buf_T *find_buffer __ARGS((typval_T *avar)); 7866 7867 /* 7868 * Find a buffer by number or exact name. 7869 */ 7870 static buf_T * 7871 find_buffer(avar) 7872 typval_T *avar; 7873 { 7874 buf_T *buf = NULL; 7875 7876 if (avar->v_type == VAR_NUMBER) 7877 buf = buflist_findnr((int)avar->vval.v_number); 7878 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7879 { 7880 buf = buflist_findname_exp(avar->vval.v_string); 7881 if (buf == NULL) 7882 { 7883 /* No full path name match, try a match with a URL or a "nofile" 7884 * buffer, these don't use the full path. */ 7885 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7886 if (buf->b_fname != NULL 7887 && (path_with_url(buf->b_fname) 7888 #ifdef FEAT_QUICKFIX 7889 || bt_nofile(buf) 7890 #endif 7891 ) 7892 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7893 break; 7894 } 7895 } 7896 return buf; 7897 } 7898 7899 /* 7900 * "bufexists(expr)" function 7901 */ 7902 static void 7903 f_bufexists(argvars, rettv) 7904 typval_T *argvars; 7905 typval_T *rettv; 7906 { 7907 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7908 } 7909 7910 /* 7911 * "buflisted(expr)" function 7912 */ 7913 static void 7914 f_buflisted(argvars, rettv) 7915 typval_T *argvars; 7916 typval_T *rettv; 7917 { 7918 buf_T *buf; 7919 7920 buf = find_buffer(&argvars[0]); 7921 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7922 } 7923 7924 /* 7925 * "bufloaded(expr)" function 7926 */ 7927 static void 7928 f_bufloaded(argvars, rettv) 7929 typval_T *argvars; 7930 typval_T *rettv; 7931 { 7932 buf_T *buf; 7933 7934 buf = find_buffer(&argvars[0]); 7935 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7936 } 7937 7938 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7939 7940 /* 7941 * Get buffer by number or pattern. 7942 */ 7943 static buf_T * 7944 get_buf_tv(tv) 7945 typval_T *tv; 7946 { 7947 char_u *name = tv->vval.v_string; 7948 int save_magic; 7949 char_u *save_cpo; 7950 buf_T *buf; 7951 7952 if (tv->v_type == VAR_NUMBER) 7953 return buflist_findnr((int)tv->vval.v_number); 7954 if (tv->v_type != VAR_STRING) 7955 return NULL; 7956 if (name == NULL || *name == NUL) 7957 return curbuf; 7958 if (name[0] == '$' && name[1] == NUL) 7959 return lastbuf; 7960 7961 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7962 save_magic = p_magic; 7963 p_magic = TRUE; 7964 save_cpo = p_cpo; 7965 p_cpo = (char_u *)""; 7966 7967 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7968 TRUE, FALSE)); 7969 7970 p_magic = save_magic; 7971 p_cpo = save_cpo; 7972 7973 /* If not found, try expanding the name, like done for bufexists(). */ 7974 if (buf == NULL) 7975 buf = find_buffer(tv); 7976 7977 return buf; 7978 } 7979 7980 /* 7981 * "bufname(expr)" function 7982 */ 7983 static void 7984 f_bufname(argvars, rettv) 7985 typval_T *argvars; 7986 typval_T *rettv; 7987 { 7988 buf_T *buf; 7989 7990 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7991 ++emsg_off; 7992 buf = get_buf_tv(&argvars[0]); 7993 rettv->v_type = VAR_STRING; 7994 if (buf != NULL && buf->b_fname != NULL) 7995 rettv->vval.v_string = vim_strsave(buf->b_fname); 7996 else 7997 rettv->vval.v_string = NULL; 7998 --emsg_off; 7999 } 8000 8001 /* 8002 * "bufnr(expr)" function 8003 */ 8004 static void 8005 f_bufnr(argvars, rettv) 8006 typval_T *argvars; 8007 typval_T *rettv; 8008 { 8009 buf_T *buf; 8010 int error = FALSE; 8011 char_u *name; 8012 8013 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8014 ++emsg_off; 8015 buf = get_buf_tv(&argvars[0]); 8016 --emsg_off; 8017 8018 /* If the buffer isn't found and the second argument is not zero create a 8019 * new buffer. */ 8020 if (buf == NULL 8021 && argvars[1].v_type != VAR_UNKNOWN 8022 && get_tv_number_chk(&argvars[1], &error) != 0 8023 && !error 8024 && (name = get_tv_string_chk(&argvars[0])) != NULL 8025 && !error) 8026 buf = buflist_new(name, NULL, (linenr_T)1, 0); 8027 8028 if (buf != NULL) 8029 rettv->vval.v_number = buf->b_fnum; 8030 else 8031 rettv->vval.v_number = -1; 8032 } 8033 8034 /* 8035 * "bufwinnr(nr)" function 8036 */ 8037 static void 8038 f_bufwinnr(argvars, rettv) 8039 typval_T *argvars; 8040 typval_T *rettv; 8041 { 8042 #ifdef FEAT_WINDOWS 8043 win_T *wp; 8044 int winnr = 0; 8045 #endif 8046 buf_T *buf; 8047 8048 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 8049 ++emsg_off; 8050 buf = get_buf_tv(&argvars[0]); 8051 #ifdef FEAT_WINDOWS 8052 for (wp = firstwin; wp; wp = wp->w_next) 8053 { 8054 ++winnr; 8055 if (wp->w_buffer == buf) 8056 break; 8057 } 8058 rettv->vval.v_number = (wp != NULL ? winnr : -1); 8059 #else 8060 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 8061 #endif 8062 --emsg_off; 8063 } 8064 8065 /* 8066 * "byte2line(byte)" function 8067 */ 8068 /*ARGSUSED*/ 8069 static void 8070 f_byte2line(argvars, rettv) 8071 typval_T *argvars; 8072 typval_T *rettv; 8073 { 8074 #ifndef FEAT_BYTEOFF 8075 rettv->vval.v_number = -1; 8076 #else 8077 long boff = 0; 8078 8079 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 8080 if (boff < 0) 8081 rettv->vval.v_number = -1; 8082 else 8083 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 8084 (linenr_T)0, &boff); 8085 #endif 8086 } 8087 8088 /* 8089 * "byteidx()" function 8090 */ 8091 /*ARGSUSED*/ 8092 static void 8093 f_byteidx(argvars, rettv) 8094 typval_T *argvars; 8095 typval_T *rettv; 8096 { 8097 #ifdef FEAT_MBYTE 8098 char_u *t; 8099 #endif 8100 char_u *str; 8101 long idx; 8102 8103 str = get_tv_string_chk(&argvars[0]); 8104 idx = get_tv_number_chk(&argvars[1], NULL); 8105 rettv->vval.v_number = -1; 8106 if (str == NULL || idx < 0) 8107 return; 8108 8109 #ifdef FEAT_MBYTE 8110 t = str; 8111 for ( ; idx > 0; idx--) 8112 { 8113 if (*t == NUL) /* EOL reached */ 8114 return; 8115 t += (*mb_ptr2len)(t); 8116 } 8117 rettv->vval.v_number = (varnumber_T)(t - str); 8118 #else 8119 if (idx <= STRLEN(str)) 8120 rettv->vval.v_number = idx; 8121 #endif 8122 } 8123 8124 /* 8125 * "call(func, arglist)" function 8126 */ 8127 static void 8128 f_call(argvars, rettv) 8129 typval_T *argvars; 8130 typval_T *rettv; 8131 { 8132 char_u *func; 8133 typval_T argv[MAX_FUNC_ARGS + 1]; 8134 int argc = 0; 8135 listitem_T *item; 8136 int dummy; 8137 dict_T *selfdict = NULL; 8138 8139 rettv->vval.v_number = 0; 8140 if (argvars[1].v_type != VAR_LIST) 8141 { 8142 EMSG(_(e_listreq)); 8143 return; 8144 } 8145 if (argvars[1].vval.v_list == NULL) 8146 return; 8147 8148 if (argvars[0].v_type == VAR_FUNC) 8149 func = argvars[0].vval.v_string; 8150 else 8151 func = get_tv_string(&argvars[0]); 8152 if (*func == NUL) 8153 return; /* type error or empty name */ 8154 8155 if (argvars[2].v_type != VAR_UNKNOWN) 8156 { 8157 if (argvars[2].v_type != VAR_DICT) 8158 { 8159 EMSG(_(e_dictreq)); 8160 return; 8161 } 8162 selfdict = argvars[2].vval.v_dict; 8163 } 8164 8165 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 8166 item = item->li_next) 8167 { 8168 if (argc == MAX_FUNC_ARGS) 8169 { 8170 EMSG(_("E699: Too many arguments")); 8171 break; 8172 } 8173 /* Make a copy of each argument. This is needed to be able to set 8174 * v_lock to VAR_FIXED in the copy without changing the original list. 8175 */ 8176 copy_tv(&item->li_tv, &argv[argc++]); 8177 } 8178 8179 if (item == NULL) 8180 (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, 8181 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 8182 &dummy, TRUE, selfdict); 8183 8184 /* Free the arguments. */ 8185 while (argc > 0) 8186 clear_tv(&argv[--argc]); 8187 } 8188 8189 /* 8190 * "changenr()" function 8191 */ 8192 /*ARGSUSED*/ 8193 static void 8194 f_changenr(argvars, rettv) 8195 typval_T *argvars; 8196 typval_T *rettv; 8197 { 8198 rettv->vval.v_number = curbuf->b_u_seq_cur; 8199 } 8200 8201 /* 8202 * "char2nr(string)" function 8203 */ 8204 static void 8205 f_char2nr(argvars, rettv) 8206 typval_T *argvars; 8207 typval_T *rettv; 8208 { 8209 #ifdef FEAT_MBYTE 8210 if (has_mbyte) 8211 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 8212 else 8213 #endif 8214 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 8215 } 8216 8217 /* 8218 * "cindent(lnum)" function 8219 */ 8220 static void 8221 f_cindent(argvars, rettv) 8222 typval_T *argvars; 8223 typval_T *rettv; 8224 { 8225 #ifdef FEAT_CINDENT 8226 pos_T pos; 8227 linenr_T lnum; 8228 8229 pos = curwin->w_cursor; 8230 lnum = get_tv_lnum(argvars); 8231 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8232 { 8233 curwin->w_cursor.lnum = lnum; 8234 rettv->vval.v_number = get_c_indent(); 8235 curwin->w_cursor = pos; 8236 } 8237 else 8238 #endif 8239 rettv->vval.v_number = -1; 8240 } 8241 8242 /* 8243 * "col(string)" function 8244 */ 8245 static void 8246 f_col(argvars, rettv) 8247 typval_T *argvars; 8248 typval_T *rettv; 8249 { 8250 colnr_T col = 0; 8251 pos_T *fp; 8252 int fnum = curbuf->b_fnum; 8253 8254 fp = var2fpos(&argvars[0], FALSE, &fnum); 8255 if (fp != NULL && fnum == curbuf->b_fnum) 8256 { 8257 if (fp->col == MAXCOL) 8258 { 8259 /* '> can be MAXCOL, get the length of the line then */ 8260 if (fp->lnum <= curbuf->b_ml.ml_line_count) 8261 col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; 8262 else 8263 col = MAXCOL; 8264 } 8265 else 8266 { 8267 col = fp->col + 1; 8268 #ifdef FEAT_VIRTUALEDIT 8269 /* col(".") when the cursor is on the NUL at the end of the line 8270 * because of "coladd" can be seen as an extra column. */ 8271 if (virtual_active() && fp == &curwin->w_cursor) 8272 { 8273 char_u *p = ml_get_cursor(); 8274 8275 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 8276 curwin->w_virtcol - curwin->w_cursor.coladd)) 8277 { 8278 # ifdef FEAT_MBYTE 8279 int l; 8280 8281 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 8282 col += l; 8283 # else 8284 if (*p != NUL && p[1] == NUL) 8285 ++col; 8286 # endif 8287 } 8288 } 8289 #endif 8290 } 8291 } 8292 rettv->vval.v_number = col; 8293 } 8294 8295 #if defined(FEAT_INS_EXPAND) 8296 /* 8297 * "complete()" function 8298 */ 8299 /*ARGSUSED*/ 8300 static void 8301 f_complete(argvars, rettv) 8302 typval_T *argvars; 8303 typval_T *rettv; 8304 { 8305 int startcol; 8306 8307 if ((State & INSERT) == 0) 8308 { 8309 EMSG(_("E785: complete() can only be used in Insert mode")); 8310 return; 8311 } 8312 8313 /* Check for undo allowed here, because if something was already inserted 8314 * the line was already saved for undo and this check isn't done. */ 8315 if (!undo_allowed()) 8316 return; 8317 8318 if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) 8319 { 8320 EMSG(_(e_invarg)); 8321 return; 8322 } 8323 8324 startcol = get_tv_number_chk(&argvars[0], NULL); 8325 if (startcol <= 0) 8326 return; 8327 8328 set_completion(startcol - 1, argvars[1].vval.v_list); 8329 } 8330 8331 /* 8332 * "complete_add()" function 8333 */ 8334 /*ARGSUSED*/ 8335 static void 8336 f_complete_add(argvars, rettv) 8337 typval_T *argvars; 8338 typval_T *rettv; 8339 { 8340 rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0); 8341 } 8342 8343 /* 8344 * "complete_check()" function 8345 */ 8346 /*ARGSUSED*/ 8347 static void 8348 f_complete_check(argvars, rettv) 8349 typval_T *argvars; 8350 typval_T *rettv; 8351 { 8352 int saved = RedrawingDisabled; 8353 8354 RedrawingDisabled = 0; 8355 ins_compl_check_keys(0); 8356 rettv->vval.v_number = compl_interrupted; 8357 RedrawingDisabled = saved; 8358 } 8359 #endif 8360 8361 /* 8362 * "confirm(message, buttons[, default [, type]])" function 8363 */ 8364 /*ARGSUSED*/ 8365 static void 8366 f_confirm(argvars, rettv) 8367 typval_T *argvars; 8368 typval_T *rettv; 8369 { 8370 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 8371 char_u *message; 8372 char_u *buttons = NULL; 8373 char_u buf[NUMBUFLEN]; 8374 char_u buf2[NUMBUFLEN]; 8375 int def = 1; 8376 int type = VIM_GENERIC; 8377 char_u *typestr; 8378 int error = FALSE; 8379 8380 message = get_tv_string_chk(&argvars[0]); 8381 if (message == NULL) 8382 error = TRUE; 8383 if (argvars[1].v_type != VAR_UNKNOWN) 8384 { 8385 buttons = get_tv_string_buf_chk(&argvars[1], buf); 8386 if (buttons == NULL) 8387 error = TRUE; 8388 if (argvars[2].v_type != VAR_UNKNOWN) 8389 { 8390 def = get_tv_number_chk(&argvars[2], &error); 8391 if (argvars[3].v_type != VAR_UNKNOWN) 8392 { 8393 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 8394 if (typestr == NULL) 8395 error = TRUE; 8396 else 8397 { 8398 switch (TOUPPER_ASC(*typestr)) 8399 { 8400 case 'E': type = VIM_ERROR; break; 8401 case 'Q': type = VIM_QUESTION; break; 8402 case 'I': type = VIM_INFO; break; 8403 case 'W': type = VIM_WARNING; break; 8404 case 'G': type = VIM_GENERIC; break; 8405 } 8406 } 8407 } 8408 } 8409 } 8410 8411 if (buttons == NULL || *buttons == NUL) 8412 buttons = (char_u *)_("&Ok"); 8413 8414 if (error) 8415 rettv->vval.v_number = 0; 8416 else 8417 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8418 def, NULL); 8419 #else 8420 rettv->vval.v_number = 0; 8421 #endif 8422 } 8423 8424 /* 8425 * "copy()" function 8426 */ 8427 static void 8428 f_copy(argvars, rettv) 8429 typval_T *argvars; 8430 typval_T *rettv; 8431 { 8432 item_copy(&argvars[0], rettv, FALSE, 0); 8433 } 8434 8435 /* 8436 * "count()" function 8437 */ 8438 static void 8439 f_count(argvars, rettv) 8440 typval_T *argvars; 8441 typval_T *rettv; 8442 { 8443 long n = 0; 8444 int ic = FALSE; 8445 8446 if (argvars[0].v_type == VAR_LIST) 8447 { 8448 listitem_T *li; 8449 list_T *l; 8450 long idx; 8451 8452 if ((l = argvars[0].vval.v_list) != NULL) 8453 { 8454 li = l->lv_first; 8455 if (argvars[2].v_type != VAR_UNKNOWN) 8456 { 8457 int error = FALSE; 8458 8459 ic = get_tv_number_chk(&argvars[2], &error); 8460 if (argvars[3].v_type != VAR_UNKNOWN) 8461 { 8462 idx = get_tv_number_chk(&argvars[3], &error); 8463 if (!error) 8464 { 8465 li = list_find(l, idx); 8466 if (li == NULL) 8467 EMSGN(_(e_listidx), idx); 8468 } 8469 } 8470 if (error) 8471 li = NULL; 8472 } 8473 8474 for ( ; li != NULL; li = li->li_next) 8475 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8476 ++n; 8477 } 8478 } 8479 else if (argvars[0].v_type == VAR_DICT) 8480 { 8481 int todo; 8482 dict_T *d; 8483 hashitem_T *hi; 8484 8485 if ((d = argvars[0].vval.v_dict) != NULL) 8486 { 8487 int error = FALSE; 8488 8489 if (argvars[2].v_type != VAR_UNKNOWN) 8490 { 8491 ic = get_tv_number_chk(&argvars[2], &error); 8492 if (argvars[3].v_type != VAR_UNKNOWN) 8493 EMSG(_(e_invarg)); 8494 } 8495 8496 todo = error ? 0 : (int)d->dv_hashtab.ht_used; 8497 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8498 { 8499 if (!HASHITEM_EMPTY(hi)) 8500 { 8501 --todo; 8502 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8503 ++n; 8504 } 8505 } 8506 } 8507 } 8508 else 8509 EMSG2(_(e_listdictarg), "count()"); 8510 rettv->vval.v_number = n; 8511 } 8512 8513 /* 8514 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8515 * 8516 * Checks the existence of a cscope connection. 8517 */ 8518 /*ARGSUSED*/ 8519 static void 8520 f_cscope_connection(argvars, rettv) 8521 typval_T *argvars; 8522 typval_T *rettv; 8523 { 8524 #ifdef FEAT_CSCOPE 8525 int num = 0; 8526 char_u *dbpath = NULL; 8527 char_u *prepend = NULL; 8528 char_u buf[NUMBUFLEN]; 8529 8530 if (argvars[0].v_type != VAR_UNKNOWN 8531 && argvars[1].v_type != VAR_UNKNOWN) 8532 { 8533 num = (int)get_tv_number(&argvars[0]); 8534 dbpath = get_tv_string(&argvars[1]); 8535 if (argvars[2].v_type != VAR_UNKNOWN) 8536 prepend = get_tv_string_buf(&argvars[2], buf); 8537 } 8538 8539 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8540 #else 8541 rettv->vval.v_number = 0; 8542 #endif 8543 } 8544 8545 /* 8546 * "cursor(lnum, col)" function 8547 * 8548 * Moves the cursor to the specified line and column 8549 */ 8550 /*ARGSUSED*/ 8551 static void 8552 f_cursor(argvars, rettv) 8553 typval_T *argvars; 8554 typval_T *rettv; 8555 { 8556 long line, col; 8557 #ifdef FEAT_VIRTUALEDIT 8558 long coladd = 0; 8559 #endif 8560 8561 if (argvars[1].v_type == VAR_UNKNOWN) 8562 { 8563 pos_T pos; 8564 8565 if (list2fpos(argvars, &pos, NULL) == FAIL) 8566 return; 8567 line = pos.lnum; 8568 col = pos.col; 8569 #ifdef FEAT_VIRTUALEDIT 8570 coladd = pos.coladd; 8571 #endif 8572 } 8573 else 8574 { 8575 line = get_tv_lnum(argvars); 8576 col = get_tv_number_chk(&argvars[1], NULL); 8577 #ifdef FEAT_VIRTUALEDIT 8578 if (argvars[2].v_type != VAR_UNKNOWN) 8579 coladd = get_tv_number_chk(&argvars[2], NULL); 8580 #endif 8581 } 8582 if (line < 0 || col < 0 8583 #ifdef FEAT_VIRTUALEDIT 8584 || coladd < 0 8585 #endif 8586 ) 8587 return; /* type error; errmsg already given */ 8588 if (line > 0) 8589 curwin->w_cursor.lnum = line; 8590 if (col > 0) 8591 curwin->w_cursor.col = col - 1; 8592 #ifdef FEAT_VIRTUALEDIT 8593 curwin->w_cursor.coladd = coladd; 8594 #endif 8595 8596 /* Make sure the cursor is in a valid position. */ 8597 check_cursor(); 8598 #ifdef FEAT_MBYTE 8599 /* Correct cursor for multi-byte character. */ 8600 if (has_mbyte) 8601 mb_adjust_cursor(); 8602 #endif 8603 8604 curwin->w_set_curswant = TRUE; 8605 } 8606 8607 /* 8608 * "deepcopy()" function 8609 */ 8610 static void 8611 f_deepcopy(argvars, rettv) 8612 typval_T *argvars; 8613 typval_T *rettv; 8614 { 8615 int noref = 0; 8616 8617 if (argvars[1].v_type != VAR_UNKNOWN) 8618 noref = get_tv_number_chk(&argvars[1], NULL); 8619 if (noref < 0 || noref > 1) 8620 EMSG(_(e_invarg)); 8621 else 8622 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8623 } 8624 8625 /* 8626 * "delete()" function 8627 */ 8628 static void 8629 f_delete(argvars, rettv) 8630 typval_T *argvars; 8631 typval_T *rettv; 8632 { 8633 if (check_restricted() || check_secure()) 8634 rettv->vval.v_number = -1; 8635 else 8636 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8637 } 8638 8639 /* 8640 * "did_filetype()" function 8641 */ 8642 /*ARGSUSED*/ 8643 static void 8644 f_did_filetype(argvars, rettv) 8645 typval_T *argvars; 8646 typval_T *rettv; 8647 { 8648 #ifdef FEAT_AUTOCMD 8649 rettv->vval.v_number = did_filetype; 8650 #else 8651 rettv->vval.v_number = 0; 8652 #endif 8653 } 8654 8655 /* 8656 * "diff_filler()" function 8657 */ 8658 /*ARGSUSED*/ 8659 static void 8660 f_diff_filler(argvars, rettv) 8661 typval_T *argvars; 8662 typval_T *rettv; 8663 { 8664 #ifdef FEAT_DIFF 8665 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8666 #endif 8667 } 8668 8669 /* 8670 * "diff_hlID()" function 8671 */ 8672 /*ARGSUSED*/ 8673 static void 8674 f_diff_hlID(argvars, rettv) 8675 typval_T *argvars; 8676 typval_T *rettv; 8677 { 8678 #ifdef FEAT_DIFF 8679 linenr_T lnum = get_tv_lnum(argvars); 8680 static linenr_T prev_lnum = 0; 8681 static int changedtick = 0; 8682 static int fnum = 0; 8683 static int change_start = 0; 8684 static int change_end = 0; 8685 static hlf_T hlID = 0; 8686 int filler_lines; 8687 int col; 8688 8689 if (lnum < 0) /* ignore type error in {lnum} arg */ 8690 lnum = 0; 8691 if (lnum != prev_lnum 8692 || changedtick != curbuf->b_changedtick 8693 || fnum != curbuf->b_fnum) 8694 { 8695 /* New line, buffer, change: need to get the values. */ 8696 filler_lines = diff_check(curwin, lnum); 8697 if (filler_lines < 0) 8698 { 8699 if (filler_lines == -1) 8700 { 8701 change_start = MAXCOL; 8702 change_end = -1; 8703 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8704 hlID = HLF_ADD; /* added line */ 8705 else 8706 hlID = HLF_CHD; /* changed line */ 8707 } 8708 else 8709 hlID = HLF_ADD; /* added line */ 8710 } 8711 else 8712 hlID = (hlf_T)0; 8713 prev_lnum = lnum; 8714 changedtick = curbuf->b_changedtick; 8715 fnum = curbuf->b_fnum; 8716 } 8717 8718 if (hlID == HLF_CHD || hlID == HLF_TXD) 8719 { 8720 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8721 if (col >= change_start && col <= change_end) 8722 hlID = HLF_TXD; /* changed text */ 8723 else 8724 hlID = HLF_CHD; /* changed line */ 8725 } 8726 rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID; 8727 #endif 8728 } 8729 8730 /* 8731 * "empty({expr})" function 8732 */ 8733 static void 8734 f_empty(argvars, rettv) 8735 typval_T *argvars; 8736 typval_T *rettv; 8737 { 8738 int n; 8739 8740 switch (argvars[0].v_type) 8741 { 8742 case VAR_STRING: 8743 case VAR_FUNC: 8744 n = argvars[0].vval.v_string == NULL 8745 || *argvars[0].vval.v_string == NUL; 8746 break; 8747 case VAR_NUMBER: 8748 n = argvars[0].vval.v_number == 0; 8749 break; 8750 case VAR_LIST: 8751 n = argvars[0].vval.v_list == NULL 8752 || argvars[0].vval.v_list->lv_first == NULL; 8753 break; 8754 case VAR_DICT: 8755 n = argvars[0].vval.v_dict == NULL 8756 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8757 break; 8758 default: 8759 EMSG2(_(e_intern2), "f_empty()"); 8760 n = 0; 8761 } 8762 8763 rettv->vval.v_number = n; 8764 } 8765 8766 /* 8767 * "escape({string}, {chars})" function 8768 */ 8769 static void 8770 f_escape(argvars, rettv) 8771 typval_T *argvars; 8772 typval_T *rettv; 8773 { 8774 char_u buf[NUMBUFLEN]; 8775 8776 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8777 get_tv_string_buf(&argvars[1], buf)); 8778 rettv->v_type = VAR_STRING; 8779 } 8780 8781 /* 8782 * "eval()" function 8783 */ 8784 /*ARGSUSED*/ 8785 static void 8786 f_eval(argvars, rettv) 8787 typval_T *argvars; 8788 typval_T *rettv; 8789 { 8790 char_u *s; 8791 8792 s = get_tv_string_chk(&argvars[0]); 8793 if (s != NULL) 8794 s = skipwhite(s); 8795 8796 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8797 { 8798 rettv->v_type = VAR_NUMBER; 8799 rettv->vval.v_number = 0; 8800 } 8801 else if (*s != NUL) 8802 EMSG(_(e_trailing)); 8803 } 8804 8805 /* 8806 * "eventhandler()" function 8807 */ 8808 /*ARGSUSED*/ 8809 static void 8810 f_eventhandler(argvars, rettv) 8811 typval_T *argvars; 8812 typval_T *rettv; 8813 { 8814 rettv->vval.v_number = vgetc_busy; 8815 } 8816 8817 /* 8818 * "executable()" function 8819 */ 8820 static void 8821 f_executable(argvars, rettv) 8822 typval_T *argvars; 8823 typval_T *rettv; 8824 { 8825 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8826 } 8827 8828 /* 8829 * "exists()" function 8830 */ 8831 static void 8832 f_exists(argvars, rettv) 8833 typval_T *argvars; 8834 typval_T *rettv; 8835 { 8836 char_u *p; 8837 char_u *name; 8838 int n = FALSE; 8839 int len = 0; 8840 8841 p = get_tv_string(&argvars[0]); 8842 if (*p == '$') /* environment variable */ 8843 { 8844 /* first try "normal" environment variables (fast) */ 8845 if (mch_getenv(p + 1) != NULL) 8846 n = TRUE; 8847 else 8848 { 8849 /* try expanding things like $VIM and ${HOME} */ 8850 p = expand_env_save(p); 8851 if (p != NULL && *p != '$') 8852 n = TRUE; 8853 vim_free(p); 8854 } 8855 } 8856 else if (*p == '&' || *p == '+') /* option */ 8857 { 8858 n = (get_option_tv(&p, NULL, TRUE) == OK); 8859 if (*skipwhite(p) != NUL) 8860 n = FALSE; /* trailing garbage */ 8861 } 8862 else if (*p == '*') /* internal or user defined function */ 8863 { 8864 n = function_exists(p + 1); 8865 } 8866 else if (*p == ':') 8867 { 8868 n = cmd_exists(p + 1); 8869 } 8870 else if (*p == '#') 8871 { 8872 #ifdef FEAT_AUTOCMD 8873 if (p[1] == '#') 8874 n = autocmd_supported(p + 2); 8875 else 8876 n = au_exists(p + 1); 8877 #endif 8878 } 8879 else /* internal variable */ 8880 { 8881 char_u *tofree; 8882 typval_T tv; 8883 8884 /* get_name_len() takes care of expanding curly braces */ 8885 name = p; 8886 len = get_name_len(&p, &tofree, TRUE, FALSE); 8887 if (len > 0) 8888 { 8889 if (tofree != NULL) 8890 name = tofree; 8891 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8892 if (n) 8893 { 8894 /* handle d.key, l[idx], f(expr) */ 8895 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8896 if (n) 8897 clear_tv(&tv); 8898 } 8899 } 8900 if (*p != NUL) 8901 n = FALSE; 8902 8903 vim_free(tofree); 8904 } 8905 8906 rettv->vval.v_number = n; 8907 } 8908 8909 /* 8910 * "expand()" function 8911 */ 8912 static void 8913 f_expand(argvars, rettv) 8914 typval_T *argvars; 8915 typval_T *rettv; 8916 { 8917 char_u *s; 8918 int len; 8919 char_u *errormsg; 8920 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8921 expand_T xpc; 8922 int error = FALSE; 8923 8924 rettv->v_type = VAR_STRING; 8925 s = get_tv_string(&argvars[0]); 8926 if (*s == '%' || *s == '#' || *s == '<') 8927 { 8928 ++emsg_off; 8929 rettv->vval.v_string = eval_vars(s, s, &len, NULL, &errormsg, NULL); 8930 --emsg_off; 8931 } 8932 else 8933 { 8934 /* When the optional second argument is non-zero, don't remove matches 8935 * for 'suffixes' and 'wildignore' */ 8936 if (argvars[1].v_type != VAR_UNKNOWN 8937 && get_tv_number_chk(&argvars[1], &error)) 8938 flags |= WILD_KEEP_ALL; 8939 if (!error) 8940 { 8941 ExpandInit(&xpc); 8942 xpc.xp_context = EXPAND_FILES; 8943 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8944 } 8945 else 8946 rettv->vval.v_string = NULL; 8947 } 8948 } 8949 8950 /* 8951 * "extend(list, list [, idx])" function 8952 * "extend(dict, dict [, action])" function 8953 */ 8954 static void 8955 f_extend(argvars, rettv) 8956 typval_T *argvars; 8957 typval_T *rettv; 8958 { 8959 rettv->vval.v_number = 0; 8960 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8961 { 8962 list_T *l1, *l2; 8963 listitem_T *item; 8964 long before; 8965 int error = FALSE; 8966 8967 l1 = argvars[0].vval.v_list; 8968 l2 = argvars[1].vval.v_list; 8969 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8970 && l2 != NULL) 8971 { 8972 if (argvars[2].v_type != VAR_UNKNOWN) 8973 { 8974 before = get_tv_number_chk(&argvars[2], &error); 8975 if (error) 8976 return; /* type error; errmsg already given */ 8977 8978 if (before == l1->lv_len) 8979 item = NULL; 8980 else 8981 { 8982 item = list_find(l1, before); 8983 if (item == NULL) 8984 { 8985 EMSGN(_(e_listidx), before); 8986 return; 8987 } 8988 } 8989 } 8990 else 8991 item = NULL; 8992 list_extend(l1, l2, item); 8993 8994 copy_tv(&argvars[0], rettv); 8995 } 8996 } 8997 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8998 { 8999 dict_T *d1, *d2; 9000 dictitem_T *di1; 9001 char_u *action; 9002 int i; 9003 hashitem_T *hi2; 9004 int todo; 9005 9006 d1 = argvars[0].vval.v_dict; 9007 d2 = argvars[1].vval.v_dict; 9008 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 9009 && d2 != NULL) 9010 { 9011 /* Check the third argument. */ 9012 if (argvars[2].v_type != VAR_UNKNOWN) 9013 { 9014 static char *(av[]) = {"keep", "force", "error"}; 9015 9016 action = get_tv_string_chk(&argvars[2]); 9017 if (action == NULL) 9018 return; /* type error; errmsg already given */ 9019 for (i = 0; i < 3; ++i) 9020 if (STRCMP(action, av[i]) == 0) 9021 break; 9022 if (i == 3) 9023 { 9024 EMSG2(_(e_invarg2), action); 9025 return; 9026 } 9027 } 9028 else 9029 action = (char_u *)"force"; 9030 9031 /* Go over all entries in the second dict and add them to the 9032 * first dict. */ 9033 todo = (int)d2->dv_hashtab.ht_used; 9034 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 9035 { 9036 if (!HASHITEM_EMPTY(hi2)) 9037 { 9038 --todo; 9039 di1 = dict_find(d1, hi2->hi_key, -1); 9040 if (di1 == NULL) 9041 { 9042 di1 = dictitem_copy(HI2DI(hi2)); 9043 if (di1 != NULL && dict_add(d1, di1) == FAIL) 9044 dictitem_free(di1); 9045 } 9046 else if (*action == 'e') 9047 { 9048 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 9049 break; 9050 } 9051 else if (*action == 'f') 9052 { 9053 clear_tv(&di1->di_tv); 9054 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 9055 } 9056 } 9057 } 9058 9059 copy_tv(&argvars[0], rettv); 9060 } 9061 } 9062 else 9063 EMSG2(_(e_listdictarg), "extend()"); 9064 } 9065 9066 /* 9067 * "feedkeys()" function 9068 */ 9069 /*ARGSUSED*/ 9070 static void 9071 f_feedkeys(argvars, rettv) 9072 typval_T *argvars; 9073 typval_T *rettv; 9074 { 9075 int remap = TRUE; 9076 char_u *keys, *flags; 9077 char_u nbuf[NUMBUFLEN]; 9078 int typed = FALSE; 9079 char_u *keys_esc; 9080 9081 /* This is not allowed in the sandbox. If the commands would still be 9082 * executed in the sandbox it would be OK, but it probably happens later, 9083 * when "sandbox" is no longer set. */ 9084 if (check_secure()) 9085 return; 9086 9087 rettv->vval.v_number = 0; 9088 keys = get_tv_string(&argvars[0]); 9089 if (*keys != NUL) 9090 { 9091 if (argvars[1].v_type != VAR_UNKNOWN) 9092 { 9093 flags = get_tv_string_buf(&argvars[1], nbuf); 9094 for ( ; *flags != NUL; ++flags) 9095 { 9096 switch (*flags) 9097 { 9098 case 'n': remap = FALSE; break; 9099 case 'm': remap = TRUE; break; 9100 case 't': typed = TRUE; break; 9101 } 9102 } 9103 } 9104 9105 /* Need to escape K_SPECIAL and CSI before putting the string in the 9106 * typeahead buffer. */ 9107 keys_esc = vim_strsave_escape_csi(keys); 9108 if (keys_esc != NULL) 9109 { 9110 ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE), 9111 typebuf.tb_len, !typed, FALSE); 9112 vim_free(keys_esc); 9113 if (vgetc_busy) 9114 typebuf_was_filled = TRUE; 9115 } 9116 } 9117 } 9118 9119 /* 9120 * "filereadable()" function 9121 */ 9122 static void 9123 f_filereadable(argvars, rettv) 9124 typval_T *argvars; 9125 typval_T *rettv; 9126 { 9127 FILE *fd; 9128 char_u *p; 9129 int n; 9130 9131 p = get_tv_string(&argvars[0]); 9132 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 9133 { 9134 n = TRUE; 9135 fclose(fd); 9136 } 9137 else 9138 n = FALSE; 9139 9140 rettv->vval.v_number = n; 9141 } 9142 9143 /* 9144 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 9145 * rights to write into. 9146 */ 9147 static void 9148 f_filewritable(argvars, rettv) 9149 typval_T *argvars; 9150 typval_T *rettv; 9151 { 9152 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 9153 } 9154 9155 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 9156 9157 static void 9158 findfilendir(argvars, rettv, dir) 9159 typval_T *argvars; 9160 typval_T *rettv; 9161 int dir; 9162 { 9163 #ifdef FEAT_SEARCHPATH 9164 char_u *fname; 9165 char_u *fresult = NULL; 9166 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 9167 char_u *p; 9168 char_u pathbuf[NUMBUFLEN]; 9169 int count = 1; 9170 int first = TRUE; 9171 int error = FALSE; 9172 #endif 9173 9174 rettv->vval.v_string = NULL; 9175 rettv->v_type = VAR_STRING; 9176 9177 #ifdef FEAT_SEARCHPATH 9178 fname = get_tv_string(&argvars[0]); 9179 9180 if (argvars[1].v_type != VAR_UNKNOWN) 9181 { 9182 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 9183 if (p == NULL) 9184 error = TRUE; 9185 else 9186 { 9187 if (*p != NUL) 9188 path = p; 9189 9190 if (argvars[2].v_type != VAR_UNKNOWN) 9191 count = get_tv_number_chk(&argvars[2], &error); 9192 } 9193 } 9194 9195 if (count < 0 && rettv_list_alloc(rettv) == FAIL) 9196 error = TRUE; 9197 9198 if (*fname != NUL && !error) 9199 { 9200 do 9201 { 9202 if (rettv->v_type == VAR_STRING) 9203 vim_free(fresult); 9204 fresult = find_file_in_path_option(first ? fname : NULL, 9205 first ? (int)STRLEN(fname) : 0, 9206 0, first, path, dir, curbuf->b_ffname, 9207 dir ? (char_u *)"" : curbuf->b_p_sua); 9208 first = FALSE; 9209 9210 if (fresult != NULL && rettv->v_type == VAR_LIST) 9211 list_append_string(rettv->vval.v_list, fresult, -1); 9212 9213 } while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL); 9214 } 9215 9216 if (rettv->v_type == VAR_STRING) 9217 rettv->vval.v_string = fresult; 9218 #endif 9219 } 9220 9221 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 9222 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 9223 9224 /* 9225 * Implementation of map() and filter(). 9226 */ 9227 static void 9228 filter_map(argvars, rettv, map) 9229 typval_T *argvars; 9230 typval_T *rettv; 9231 int map; 9232 { 9233 char_u buf[NUMBUFLEN]; 9234 char_u *expr; 9235 listitem_T *li, *nli; 9236 list_T *l = NULL; 9237 dictitem_T *di; 9238 hashtab_T *ht; 9239 hashitem_T *hi; 9240 dict_T *d = NULL; 9241 typval_T save_val; 9242 typval_T save_key; 9243 int rem; 9244 int todo; 9245 char_u *ermsg = map ? (char_u *)"map()" : (char_u *)"filter()"; 9246 int save_did_emsg; 9247 9248 rettv->vval.v_number = 0; 9249 if (argvars[0].v_type == VAR_LIST) 9250 { 9251 if ((l = argvars[0].vval.v_list) == NULL 9252 || (map && tv_check_lock(l->lv_lock, ermsg))) 9253 return; 9254 } 9255 else if (argvars[0].v_type == VAR_DICT) 9256 { 9257 if ((d = argvars[0].vval.v_dict) == NULL 9258 || (map && tv_check_lock(d->dv_lock, ermsg))) 9259 return; 9260 } 9261 else 9262 { 9263 EMSG2(_(e_listdictarg), ermsg); 9264 return; 9265 } 9266 9267 expr = get_tv_string_buf_chk(&argvars[1], buf); 9268 /* On type errors, the preceding call has already displayed an error 9269 * message. Avoid a misleading error message for an empty string that 9270 * was not passed as argument. */ 9271 if (expr != NULL) 9272 { 9273 prepare_vimvar(VV_VAL, &save_val); 9274 expr = skipwhite(expr); 9275 9276 /* We reset "did_emsg" to be able to detect whether an error 9277 * occurred during evaluation of the expression. */ 9278 save_did_emsg = did_emsg; 9279 did_emsg = FALSE; 9280 9281 if (argvars[0].v_type == VAR_DICT) 9282 { 9283 prepare_vimvar(VV_KEY, &save_key); 9284 vimvars[VV_KEY].vv_type = VAR_STRING; 9285 9286 ht = &d->dv_hashtab; 9287 hash_lock(ht); 9288 todo = (int)ht->ht_used; 9289 for (hi = ht->ht_array; todo > 0; ++hi) 9290 { 9291 if (!HASHITEM_EMPTY(hi)) 9292 { 9293 --todo; 9294 di = HI2DI(hi); 9295 if (tv_check_lock(di->di_tv.v_lock, ermsg)) 9296 break; 9297 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 9298 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL 9299 || did_emsg) 9300 break; 9301 if (!map && rem) 9302 dictitem_remove(d, di); 9303 clear_tv(&vimvars[VV_KEY].vv_tv); 9304 } 9305 } 9306 hash_unlock(ht); 9307 9308 restore_vimvar(VV_KEY, &save_key); 9309 } 9310 else 9311 { 9312 for (li = l->lv_first; li != NULL; li = nli) 9313 { 9314 if (tv_check_lock(li->li_tv.v_lock, ermsg)) 9315 break; 9316 nli = li->li_next; 9317 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL 9318 || did_emsg) 9319 break; 9320 if (!map && rem) 9321 listitem_remove(l, li); 9322 } 9323 } 9324 9325 restore_vimvar(VV_VAL, &save_val); 9326 9327 did_emsg |= save_did_emsg; 9328 } 9329 9330 copy_tv(&argvars[0], rettv); 9331 } 9332 9333 static int 9334 filter_map_one(tv, expr, map, remp) 9335 typval_T *tv; 9336 char_u *expr; 9337 int map; 9338 int *remp; 9339 { 9340 typval_T rettv; 9341 char_u *s; 9342 9343 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 9344 s = expr; 9345 if (eval1(&s, &rettv, TRUE) == FAIL) 9346 return FAIL; 9347 if (*s != NUL) /* check for trailing chars after expr */ 9348 { 9349 EMSG2(_(e_invexpr2), s); 9350 return FAIL; 9351 } 9352 if (map) 9353 { 9354 /* map(): replace the list item value */ 9355 clear_tv(tv); 9356 rettv.v_lock = 0; 9357 *tv = rettv; 9358 } 9359 else 9360 { 9361 int error = FALSE; 9362 9363 /* filter(): when expr is zero remove the item */ 9364 *remp = (get_tv_number_chk(&rettv, &error) == 0); 9365 clear_tv(&rettv); 9366 /* On type error, nothing has been removed; return FAIL to stop the 9367 * loop. The error message was given by get_tv_number_chk(). */ 9368 if (error) 9369 return FAIL; 9370 } 9371 clear_tv(&vimvars[VV_VAL].vv_tv); 9372 return OK; 9373 } 9374 9375 /* 9376 * "filter()" function 9377 */ 9378 static void 9379 f_filter(argvars, rettv) 9380 typval_T *argvars; 9381 typval_T *rettv; 9382 { 9383 filter_map(argvars, rettv, FALSE); 9384 } 9385 9386 /* 9387 * "finddir({fname}[, {path}[, {count}]])" function 9388 */ 9389 static void 9390 f_finddir(argvars, rettv) 9391 typval_T *argvars; 9392 typval_T *rettv; 9393 { 9394 findfilendir(argvars, rettv, TRUE); 9395 } 9396 9397 /* 9398 * "findfile({fname}[, {path}[, {count}]])" function 9399 */ 9400 static void 9401 f_findfile(argvars, rettv) 9402 typval_T *argvars; 9403 typval_T *rettv; 9404 { 9405 findfilendir(argvars, rettv, FALSE); 9406 } 9407 9408 /* 9409 * "fnamemodify({fname}, {mods})" function 9410 */ 9411 static void 9412 f_fnamemodify(argvars, rettv) 9413 typval_T *argvars; 9414 typval_T *rettv; 9415 { 9416 char_u *fname; 9417 char_u *mods; 9418 int usedlen = 0; 9419 int len; 9420 char_u *fbuf = NULL; 9421 char_u buf[NUMBUFLEN]; 9422 9423 fname = get_tv_string_chk(&argvars[0]); 9424 mods = get_tv_string_buf_chk(&argvars[1], buf); 9425 if (fname == NULL || mods == NULL) 9426 fname = NULL; 9427 else 9428 { 9429 len = (int)STRLEN(fname); 9430 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 9431 } 9432 9433 rettv->v_type = VAR_STRING; 9434 if (fname == NULL) 9435 rettv->vval.v_string = NULL; 9436 else 9437 rettv->vval.v_string = vim_strnsave(fname, len); 9438 vim_free(fbuf); 9439 } 9440 9441 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 9442 9443 /* 9444 * "foldclosed()" function 9445 */ 9446 static void 9447 foldclosed_both(argvars, rettv, end) 9448 typval_T *argvars; 9449 typval_T *rettv; 9450 int end; 9451 { 9452 #ifdef FEAT_FOLDING 9453 linenr_T lnum; 9454 linenr_T first, last; 9455 9456 lnum = get_tv_lnum(argvars); 9457 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9458 { 9459 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 9460 { 9461 if (end) 9462 rettv->vval.v_number = (varnumber_T)last; 9463 else 9464 rettv->vval.v_number = (varnumber_T)first; 9465 return; 9466 } 9467 } 9468 #endif 9469 rettv->vval.v_number = -1; 9470 } 9471 9472 /* 9473 * "foldclosed()" function 9474 */ 9475 static void 9476 f_foldclosed(argvars, rettv) 9477 typval_T *argvars; 9478 typval_T *rettv; 9479 { 9480 foldclosed_both(argvars, rettv, FALSE); 9481 } 9482 9483 /* 9484 * "foldclosedend()" function 9485 */ 9486 static void 9487 f_foldclosedend(argvars, rettv) 9488 typval_T *argvars; 9489 typval_T *rettv; 9490 { 9491 foldclosed_both(argvars, rettv, TRUE); 9492 } 9493 9494 /* 9495 * "foldlevel()" function 9496 */ 9497 static void 9498 f_foldlevel(argvars, rettv) 9499 typval_T *argvars; 9500 typval_T *rettv; 9501 { 9502 #ifdef FEAT_FOLDING 9503 linenr_T lnum; 9504 9505 lnum = get_tv_lnum(argvars); 9506 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 9507 rettv->vval.v_number = foldLevel(lnum); 9508 else 9509 #endif 9510 rettv->vval.v_number = 0; 9511 } 9512 9513 /* 9514 * "foldtext()" function 9515 */ 9516 /*ARGSUSED*/ 9517 static void 9518 f_foldtext(argvars, rettv) 9519 typval_T *argvars; 9520 typval_T *rettv; 9521 { 9522 #ifdef FEAT_FOLDING 9523 linenr_T lnum; 9524 char_u *s; 9525 char_u *r; 9526 int len; 9527 char *txt; 9528 #endif 9529 9530 rettv->v_type = VAR_STRING; 9531 rettv->vval.v_string = NULL; 9532 #ifdef FEAT_FOLDING 9533 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9534 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9535 <= curbuf->b_ml.ml_line_count 9536 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9537 { 9538 /* Find first non-empty line in the fold. */ 9539 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9540 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9541 { 9542 if (!linewhite(lnum)) 9543 break; 9544 ++lnum; 9545 } 9546 9547 /* Find interesting text in this line. */ 9548 s = skipwhite(ml_get(lnum)); 9549 /* skip C comment-start */ 9550 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9551 { 9552 s = skipwhite(s + 2); 9553 if (*skipwhite(s) == NUL 9554 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9555 { 9556 s = skipwhite(ml_get(lnum + 1)); 9557 if (*s == '*') 9558 s = skipwhite(s + 1); 9559 } 9560 } 9561 txt = _("+-%s%3ld lines: "); 9562 r = alloc((unsigned)(STRLEN(txt) 9563 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9564 + 20 /* for %3ld */ 9565 + STRLEN(s))); /* concatenated */ 9566 if (r != NULL) 9567 { 9568 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9569 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9570 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9571 len = (int)STRLEN(r); 9572 STRCAT(r, s); 9573 /* remove 'foldmarker' and 'commentstring' */ 9574 foldtext_cleanup(r + len); 9575 rettv->vval.v_string = r; 9576 } 9577 } 9578 #endif 9579 } 9580 9581 /* 9582 * "foldtextresult(lnum)" function 9583 */ 9584 /*ARGSUSED*/ 9585 static void 9586 f_foldtextresult(argvars, rettv) 9587 typval_T *argvars; 9588 typval_T *rettv; 9589 { 9590 #ifdef FEAT_FOLDING 9591 linenr_T lnum; 9592 char_u *text; 9593 char_u buf[51]; 9594 foldinfo_T foldinfo; 9595 int fold_count; 9596 #endif 9597 9598 rettv->v_type = VAR_STRING; 9599 rettv->vval.v_string = NULL; 9600 #ifdef FEAT_FOLDING 9601 lnum = get_tv_lnum(argvars); 9602 /* treat illegal types and illegal string values for {lnum} the same */ 9603 if (lnum < 0) 9604 lnum = 0; 9605 fold_count = foldedCount(curwin, lnum, &foldinfo); 9606 if (fold_count > 0) 9607 { 9608 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9609 &foldinfo, buf); 9610 if (text == buf) 9611 text = vim_strsave(text); 9612 rettv->vval.v_string = text; 9613 } 9614 #endif 9615 } 9616 9617 /* 9618 * "foreground()" function 9619 */ 9620 /*ARGSUSED*/ 9621 static void 9622 f_foreground(argvars, rettv) 9623 typval_T *argvars; 9624 typval_T *rettv; 9625 { 9626 rettv->vval.v_number = 0; 9627 #ifdef FEAT_GUI 9628 if (gui.in_use) 9629 gui_mch_set_foreground(); 9630 #else 9631 # ifdef WIN32 9632 win32_set_foreground(); 9633 # endif 9634 #endif 9635 } 9636 9637 /* 9638 * "function()" function 9639 */ 9640 /*ARGSUSED*/ 9641 static void 9642 f_function(argvars, rettv) 9643 typval_T *argvars; 9644 typval_T *rettv; 9645 { 9646 char_u *s; 9647 9648 rettv->vval.v_number = 0; 9649 s = get_tv_string(&argvars[0]); 9650 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9651 EMSG2(_(e_invarg2), s); 9652 else if (!function_exists(s)) 9653 EMSG2(_("E700: Unknown function: %s"), s); 9654 else 9655 { 9656 rettv->vval.v_string = vim_strsave(s); 9657 rettv->v_type = VAR_FUNC; 9658 } 9659 } 9660 9661 /* 9662 * "garbagecollect()" function 9663 */ 9664 /*ARGSUSED*/ 9665 static void 9666 f_garbagecollect(argvars, rettv) 9667 typval_T *argvars; 9668 typval_T *rettv; 9669 { 9670 /* This is postponed until we are back at the toplevel, because we may be 9671 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ 9672 want_garbage_collect = TRUE; 9673 } 9674 9675 /* 9676 * "get()" function 9677 */ 9678 static void 9679 f_get(argvars, rettv) 9680 typval_T *argvars; 9681 typval_T *rettv; 9682 { 9683 listitem_T *li; 9684 list_T *l; 9685 dictitem_T *di; 9686 dict_T *d; 9687 typval_T *tv = NULL; 9688 9689 if (argvars[0].v_type == VAR_LIST) 9690 { 9691 if ((l = argvars[0].vval.v_list) != NULL) 9692 { 9693 int error = FALSE; 9694 9695 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9696 if (!error && li != NULL) 9697 tv = &li->li_tv; 9698 } 9699 } 9700 else if (argvars[0].v_type == VAR_DICT) 9701 { 9702 if ((d = argvars[0].vval.v_dict) != NULL) 9703 { 9704 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9705 if (di != NULL) 9706 tv = &di->di_tv; 9707 } 9708 } 9709 else 9710 EMSG2(_(e_listdictarg), "get()"); 9711 9712 if (tv == NULL) 9713 { 9714 if (argvars[2].v_type == VAR_UNKNOWN) 9715 rettv->vval.v_number = 0; 9716 else 9717 copy_tv(&argvars[2], rettv); 9718 } 9719 else 9720 copy_tv(tv, rettv); 9721 } 9722 9723 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9724 9725 /* 9726 * Get line or list of lines from buffer "buf" into "rettv". 9727 * Return a range (from start to end) of lines in rettv from the specified 9728 * buffer. 9729 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9730 */ 9731 static void 9732 get_buffer_lines(buf, start, end, retlist, rettv) 9733 buf_T *buf; 9734 linenr_T start; 9735 linenr_T end; 9736 int retlist; 9737 typval_T *rettv; 9738 { 9739 char_u *p; 9740 9741 if (retlist) 9742 { 9743 if (rettv_list_alloc(rettv) == FAIL) 9744 return; 9745 } 9746 else 9747 rettv->vval.v_number = 0; 9748 9749 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9750 return; 9751 9752 if (!retlist) 9753 { 9754 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9755 p = ml_get_buf(buf, start, FALSE); 9756 else 9757 p = (char_u *)""; 9758 9759 rettv->v_type = VAR_STRING; 9760 rettv->vval.v_string = vim_strsave(p); 9761 } 9762 else 9763 { 9764 if (end < start) 9765 return; 9766 9767 if (start < 1) 9768 start = 1; 9769 if (end > buf->b_ml.ml_line_count) 9770 end = buf->b_ml.ml_line_count; 9771 while (start <= end) 9772 if (list_append_string(rettv->vval.v_list, 9773 ml_get_buf(buf, start++, FALSE), -1) == FAIL) 9774 break; 9775 } 9776 } 9777 9778 /* 9779 * "getbufline()" function 9780 */ 9781 static void 9782 f_getbufline(argvars, rettv) 9783 typval_T *argvars; 9784 typval_T *rettv; 9785 { 9786 linenr_T lnum; 9787 linenr_T end; 9788 buf_T *buf; 9789 9790 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9791 ++emsg_off; 9792 buf = get_buf_tv(&argvars[0]); 9793 --emsg_off; 9794 9795 lnum = get_tv_lnum_buf(&argvars[1], buf); 9796 if (argvars[2].v_type == VAR_UNKNOWN) 9797 end = lnum; 9798 else 9799 end = get_tv_lnum_buf(&argvars[2], buf); 9800 9801 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9802 } 9803 9804 /* 9805 * "getbufvar()" function 9806 */ 9807 static void 9808 f_getbufvar(argvars, rettv) 9809 typval_T *argvars; 9810 typval_T *rettv; 9811 { 9812 buf_T *buf; 9813 buf_T *save_curbuf; 9814 char_u *varname; 9815 dictitem_T *v; 9816 9817 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9818 varname = get_tv_string_chk(&argvars[1]); 9819 ++emsg_off; 9820 buf = get_buf_tv(&argvars[0]); 9821 9822 rettv->v_type = VAR_STRING; 9823 rettv->vval.v_string = NULL; 9824 9825 if (buf != NULL && varname != NULL) 9826 { 9827 if (*varname == '&') /* buffer-local-option */ 9828 { 9829 /* set curbuf to be our buf, temporarily */ 9830 save_curbuf = curbuf; 9831 curbuf = buf; 9832 9833 get_option_tv(&varname, rettv, TRUE); 9834 9835 /* restore previous notion of curbuf */ 9836 curbuf = save_curbuf; 9837 } 9838 else 9839 { 9840 if (*varname == NUL) 9841 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9842 * scope prefix before the NUL byte is required by 9843 * find_var_in_ht(). */ 9844 varname = (char_u *)"b:" + 2; 9845 /* look up the variable */ 9846 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9847 if (v != NULL) 9848 copy_tv(&v->di_tv, rettv); 9849 } 9850 } 9851 9852 --emsg_off; 9853 } 9854 9855 /* 9856 * "getchar()" function 9857 */ 9858 static void 9859 f_getchar(argvars, rettv) 9860 typval_T *argvars; 9861 typval_T *rettv; 9862 { 9863 varnumber_T n; 9864 int error = FALSE; 9865 9866 /* Position the cursor. Needed after a message that ends in a space. */ 9867 windgoto(msg_row, msg_col); 9868 9869 ++no_mapping; 9870 ++allow_keys; 9871 if (argvars[0].v_type == VAR_UNKNOWN) 9872 /* getchar(): blocking wait. */ 9873 n = safe_vgetc(); 9874 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9875 /* getchar(1): only check if char avail */ 9876 n = vpeekc(); 9877 else if (error || vpeekc() == NUL) 9878 /* illegal argument or getchar(0) and no char avail: return zero */ 9879 n = 0; 9880 else 9881 /* getchar(0) and char avail: return char */ 9882 n = safe_vgetc(); 9883 --no_mapping; 9884 --allow_keys; 9885 9886 vimvars[VV_MOUSE_WIN].vv_nr = 0; 9887 vimvars[VV_MOUSE_LNUM].vv_nr = 0; 9888 vimvars[VV_MOUSE_COL].vv_nr = 0; 9889 9890 rettv->vval.v_number = n; 9891 if (IS_SPECIAL(n) || mod_mask != 0) 9892 { 9893 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9894 int i = 0; 9895 9896 /* Turn a special key into three bytes, plus modifier. */ 9897 if (mod_mask != 0) 9898 { 9899 temp[i++] = K_SPECIAL; 9900 temp[i++] = KS_MODIFIER; 9901 temp[i++] = mod_mask; 9902 } 9903 if (IS_SPECIAL(n)) 9904 { 9905 temp[i++] = K_SPECIAL; 9906 temp[i++] = K_SECOND(n); 9907 temp[i++] = K_THIRD(n); 9908 } 9909 #ifdef FEAT_MBYTE 9910 else if (has_mbyte) 9911 i += (*mb_char2bytes)(n, temp + i); 9912 #endif 9913 else 9914 temp[i++] = n; 9915 temp[i++] = NUL; 9916 rettv->v_type = VAR_STRING; 9917 rettv->vval.v_string = vim_strsave(temp); 9918 9919 #ifdef FEAT_MOUSE 9920 if (n == K_LEFTMOUSE 9921 || n == K_LEFTMOUSE_NM 9922 || n == K_LEFTDRAG 9923 || n == K_LEFTRELEASE 9924 || n == K_LEFTRELEASE_NM 9925 || n == K_MIDDLEMOUSE 9926 || n == K_MIDDLEDRAG 9927 || n == K_MIDDLERELEASE 9928 || n == K_RIGHTMOUSE 9929 || n == K_RIGHTDRAG 9930 || n == K_RIGHTRELEASE 9931 || n == K_X1MOUSE 9932 || n == K_X1DRAG 9933 || n == K_X1RELEASE 9934 || n == K_X2MOUSE 9935 || n == K_X2DRAG 9936 || n == K_X2RELEASE 9937 || n == K_MOUSEDOWN 9938 || n == K_MOUSEUP) 9939 { 9940 int row = mouse_row; 9941 int col = mouse_col; 9942 win_T *win; 9943 linenr_T lnum; 9944 # ifdef FEAT_WINDOWS 9945 win_T *wp; 9946 # endif 9947 int n = 1; 9948 9949 if (row >= 0 && col >= 0) 9950 { 9951 /* Find the window at the mouse coordinates and compute the 9952 * text position. */ 9953 win = mouse_find_win(&row, &col); 9954 (void)mouse_comp_pos(win, &row, &col, &lnum); 9955 # ifdef FEAT_WINDOWS 9956 for (wp = firstwin; wp != win; wp = wp->w_next) 9957 ++n; 9958 # endif 9959 vimvars[VV_MOUSE_WIN].vv_nr = n; 9960 vimvars[VV_MOUSE_LNUM].vv_nr = lnum; 9961 vimvars[VV_MOUSE_COL].vv_nr = col + 1; 9962 } 9963 } 9964 #endif 9965 } 9966 } 9967 9968 /* 9969 * "getcharmod()" function 9970 */ 9971 /*ARGSUSED*/ 9972 static void 9973 f_getcharmod(argvars, rettv) 9974 typval_T *argvars; 9975 typval_T *rettv; 9976 { 9977 rettv->vval.v_number = mod_mask; 9978 } 9979 9980 /* 9981 * "getcmdline()" function 9982 */ 9983 /*ARGSUSED*/ 9984 static void 9985 f_getcmdline(argvars, rettv) 9986 typval_T *argvars; 9987 typval_T *rettv; 9988 { 9989 rettv->v_type = VAR_STRING; 9990 rettv->vval.v_string = get_cmdline_str(); 9991 } 9992 9993 /* 9994 * "getcmdpos()" function 9995 */ 9996 /*ARGSUSED*/ 9997 static void 9998 f_getcmdpos(argvars, rettv) 9999 typval_T *argvars; 10000 typval_T *rettv; 10001 { 10002 rettv->vval.v_number = get_cmdline_pos() + 1; 10003 } 10004 10005 /* 10006 * "getcmdtype()" function 10007 */ 10008 /*ARGSUSED*/ 10009 static void 10010 f_getcmdtype(argvars, rettv) 10011 typval_T *argvars; 10012 typval_T *rettv; 10013 { 10014 rettv->v_type = VAR_STRING; 10015 rettv->vval.v_string = alloc(2); 10016 if (rettv->vval.v_string != NULL) 10017 { 10018 rettv->vval.v_string[0] = get_cmdline_type(); 10019 rettv->vval.v_string[1] = NUL; 10020 } 10021 } 10022 10023 /* 10024 * "getcwd()" function 10025 */ 10026 /*ARGSUSED*/ 10027 static void 10028 f_getcwd(argvars, rettv) 10029 typval_T *argvars; 10030 typval_T *rettv; 10031 { 10032 char_u cwd[MAXPATHL]; 10033 10034 rettv->v_type = VAR_STRING; 10035 if (mch_dirname(cwd, MAXPATHL) == FAIL) 10036 rettv->vval.v_string = NULL; 10037 else 10038 { 10039 rettv->vval.v_string = vim_strsave(cwd); 10040 #ifdef BACKSLASH_IN_FILENAME 10041 if (rettv->vval.v_string != NULL) 10042 slash_adjust(rettv->vval.v_string); 10043 #endif 10044 } 10045 } 10046 10047 /* 10048 * "getfontname()" function 10049 */ 10050 /*ARGSUSED*/ 10051 static void 10052 f_getfontname(argvars, rettv) 10053 typval_T *argvars; 10054 typval_T *rettv; 10055 { 10056 rettv->v_type = VAR_STRING; 10057 rettv->vval.v_string = NULL; 10058 #ifdef FEAT_GUI 10059 if (gui.in_use) 10060 { 10061 GuiFont font; 10062 char_u *name = NULL; 10063 10064 if (argvars[0].v_type == VAR_UNKNOWN) 10065 { 10066 /* Get the "Normal" font. Either the name saved by 10067 * hl_set_font_name() or from the font ID. */ 10068 font = gui.norm_font; 10069 name = hl_get_font_name(); 10070 } 10071 else 10072 { 10073 name = get_tv_string(&argvars[0]); 10074 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 10075 return; 10076 font = gui_mch_get_font(name, FALSE); 10077 if (font == NOFONT) 10078 return; /* Invalid font name, return empty string. */ 10079 } 10080 rettv->vval.v_string = gui_mch_get_fontname(font, name); 10081 if (argvars[0].v_type != VAR_UNKNOWN) 10082 gui_mch_free_font(font); 10083 } 10084 #endif 10085 } 10086 10087 /* 10088 * "getfperm({fname})" function 10089 */ 10090 static void 10091 f_getfperm(argvars, rettv) 10092 typval_T *argvars; 10093 typval_T *rettv; 10094 { 10095 char_u *fname; 10096 struct stat st; 10097 char_u *perm = NULL; 10098 char_u flags[] = "rwx"; 10099 int i; 10100 10101 fname = get_tv_string(&argvars[0]); 10102 10103 rettv->v_type = VAR_STRING; 10104 if (mch_stat((char *)fname, &st) >= 0) 10105 { 10106 perm = vim_strsave((char_u *)"---------"); 10107 if (perm != NULL) 10108 { 10109 for (i = 0; i < 9; i++) 10110 { 10111 if (st.st_mode & (1 << (8 - i))) 10112 perm[i] = flags[i % 3]; 10113 } 10114 } 10115 } 10116 rettv->vval.v_string = perm; 10117 } 10118 10119 /* 10120 * "getfsize({fname})" function 10121 */ 10122 static void 10123 f_getfsize(argvars, rettv) 10124 typval_T *argvars; 10125 typval_T *rettv; 10126 { 10127 char_u *fname; 10128 struct stat st; 10129 10130 fname = get_tv_string(&argvars[0]); 10131 10132 rettv->v_type = VAR_NUMBER; 10133 10134 if (mch_stat((char *)fname, &st) >= 0) 10135 { 10136 if (mch_isdir(fname)) 10137 rettv->vval.v_number = 0; 10138 else 10139 rettv->vval.v_number = (varnumber_T)st.st_size; 10140 } 10141 else 10142 rettv->vval.v_number = -1; 10143 } 10144 10145 /* 10146 * "getftime({fname})" function 10147 */ 10148 static void 10149 f_getftime(argvars, rettv) 10150 typval_T *argvars; 10151 typval_T *rettv; 10152 { 10153 char_u *fname; 10154 struct stat st; 10155 10156 fname = get_tv_string(&argvars[0]); 10157 10158 if (mch_stat((char *)fname, &st) >= 0) 10159 rettv->vval.v_number = (varnumber_T)st.st_mtime; 10160 else 10161 rettv->vval.v_number = -1; 10162 } 10163 10164 /* 10165 * "getftype({fname})" function 10166 */ 10167 static void 10168 f_getftype(argvars, rettv) 10169 typval_T *argvars; 10170 typval_T *rettv; 10171 { 10172 char_u *fname; 10173 struct stat st; 10174 char_u *type = NULL; 10175 char *t; 10176 10177 fname = get_tv_string(&argvars[0]); 10178 10179 rettv->v_type = VAR_STRING; 10180 if (mch_lstat((char *)fname, &st) >= 0) 10181 { 10182 #ifdef S_ISREG 10183 if (S_ISREG(st.st_mode)) 10184 t = "file"; 10185 else if (S_ISDIR(st.st_mode)) 10186 t = "dir"; 10187 # ifdef S_ISLNK 10188 else if (S_ISLNK(st.st_mode)) 10189 t = "link"; 10190 # endif 10191 # ifdef S_ISBLK 10192 else if (S_ISBLK(st.st_mode)) 10193 t = "bdev"; 10194 # endif 10195 # ifdef S_ISCHR 10196 else if (S_ISCHR(st.st_mode)) 10197 t = "cdev"; 10198 # endif 10199 # ifdef S_ISFIFO 10200 else if (S_ISFIFO(st.st_mode)) 10201 t = "fifo"; 10202 # endif 10203 # ifdef S_ISSOCK 10204 else if (S_ISSOCK(st.st_mode)) 10205 t = "fifo"; 10206 # endif 10207 else 10208 t = "other"; 10209 #else 10210 # ifdef S_IFMT 10211 switch (st.st_mode & S_IFMT) 10212 { 10213 case S_IFREG: t = "file"; break; 10214 case S_IFDIR: t = "dir"; break; 10215 # ifdef S_IFLNK 10216 case S_IFLNK: t = "link"; break; 10217 # endif 10218 # ifdef S_IFBLK 10219 case S_IFBLK: t = "bdev"; break; 10220 # endif 10221 # ifdef S_IFCHR 10222 case S_IFCHR: t = "cdev"; break; 10223 # endif 10224 # ifdef S_IFIFO 10225 case S_IFIFO: t = "fifo"; break; 10226 # endif 10227 # ifdef S_IFSOCK 10228 case S_IFSOCK: t = "socket"; break; 10229 # endif 10230 default: t = "other"; 10231 } 10232 # else 10233 if (mch_isdir(fname)) 10234 t = "dir"; 10235 else 10236 t = "file"; 10237 # endif 10238 #endif 10239 type = vim_strsave((char_u *)t); 10240 } 10241 rettv->vval.v_string = type; 10242 } 10243 10244 /* 10245 * "getline(lnum, [end])" function 10246 */ 10247 static void 10248 f_getline(argvars, rettv) 10249 typval_T *argvars; 10250 typval_T *rettv; 10251 { 10252 linenr_T lnum; 10253 linenr_T end; 10254 int retlist; 10255 10256 lnum = get_tv_lnum(argvars); 10257 if (argvars[1].v_type == VAR_UNKNOWN) 10258 { 10259 end = 0; 10260 retlist = FALSE; 10261 } 10262 else 10263 { 10264 end = get_tv_lnum(&argvars[1]); 10265 retlist = TRUE; 10266 } 10267 10268 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 10269 } 10270 10271 /* 10272 * "getpos(string)" function 10273 */ 10274 static void 10275 f_getpos(argvars, rettv) 10276 typval_T *argvars; 10277 typval_T *rettv; 10278 { 10279 pos_T *fp; 10280 list_T *l; 10281 int fnum = -1; 10282 10283 if (rettv_list_alloc(rettv) == OK) 10284 { 10285 l = rettv->vval.v_list; 10286 fp = var2fpos(&argvars[0], TRUE, &fnum); 10287 if (fnum != -1) 10288 list_append_number(l, (varnumber_T)fnum); 10289 else 10290 list_append_number(l, (varnumber_T)0); 10291 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum 10292 : (varnumber_T)0); 10293 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1 10294 : (varnumber_T)0); 10295 list_append_number(l, 10296 #ifdef FEAT_VIRTUALEDIT 10297 (fp != NULL) ? (varnumber_T)fp->coladd : 10298 #endif 10299 (varnumber_T)0); 10300 } 10301 else 10302 rettv->vval.v_number = FALSE; 10303 } 10304 10305 /* 10306 * "getqflist()" and "getloclist()" functions 10307 */ 10308 /*ARGSUSED*/ 10309 static void 10310 f_getqflist(argvars, rettv) 10311 typval_T *argvars; 10312 typval_T *rettv; 10313 { 10314 #ifdef FEAT_QUICKFIX 10315 win_T *wp; 10316 #endif 10317 10318 rettv->vval.v_number = 0; 10319 #ifdef FEAT_QUICKFIX 10320 if (rettv_list_alloc(rettv) == OK) 10321 { 10322 wp = NULL; 10323 if (argvars[0].v_type != VAR_UNKNOWN) /* getloclist() */ 10324 { 10325 wp = find_win_by_nr(&argvars[0], NULL); 10326 if (wp == NULL) 10327 return; 10328 } 10329 10330 (void)get_errorlist(wp, rettv->vval.v_list); 10331 } 10332 #endif 10333 } 10334 10335 /* 10336 * "getreg()" function 10337 */ 10338 static void 10339 f_getreg(argvars, rettv) 10340 typval_T *argvars; 10341 typval_T *rettv; 10342 { 10343 char_u *strregname; 10344 int regname; 10345 int arg2 = FALSE; 10346 int error = FALSE; 10347 10348 if (argvars[0].v_type != VAR_UNKNOWN) 10349 { 10350 strregname = get_tv_string_chk(&argvars[0]); 10351 error = strregname == NULL; 10352 if (argvars[1].v_type != VAR_UNKNOWN) 10353 arg2 = get_tv_number_chk(&argvars[1], &error); 10354 } 10355 else 10356 strregname = vimvars[VV_REG].vv_str; 10357 regname = (strregname == NULL ? '"' : *strregname); 10358 if (regname == 0) 10359 regname = '"'; 10360 10361 rettv->v_type = VAR_STRING; 10362 rettv->vval.v_string = error ? NULL : 10363 get_reg_contents(regname, TRUE, arg2); 10364 } 10365 10366 /* 10367 * "getregtype()" function 10368 */ 10369 static void 10370 f_getregtype(argvars, rettv) 10371 typval_T *argvars; 10372 typval_T *rettv; 10373 { 10374 char_u *strregname; 10375 int regname; 10376 char_u buf[NUMBUFLEN + 2]; 10377 long reglen = 0; 10378 10379 if (argvars[0].v_type != VAR_UNKNOWN) 10380 { 10381 strregname = get_tv_string_chk(&argvars[0]); 10382 if (strregname == NULL) /* type error; errmsg already given */ 10383 { 10384 rettv->v_type = VAR_STRING; 10385 rettv->vval.v_string = NULL; 10386 return; 10387 } 10388 } 10389 else 10390 /* Default to v:register */ 10391 strregname = vimvars[VV_REG].vv_str; 10392 10393 regname = (strregname == NULL ? '"' : *strregname); 10394 if (regname == 0) 10395 regname = '"'; 10396 10397 buf[0] = NUL; 10398 buf[1] = NUL; 10399 switch (get_reg_type(regname, ®len)) 10400 { 10401 case MLINE: buf[0] = 'V'; break; 10402 case MCHAR: buf[0] = 'v'; break; 10403 #ifdef FEAT_VISUAL 10404 case MBLOCK: 10405 buf[0] = Ctrl_V; 10406 sprintf((char *)buf + 1, "%ld", reglen + 1); 10407 break; 10408 #endif 10409 } 10410 rettv->v_type = VAR_STRING; 10411 rettv->vval.v_string = vim_strsave(buf); 10412 } 10413 10414 /* 10415 * "gettabwinvar()" function 10416 */ 10417 static void 10418 f_gettabwinvar(argvars, rettv) 10419 typval_T *argvars; 10420 typval_T *rettv; 10421 { 10422 getwinvar(argvars, rettv, 1); 10423 } 10424 10425 /* 10426 * "getwinposx()" function 10427 */ 10428 /*ARGSUSED*/ 10429 static void 10430 f_getwinposx(argvars, rettv) 10431 typval_T *argvars; 10432 typval_T *rettv; 10433 { 10434 rettv->vval.v_number = -1; 10435 #ifdef FEAT_GUI 10436 if (gui.in_use) 10437 { 10438 int x, y; 10439 10440 if (gui_mch_get_winpos(&x, &y) == OK) 10441 rettv->vval.v_number = x; 10442 } 10443 #endif 10444 } 10445 10446 /* 10447 * "getwinposy()" function 10448 */ 10449 /*ARGSUSED*/ 10450 static void 10451 f_getwinposy(argvars, rettv) 10452 typval_T *argvars; 10453 typval_T *rettv; 10454 { 10455 rettv->vval.v_number = -1; 10456 #ifdef FEAT_GUI 10457 if (gui.in_use) 10458 { 10459 int x, y; 10460 10461 if (gui_mch_get_winpos(&x, &y) == OK) 10462 rettv->vval.v_number = y; 10463 } 10464 #endif 10465 } 10466 10467 /* 10468 * Find window specifed by "vp" in tabpage "tp". 10469 */ 10470 static win_T * 10471 find_win_by_nr(vp, tp) 10472 typval_T *vp; 10473 tabpage_T *tp; /* NULL for current tab page */ 10474 { 10475 #ifdef FEAT_WINDOWS 10476 win_T *wp; 10477 #endif 10478 int nr; 10479 10480 nr = get_tv_number_chk(vp, NULL); 10481 10482 #ifdef FEAT_WINDOWS 10483 if (nr < 0) 10484 return NULL; 10485 if (nr == 0) 10486 return curwin; 10487 10488 for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin; 10489 wp != NULL; wp = wp->w_next) 10490 if (--nr <= 0) 10491 break; 10492 return wp; 10493 #else 10494 if (nr == 0 || nr == 1) 10495 return curwin; 10496 return NULL; 10497 #endif 10498 } 10499 10500 /* 10501 * "getwinvar()" function 10502 */ 10503 static void 10504 f_getwinvar(argvars, rettv) 10505 typval_T *argvars; 10506 typval_T *rettv; 10507 { 10508 getwinvar(argvars, rettv, 0); 10509 } 10510 10511 /* 10512 * getwinvar() and gettabwinvar() 10513 */ 10514 static void 10515 getwinvar(argvars, rettv, off) 10516 typval_T *argvars; 10517 typval_T *rettv; 10518 int off; /* 1 for gettabwinvar() */ 10519 { 10520 win_T *win, *oldcurwin; 10521 char_u *varname; 10522 dictitem_T *v; 10523 tabpage_T *tp; 10524 10525 #ifdef FEAT_WINDOWS 10526 if (off == 1) 10527 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 10528 else 10529 tp = curtab; 10530 #endif 10531 win = find_win_by_nr(&argvars[off], tp); 10532 varname = get_tv_string_chk(&argvars[off + 1]); 10533 ++emsg_off; 10534 10535 rettv->v_type = VAR_STRING; 10536 rettv->vval.v_string = NULL; 10537 10538 if (win != NULL && varname != NULL) 10539 { 10540 /* Set curwin to be our win, temporarily. Also set curbuf, so 10541 * that we can get buffer-local options. */ 10542 oldcurwin = curwin; 10543 curwin = win; 10544 curbuf = win->w_buffer; 10545 10546 if (*varname == '&') /* window-local-option */ 10547 get_option_tv(&varname, rettv, 1); 10548 else 10549 { 10550 if (*varname == NUL) 10551 /* let getwinvar({nr}, "") return the "w:" dictionary. The 10552 * scope prefix before the NUL byte is required by 10553 * find_var_in_ht(). */ 10554 varname = (char_u *)"w:" + 2; 10555 /* look up the variable */ 10556 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 10557 if (v != NULL) 10558 copy_tv(&v->di_tv, rettv); 10559 } 10560 10561 /* restore previous notion of curwin */ 10562 curwin = oldcurwin; 10563 curbuf = curwin->w_buffer; 10564 } 10565 10566 --emsg_off; 10567 } 10568 10569 /* 10570 * "glob()" function 10571 */ 10572 static void 10573 f_glob(argvars, rettv) 10574 typval_T *argvars; 10575 typval_T *rettv; 10576 { 10577 expand_T xpc; 10578 10579 ExpandInit(&xpc); 10580 xpc.xp_context = EXPAND_FILES; 10581 rettv->v_type = VAR_STRING; 10582 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 10583 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 10584 } 10585 10586 /* 10587 * "globpath()" function 10588 */ 10589 static void 10590 f_globpath(argvars, rettv) 10591 typval_T *argvars; 10592 typval_T *rettv; 10593 { 10594 char_u buf1[NUMBUFLEN]; 10595 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 10596 10597 rettv->v_type = VAR_STRING; 10598 if (file == NULL) 10599 rettv->vval.v_string = NULL; 10600 else 10601 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 10602 } 10603 10604 /* 10605 * "has()" function 10606 */ 10607 static void 10608 f_has(argvars, rettv) 10609 typval_T *argvars; 10610 typval_T *rettv; 10611 { 10612 int i; 10613 char_u *name; 10614 int n = FALSE; 10615 static char *(has_list[]) = 10616 { 10617 #ifdef AMIGA 10618 "amiga", 10619 # ifdef FEAT_ARP 10620 "arp", 10621 # endif 10622 #endif 10623 #ifdef __BEOS__ 10624 "beos", 10625 #endif 10626 #ifdef MSDOS 10627 # ifdef DJGPP 10628 "dos32", 10629 # else 10630 "dos16", 10631 # endif 10632 #endif 10633 #ifdef MACOS 10634 "mac", 10635 #endif 10636 #if defined(MACOS_X_UNIX) 10637 "macunix", 10638 #endif 10639 #ifdef OS2 10640 "os2", 10641 #endif 10642 #ifdef __QNX__ 10643 "qnx", 10644 #endif 10645 #ifdef RISCOS 10646 "riscos", 10647 #endif 10648 #ifdef UNIX 10649 "unix", 10650 #endif 10651 #ifdef VMS 10652 "vms", 10653 #endif 10654 #ifdef WIN16 10655 "win16", 10656 #endif 10657 #ifdef WIN32 10658 "win32", 10659 #endif 10660 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10661 "win32unix", 10662 #endif 10663 #ifdef WIN64 10664 "win64", 10665 #endif 10666 #ifdef EBCDIC 10667 "ebcdic", 10668 #endif 10669 #ifndef CASE_INSENSITIVE_FILENAME 10670 "fname_case", 10671 #endif 10672 #ifdef FEAT_ARABIC 10673 "arabic", 10674 #endif 10675 #ifdef FEAT_AUTOCMD 10676 "autocmd", 10677 #endif 10678 #ifdef FEAT_BEVAL 10679 "balloon_eval", 10680 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10681 "balloon_multiline", 10682 # endif 10683 #endif 10684 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10685 "builtin_terms", 10686 # ifdef ALL_BUILTIN_TCAPS 10687 "all_builtin_terms", 10688 # endif 10689 #endif 10690 #ifdef FEAT_BYTEOFF 10691 "byte_offset", 10692 #endif 10693 #ifdef FEAT_CINDENT 10694 "cindent", 10695 #endif 10696 #ifdef FEAT_CLIENTSERVER 10697 "clientserver", 10698 #endif 10699 #ifdef FEAT_CLIPBOARD 10700 "clipboard", 10701 #endif 10702 #ifdef FEAT_CMDL_COMPL 10703 "cmdline_compl", 10704 #endif 10705 #ifdef FEAT_CMDHIST 10706 "cmdline_hist", 10707 #endif 10708 #ifdef FEAT_COMMENTS 10709 "comments", 10710 #endif 10711 #ifdef FEAT_CRYPT 10712 "cryptv", 10713 #endif 10714 #ifdef FEAT_CSCOPE 10715 "cscope", 10716 #endif 10717 #ifdef CURSOR_SHAPE 10718 "cursorshape", 10719 #endif 10720 #ifdef DEBUG 10721 "debug", 10722 #endif 10723 #ifdef FEAT_CON_DIALOG 10724 "dialog_con", 10725 #endif 10726 #ifdef FEAT_GUI_DIALOG 10727 "dialog_gui", 10728 #endif 10729 #ifdef FEAT_DIFF 10730 "diff", 10731 #endif 10732 #ifdef FEAT_DIGRAPHS 10733 "digraphs", 10734 #endif 10735 #ifdef FEAT_DND 10736 "dnd", 10737 #endif 10738 #ifdef FEAT_EMACS_TAGS 10739 "emacs_tags", 10740 #endif 10741 "eval", /* always present, of course! */ 10742 #ifdef FEAT_EX_EXTRA 10743 "ex_extra", 10744 #endif 10745 #ifdef FEAT_SEARCH_EXTRA 10746 "extra_search", 10747 #endif 10748 #ifdef FEAT_FKMAP 10749 "farsi", 10750 #endif 10751 #ifdef FEAT_SEARCHPATH 10752 "file_in_path", 10753 #endif 10754 #if defined(UNIX) && !defined(USE_SYSTEM) 10755 "filterpipe", 10756 #endif 10757 #ifdef FEAT_FIND_ID 10758 "find_in_path", 10759 #endif 10760 #ifdef FEAT_FOLDING 10761 "folding", 10762 #endif 10763 #ifdef FEAT_FOOTER 10764 "footer", 10765 #endif 10766 #if !defined(USE_SYSTEM) && defined(UNIX) 10767 "fork", 10768 #endif 10769 #ifdef FEAT_GETTEXT 10770 "gettext", 10771 #endif 10772 #ifdef FEAT_GUI 10773 "gui", 10774 #endif 10775 #ifdef FEAT_GUI_ATHENA 10776 # ifdef FEAT_GUI_NEXTAW 10777 "gui_neXtaw", 10778 # else 10779 "gui_athena", 10780 # endif 10781 #endif 10782 #ifdef FEAT_GUI_GTK 10783 "gui_gtk", 10784 # ifdef HAVE_GTK2 10785 "gui_gtk2", 10786 # endif 10787 #endif 10788 #ifdef FEAT_GUI_MAC 10789 "gui_mac", 10790 #endif 10791 #ifdef FEAT_GUI_MOTIF 10792 "gui_motif", 10793 #endif 10794 #ifdef FEAT_GUI_PHOTON 10795 "gui_photon", 10796 #endif 10797 #ifdef FEAT_GUI_W16 10798 "gui_win16", 10799 #endif 10800 #ifdef FEAT_GUI_W32 10801 "gui_win32", 10802 #endif 10803 #ifdef FEAT_HANGULIN 10804 "hangul_input", 10805 #endif 10806 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10807 "iconv", 10808 #endif 10809 #ifdef FEAT_INS_EXPAND 10810 "insert_expand", 10811 #endif 10812 #ifdef FEAT_JUMPLIST 10813 "jumplist", 10814 #endif 10815 #ifdef FEAT_KEYMAP 10816 "keymap", 10817 #endif 10818 #ifdef FEAT_LANGMAP 10819 "langmap", 10820 #endif 10821 #ifdef FEAT_LIBCALL 10822 "libcall", 10823 #endif 10824 #ifdef FEAT_LINEBREAK 10825 "linebreak", 10826 #endif 10827 #ifdef FEAT_LISP 10828 "lispindent", 10829 #endif 10830 #ifdef FEAT_LISTCMDS 10831 "listcmds", 10832 #endif 10833 #ifdef FEAT_LOCALMAP 10834 "localmap", 10835 #endif 10836 #ifdef FEAT_MENU 10837 "menu", 10838 #endif 10839 #ifdef FEAT_SESSION 10840 "mksession", 10841 #endif 10842 #ifdef FEAT_MODIFY_FNAME 10843 "modify_fname", 10844 #endif 10845 #ifdef FEAT_MOUSE 10846 "mouse", 10847 #endif 10848 #ifdef FEAT_MOUSESHAPE 10849 "mouseshape", 10850 #endif 10851 #if defined(UNIX) || defined(VMS) 10852 # ifdef FEAT_MOUSE_DEC 10853 "mouse_dec", 10854 # endif 10855 # ifdef FEAT_MOUSE_GPM 10856 "mouse_gpm", 10857 # endif 10858 # ifdef FEAT_MOUSE_JSB 10859 "mouse_jsbterm", 10860 # endif 10861 # ifdef FEAT_MOUSE_NET 10862 "mouse_netterm", 10863 # endif 10864 # ifdef FEAT_MOUSE_PTERM 10865 "mouse_pterm", 10866 # endif 10867 # ifdef FEAT_MOUSE_XTERM 10868 "mouse_xterm", 10869 # endif 10870 #endif 10871 #ifdef FEAT_MBYTE 10872 "multi_byte", 10873 #endif 10874 #ifdef FEAT_MBYTE_IME 10875 "multi_byte_ime", 10876 #endif 10877 #ifdef FEAT_MULTI_LANG 10878 "multi_lang", 10879 #endif 10880 #ifdef FEAT_MZSCHEME 10881 #ifndef DYNAMIC_MZSCHEME 10882 "mzscheme", 10883 #endif 10884 #endif 10885 #ifdef FEAT_OLE 10886 "ole", 10887 #endif 10888 #ifdef FEAT_OSFILETYPE 10889 "osfiletype", 10890 #endif 10891 #ifdef FEAT_PATH_EXTRA 10892 "path_extra", 10893 #endif 10894 #ifdef FEAT_PERL 10895 #ifndef DYNAMIC_PERL 10896 "perl", 10897 #endif 10898 #endif 10899 #ifdef FEAT_PYTHON 10900 #ifndef DYNAMIC_PYTHON 10901 "python", 10902 #endif 10903 #endif 10904 #ifdef FEAT_POSTSCRIPT 10905 "postscript", 10906 #endif 10907 #ifdef FEAT_PRINTER 10908 "printer", 10909 #endif 10910 #ifdef FEAT_PROFILE 10911 "profile", 10912 #endif 10913 #ifdef FEAT_RELTIME 10914 "reltime", 10915 #endif 10916 #ifdef FEAT_QUICKFIX 10917 "quickfix", 10918 #endif 10919 #ifdef FEAT_RIGHTLEFT 10920 "rightleft", 10921 #endif 10922 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10923 "ruby", 10924 #endif 10925 #ifdef FEAT_SCROLLBIND 10926 "scrollbind", 10927 #endif 10928 #ifdef FEAT_CMDL_INFO 10929 "showcmd", 10930 "cmdline_info", 10931 #endif 10932 #ifdef FEAT_SIGNS 10933 "signs", 10934 #endif 10935 #ifdef FEAT_SMARTINDENT 10936 "smartindent", 10937 #endif 10938 #ifdef FEAT_SNIFF 10939 "sniff", 10940 #endif 10941 #ifdef FEAT_STL_OPT 10942 "statusline", 10943 #endif 10944 #ifdef FEAT_SUN_WORKSHOP 10945 "sun_workshop", 10946 #endif 10947 #ifdef FEAT_NETBEANS_INTG 10948 "netbeans_intg", 10949 #endif 10950 #ifdef FEAT_SPELL 10951 "spell", 10952 #endif 10953 #ifdef FEAT_SYN_HL 10954 "syntax", 10955 #endif 10956 #if defined(USE_SYSTEM) || !defined(UNIX) 10957 "system", 10958 #endif 10959 #ifdef FEAT_TAG_BINS 10960 "tag_binary", 10961 #endif 10962 #ifdef FEAT_TAG_OLDSTATIC 10963 "tag_old_static", 10964 #endif 10965 #ifdef FEAT_TAG_ANYWHITE 10966 "tag_any_white", 10967 #endif 10968 #ifdef FEAT_TCL 10969 # ifndef DYNAMIC_TCL 10970 "tcl", 10971 # endif 10972 #endif 10973 #ifdef TERMINFO 10974 "terminfo", 10975 #endif 10976 #ifdef FEAT_TERMRESPONSE 10977 "termresponse", 10978 #endif 10979 #ifdef FEAT_TEXTOBJ 10980 "textobjects", 10981 #endif 10982 #ifdef HAVE_TGETENT 10983 "tgetent", 10984 #endif 10985 #ifdef FEAT_TITLE 10986 "title", 10987 #endif 10988 #ifdef FEAT_TOOLBAR 10989 "toolbar", 10990 #endif 10991 #ifdef FEAT_USR_CMDS 10992 "user-commands", /* was accidentally included in 5.4 */ 10993 "user_commands", 10994 #endif 10995 #ifdef FEAT_VIMINFO 10996 "viminfo", 10997 #endif 10998 #ifdef FEAT_VERTSPLIT 10999 "vertsplit", 11000 #endif 11001 #ifdef FEAT_VIRTUALEDIT 11002 "virtualedit", 11003 #endif 11004 #ifdef FEAT_VISUAL 11005 "visual", 11006 #endif 11007 #ifdef FEAT_VISUALEXTRA 11008 "visualextra", 11009 #endif 11010 #ifdef FEAT_VREPLACE 11011 "vreplace", 11012 #endif 11013 #ifdef FEAT_WILDIGN 11014 "wildignore", 11015 #endif 11016 #ifdef FEAT_WILDMENU 11017 "wildmenu", 11018 #endif 11019 #ifdef FEAT_WINDOWS 11020 "windows", 11021 #endif 11022 #ifdef FEAT_WAK 11023 "winaltkeys", 11024 #endif 11025 #ifdef FEAT_WRITEBACKUP 11026 "writebackup", 11027 #endif 11028 #ifdef FEAT_XIM 11029 "xim", 11030 #endif 11031 #ifdef FEAT_XFONTSET 11032 "xfontset", 11033 #endif 11034 #ifdef USE_XSMP 11035 "xsmp", 11036 #endif 11037 #ifdef USE_XSMP_INTERACT 11038 "xsmp_interact", 11039 #endif 11040 #ifdef FEAT_XCLIPBOARD 11041 "xterm_clipboard", 11042 #endif 11043 #ifdef FEAT_XTERM_SAVE 11044 "xterm_save", 11045 #endif 11046 #if defined(UNIX) && defined(FEAT_X11) 11047 "X11", 11048 #endif 11049 NULL 11050 }; 11051 11052 name = get_tv_string(&argvars[0]); 11053 for (i = 0; has_list[i] != NULL; ++i) 11054 if (STRICMP(name, has_list[i]) == 0) 11055 { 11056 n = TRUE; 11057 break; 11058 } 11059 11060 if (n == FALSE) 11061 { 11062 if (STRNICMP(name, "patch", 5) == 0) 11063 n = has_patch(atoi((char *)name + 5)); 11064 else if (STRICMP(name, "vim_starting") == 0) 11065 n = (starting != 0); 11066 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 11067 else if (STRICMP(name, "balloon_multiline") == 0) 11068 n = multiline_balloon_available(); 11069 #endif 11070 #ifdef DYNAMIC_TCL 11071 else if (STRICMP(name, "tcl") == 0) 11072 n = tcl_enabled(FALSE); 11073 #endif 11074 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 11075 else if (STRICMP(name, "iconv") == 0) 11076 n = iconv_enabled(FALSE); 11077 #endif 11078 #ifdef DYNAMIC_MZSCHEME 11079 else if (STRICMP(name, "mzscheme") == 0) 11080 n = mzscheme_enabled(FALSE); 11081 #endif 11082 #ifdef DYNAMIC_RUBY 11083 else if (STRICMP(name, "ruby") == 0) 11084 n = ruby_enabled(FALSE); 11085 #endif 11086 #ifdef DYNAMIC_PYTHON 11087 else if (STRICMP(name, "python") == 0) 11088 n = python_enabled(FALSE); 11089 #endif 11090 #ifdef DYNAMIC_PERL 11091 else if (STRICMP(name, "perl") == 0) 11092 n = perl_enabled(FALSE); 11093 #endif 11094 #ifdef FEAT_GUI 11095 else if (STRICMP(name, "gui_running") == 0) 11096 n = (gui.in_use || gui.starting); 11097 # ifdef FEAT_GUI_W32 11098 else if (STRICMP(name, "gui_win32s") == 0) 11099 n = gui_is_win32s(); 11100 # endif 11101 # ifdef FEAT_BROWSE 11102 else if (STRICMP(name, "browse") == 0) 11103 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 11104 # endif 11105 #endif 11106 #ifdef FEAT_SYN_HL 11107 else if (STRICMP(name, "syntax_items") == 0) 11108 n = syntax_present(curbuf); 11109 #endif 11110 #if defined(WIN3264) 11111 else if (STRICMP(name, "win95") == 0) 11112 n = mch_windows95(); 11113 #endif 11114 #ifdef FEAT_NETBEANS_INTG 11115 else if (STRICMP(name, "netbeans_enabled") == 0) 11116 n = usingNetbeans; 11117 #endif 11118 } 11119 11120 rettv->vval.v_number = n; 11121 } 11122 11123 /* 11124 * "has_key()" function 11125 */ 11126 static void 11127 f_has_key(argvars, rettv) 11128 typval_T *argvars; 11129 typval_T *rettv; 11130 { 11131 rettv->vval.v_number = 0; 11132 if (argvars[0].v_type != VAR_DICT) 11133 { 11134 EMSG(_(e_dictreq)); 11135 return; 11136 } 11137 if (argvars[0].vval.v_dict == NULL) 11138 return; 11139 11140 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 11141 get_tv_string(&argvars[1]), -1) != NULL; 11142 } 11143 11144 /* 11145 * "haslocaldir()" function 11146 */ 11147 /*ARGSUSED*/ 11148 static void 11149 f_haslocaldir(argvars, rettv) 11150 typval_T *argvars; 11151 typval_T *rettv; 11152 { 11153 rettv->vval.v_number = (curwin->w_localdir != NULL); 11154 } 11155 11156 /* 11157 * "hasmapto()" function 11158 */ 11159 static void 11160 f_hasmapto(argvars, rettv) 11161 typval_T *argvars; 11162 typval_T *rettv; 11163 { 11164 char_u *name; 11165 char_u *mode; 11166 char_u buf[NUMBUFLEN]; 11167 int abbr = FALSE; 11168 11169 name = get_tv_string(&argvars[0]); 11170 if (argvars[1].v_type == VAR_UNKNOWN) 11171 mode = (char_u *)"nvo"; 11172 else 11173 { 11174 mode = get_tv_string_buf(&argvars[1], buf); 11175 if (argvars[2].v_type != VAR_UNKNOWN) 11176 abbr = get_tv_number(&argvars[2]); 11177 } 11178 11179 if (map_to_exists(name, mode, abbr)) 11180 rettv->vval.v_number = TRUE; 11181 else 11182 rettv->vval.v_number = FALSE; 11183 } 11184 11185 /* 11186 * "histadd()" function 11187 */ 11188 /*ARGSUSED*/ 11189 static void 11190 f_histadd(argvars, rettv) 11191 typval_T *argvars; 11192 typval_T *rettv; 11193 { 11194 #ifdef FEAT_CMDHIST 11195 int histype; 11196 char_u *str; 11197 char_u buf[NUMBUFLEN]; 11198 #endif 11199 11200 rettv->vval.v_number = FALSE; 11201 if (check_restricted() || check_secure()) 11202 return; 11203 #ifdef FEAT_CMDHIST 11204 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11205 histype = str != NULL ? get_histtype(str) : -1; 11206 if (histype >= 0) 11207 { 11208 str = get_tv_string_buf(&argvars[1], buf); 11209 if (*str != NUL) 11210 { 11211 add_to_history(histype, str, FALSE, NUL); 11212 rettv->vval.v_number = TRUE; 11213 return; 11214 } 11215 } 11216 #endif 11217 } 11218 11219 /* 11220 * "histdel()" function 11221 */ 11222 /*ARGSUSED*/ 11223 static void 11224 f_histdel(argvars, rettv) 11225 typval_T *argvars; 11226 typval_T *rettv; 11227 { 11228 #ifdef FEAT_CMDHIST 11229 int n; 11230 char_u buf[NUMBUFLEN]; 11231 char_u *str; 11232 11233 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11234 if (str == NULL) 11235 n = 0; 11236 else if (argvars[1].v_type == VAR_UNKNOWN) 11237 /* only one argument: clear entire history */ 11238 n = clr_history(get_histtype(str)); 11239 else if (argvars[1].v_type == VAR_NUMBER) 11240 /* index given: remove that entry */ 11241 n = del_history_idx(get_histtype(str), 11242 (int)get_tv_number(&argvars[1])); 11243 else 11244 /* string given: remove all matching entries */ 11245 n = del_history_entry(get_histtype(str), 11246 get_tv_string_buf(&argvars[1], buf)); 11247 rettv->vval.v_number = n; 11248 #else 11249 rettv->vval.v_number = 0; 11250 #endif 11251 } 11252 11253 /* 11254 * "histget()" function 11255 */ 11256 /*ARGSUSED*/ 11257 static void 11258 f_histget(argvars, rettv) 11259 typval_T *argvars; 11260 typval_T *rettv; 11261 { 11262 #ifdef FEAT_CMDHIST 11263 int type; 11264 int idx; 11265 char_u *str; 11266 11267 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 11268 if (str == NULL) 11269 rettv->vval.v_string = NULL; 11270 else 11271 { 11272 type = get_histtype(str); 11273 if (argvars[1].v_type == VAR_UNKNOWN) 11274 idx = get_history_idx(type); 11275 else 11276 idx = (int)get_tv_number_chk(&argvars[1], NULL); 11277 /* -1 on type error */ 11278 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 11279 } 11280 #else 11281 rettv->vval.v_string = NULL; 11282 #endif 11283 rettv->v_type = VAR_STRING; 11284 } 11285 11286 /* 11287 * "histnr()" function 11288 */ 11289 /*ARGSUSED*/ 11290 static void 11291 f_histnr(argvars, rettv) 11292 typval_T *argvars; 11293 typval_T *rettv; 11294 { 11295 int i; 11296 11297 #ifdef FEAT_CMDHIST 11298 char_u *history = get_tv_string_chk(&argvars[0]); 11299 11300 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 11301 if (i >= HIST_CMD && i < HIST_COUNT) 11302 i = get_history_idx(i); 11303 else 11304 #endif 11305 i = -1; 11306 rettv->vval.v_number = i; 11307 } 11308 11309 /* 11310 * "highlightID(name)" function 11311 */ 11312 static void 11313 f_hlID(argvars, rettv) 11314 typval_T *argvars; 11315 typval_T *rettv; 11316 { 11317 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 11318 } 11319 11320 /* 11321 * "highlight_exists()" function 11322 */ 11323 static void 11324 f_hlexists(argvars, rettv) 11325 typval_T *argvars; 11326 typval_T *rettv; 11327 { 11328 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 11329 } 11330 11331 /* 11332 * "hostname()" function 11333 */ 11334 /*ARGSUSED*/ 11335 static void 11336 f_hostname(argvars, rettv) 11337 typval_T *argvars; 11338 typval_T *rettv; 11339 { 11340 char_u hostname[256]; 11341 11342 mch_get_host_name(hostname, 256); 11343 rettv->v_type = VAR_STRING; 11344 rettv->vval.v_string = vim_strsave(hostname); 11345 } 11346 11347 /* 11348 * iconv() function 11349 */ 11350 /*ARGSUSED*/ 11351 static void 11352 f_iconv(argvars, rettv) 11353 typval_T *argvars; 11354 typval_T *rettv; 11355 { 11356 #ifdef FEAT_MBYTE 11357 char_u buf1[NUMBUFLEN]; 11358 char_u buf2[NUMBUFLEN]; 11359 char_u *from, *to, *str; 11360 vimconv_T vimconv; 11361 #endif 11362 11363 rettv->v_type = VAR_STRING; 11364 rettv->vval.v_string = NULL; 11365 11366 #ifdef FEAT_MBYTE 11367 str = get_tv_string(&argvars[0]); 11368 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 11369 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 11370 vimconv.vc_type = CONV_NONE; 11371 convert_setup(&vimconv, from, to); 11372 11373 /* If the encodings are equal, no conversion needed. */ 11374 if (vimconv.vc_type == CONV_NONE) 11375 rettv->vval.v_string = vim_strsave(str); 11376 else 11377 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 11378 11379 convert_setup(&vimconv, NULL, NULL); 11380 vim_free(from); 11381 vim_free(to); 11382 #endif 11383 } 11384 11385 /* 11386 * "indent()" function 11387 */ 11388 static void 11389 f_indent(argvars, rettv) 11390 typval_T *argvars; 11391 typval_T *rettv; 11392 { 11393 linenr_T lnum; 11394 11395 lnum = get_tv_lnum(argvars); 11396 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11397 rettv->vval.v_number = get_indent_lnum(lnum); 11398 else 11399 rettv->vval.v_number = -1; 11400 } 11401 11402 /* 11403 * "index()" function 11404 */ 11405 static void 11406 f_index(argvars, rettv) 11407 typval_T *argvars; 11408 typval_T *rettv; 11409 { 11410 list_T *l; 11411 listitem_T *item; 11412 long idx = 0; 11413 int ic = FALSE; 11414 11415 rettv->vval.v_number = -1; 11416 if (argvars[0].v_type != VAR_LIST) 11417 { 11418 EMSG(_(e_listreq)); 11419 return; 11420 } 11421 l = argvars[0].vval.v_list; 11422 if (l != NULL) 11423 { 11424 item = l->lv_first; 11425 if (argvars[2].v_type != VAR_UNKNOWN) 11426 { 11427 int error = FALSE; 11428 11429 /* Start at specified item. Use the cached index that list_find() 11430 * sets, so that a negative number also works. */ 11431 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 11432 idx = l->lv_idx; 11433 if (argvars[3].v_type != VAR_UNKNOWN) 11434 ic = get_tv_number_chk(&argvars[3], &error); 11435 if (error) 11436 item = NULL; 11437 } 11438 11439 for ( ; item != NULL; item = item->li_next, ++idx) 11440 if (tv_equal(&item->li_tv, &argvars[1], ic)) 11441 { 11442 rettv->vval.v_number = idx; 11443 break; 11444 } 11445 } 11446 } 11447 11448 static int inputsecret_flag = 0; 11449 11450 static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog)); 11451 11452 /* 11453 * This function is used by f_input() and f_inputdialog() functions. The third 11454 * argument to f_input() specifies the type of completion to use at the 11455 * prompt. The third argument to f_inputdialog() specifies the value to return 11456 * when the user cancels the prompt. 11457 */ 11458 static void 11459 get_user_input(argvars, rettv, inputdialog) 11460 typval_T *argvars; 11461 typval_T *rettv; 11462 int inputdialog; 11463 { 11464 char_u *prompt = get_tv_string_chk(&argvars[0]); 11465 char_u *p = NULL; 11466 int c; 11467 char_u buf[NUMBUFLEN]; 11468 int cmd_silent_save = cmd_silent; 11469 char_u *defstr = (char_u *)""; 11470 int xp_type = EXPAND_NOTHING; 11471 char_u *xp_arg = NULL; 11472 11473 rettv->v_type = VAR_STRING; 11474 11475 #ifdef NO_CONSOLE_INPUT 11476 /* While starting up, there is no place to enter text. */ 11477 if (no_console_input()) 11478 { 11479 rettv->vval.v_string = NULL; 11480 return; 11481 } 11482 #endif 11483 11484 cmd_silent = FALSE; /* Want to see the prompt. */ 11485 if (prompt != NULL) 11486 { 11487 /* Only the part of the message after the last NL is considered as 11488 * prompt for the command line */ 11489 p = vim_strrchr(prompt, '\n'); 11490 if (p == NULL) 11491 p = prompt; 11492 else 11493 { 11494 ++p; 11495 c = *p; 11496 *p = NUL; 11497 msg_start(); 11498 msg_clr_eos(); 11499 msg_puts_attr(prompt, echo_attr); 11500 msg_didout = FALSE; 11501 msg_starthere(); 11502 *p = c; 11503 } 11504 cmdline_row = msg_row; 11505 11506 if (argvars[1].v_type != VAR_UNKNOWN) 11507 { 11508 defstr = get_tv_string_buf_chk(&argvars[1], buf); 11509 if (defstr != NULL) 11510 stuffReadbuffSpec(defstr); 11511 11512 if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) 11513 { 11514 char_u *xp_name; 11515 int xp_namelen; 11516 long argt; 11517 11518 rettv->vval.v_string = NULL; 11519 11520 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 11521 if (xp_name == NULL) 11522 return; 11523 11524 xp_namelen = (int)STRLEN(xp_name); 11525 11526 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, 11527 &xp_arg) == FAIL) 11528 return; 11529 } 11530 } 11531 11532 if (defstr != NULL) 11533 rettv->vval.v_string = 11534 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 11535 xp_type, xp_arg); 11536 11537 vim_free(xp_arg); 11538 11539 /* since the user typed this, no need to wait for return */ 11540 need_wait_return = FALSE; 11541 msg_didout = FALSE; 11542 } 11543 cmd_silent = cmd_silent_save; 11544 } 11545 11546 /* 11547 * "input()" function 11548 * Also handles inputsecret() when inputsecret is set. 11549 */ 11550 static void 11551 f_input(argvars, rettv) 11552 typval_T *argvars; 11553 typval_T *rettv; 11554 { 11555 get_user_input(argvars, rettv, FALSE); 11556 } 11557 11558 /* 11559 * "inputdialog()" function 11560 */ 11561 static void 11562 f_inputdialog(argvars, rettv) 11563 typval_T *argvars; 11564 typval_T *rettv; 11565 { 11566 #if defined(FEAT_GUI_TEXTDIALOG) 11567 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 11568 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 11569 { 11570 char_u *message; 11571 char_u buf[NUMBUFLEN]; 11572 char_u *defstr = (char_u *)""; 11573 11574 message = get_tv_string_chk(&argvars[0]); 11575 if (argvars[1].v_type != VAR_UNKNOWN 11576 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 11577 vim_strncpy(IObuff, defstr, IOSIZE - 1); 11578 else 11579 IObuff[0] = NUL; 11580 if (message != NULL && defstr != NULL 11581 && do_dialog(VIM_QUESTION, NULL, message, 11582 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 11583 rettv->vval.v_string = vim_strsave(IObuff); 11584 else 11585 { 11586 if (message != NULL && defstr != NULL 11587 && argvars[1].v_type != VAR_UNKNOWN 11588 && argvars[2].v_type != VAR_UNKNOWN) 11589 rettv->vval.v_string = vim_strsave( 11590 get_tv_string_buf(&argvars[2], buf)); 11591 else 11592 rettv->vval.v_string = NULL; 11593 } 11594 rettv->v_type = VAR_STRING; 11595 } 11596 else 11597 #endif 11598 get_user_input(argvars, rettv, TRUE); 11599 } 11600 11601 /* 11602 * "inputlist()" function 11603 */ 11604 static void 11605 f_inputlist(argvars, rettv) 11606 typval_T *argvars; 11607 typval_T *rettv; 11608 { 11609 listitem_T *li; 11610 int selected; 11611 int mouse_used; 11612 11613 rettv->vval.v_number = 0; 11614 #ifdef NO_CONSOLE_INPUT 11615 /* While starting up, there is no place to enter text. */ 11616 if (no_console_input()) 11617 return; 11618 #endif 11619 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 11620 { 11621 EMSG2(_(e_listarg), "inputlist()"); 11622 return; 11623 } 11624 11625 msg_start(); 11626 msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ 11627 lines_left = Rows; /* avoid more prompt */ 11628 msg_scroll = TRUE; 11629 msg_clr_eos(); 11630 11631 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 11632 { 11633 msg_puts(get_tv_string(&li->li_tv)); 11634 msg_putchar('\n'); 11635 } 11636 11637 /* Ask for choice. */ 11638 selected = prompt_for_number(&mouse_used); 11639 if (mouse_used) 11640 selected -= lines_left; 11641 11642 rettv->vval.v_number = selected; 11643 } 11644 11645 11646 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 11647 11648 /* 11649 * "inputrestore()" function 11650 */ 11651 /*ARGSUSED*/ 11652 static void 11653 f_inputrestore(argvars, rettv) 11654 typval_T *argvars; 11655 typval_T *rettv; 11656 { 11657 if (ga_userinput.ga_len > 0) 11658 { 11659 --ga_userinput.ga_len; 11660 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 11661 + ga_userinput.ga_len); 11662 rettv->vval.v_number = 0; /* OK */ 11663 } 11664 else if (p_verbose > 1) 11665 { 11666 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11667 rettv->vval.v_number = 1; /* Failed */ 11668 } 11669 } 11670 11671 /* 11672 * "inputsave()" function 11673 */ 11674 /*ARGSUSED*/ 11675 static void 11676 f_inputsave(argvars, rettv) 11677 typval_T *argvars; 11678 typval_T *rettv; 11679 { 11680 /* Add an entry to the stack of typehead storage. */ 11681 if (ga_grow(&ga_userinput, 1) == OK) 11682 { 11683 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11684 + ga_userinput.ga_len); 11685 ++ga_userinput.ga_len; 11686 rettv->vval.v_number = 0; /* OK */ 11687 } 11688 else 11689 rettv->vval.v_number = 1; /* Failed */ 11690 } 11691 11692 /* 11693 * "inputsecret()" function 11694 */ 11695 static void 11696 f_inputsecret(argvars, rettv) 11697 typval_T *argvars; 11698 typval_T *rettv; 11699 { 11700 ++cmdline_star; 11701 ++inputsecret_flag; 11702 f_input(argvars, rettv); 11703 --cmdline_star; 11704 --inputsecret_flag; 11705 } 11706 11707 /* 11708 * "insert()" function 11709 */ 11710 static void 11711 f_insert(argvars, rettv) 11712 typval_T *argvars; 11713 typval_T *rettv; 11714 { 11715 long before = 0; 11716 listitem_T *item; 11717 list_T *l; 11718 int error = FALSE; 11719 11720 rettv->vval.v_number = 0; 11721 if (argvars[0].v_type != VAR_LIST) 11722 EMSG2(_(e_listarg), "insert()"); 11723 else if ((l = argvars[0].vval.v_list) != NULL 11724 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11725 { 11726 if (argvars[2].v_type != VAR_UNKNOWN) 11727 before = get_tv_number_chk(&argvars[2], &error); 11728 if (error) 11729 return; /* type error; errmsg already given */ 11730 11731 if (before == l->lv_len) 11732 item = NULL; 11733 else 11734 { 11735 item = list_find(l, before); 11736 if (item == NULL) 11737 { 11738 EMSGN(_(e_listidx), before); 11739 l = NULL; 11740 } 11741 } 11742 if (l != NULL) 11743 { 11744 list_insert_tv(l, &argvars[1], item); 11745 copy_tv(&argvars[0], rettv); 11746 } 11747 } 11748 } 11749 11750 /* 11751 * "isdirectory()" function 11752 */ 11753 static void 11754 f_isdirectory(argvars, rettv) 11755 typval_T *argvars; 11756 typval_T *rettv; 11757 { 11758 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11759 } 11760 11761 /* 11762 * "islocked()" function 11763 */ 11764 static void 11765 f_islocked(argvars, rettv) 11766 typval_T *argvars; 11767 typval_T *rettv; 11768 { 11769 lval_T lv; 11770 char_u *end; 11771 dictitem_T *di; 11772 11773 rettv->vval.v_number = -1; 11774 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11775 FNE_CHECK_START); 11776 if (end != NULL && lv.ll_name != NULL) 11777 { 11778 if (*end != NUL) 11779 EMSG(_(e_trailing)); 11780 else 11781 { 11782 if (lv.ll_tv == NULL) 11783 { 11784 if (check_changedtick(lv.ll_name)) 11785 rettv->vval.v_number = 1; /* always locked */ 11786 else 11787 { 11788 di = find_var(lv.ll_name, NULL); 11789 if (di != NULL) 11790 { 11791 /* Consider a variable locked when: 11792 * 1. the variable itself is locked 11793 * 2. the value of the variable is locked. 11794 * 3. the List or Dict value is locked. 11795 */ 11796 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11797 || tv_islocked(&di->di_tv)); 11798 } 11799 } 11800 } 11801 else if (lv.ll_range) 11802 EMSG(_("E786: Range not allowed")); 11803 else if (lv.ll_newkey != NULL) 11804 EMSG2(_(e_dictkey), lv.ll_newkey); 11805 else if (lv.ll_list != NULL) 11806 /* List item. */ 11807 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11808 else 11809 /* Dictionary item. */ 11810 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11811 } 11812 } 11813 11814 clear_lval(&lv); 11815 } 11816 11817 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11818 11819 /* 11820 * Turn a dict into a list: 11821 * "what" == 0: list of keys 11822 * "what" == 1: list of values 11823 * "what" == 2: list of items 11824 */ 11825 static void 11826 dict_list(argvars, rettv, what) 11827 typval_T *argvars; 11828 typval_T *rettv; 11829 int what; 11830 { 11831 list_T *l2; 11832 dictitem_T *di; 11833 hashitem_T *hi; 11834 listitem_T *li; 11835 listitem_T *li2; 11836 dict_T *d; 11837 int todo; 11838 11839 rettv->vval.v_number = 0; 11840 if (argvars[0].v_type != VAR_DICT) 11841 { 11842 EMSG(_(e_dictreq)); 11843 return; 11844 } 11845 if ((d = argvars[0].vval.v_dict) == NULL) 11846 return; 11847 11848 if (rettv_list_alloc(rettv) == FAIL) 11849 return; 11850 11851 todo = (int)d->dv_hashtab.ht_used; 11852 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11853 { 11854 if (!HASHITEM_EMPTY(hi)) 11855 { 11856 --todo; 11857 di = HI2DI(hi); 11858 11859 li = listitem_alloc(); 11860 if (li == NULL) 11861 break; 11862 list_append(rettv->vval.v_list, li); 11863 11864 if (what == 0) 11865 { 11866 /* keys() */ 11867 li->li_tv.v_type = VAR_STRING; 11868 li->li_tv.v_lock = 0; 11869 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11870 } 11871 else if (what == 1) 11872 { 11873 /* values() */ 11874 copy_tv(&di->di_tv, &li->li_tv); 11875 } 11876 else 11877 { 11878 /* items() */ 11879 l2 = list_alloc(); 11880 li->li_tv.v_type = VAR_LIST; 11881 li->li_tv.v_lock = 0; 11882 li->li_tv.vval.v_list = l2; 11883 if (l2 == NULL) 11884 break; 11885 ++l2->lv_refcount; 11886 11887 li2 = listitem_alloc(); 11888 if (li2 == NULL) 11889 break; 11890 list_append(l2, li2); 11891 li2->li_tv.v_type = VAR_STRING; 11892 li2->li_tv.v_lock = 0; 11893 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11894 11895 li2 = listitem_alloc(); 11896 if (li2 == NULL) 11897 break; 11898 list_append(l2, li2); 11899 copy_tv(&di->di_tv, &li2->li_tv); 11900 } 11901 } 11902 } 11903 } 11904 11905 /* 11906 * "items(dict)" function 11907 */ 11908 static void 11909 f_items(argvars, rettv) 11910 typval_T *argvars; 11911 typval_T *rettv; 11912 { 11913 dict_list(argvars, rettv, 2); 11914 } 11915 11916 /* 11917 * "join()" function 11918 */ 11919 static void 11920 f_join(argvars, rettv) 11921 typval_T *argvars; 11922 typval_T *rettv; 11923 { 11924 garray_T ga; 11925 char_u *sep; 11926 11927 rettv->vval.v_number = 0; 11928 if (argvars[0].v_type != VAR_LIST) 11929 { 11930 EMSG(_(e_listreq)); 11931 return; 11932 } 11933 if (argvars[0].vval.v_list == NULL) 11934 return; 11935 if (argvars[1].v_type == VAR_UNKNOWN) 11936 sep = (char_u *)" "; 11937 else 11938 sep = get_tv_string_chk(&argvars[1]); 11939 11940 rettv->v_type = VAR_STRING; 11941 11942 if (sep != NULL) 11943 { 11944 ga_init2(&ga, (int)sizeof(char), 80); 11945 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0); 11946 ga_append(&ga, NUL); 11947 rettv->vval.v_string = (char_u *)ga.ga_data; 11948 } 11949 else 11950 rettv->vval.v_string = NULL; 11951 } 11952 11953 /* 11954 * "keys()" function 11955 */ 11956 static void 11957 f_keys(argvars, rettv) 11958 typval_T *argvars; 11959 typval_T *rettv; 11960 { 11961 dict_list(argvars, rettv, 0); 11962 } 11963 11964 /* 11965 * "last_buffer_nr()" function. 11966 */ 11967 /*ARGSUSED*/ 11968 static void 11969 f_last_buffer_nr(argvars, rettv) 11970 typval_T *argvars; 11971 typval_T *rettv; 11972 { 11973 int n = 0; 11974 buf_T *buf; 11975 11976 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11977 if (n < buf->b_fnum) 11978 n = buf->b_fnum; 11979 11980 rettv->vval.v_number = n; 11981 } 11982 11983 /* 11984 * "len()" function 11985 */ 11986 static void 11987 f_len(argvars, rettv) 11988 typval_T *argvars; 11989 typval_T *rettv; 11990 { 11991 switch (argvars[0].v_type) 11992 { 11993 case VAR_STRING: 11994 case VAR_NUMBER: 11995 rettv->vval.v_number = (varnumber_T)STRLEN( 11996 get_tv_string(&argvars[0])); 11997 break; 11998 case VAR_LIST: 11999 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 12000 break; 12001 case VAR_DICT: 12002 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 12003 break; 12004 default: 12005 EMSG(_("E701: Invalid type for len()")); 12006 break; 12007 } 12008 } 12009 12010 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 12011 12012 static void 12013 libcall_common(argvars, rettv, type) 12014 typval_T *argvars; 12015 typval_T *rettv; 12016 int type; 12017 { 12018 #ifdef FEAT_LIBCALL 12019 char_u *string_in; 12020 char_u **string_result; 12021 int nr_result; 12022 #endif 12023 12024 rettv->v_type = type; 12025 if (type == VAR_NUMBER) 12026 rettv->vval.v_number = 0; 12027 else 12028 rettv->vval.v_string = NULL; 12029 12030 if (check_restricted() || check_secure()) 12031 return; 12032 12033 #ifdef FEAT_LIBCALL 12034 /* The first two args must be strings, otherwise its meaningless */ 12035 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 12036 { 12037 string_in = NULL; 12038 if (argvars[2].v_type == VAR_STRING) 12039 string_in = argvars[2].vval.v_string; 12040 if (type == VAR_NUMBER) 12041 string_result = NULL; 12042 else 12043 string_result = &rettv->vval.v_string; 12044 if (mch_libcall(argvars[0].vval.v_string, 12045 argvars[1].vval.v_string, 12046 string_in, 12047 argvars[2].vval.v_number, 12048 string_result, 12049 &nr_result) == OK 12050 && type == VAR_NUMBER) 12051 rettv->vval.v_number = nr_result; 12052 } 12053 #endif 12054 } 12055 12056 /* 12057 * "libcall()" function 12058 */ 12059 static void 12060 f_libcall(argvars, rettv) 12061 typval_T *argvars; 12062 typval_T *rettv; 12063 { 12064 libcall_common(argvars, rettv, VAR_STRING); 12065 } 12066 12067 /* 12068 * "libcallnr()" function 12069 */ 12070 static void 12071 f_libcallnr(argvars, rettv) 12072 typval_T *argvars; 12073 typval_T *rettv; 12074 { 12075 libcall_common(argvars, rettv, VAR_NUMBER); 12076 } 12077 12078 /* 12079 * "line(string)" function 12080 */ 12081 static void 12082 f_line(argvars, rettv) 12083 typval_T *argvars; 12084 typval_T *rettv; 12085 { 12086 linenr_T lnum = 0; 12087 pos_T *fp; 12088 int fnum; 12089 12090 fp = var2fpos(&argvars[0], TRUE, &fnum); 12091 if (fp != NULL) 12092 lnum = fp->lnum; 12093 rettv->vval.v_number = lnum; 12094 } 12095 12096 /* 12097 * "line2byte(lnum)" function 12098 */ 12099 /*ARGSUSED*/ 12100 static void 12101 f_line2byte(argvars, rettv) 12102 typval_T *argvars; 12103 typval_T *rettv; 12104 { 12105 #ifndef FEAT_BYTEOFF 12106 rettv->vval.v_number = -1; 12107 #else 12108 linenr_T lnum; 12109 12110 lnum = get_tv_lnum(argvars); 12111 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 12112 rettv->vval.v_number = -1; 12113 else 12114 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 12115 if (rettv->vval.v_number >= 0) 12116 ++rettv->vval.v_number; 12117 #endif 12118 } 12119 12120 /* 12121 * "lispindent(lnum)" function 12122 */ 12123 static void 12124 f_lispindent(argvars, rettv) 12125 typval_T *argvars; 12126 typval_T *rettv; 12127 { 12128 #ifdef FEAT_LISP 12129 pos_T pos; 12130 linenr_T lnum; 12131 12132 pos = curwin->w_cursor; 12133 lnum = get_tv_lnum(argvars); 12134 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 12135 { 12136 curwin->w_cursor.lnum = lnum; 12137 rettv->vval.v_number = get_lisp_indent(); 12138 curwin->w_cursor = pos; 12139 } 12140 else 12141 #endif 12142 rettv->vval.v_number = -1; 12143 } 12144 12145 /* 12146 * "localtime()" function 12147 */ 12148 /*ARGSUSED*/ 12149 static void 12150 f_localtime(argvars, rettv) 12151 typval_T *argvars; 12152 typval_T *rettv; 12153 { 12154 rettv->vval.v_number = (varnumber_T)time(NULL); 12155 } 12156 12157 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 12158 12159 static void 12160 get_maparg(argvars, rettv, exact) 12161 typval_T *argvars; 12162 typval_T *rettv; 12163 int exact; 12164 { 12165 char_u *keys; 12166 char_u *which; 12167 char_u buf[NUMBUFLEN]; 12168 char_u *keys_buf = NULL; 12169 char_u *rhs; 12170 int mode; 12171 garray_T ga; 12172 int abbr = FALSE; 12173 12174 /* return empty string for failure */ 12175 rettv->v_type = VAR_STRING; 12176 rettv->vval.v_string = NULL; 12177 12178 keys = get_tv_string(&argvars[0]); 12179 if (*keys == NUL) 12180 return; 12181 12182 if (argvars[1].v_type != VAR_UNKNOWN) 12183 { 12184 which = get_tv_string_buf_chk(&argvars[1], buf); 12185 if (argvars[2].v_type != VAR_UNKNOWN) 12186 abbr = get_tv_number(&argvars[2]); 12187 } 12188 else 12189 which = (char_u *)""; 12190 if (which == NULL) 12191 return; 12192 12193 mode = get_map_mode(&which, 0); 12194 12195 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); 12196 rhs = check_map(keys, mode, exact, FALSE, abbr); 12197 vim_free(keys_buf); 12198 if (rhs != NULL) 12199 { 12200 ga_init(&ga); 12201 ga.ga_itemsize = 1; 12202 ga.ga_growsize = 40; 12203 12204 while (*rhs != NUL) 12205 ga_concat(&ga, str2special(&rhs, FALSE)); 12206 12207 ga_append(&ga, NUL); 12208 rettv->vval.v_string = (char_u *)ga.ga_data; 12209 } 12210 } 12211 12212 /* 12213 * "map()" function 12214 */ 12215 static void 12216 f_map(argvars, rettv) 12217 typval_T *argvars; 12218 typval_T *rettv; 12219 { 12220 filter_map(argvars, rettv, TRUE); 12221 } 12222 12223 /* 12224 * "maparg()" function 12225 */ 12226 static void 12227 f_maparg(argvars, rettv) 12228 typval_T *argvars; 12229 typval_T *rettv; 12230 { 12231 get_maparg(argvars, rettv, TRUE); 12232 } 12233 12234 /* 12235 * "mapcheck()" function 12236 */ 12237 static void 12238 f_mapcheck(argvars, rettv) 12239 typval_T *argvars; 12240 typval_T *rettv; 12241 { 12242 get_maparg(argvars, rettv, FALSE); 12243 } 12244 12245 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 12246 12247 static void 12248 find_some_match(argvars, rettv, type) 12249 typval_T *argvars; 12250 typval_T *rettv; 12251 int type; 12252 { 12253 char_u *str = NULL; 12254 char_u *expr = NULL; 12255 char_u *pat; 12256 regmatch_T regmatch; 12257 char_u patbuf[NUMBUFLEN]; 12258 char_u strbuf[NUMBUFLEN]; 12259 char_u *save_cpo; 12260 long start = 0; 12261 long nth = 1; 12262 colnr_T startcol = 0; 12263 int match = 0; 12264 list_T *l = NULL; 12265 listitem_T *li = NULL; 12266 long idx = 0; 12267 char_u *tofree = NULL; 12268 12269 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 12270 save_cpo = p_cpo; 12271 p_cpo = (char_u *)""; 12272 12273 rettv->vval.v_number = -1; 12274 if (type == 3) 12275 { 12276 /* return empty list when there are no matches */ 12277 if (rettv_list_alloc(rettv) == FAIL) 12278 goto theend; 12279 } 12280 else if (type == 2) 12281 { 12282 rettv->v_type = VAR_STRING; 12283 rettv->vval.v_string = NULL; 12284 } 12285 12286 if (argvars[0].v_type == VAR_LIST) 12287 { 12288 if ((l = argvars[0].vval.v_list) == NULL) 12289 goto theend; 12290 li = l->lv_first; 12291 } 12292 else 12293 expr = str = get_tv_string(&argvars[0]); 12294 12295 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 12296 if (pat == NULL) 12297 goto theend; 12298 12299 if (argvars[2].v_type != VAR_UNKNOWN) 12300 { 12301 int error = FALSE; 12302 12303 start = get_tv_number_chk(&argvars[2], &error); 12304 if (error) 12305 goto theend; 12306 if (l != NULL) 12307 { 12308 li = list_find(l, start); 12309 if (li == NULL) 12310 goto theend; 12311 idx = l->lv_idx; /* use the cached index */ 12312 } 12313 else 12314 { 12315 if (start < 0) 12316 start = 0; 12317 if (start > (long)STRLEN(str)) 12318 goto theend; 12319 /* When "count" argument is there ignore matches before "start", 12320 * otherwise skip part of the string. Differs when pattern is "^" 12321 * or "\<". */ 12322 if (argvars[3].v_type != VAR_UNKNOWN) 12323 startcol = start; 12324 else 12325 str += start; 12326 } 12327 12328 if (argvars[3].v_type != VAR_UNKNOWN) 12329 nth = get_tv_number_chk(&argvars[3], &error); 12330 if (error) 12331 goto theend; 12332 } 12333 12334 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 12335 if (regmatch.regprog != NULL) 12336 { 12337 regmatch.rm_ic = p_ic; 12338 12339 for (;;) 12340 { 12341 if (l != NULL) 12342 { 12343 if (li == NULL) 12344 { 12345 match = FALSE; 12346 break; 12347 } 12348 vim_free(tofree); 12349 str = echo_string(&li->li_tv, &tofree, strbuf, 0); 12350 if (str == NULL) 12351 break; 12352 } 12353 12354 match = vim_regexec_nl(®match, str, (colnr_T)startcol); 12355 12356 if (match && --nth <= 0) 12357 break; 12358 if (l == NULL && !match) 12359 break; 12360 12361 /* Advance to just after the match. */ 12362 if (l != NULL) 12363 { 12364 li = li->li_next; 12365 ++idx; 12366 } 12367 else 12368 { 12369 #ifdef FEAT_MBYTE 12370 startcol = (colnr_T)(regmatch.startp[0] 12371 + (*mb_ptr2len)(regmatch.startp[0]) - str); 12372 #else 12373 startcol = regmatch.startp[0] + 1 - str; 12374 #endif 12375 } 12376 } 12377 12378 if (match) 12379 { 12380 if (type == 3) 12381 { 12382 int i; 12383 12384 /* return list with matched string and submatches */ 12385 for (i = 0; i < NSUBEXP; ++i) 12386 { 12387 if (regmatch.endp[i] == NULL) 12388 { 12389 if (list_append_string(rettv->vval.v_list, 12390 (char_u *)"", 0) == FAIL) 12391 break; 12392 } 12393 else if (list_append_string(rettv->vval.v_list, 12394 regmatch.startp[i], 12395 (int)(regmatch.endp[i] - regmatch.startp[i])) 12396 == FAIL) 12397 break; 12398 } 12399 } 12400 else if (type == 2) 12401 { 12402 /* return matched string */ 12403 if (l != NULL) 12404 copy_tv(&li->li_tv, rettv); 12405 else 12406 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 12407 (int)(regmatch.endp[0] - regmatch.startp[0])); 12408 } 12409 else if (l != NULL) 12410 rettv->vval.v_number = idx; 12411 else 12412 { 12413 if (type != 0) 12414 rettv->vval.v_number = 12415 (varnumber_T)(regmatch.startp[0] - str); 12416 else 12417 rettv->vval.v_number = 12418 (varnumber_T)(regmatch.endp[0] - str); 12419 rettv->vval.v_number += (varnumber_T)(str - expr); 12420 } 12421 } 12422 vim_free(regmatch.regprog); 12423 } 12424 12425 theend: 12426 vim_free(tofree); 12427 p_cpo = save_cpo; 12428 } 12429 12430 /* 12431 * "match()" function 12432 */ 12433 static void 12434 f_match(argvars, rettv) 12435 typval_T *argvars; 12436 typval_T *rettv; 12437 { 12438 find_some_match(argvars, rettv, 1); 12439 } 12440 12441 /* 12442 * "matcharg()" function 12443 */ 12444 static void 12445 f_matcharg(argvars, rettv) 12446 typval_T *argvars; 12447 typval_T *rettv; 12448 { 12449 if (rettv_list_alloc(rettv) == OK) 12450 { 12451 #ifdef FEAT_SEARCH_EXTRA 12452 int mi = get_tv_number(&argvars[0]); 12453 12454 if (mi >= 1 && mi <= 3) 12455 { 12456 list_append_string(rettv->vval.v_list, 12457 syn_id2name(curwin->w_match_id[mi - 1]), -1); 12458 list_append_string(rettv->vval.v_list, 12459 curwin->w_match_pat[mi - 1], -1); 12460 } 12461 #endif 12462 } 12463 } 12464 12465 /* 12466 * "matchend()" function 12467 */ 12468 static void 12469 f_matchend(argvars, rettv) 12470 typval_T *argvars; 12471 typval_T *rettv; 12472 { 12473 find_some_match(argvars, rettv, 0); 12474 } 12475 12476 /* 12477 * "matchlist()" function 12478 */ 12479 static void 12480 f_matchlist(argvars, rettv) 12481 typval_T *argvars; 12482 typval_T *rettv; 12483 { 12484 find_some_match(argvars, rettv, 3); 12485 } 12486 12487 /* 12488 * "matchstr()" function 12489 */ 12490 static void 12491 f_matchstr(argvars, rettv) 12492 typval_T *argvars; 12493 typval_T *rettv; 12494 { 12495 find_some_match(argvars, rettv, 2); 12496 } 12497 12498 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 12499 12500 static void 12501 max_min(argvars, rettv, domax) 12502 typval_T *argvars; 12503 typval_T *rettv; 12504 int domax; 12505 { 12506 long n = 0; 12507 long i; 12508 int error = FALSE; 12509 12510 if (argvars[0].v_type == VAR_LIST) 12511 { 12512 list_T *l; 12513 listitem_T *li; 12514 12515 l = argvars[0].vval.v_list; 12516 if (l != NULL) 12517 { 12518 li = l->lv_first; 12519 if (li != NULL) 12520 { 12521 n = get_tv_number_chk(&li->li_tv, &error); 12522 for (;;) 12523 { 12524 li = li->li_next; 12525 if (li == NULL) 12526 break; 12527 i = get_tv_number_chk(&li->li_tv, &error); 12528 if (domax ? i > n : i < n) 12529 n = i; 12530 } 12531 } 12532 } 12533 } 12534 else if (argvars[0].v_type == VAR_DICT) 12535 { 12536 dict_T *d; 12537 int first = TRUE; 12538 hashitem_T *hi; 12539 int todo; 12540 12541 d = argvars[0].vval.v_dict; 12542 if (d != NULL) 12543 { 12544 todo = (int)d->dv_hashtab.ht_used; 12545 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 12546 { 12547 if (!HASHITEM_EMPTY(hi)) 12548 { 12549 --todo; 12550 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 12551 if (first) 12552 { 12553 n = i; 12554 first = FALSE; 12555 } 12556 else if (domax ? i > n : i < n) 12557 n = i; 12558 } 12559 } 12560 } 12561 } 12562 else 12563 EMSG(_(e_listdictarg)); 12564 rettv->vval.v_number = error ? 0 : n; 12565 } 12566 12567 /* 12568 * "max()" function 12569 */ 12570 static void 12571 f_max(argvars, rettv) 12572 typval_T *argvars; 12573 typval_T *rettv; 12574 { 12575 max_min(argvars, rettv, TRUE); 12576 } 12577 12578 /* 12579 * "min()" function 12580 */ 12581 static void 12582 f_min(argvars, rettv) 12583 typval_T *argvars; 12584 typval_T *rettv; 12585 { 12586 max_min(argvars, rettv, FALSE); 12587 } 12588 12589 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 12590 12591 /* 12592 * Create the directory in which "dir" is located, and higher levels when 12593 * needed. 12594 */ 12595 static int 12596 mkdir_recurse(dir, prot) 12597 char_u *dir; 12598 int prot; 12599 { 12600 char_u *p; 12601 char_u *updir; 12602 int r = FAIL; 12603 12604 /* Get end of directory name in "dir". 12605 * We're done when it's "/" or "c:/". */ 12606 p = gettail_sep(dir); 12607 if (p <= get_past_head(dir)) 12608 return OK; 12609 12610 /* If the directory exists we're done. Otherwise: create it.*/ 12611 updir = vim_strnsave(dir, (int)(p - dir)); 12612 if (updir == NULL) 12613 return FAIL; 12614 if (mch_isdir(updir)) 12615 r = OK; 12616 else if (mkdir_recurse(updir, prot) == OK) 12617 r = vim_mkdir_emsg(updir, prot); 12618 vim_free(updir); 12619 return r; 12620 } 12621 12622 #ifdef vim_mkdir 12623 /* 12624 * "mkdir()" function 12625 */ 12626 static void 12627 f_mkdir(argvars, rettv) 12628 typval_T *argvars; 12629 typval_T *rettv; 12630 { 12631 char_u *dir; 12632 char_u buf[NUMBUFLEN]; 12633 int prot = 0755; 12634 12635 rettv->vval.v_number = FAIL; 12636 if (check_restricted() || check_secure()) 12637 return; 12638 12639 dir = get_tv_string_buf(&argvars[0], buf); 12640 if (argvars[1].v_type != VAR_UNKNOWN) 12641 { 12642 if (argvars[2].v_type != VAR_UNKNOWN) 12643 prot = get_tv_number_chk(&argvars[2], NULL); 12644 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 12645 mkdir_recurse(dir, prot); 12646 } 12647 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 12648 } 12649 #endif 12650 12651 /* 12652 * "mode()" function 12653 */ 12654 /*ARGSUSED*/ 12655 static void 12656 f_mode(argvars, rettv) 12657 typval_T *argvars; 12658 typval_T *rettv; 12659 { 12660 char_u buf[2]; 12661 12662 #ifdef FEAT_VISUAL 12663 if (VIsual_active) 12664 { 12665 if (VIsual_select) 12666 buf[0] = VIsual_mode + 's' - 'v'; 12667 else 12668 buf[0] = VIsual_mode; 12669 } 12670 else 12671 #endif 12672 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 12673 buf[0] = 'r'; 12674 else if (State & INSERT) 12675 { 12676 if (State & REPLACE_FLAG) 12677 buf[0] = 'R'; 12678 else 12679 buf[0] = 'i'; 12680 } 12681 else if (State & CMDLINE) 12682 buf[0] = 'c'; 12683 else 12684 buf[0] = 'n'; 12685 12686 buf[1] = NUL; 12687 rettv->vval.v_string = vim_strsave(buf); 12688 rettv->v_type = VAR_STRING; 12689 } 12690 12691 /* 12692 * "nextnonblank()" function 12693 */ 12694 static void 12695 f_nextnonblank(argvars, rettv) 12696 typval_T *argvars; 12697 typval_T *rettv; 12698 { 12699 linenr_T lnum; 12700 12701 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12702 { 12703 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12704 { 12705 lnum = 0; 12706 break; 12707 } 12708 if (*skipwhite(ml_get(lnum)) != NUL) 12709 break; 12710 } 12711 rettv->vval.v_number = lnum; 12712 } 12713 12714 /* 12715 * "nr2char()" function 12716 */ 12717 static void 12718 f_nr2char(argvars, rettv) 12719 typval_T *argvars; 12720 typval_T *rettv; 12721 { 12722 char_u buf[NUMBUFLEN]; 12723 12724 #ifdef FEAT_MBYTE 12725 if (has_mbyte) 12726 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12727 else 12728 #endif 12729 { 12730 buf[0] = (char_u)get_tv_number(&argvars[0]); 12731 buf[1] = NUL; 12732 } 12733 rettv->v_type = VAR_STRING; 12734 rettv->vval.v_string = vim_strsave(buf); 12735 } 12736 12737 /* 12738 * "pathshorten()" function 12739 */ 12740 static void 12741 f_pathshorten(argvars, rettv) 12742 typval_T *argvars; 12743 typval_T *rettv; 12744 { 12745 char_u *p; 12746 12747 rettv->v_type = VAR_STRING; 12748 p = get_tv_string_chk(&argvars[0]); 12749 if (p == NULL) 12750 rettv->vval.v_string = NULL; 12751 else 12752 { 12753 p = vim_strsave(p); 12754 rettv->vval.v_string = p; 12755 if (p != NULL) 12756 shorten_dir(p); 12757 } 12758 } 12759 12760 /* 12761 * "prevnonblank()" function 12762 */ 12763 static void 12764 f_prevnonblank(argvars, rettv) 12765 typval_T *argvars; 12766 typval_T *rettv; 12767 { 12768 linenr_T lnum; 12769 12770 lnum = get_tv_lnum(argvars); 12771 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12772 lnum = 0; 12773 else 12774 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12775 --lnum; 12776 rettv->vval.v_number = lnum; 12777 } 12778 12779 #ifdef HAVE_STDARG_H 12780 /* This dummy va_list is here because: 12781 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12782 * - locally in the function results in a "used before set" warning 12783 * - using va_start() to initialize it gives "function with fixed args" error */ 12784 static va_list ap; 12785 #endif 12786 12787 /* 12788 * "printf()" function 12789 */ 12790 static void 12791 f_printf(argvars, rettv) 12792 typval_T *argvars; 12793 typval_T *rettv; 12794 { 12795 rettv->v_type = VAR_STRING; 12796 rettv->vval.v_string = NULL; 12797 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12798 { 12799 char_u buf[NUMBUFLEN]; 12800 int len; 12801 char_u *s; 12802 int saved_did_emsg = did_emsg; 12803 char *fmt; 12804 12805 /* Get the required length, allocate the buffer and do it for real. */ 12806 did_emsg = FALSE; 12807 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12808 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12809 if (!did_emsg) 12810 { 12811 s = alloc(len + 1); 12812 if (s != NULL) 12813 { 12814 rettv->vval.v_string = s; 12815 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12816 } 12817 } 12818 did_emsg |= saved_did_emsg; 12819 } 12820 #endif 12821 } 12822 12823 /* 12824 * "pumvisible()" function 12825 */ 12826 /*ARGSUSED*/ 12827 static void 12828 f_pumvisible(argvars, rettv) 12829 typval_T *argvars; 12830 typval_T *rettv; 12831 { 12832 rettv->vval.v_number = 0; 12833 #ifdef FEAT_INS_EXPAND 12834 if (pum_visible()) 12835 rettv->vval.v_number = 1; 12836 #endif 12837 } 12838 12839 /* 12840 * "range()" function 12841 */ 12842 static void 12843 f_range(argvars, rettv) 12844 typval_T *argvars; 12845 typval_T *rettv; 12846 { 12847 long start; 12848 long end; 12849 long stride = 1; 12850 long i; 12851 int error = FALSE; 12852 12853 start = get_tv_number_chk(&argvars[0], &error); 12854 if (argvars[1].v_type == VAR_UNKNOWN) 12855 { 12856 end = start - 1; 12857 start = 0; 12858 } 12859 else 12860 { 12861 end = get_tv_number_chk(&argvars[1], &error); 12862 if (argvars[2].v_type != VAR_UNKNOWN) 12863 stride = get_tv_number_chk(&argvars[2], &error); 12864 } 12865 12866 rettv->vval.v_number = 0; 12867 if (error) 12868 return; /* type error; errmsg already given */ 12869 if (stride == 0) 12870 EMSG(_("E726: Stride is zero")); 12871 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12872 EMSG(_("E727: Start past end")); 12873 else 12874 { 12875 if (rettv_list_alloc(rettv) == OK) 12876 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12877 if (list_append_number(rettv->vval.v_list, 12878 (varnumber_T)i) == FAIL) 12879 break; 12880 } 12881 } 12882 12883 /* 12884 * "readfile()" function 12885 */ 12886 static void 12887 f_readfile(argvars, rettv) 12888 typval_T *argvars; 12889 typval_T *rettv; 12890 { 12891 int binary = FALSE; 12892 char_u *fname; 12893 FILE *fd; 12894 listitem_T *li; 12895 #define FREAD_SIZE 200 /* optimized for text lines */ 12896 char_u buf[FREAD_SIZE]; 12897 int readlen; /* size of last fread() */ 12898 int buflen; /* nr of valid chars in buf[] */ 12899 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12900 int tolist; /* first byte in buf[] still to be put in list */ 12901 int chop; /* how many CR to chop off */ 12902 char_u *prev = NULL; /* previously read bytes, if any */ 12903 int prevlen = 0; /* length of "prev" if not NULL */ 12904 char_u *s; 12905 int len; 12906 long maxline = MAXLNUM; 12907 long cnt = 0; 12908 12909 if (argvars[1].v_type != VAR_UNKNOWN) 12910 { 12911 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12912 binary = TRUE; 12913 if (argvars[2].v_type != VAR_UNKNOWN) 12914 maxline = get_tv_number(&argvars[2]); 12915 } 12916 12917 if (rettv_list_alloc(rettv) == FAIL) 12918 return; 12919 12920 /* Always open the file in binary mode, library functions have a mind of 12921 * their own about CR-LF conversion. */ 12922 fname = get_tv_string(&argvars[0]); 12923 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12924 { 12925 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12926 return; 12927 } 12928 12929 filtd = 0; 12930 while (cnt < maxline || maxline < 0) 12931 { 12932 readlen = (int)fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12933 buflen = filtd + readlen; 12934 tolist = 0; 12935 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12936 { 12937 if (buf[filtd] == '\n' || readlen <= 0) 12938 { 12939 /* Only when in binary mode add an empty list item when the 12940 * last line ends in a '\n'. */ 12941 if (!binary && readlen == 0 && filtd == 0) 12942 break; 12943 12944 /* Found end-of-line or end-of-file: add a text line to the 12945 * list. */ 12946 chop = 0; 12947 if (!binary) 12948 while (filtd - chop - 1 >= tolist 12949 && buf[filtd - chop - 1] == '\r') 12950 ++chop; 12951 len = filtd - tolist - chop; 12952 if (prev == NULL) 12953 s = vim_strnsave(buf + tolist, len); 12954 else 12955 { 12956 s = alloc((unsigned)(prevlen + len + 1)); 12957 if (s != NULL) 12958 { 12959 mch_memmove(s, prev, prevlen); 12960 vim_free(prev); 12961 prev = NULL; 12962 mch_memmove(s + prevlen, buf + tolist, len); 12963 s[prevlen + len] = NUL; 12964 } 12965 } 12966 tolist = filtd + 1; 12967 12968 li = listitem_alloc(); 12969 if (li == NULL) 12970 { 12971 vim_free(s); 12972 break; 12973 } 12974 li->li_tv.v_type = VAR_STRING; 12975 li->li_tv.v_lock = 0; 12976 li->li_tv.vval.v_string = s; 12977 list_append(rettv->vval.v_list, li); 12978 12979 if (++cnt >= maxline && maxline >= 0) 12980 break; 12981 if (readlen <= 0) 12982 break; 12983 } 12984 else if (buf[filtd] == NUL) 12985 buf[filtd] = '\n'; 12986 } 12987 if (readlen <= 0) 12988 break; 12989 12990 if (tolist == 0) 12991 { 12992 /* "buf" is full, need to move text to an allocated buffer */ 12993 if (prev == NULL) 12994 { 12995 prev = vim_strnsave(buf, buflen); 12996 prevlen = buflen; 12997 } 12998 else 12999 { 13000 s = alloc((unsigned)(prevlen + buflen)); 13001 if (s != NULL) 13002 { 13003 mch_memmove(s, prev, prevlen); 13004 mch_memmove(s + prevlen, buf, buflen); 13005 vim_free(prev); 13006 prev = s; 13007 prevlen += buflen; 13008 } 13009 } 13010 filtd = 0; 13011 } 13012 else 13013 { 13014 mch_memmove(buf, buf + tolist, buflen - tolist); 13015 filtd -= tolist; 13016 } 13017 } 13018 13019 /* 13020 * For a negative line count use only the lines at the end of the file, 13021 * free the rest. 13022 */ 13023 if (maxline < 0) 13024 while (cnt > -maxline) 13025 { 13026 listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first); 13027 --cnt; 13028 } 13029 13030 vim_free(prev); 13031 fclose(fd); 13032 } 13033 13034 #if defined(FEAT_RELTIME) 13035 static int list2proftime __ARGS((typval_T *arg, proftime_T *tm)); 13036 13037 /* 13038 * Convert a List to proftime_T. 13039 * Return FAIL when there is something wrong. 13040 */ 13041 static int 13042 list2proftime(arg, tm) 13043 typval_T *arg; 13044 proftime_T *tm; 13045 { 13046 long n1, n2; 13047 int error = FALSE; 13048 13049 if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL 13050 || arg->vval.v_list->lv_len != 2) 13051 return FAIL; 13052 n1 = list_find_nr(arg->vval.v_list, 0L, &error); 13053 n2 = list_find_nr(arg->vval.v_list, 1L, &error); 13054 # ifdef WIN3264 13055 tm->HighPart = n1; 13056 tm->LowPart = n2; 13057 # else 13058 tm->tv_sec = n1; 13059 tm->tv_usec = n2; 13060 # endif 13061 return error ? FAIL : OK; 13062 } 13063 #endif /* FEAT_RELTIME */ 13064 13065 /* 13066 * "reltime()" function 13067 */ 13068 static void 13069 f_reltime(argvars, rettv) 13070 typval_T *argvars; 13071 typval_T *rettv; 13072 { 13073 #ifdef FEAT_RELTIME 13074 proftime_T res; 13075 proftime_T start; 13076 13077 if (argvars[0].v_type == VAR_UNKNOWN) 13078 { 13079 /* No arguments: get current time. */ 13080 profile_start(&res); 13081 } 13082 else if (argvars[1].v_type == VAR_UNKNOWN) 13083 { 13084 if (list2proftime(&argvars[0], &res) == FAIL) 13085 return; 13086 profile_end(&res); 13087 } 13088 else 13089 { 13090 /* Two arguments: compute the difference. */ 13091 if (list2proftime(&argvars[0], &start) == FAIL 13092 || list2proftime(&argvars[1], &res) == FAIL) 13093 return; 13094 profile_sub(&res, &start); 13095 } 13096 13097 if (rettv_list_alloc(rettv) == OK) 13098 { 13099 long n1, n2; 13100 13101 # ifdef WIN3264 13102 n1 = res.HighPart; 13103 n2 = res.LowPart; 13104 # else 13105 n1 = res.tv_sec; 13106 n2 = res.tv_usec; 13107 # endif 13108 list_append_number(rettv->vval.v_list, (varnumber_T)n1); 13109 list_append_number(rettv->vval.v_list, (varnumber_T)n2); 13110 } 13111 #endif 13112 } 13113 13114 /* 13115 * "reltimestr()" function 13116 */ 13117 static void 13118 f_reltimestr(argvars, rettv) 13119 typval_T *argvars; 13120 typval_T *rettv; 13121 { 13122 #ifdef FEAT_RELTIME 13123 proftime_T tm; 13124 #endif 13125 13126 rettv->v_type = VAR_STRING; 13127 rettv->vval.v_string = NULL; 13128 #ifdef FEAT_RELTIME 13129 if (list2proftime(&argvars[0], &tm) == OK) 13130 rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm)); 13131 #endif 13132 } 13133 13134 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 13135 static void make_connection __ARGS((void)); 13136 static int check_connection __ARGS((void)); 13137 13138 static void 13139 make_connection() 13140 { 13141 if (X_DISPLAY == NULL 13142 # ifdef FEAT_GUI 13143 && !gui.in_use 13144 # endif 13145 ) 13146 { 13147 x_force_connect = TRUE; 13148 setup_term_clip(); 13149 x_force_connect = FALSE; 13150 } 13151 } 13152 13153 static int 13154 check_connection() 13155 { 13156 make_connection(); 13157 if (X_DISPLAY == NULL) 13158 { 13159 EMSG(_("E240: No connection to Vim server")); 13160 return FAIL; 13161 } 13162 return OK; 13163 } 13164 #endif 13165 13166 #ifdef FEAT_CLIENTSERVER 13167 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 13168 13169 static void 13170 remote_common(argvars, rettv, expr) 13171 typval_T *argvars; 13172 typval_T *rettv; 13173 int expr; 13174 { 13175 char_u *server_name; 13176 char_u *keys; 13177 char_u *r = NULL; 13178 char_u buf[NUMBUFLEN]; 13179 # ifdef WIN32 13180 HWND w; 13181 # else 13182 Window w; 13183 # endif 13184 13185 if (check_restricted() || check_secure()) 13186 return; 13187 13188 # ifdef FEAT_X11 13189 if (check_connection() == FAIL) 13190 return; 13191 # endif 13192 13193 server_name = get_tv_string_chk(&argvars[0]); 13194 if (server_name == NULL) 13195 return; /* type error; errmsg already given */ 13196 keys = get_tv_string_buf(&argvars[1], buf); 13197 # ifdef WIN32 13198 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 13199 # else 13200 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 13201 < 0) 13202 # endif 13203 { 13204 if (r != NULL) 13205 EMSG(r); /* sending worked but evaluation failed */ 13206 else 13207 EMSG2(_("E241: Unable to send to %s"), server_name); 13208 return; 13209 } 13210 13211 rettv->vval.v_string = r; 13212 13213 if (argvars[2].v_type != VAR_UNKNOWN) 13214 { 13215 dictitem_T v; 13216 char_u str[30]; 13217 char_u *idvar; 13218 13219 sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w); 13220 v.di_tv.v_type = VAR_STRING; 13221 v.di_tv.vval.v_string = vim_strsave(str); 13222 idvar = get_tv_string_chk(&argvars[2]); 13223 if (idvar != NULL) 13224 set_var(idvar, &v.di_tv, FALSE); 13225 vim_free(v.di_tv.vval.v_string); 13226 } 13227 } 13228 #endif 13229 13230 /* 13231 * "remote_expr()" function 13232 */ 13233 /*ARGSUSED*/ 13234 static void 13235 f_remote_expr(argvars, rettv) 13236 typval_T *argvars; 13237 typval_T *rettv; 13238 { 13239 rettv->v_type = VAR_STRING; 13240 rettv->vval.v_string = NULL; 13241 #ifdef FEAT_CLIENTSERVER 13242 remote_common(argvars, rettv, TRUE); 13243 #endif 13244 } 13245 13246 /* 13247 * "remote_foreground()" function 13248 */ 13249 /*ARGSUSED*/ 13250 static void 13251 f_remote_foreground(argvars, rettv) 13252 typval_T *argvars; 13253 typval_T *rettv; 13254 { 13255 rettv->vval.v_number = 0; 13256 #ifdef FEAT_CLIENTSERVER 13257 # ifdef WIN32 13258 /* On Win32 it's done in this application. */ 13259 { 13260 char_u *server_name = get_tv_string_chk(&argvars[0]); 13261 13262 if (server_name != NULL) 13263 serverForeground(server_name); 13264 } 13265 # else 13266 /* Send a foreground() expression to the server. */ 13267 argvars[1].v_type = VAR_STRING; 13268 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 13269 argvars[2].v_type = VAR_UNKNOWN; 13270 remote_common(argvars, rettv, TRUE); 13271 vim_free(argvars[1].vval.v_string); 13272 # endif 13273 #endif 13274 } 13275 13276 /*ARGSUSED*/ 13277 static void 13278 f_remote_peek(argvars, rettv) 13279 typval_T *argvars; 13280 typval_T *rettv; 13281 { 13282 #ifdef FEAT_CLIENTSERVER 13283 dictitem_T v; 13284 char_u *s = NULL; 13285 # ifdef WIN32 13286 long_u n = 0; 13287 # endif 13288 char_u *serverid; 13289 13290 if (check_restricted() || check_secure()) 13291 { 13292 rettv->vval.v_number = -1; 13293 return; 13294 } 13295 serverid = get_tv_string_chk(&argvars[0]); 13296 if (serverid == NULL) 13297 { 13298 rettv->vval.v_number = -1; 13299 return; /* type error; errmsg already given */ 13300 } 13301 # ifdef WIN32 13302 sscanf(serverid, SCANF_HEX_LONG_U, &n); 13303 if (n == 0) 13304 rettv->vval.v_number = -1; 13305 else 13306 { 13307 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 13308 rettv->vval.v_number = (s != NULL); 13309 } 13310 # else 13311 rettv->vval.v_number = 0; 13312 if (check_connection() == FAIL) 13313 return; 13314 13315 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 13316 serverStrToWin(serverid), &s); 13317 # endif 13318 13319 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 13320 { 13321 char_u *retvar; 13322 13323 v.di_tv.v_type = VAR_STRING; 13324 v.di_tv.vval.v_string = vim_strsave(s); 13325 retvar = get_tv_string_chk(&argvars[1]); 13326 if (retvar != NULL) 13327 set_var(retvar, &v.di_tv, FALSE); 13328 vim_free(v.di_tv.vval.v_string); 13329 } 13330 #else 13331 rettv->vval.v_number = -1; 13332 #endif 13333 } 13334 13335 /*ARGSUSED*/ 13336 static void 13337 f_remote_read(argvars, rettv) 13338 typval_T *argvars; 13339 typval_T *rettv; 13340 { 13341 char_u *r = NULL; 13342 13343 #ifdef FEAT_CLIENTSERVER 13344 char_u *serverid = get_tv_string_chk(&argvars[0]); 13345 13346 if (serverid != NULL && !check_restricted() && !check_secure()) 13347 { 13348 # ifdef WIN32 13349 /* The server's HWND is encoded in the 'id' parameter */ 13350 long_u n = 0; 13351 13352 sscanf(serverid, SCANF_HEX_LONG_U, &n); 13353 if (n != 0) 13354 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 13355 if (r == NULL) 13356 # else 13357 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 13358 serverStrToWin(serverid), &r, FALSE) < 0) 13359 # endif 13360 EMSG(_("E277: Unable to read a server reply")); 13361 } 13362 #endif 13363 rettv->v_type = VAR_STRING; 13364 rettv->vval.v_string = r; 13365 } 13366 13367 /* 13368 * "remote_send()" function 13369 */ 13370 /*ARGSUSED*/ 13371 static void 13372 f_remote_send(argvars, rettv) 13373 typval_T *argvars; 13374 typval_T *rettv; 13375 { 13376 rettv->v_type = VAR_STRING; 13377 rettv->vval.v_string = NULL; 13378 #ifdef FEAT_CLIENTSERVER 13379 remote_common(argvars, rettv, FALSE); 13380 #endif 13381 } 13382 13383 /* 13384 * "remove()" function 13385 */ 13386 static void 13387 f_remove(argvars, rettv) 13388 typval_T *argvars; 13389 typval_T *rettv; 13390 { 13391 list_T *l; 13392 listitem_T *item, *item2; 13393 listitem_T *li; 13394 long idx; 13395 long end; 13396 char_u *key; 13397 dict_T *d; 13398 dictitem_T *di; 13399 13400 rettv->vval.v_number = 0; 13401 if (argvars[0].v_type == VAR_DICT) 13402 { 13403 if (argvars[2].v_type != VAR_UNKNOWN) 13404 EMSG2(_(e_toomanyarg), "remove()"); 13405 else if ((d = argvars[0].vval.v_dict) != NULL 13406 && !tv_check_lock(d->dv_lock, (char_u *)"remove() argument")) 13407 { 13408 key = get_tv_string_chk(&argvars[1]); 13409 if (key != NULL) 13410 { 13411 di = dict_find(d, key, -1); 13412 if (di == NULL) 13413 EMSG2(_(e_dictkey), key); 13414 else 13415 { 13416 *rettv = di->di_tv; 13417 init_tv(&di->di_tv); 13418 dictitem_remove(d, di); 13419 } 13420 } 13421 } 13422 } 13423 else if (argvars[0].v_type != VAR_LIST) 13424 EMSG2(_(e_listdictarg), "remove()"); 13425 else if ((l = argvars[0].vval.v_list) != NULL 13426 && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument")) 13427 { 13428 int error = FALSE; 13429 13430 idx = get_tv_number_chk(&argvars[1], &error); 13431 if (error) 13432 ; /* type error: do nothing, errmsg already given */ 13433 else if ((item = list_find(l, idx)) == NULL) 13434 EMSGN(_(e_listidx), idx); 13435 else 13436 { 13437 if (argvars[2].v_type == VAR_UNKNOWN) 13438 { 13439 /* Remove one item, return its value. */ 13440 list_remove(l, item, item); 13441 *rettv = item->li_tv; 13442 vim_free(item); 13443 } 13444 else 13445 { 13446 /* Remove range of items, return list with values. */ 13447 end = get_tv_number_chk(&argvars[2], &error); 13448 if (error) 13449 ; /* type error: do nothing */ 13450 else if ((item2 = list_find(l, end)) == NULL) 13451 EMSGN(_(e_listidx), end); 13452 else 13453 { 13454 int cnt = 0; 13455 13456 for (li = item; li != NULL; li = li->li_next) 13457 { 13458 ++cnt; 13459 if (li == item2) 13460 break; 13461 } 13462 if (li == NULL) /* didn't find "item2" after "item" */ 13463 EMSG(_(e_invrange)); 13464 else 13465 { 13466 list_remove(l, item, item2); 13467 if (rettv_list_alloc(rettv) == OK) 13468 { 13469 l = rettv->vval.v_list; 13470 l->lv_first = item; 13471 l->lv_last = item2; 13472 item->li_prev = NULL; 13473 item2->li_next = NULL; 13474 l->lv_len = cnt; 13475 } 13476 } 13477 } 13478 } 13479 } 13480 } 13481 } 13482 13483 /* 13484 * "rename({from}, {to})" function 13485 */ 13486 static void 13487 f_rename(argvars, rettv) 13488 typval_T *argvars; 13489 typval_T *rettv; 13490 { 13491 char_u buf[NUMBUFLEN]; 13492 13493 if (check_restricted() || check_secure()) 13494 rettv->vval.v_number = -1; 13495 else 13496 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 13497 get_tv_string_buf(&argvars[1], buf)); 13498 } 13499 13500 /* 13501 * "repeat()" function 13502 */ 13503 /*ARGSUSED*/ 13504 static void 13505 f_repeat(argvars, rettv) 13506 typval_T *argvars; 13507 typval_T *rettv; 13508 { 13509 char_u *p; 13510 int n; 13511 int slen; 13512 int len; 13513 char_u *r; 13514 int i; 13515 13516 n = get_tv_number(&argvars[1]); 13517 if (argvars[0].v_type == VAR_LIST) 13518 { 13519 if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) 13520 while (n-- > 0) 13521 if (list_extend(rettv->vval.v_list, 13522 argvars[0].vval.v_list, NULL) == FAIL) 13523 break; 13524 } 13525 else 13526 { 13527 p = get_tv_string(&argvars[0]); 13528 rettv->v_type = VAR_STRING; 13529 rettv->vval.v_string = NULL; 13530 13531 slen = (int)STRLEN(p); 13532 len = slen * n; 13533 if (len <= 0) 13534 return; 13535 13536 r = alloc(len + 1); 13537 if (r != NULL) 13538 { 13539 for (i = 0; i < n; i++) 13540 mch_memmove(r + i * slen, p, (size_t)slen); 13541 r[len] = NUL; 13542 } 13543 13544 rettv->vval.v_string = r; 13545 } 13546 } 13547 13548 /* 13549 * "resolve()" function 13550 */ 13551 static void 13552 f_resolve(argvars, rettv) 13553 typval_T *argvars; 13554 typval_T *rettv; 13555 { 13556 char_u *p; 13557 13558 p = get_tv_string(&argvars[0]); 13559 #ifdef FEAT_SHORTCUT 13560 { 13561 char_u *v = NULL; 13562 13563 v = mch_resolve_shortcut(p); 13564 if (v != NULL) 13565 rettv->vval.v_string = v; 13566 else 13567 rettv->vval.v_string = vim_strsave(p); 13568 } 13569 #else 13570 # ifdef HAVE_READLINK 13571 { 13572 char_u buf[MAXPATHL + 1]; 13573 char_u *cpy; 13574 int len; 13575 char_u *remain = NULL; 13576 char_u *q; 13577 int is_relative_to_current = FALSE; 13578 int has_trailing_pathsep = FALSE; 13579 int limit = 100; 13580 13581 p = vim_strsave(p); 13582 13583 if (p[0] == '.' && (vim_ispathsep(p[1]) 13584 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 13585 is_relative_to_current = TRUE; 13586 13587 len = STRLEN(p); 13588 if (len > 0 && after_pathsep(p, p + len)) 13589 has_trailing_pathsep = TRUE; 13590 13591 q = getnextcomp(p); 13592 if (*q != NUL) 13593 { 13594 /* Separate the first path component in "p", and keep the 13595 * remainder (beginning with the path separator). */ 13596 remain = vim_strsave(q - 1); 13597 q[-1] = NUL; 13598 } 13599 13600 for (;;) 13601 { 13602 for (;;) 13603 { 13604 len = readlink((char *)p, (char *)buf, MAXPATHL); 13605 if (len <= 0) 13606 break; 13607 buf[len] = NUL; 13608 13609 if (limit-- == 0) 13610 { 13611 vim_free(p); 13612 vim_free(remain); 13613 EMSG(_("E655: Too many symbolic links (cycle?)")); 13614 rettv->vval.v_string = NULL; 13615 goto fail; 13616 } 13617 13618 /* Ensure that the result will have a trailing path separator 13619 * if the argument has one. */ 13620 if (remain == NULL && has_trailing_pathsep) 13621 add_pathsep(buf); 13622 13623 /* Separate the first path component in the link value and 13624 * concatenate the remainders. */ 13625 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 13626 if (*q != NUL) 13627 { 13628 if (remain == NULL) 13629 remain = vim_strsave(q - 1); 13630 else 13631 { 13632 cpy = concat_str(q - 1, remain); 13633 if (cpy != NULL) 13634 { 13635 vim_free(remain); 13636 remain = cpy; 13637 } 13638 } 13639 q[-1] = NUL; 13640 } 13641 13642 q = gettail(p); 13643 if (q > p && *q == NUL) 13644 { 13645 /* Ignore trailing path separator. */ 13646 q[-1] = NUL; 13647 q = gettail(p); 13648 } 13649 if (q > p && !mch_isFullName(buf)) 13650 { 13651 /* symlink is relative to directory of argument */ 13652 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 13653 if (cpy != NULL) 13654 { 13655 STRCPY(cpy, p); 13656 STRCPY(gettail(cpy), buf); 13657 vim_free(p); 13658 p = cpy; 13659 } 13660 } 13661 else 13662 { 13663 vim_free(p); 13664 p = vim_strsave(buf); 13665 } 13666 } 13667 13668 if (remain == NULL) 13669 break; 13670 13671 /* Append the first path component of "remain" to "p". */ 13672 q = getnextcomp(remain + 1); 13673 len = q - remain - (*q != NUL); 13674 cpy = vim_strnsave(p, STRLEN(p) + len); 13675 if (cpy != NULL) 13676 { 13677 STRNCAT(cpy, remain, len); 13678 vim_free(p); 13679 p = cpy; 13680 } 13681 /* Shorten "remain". */ 13682 if (*q != NUL) 13683 STRCPY(remain, q - 1); 13684 else 13685 { 13686 vim_free(remain); 13687 remain = NULL; 13688 } 13689 } 13690 13691 /* If the result is a relative path name, make it explicitly relative to 13692 * the current directory if and only if the argument had this form. */ 13693 if (!vim_ispathsep(*p)) 13694 { 13695 if (is_relative_to_current 13696 && *p != NUL 13697 && !(p[0] == '.' 13698 && (p[1] == NUL 13699 || vim_ispathsep(p[1]) 13700 || (p[1] == '.' 13701 && (p[2] == NUL 13702 || vim_ispathsep(p[2])))))) 13703 { 13704 /* Prepend "./". */ 13705 cpy = concat_str((char_u *)"./", p); 13706 if (cpy != NULL) 13707 { 13708 vim_free(p); 13709 p = cpy; 13710 } 13711 } 13712 else if (!is_relative_to_current) 13713 { 13714 /* Strip leading "./". */ 13715 q = p; 13716 while (q[0] == '.' && vim_ispathsep(q[1])) 13717 q += 2; 13718 if (q > p) 13719 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 13720 } 13721 } 13722 13723 /* Ensure that the result will have no trailing path separator 13724 * if the argument had none. But keep "/" or "//". */ 13725 if (!has_trailing_pathsep) 13726 { 13727 q = p + STRLEN(p); 13728 if (after_pathsep(p, q)) 13729 *gettail_sep(p) = NUL; 13730 } 13731 13732 rettv->vval.v_string = p; 13733 } 13734 # else 13735 rettv->vval.v_string = vim_strsave(p); 13736 # endif 13737 #endif 13738 13739 simplify_filename(rettv->vval.v_string); 13740 13741 #ifdef HAVE_READLINK 13742 fail: 13743 #endif 13744 rettv->v_type = VAR_STRING; 13745 } 13746 13747 /* 13748 * "reverse({list})" function 13749 */ 13750 static void 13751 f_reverse(argvars, rettv) 13752 typval_T *argvars; 13753 typval_T *rettv; 13754 { 13755 list_T *l; 13756 listitem_T *li, *ni; 13757 13758 rettv->vval.v_number = 0; 13759 if (argvars[0].v_type != VAR_LIST) 13760 EMSG2(_(e_listarg), "reverse()"); 13761 else if ((l = argvars[0].vval.v_list) != NULL 13762 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 13763 { 13764 li = l->lv_last; 13765 l->lv_first = l->lv_last = NULL; 13766 l->lv_len = 0; 13767 while (li != NULL) 13768 { 13769 ni = li->li_prev; 13770 list_append(l, li); 13771 li = ni; 13772 } 13773 rettv->vval.v_list = l; 13774 rettv->v_type = VAR_LIST; 13775 ++l->lv_refcount; 13776 } 13777 } 13778 13779 #define SP_NOMOVE 0x01 /* don't move cursor */ 13780 #define SP_REPEAT 0x02 /* repeat to find outer pair */ 13781 #define SP_RETCOUNT 0x04 /* return matchcount */ 13782 #define SP_SETPCMARK 0x08 /* set previous context mark */ 13783 #define SP_START 0x10 /* accept match at start position */ 13784 #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ 13785 #define SP_END 0x40 /* leave cursor at end of match */ 13786 13787 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 13788 13789 /* 13790 * Get flags for a search function. 13791 * Possibly sets "p_ws". 13792 * Returns BACKWARD, FORWARD or zero (for an error). 13793 */ 13794 static int 13795 get_search_arg(varp, flagsp) 13796 typval_T *varp; 13797 int *flagsp; 13798 { 13799 int dir = FORWARD; 13800 char_u *flags; 13801 char_u nbuf[NUMBUFLEN]; 13802 int mask; 13803 13804 if (varp->v_type != VAR_UNKNOWN) 13805 { 13806 flags = get_tv_string_buf_chk(varp, nbuf); 13807 if (flags == NULL) 13808 return 0; /* type error; errmsg already given */ 13809 while (*flags != NUL) 13810 { 13811 switch (*flags) 13812 { 13813 case 'b': dir = BACKWARD; break; 13814 case 'w': p_ws = TRUE; break; 13815 case 'W': p_ws = FALSE; break; 13816 default: mask = 0; 13817 if (flagsp != NULL) 13818 switch (*flags) 13819 { 13820 case 'c': mask = SP_START; break; 13821 case 'e': mask = SP_END; break; 13822 case 'm': mask = SP_RETCOUNT; break; 13823 case 'n': mask = SP_NOMOVE; break; 13824 case 'p': mask = SP_SUBPAT; break; 13825 case 'r': mask = SP_REPEAT; break; 13826 case 's': mask = SP_SETPCMARK; break; 13827 } 13828 if (mask == 0) 13829 { 13830 EMSG2(_(e_invarg2), flags); 13831 dir = 0; 13832 } 13833 else 13834 *flagsp |= mask; 13835 } 13836 if (dir == 0) 13837 break; 13838 ++flags; 13839 } 13840 } 13841 return dir; 13842 } 13843 13844 /* 13845 * Shared by search() and searchpos() functions 13846 */ 13847 static int 13848 search_cmn(argvars, match_pos, flagsp) 13849 typval_T *argvars; 13850 pos_T *match_pos; 13851 int *flagsp; 13852 { 13853 int flags; 13854 char_u *pat; 13855 pos_T pos; 13856 pos_T save_cursor; 13857 int save_p_ws = p_ws; 13858 int dir; 13859 int retval = 0; /* default: FAIL */ 13860 long lnum_stop = 0; 13861 int options = SEARCH_KEEP; 13862 int subpatnum; 13863 13864 pat = get_tv_string(&argvars[0]); 13865 dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */ 13866 if (dir == 0) 13867 goto theend; 13868 flags = *flagsp; 13869 if (flags & SP_START) 13870 options |= SEARCH_START; 13871 if (flags & SP_END) 13872 options |= SEARCH_END; 13873 13874 /* Optional extra argument: line number to stop searching. */ 13875 if (argvars[1].v_type != VAR_UNKNOWN 13876 && argvars[2].v_type != VAR_UNKNOWN) 13877 { 13878 lnum_stop = get_tv_number_chk(&argvars[2], NULL); 13879 if (lnum_stop < 0) 13880 goto theend; 13881 } 13882 13883 /* 13884 * This function does not accept SP_REPEAT and SP_RETCOUNT flags. 13885 * Check to make sure only those flags are set. 13886 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13887 * flags cannot be set. Check for that condition also. 13888 */ 13889 if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0) 13890 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13891 { 13892 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13893 goto theend; 13894 } 13895 13896 pos = save_cursor = curwin->w_cursor; 13897 subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13898 options, RE_SEARCH, (linenr_T)lnum_stop); 13899 if (subpatnum != FAIL) 13900 { 13901 if (flags & SP_SUBPAT) 13902 retval = subpatnum; 13903 else 13904 retval = pos.lnum; 13905 if (flags & SP_SETPCMARK) 13906 setpcmark(); 13907 curwin->w_cursor = pos; 13908 if (match_pos != NULL) 13909 { 13910 /* Store the match cursor position */ 13911 match_pos->lnum = pos.lnum; 13912 match_pos->col = pos.col + 1; 13913 } 13914 /* "/$" will put the cursor after the end of the line, may need to 13915 * correct that here */ 13916 check_cursor(); 13917 } 13918 13919 /* If 'n' flag is used: restore cursor position. */ 13920 if (flags & SP_NOMOVE) 13921 curwin->w_cursor = save_cursor; 13922 theend: 13923 p_ws = save_p_ws; 13924 13925 return retval; 13926 } 13927 13928 /* 13929 * "search()" function 13930 */ 13931 static void 13932 f_search(argvars, rettv) 13933 typval_T *argvars; 13934 typval_T *rettv; 13935 { 13936 int flags = 0; 13937 13938 rettv->vval.v_number = search_cmn(argvars, NULL, &flags); 13939 } 13940 13941 /* 13942 * "searchdecl()" function 13943 */ 13944 static void 13945 f_searchdecl(argvars, rettv) 13946 typval_T *argvars; 13947 typval_T *rettv; 13948 { 13949 int locally = 1; 13950 int thisblock = 0; 13951 int error = FALSE; 13952 char_u *name; 13953 13954 rettv->vval.v_number = 1; /* default: FAIL */ 13955 13956 name = get_tv_string_chk(&argvars[0]); 13957 if (argvars[1].v_type != VAR_UNKNOWN) 13958 { 13959 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13960 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13961 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13962 } 13963 if (!error && name != NULL) 13964 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13965 locally, thisblock, SEARCH_KEEP) == FAIL; 13966 } 13967 13968 /* 13969 * Used by searchpair() and searchpairpos() 13970 */ 13971 static int 13972 searchpair_cmn(argvars, match_pos) 13973 typval_T *argvars; 13974 pos_T *match_pos; 13975 { 13976 char_u *spat, *mpat, *epat; 13977 char_u *skip; 13978 int save_p_ws = p_ws; 13979 int dir; 13980 int flags = 0; 13981 char_u nbuf1[NUMBUFLEN]; 13982 char_u nbuf2[NUMBUFLEN]; 13983 char_u nbuf3[NUMBUFLEN]; 13984 int retval = 0; /* default: FAIL */ 13985 long lnum_stop = 0; 13986 13987 /* Get the three pattern arguments: start, middle, end. */ 13988 spat = get_tv_string_chk(&argvars[0]); 13989 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13990 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13991 if (spat == NULL || mpat == NULL || epat == NULL) 13992 goto theend; /* type error */ 13993 13994 /* Handle the optional fourth argument: flags */ 13995 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13996 if (dir == 0) 13997 goto theend; 13998 13999 /* Don't accept SP_END or SP_SUBPAT. 14000 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 14001 */ 14002 if ((flags & (SP_END | SP_SUBPAT)) != 0 14003 || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 14004 { 14005 EMSG2(_(e_invarg2), get_tv_string(&argvars[3])); 14006 goto theend; 14007 } 14008 14009 /* Optional fifth argument: skip expression */ 14010 if (argvars[3].v_type == VAR_UNKNOWN 14011 || argvars[4].v_type == VAR_UNKNOWN) 14012 skip = (char_u *)""; 14013 else 14014 { 14015 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 14016 if (argvars[5].v_type != VAR_UNKNOWN) 14017 { 14018 lnum_stop = get_tv_number_chk(&argvars[5], NULL); 14019 if (lnum_stop < 0) 14020 goto theend; 14021 } 14022 } 14023 if (skip == NULL) 14024 goto theend; /* type error */ 14025 14026 retval = do_searchpair(spat, mpat, epat, dir, skip, flags, 14027 match_pos, lnum_stop); 14028 14029 theend: 14030 p_ws = save_p_ws; 14031 14032 return retval; 14033 } 14034 14035 /* 14036 * "searchpair()" function 14037 */ 14038 static void 14039 f_searchpair(argvars, rettv) 14040 typval_T *argvars; 14041 typval_T *rettv; 14042 { 14043 rettv->vval.v_number = searchpair_cmn(argvars, NULL); 14044 } 14045 14046 /* 14047 * "searchpairpos()" function 14048 */ 14049 static void 14050 f_searchpairpos(argvars, rettv) 14051 typval_T *argvars; 14052 typval_T *rettv; 14053 { 14054 pos_T match_pos; 14055 int lnum = 0; 14056 int col = 0; 14057 14058 rettv->vval.v_number = 0; 14059 14060 if (rettv_list_alloc(rettv) == FAIL) 14061 return; 14062 14063 if (searchpair_cmn(argvars, &match_pos) > 0) 14064 { 14065 lnum = match_pos.lnum; 14066 col = match_pos.col; 14067 } 14068 14069 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 14070 list_append_number(rettv->vval.v_list, (varnumber_T)col); 14071 } 14072 14073 /* 14074 * Search for a start/middle/end thing. 14075 * Used by searchpair(), see its documentation for the details. 14076 * Returns 0 or -1 for no match, 14077 */ 14078 long 14079 do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop) 14080 char_u *spat; /* start pattern */ 14081 char_u *mpat; /* middle pattern */ 14082 char_u *epat; /* end pattern */ 14083 int dir; /* BACKWARD or FORWARD */ 14084 char_u *skip; /* skip expression */ 14085 int flags; /* SP_SETPCMARK and other SP_ values */ 14086 pos_T *match_pos; 14087 linenr_T lnum_stop; /* stop at this line if not zero */ 14088 { 14089 char_u *save_cpo; 14090 char_u *pat, *pat2 = NULL, *pat3 = NULL; 14091 long retval = 0; 14092 pos_T pos; 14093 pos_T firstpos; 14094 pos_T foundpos; 14095 pos_T save_cursor; 14096 pos_T save_pos; 14097 int n; 14098 int r; 14099 int nest = 1; 14100 int err; 14101 int options = SEARCH_KEEP; 14102 14103 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 14104 save_cpo = p_cpo; 14105 p_cpo = (char_u *)""; 14106 14107 /* Make two search patterns: start/end (pat2, for in nested pairs) and 14108 * start/middle/end (pat3, for the top pair). */ 14109 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 14110 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 14111 if (pat2 == NULL || pat3 == NULL) 14112 goto theend; 14113 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 14114 if (*mpat == NUL) 14115 STRCPY(pat3, pat2); 14116 else 14117 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 14118 spat, epat, mpat); 14119 if (flags & SP_START) 14120 options |= SEARCH_START; 14121 14122 save_cursor = curwin->w_cursor; 14123 pos = curwin->w_cursor; 14124 clearpos(&firstpos); 14125 clearpos(&foundpos); 14126 pat = pat3; 14127 for (;;) 14128 { 14129 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 14130 options, RE_SEARCH, lnum_stop); 14131 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 14132 /* didn't find it or found the first match again: FAIL */ 14133 break; 14134 14135 if (firstpos.lnum == 0) 14136 firstpos = pos; 14137 if (equalpos(pos, foundpos)) 14138 { 14139 /* Found the same position again. Can happen with a pattern that 14140 * has "\zs" at the end and searching backwards. Advance one 14141 * character and try again. */ 14142 if (dir == BACKWARD) 14143 decl(&pos); 14144 else 14145 incl(&pos); 14146 } 14147 foundpos = pos; 14148 14149 /* If the skip pattern matches, ignore this match. */ 14150 if (*skip != NUL) 14151 { 14152 save_pos = curwin->w_cursor; 14153 curwin->w_cursor = pos; 14154 r = eval_to_bool(skip, &err, NULL, FALSE); 14155 curwin->w_cursor = save_pos; 14156 if (err) 14157 { 14158 /* Evaluating {skip} caused an error, break here. */ 14159 curwin->w_cursor = save_cursor; 14160 retval = -1; 14161 break; 14162 } 14163 if (r) 14164 continue; 14165 } 14166 14167 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 14168 { 14169 /* Found end when searching backwards or start when searching 14170 * forward: nested pair. */ 14171 ++nest; 14172 pat = pat2; /* nested, don't search for middle */ 14173 } 14174 else 14175 { 14176 /* Found end when searching forward or start when searching 14177 * backward: end of (nested) pair; or found middle in outer pair. */ 14178 if (--nest == 1) 14179 pat = pat3; /* outer level, search for middle */ 14180 } 14181 14182 if (nest == 0) 14183 { 14184 /* Found the match: return matchcount or line number. */ 14185 if (flags & SP_RETCOUNT) 14186 ++retval; 14187 else 14188 retval = pos.lnum; 14189 if (flags & SP_SETPCMARK) 14190 setpcmark(); 14191 curwin->w_cursor = pos; 14192 if (!(flags & SP_REPEAT)) 14193 break; 14194 nest = 1; /* search for next unmatched */ 14195 } 14196 } 14197 14198 if (match_pos != NULL) 14199 { 14200 /* Store the match cursor position */ 14201 match_pos->lnum = curwin->w_cursor.lnum; 14202 match_pos->col = curwin->w_cursor.col + 1; 14203 } 14204 14205 /* If 'n' flag is used or search failed: restore cursor position. */ 14206 if ((flags & SP_NOMOVE) || retval == 0) 14207 curwin->w_cursor = save_cursor; 14208 14209 theend: 14210 vim_free(pat2); 14211 vim_free(pat3); 14212 p_cpo = save_cpo; 14213 14214 return retval; 14215 } 14216 14217 /* 14218 * "searchpos()" function 14219 */ 14220 static void 14221 f_searchpos(argvars, rettv) 14222 typval_T *argvars; 14223 typval_T *rettv; 14224 { 14225 pos_T match_pos; 14226 int lnum = 0; 14227 int col = 0; 14228 int n; 14229 int flags = 0; 14230 14231 rettv->vval.v_number = 0; 14232 14233 if (rettv_list_alloc(rettv) == FAIL) 14234 return; 14235 14236 n = search_cmn(argvars, &match_pos, &flags); 14237 if (n > 0) 14238 { 14239 lnum = match_pos.lnum; 14240 col = match_pos.col; 14241 } 14242 14243 list_append_number(rettv->vval.v_list, (varnumber_T)lnum); 14244 list_append_number(rettv->vval.v_list, (varnumber_T)col); 14245 if (flags & SP_SUBPAT) 14246 list_append_number(rettv->vval.v_list, (varnumber_T)n); 14247 } 14248 14249 14250 /*ARGSUSED*/ 14251 static void 14252 f_server2client(argvars, rettv) 14253 typval_T *argvars; 14254 typval_T *rettv; 14255 { 14256 #ifdef FEAT_CLIENTSERVER 14257 char_u buf[NUMBUFLEN]; 14258 char_u *server = get_tv_string_chk(&argvars[0]); 14259 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 14260 14261 rettv->vval.v_number = -1; 14262 if (server == NULL || reply == NULL) 14263 return; 14264 if (check_restricted() || check_secure()) 14265 return; 14266 # ifdef FEAT_X11 14267 if (check_connection() == FAIL) 14268 return; 14269 # endif 14270 14271 if (serverSendReply(server, reply) < 0) 14272 { 14273 EMSG(_("E258: Unable to send to client")); 14274 return; 14275 } 14276 rettv->vval.v_number = 0; 14277 #else 14278 rettv->vval.v_number = -1; 14279 #endif 14280 } 14281 14282 /*ARGSUSED*/ 14283 static void 14284 f_serverlist(argvars, rettv) 14285 typval_T *argvars; 14286 typval_T *rettv; 14287 { 14288 char_u *r = NULL; 14289 14290 #ifdef FEAT_CLIENTSERVER 14291 # ifdef WIN32 14292 r = serverGetVimNames(); 14293 # else 14294 make_connection(); 14295 if (X_DISPLAY != NULL) 14296 r = serverGetVimNames(X_DISPLAY); 14297 # endif 14298 #endif 14299 rettv->v_type = VAR_STRING; 14300 rettv->vval.v_string = r; 14301 } 14302 14303 /* 14304 * "setbufvar()" function 14305 */ 14306 /*ARGSUSED*/ 14307 static void 14308 f_setbufvar(argvars, rettv) 14309 typval_T *argvars; 14310 typval_T *rettv; 14311 { 14312 buf_T *buf; 14313 aco_save_T aco; 14314 char_u *varname, *bufvarname; 14315 typval_T *varp; 14316 char_u nbuf[NUMBUFLEN]; 14317 14318 rettv->vval.v_number = 0; 14319 14320 if (check_restricted() || check_secure()) 14321 return; 14322 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 14323 varname = get_tv_string_chk(&argvars[1]); 14324 buf = get_buf_tv(&argvars[0]); 14325 varp = &argvars[2]; 14326 14327 if (buf != NULL && varname != NULL && varp != NULL) 14328 { 14329 /* set curbuf to be our buf, temporarily */ 14330 aucmd_prepbuf(&aco, buf); 14331 14332 if (*varname == '&') 14333 { 14334 long numval; 14335 char_u *strval; 14336 int error = FALSE; 14337 14338 ++varname; 14339 numval = get_tv_number_chk(varp, &error); 14340 strval = get_tv_string_buf_chk(varp, nbuf); 14341 if (!error && strval != NULL) 14342 set_option_value(varname, numval, strval, OPT_LOCAL); 14343 } 14344 else 14345 { 14346 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 14347 if (bufvarname != NULL) 14348 { 14349 STRCPY(bufvarname, "b:"); 14350 STRCPY(bufvarname + 2, varname); 14351 set_var(bufvarname, varp, TRUE); 14352 vim_free(bufvarname); 14353 } 14354 } 14355 14356 /* reset notion of buffer */ 14357 aucmd_restbuf(&aco); 14358 } 14359 } 14360 14361 /* 14362 * "setcmdpos()" function 14363 */ 14364 static void 14365 f_setcmdpos(argvars, rettv) 14366 typval_T *argvars; 14367 typval_T *rettv; 14368 { 14369 int pos = (int)get_tv_number(&argvars[0]) - 1; 14370 14371 if (pos >= 0) 14372 rettv->vval.v_number = set_cmdline_pos(pos); 14373 } 14374 14375 /* 14376 * "setline()" function 14377 */ 14378 static void 14379 f_setline(argvars, rettv) 14380 typval_T *argvars; 14381 typval_T *rettv; 14382 { 14383 linenr_T lnum; 14384 char_u *line = NULL; 14385 list_T *l = NULL; 14386 listitem_T *li = NULL; 14387 long added = 0; 14388 linenr_T lcount = curbuf->b_ml.ml_line_count; 14389 14390 lnum = get_tv_lnum(&argvars[0]); 14391 if (argvars[1].v_type == VAR_LIST) 14392 { 14393 l = argvars[1].vval.v_list; 14394 li = l->lv_first; 14395 } 14396 else 14397 line = get_tv_string_chk(&argvars[1]); 14398 14399 rettv->vval.v_number = 0; /* OK */ 14400 for (;;) 14401 { 14402 if (l != NULL) 14403 { 14404 /* list argument, get next string */ 14405 if (li == NULL) 14406 break; 14407 line = get_tv_string_chk(&li->li_tv); 14408 li = li->li_next; 14409 } 14410 14411 rettv->vval.v_number = 1; /* FAIL */ 14412 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 14413 break; 14414 if (lnum <= curbuf->b_ml.ml_line_count) 14415 { 14416 /* existing line, replace it */ 14417 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 14418 { 14419 changed_bytes(lnum, 0); 14420 if (lnum == curwin->w_cursor.lnum) 14421 check_cursor_col(); 14422 rettv->vval.v_number = 0; /* OK */ 14423 } 14424 } 14425 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 14426 { 14427 /* lnum is one past the last line, append the line */ 14428 ++added; 14429 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 14430 rettv->vval.v_number = 0; /* OK */ 14431 } 14432 14433 if (l == NULL) /* only one string argument */ 14434 break; 14435 ++lnum; 14436 } 14437 14438 if (added > 0) 14439 appended_lines_mark(lcount, added); 14440 } 14441 14442 /* 14443 * Used by "setqflist()" and "setloclist()" functions 14444 */ 14445 /*ARGSUSED*/ 14446 static void 14447 set_qf_ll_list(wp, list_arg, action_arg, rettv) 14448 win_T *wp; 14449 typval_T *list_arg; 14450 typval_T *action_arg; 14451 typval_T *rettv; 14452 { 14453 #ifdef FEAT_QUICKFIX 14454 char_u *act; 14455 int action = ' '; 14456 #endif 14457 14458 rettv->vval.v_number = -1; 14459 14460 #ifdef FEAT_QUICKFIX 14461 if (list_arg->v_type != VAR_LIST) 14462 EMSG(_(e_listreq)); 14463 else 14464 { 14465 list_T *l = list_arg->vval.v_list; 14466 14467 if (action_arg->v_type == VAR_STRING) 14468 { 14469 act = get_tv_string_chk(action_arg); 14470 if (act == NULL) 14471 return; /* type error; errmsg already given */ 14472 if (*act == 'a' || *act == 'r') 14473 action = *act; 14474 } 14475 14476 if (l != NULL && set_errorlist(wp, l, action) == OK) 14477 rettv->vval.v_number = 0; 14478 } 14479 #endif 14480 } 14481 14482 /* 14483 * "setloclist()" function 14484 */ 14485 /*ARGSUSED*/ 14486 static void 14487 f_setloclist(argvars, rettv) 14488 typval_T *argvars; 14489 typval_T *rettv; 14490 { 14491 win_T *win; 14492 14493 rettv->vval.v_number = -1; 14494 14495 win = find_win_by_nr(&argvars[0], NULL); 14496 if (win != NULL) 14497 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv); 14498 } 14499 14500 /* 14501 * "setpos()" function 14502 */ 14503 /*ARGSUSED*/ 14504 static void 14505 f_setpos(argvars, rettv) 14506 typval_T *argvars; 14507 typval_T *rettv; 14508 { 14509 pos_T pos; 14510 int fnum; 14511 char_u *name; 14512 14513 name = get_tv_string_chk(argvars); 14514 if (name != NULL) 14515 { 14516 if (list2fpos(&argvars[1], &pos, &fnum) == OK) 14517 { 14518 --pos.col; 14519 if (name[0] == '.') /* cursor */ 14520 { 14521 if (fnum == curbuf->b_fnum) 14522 { 14523 curwin->w_cursor = pos; 14524 check_cursor(); 14525 } 14526 else 14527 EMSG(_(e_invarg)); 14528 } 14529 else if (name[0] == '\'') /* mark */ 14530 (void)setmark_pos(name[1], &pos, fnum); 14531 else 14532 EMSG(_(e_invarg)); 14533 } 14534 } 14535 } 14536 14537 /* 14538 * "setqflist()" function 14539 */ 14540 /*ARGSUSED*/ 14541 static void 14542 f_setqflist(argvars, rettv) 14543 typval_T *argvars; 14544 typval_T *rettv; 14545 { 14546 set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv); 14547 } 14548 14549 /* 14550 * "setreg()" function 14551 */ 14552 static void 14553 f_setreg(argvars, rettv) 14554 typval_T *argvars; 14555 typval_T *rettv; 14556 { 14557 int regname; 14558 char_u *strregname; 14559 char_u *stropt; 14560 char_u *strval; 14561 int append; 14562 char_u yank_type; 14563 long block_len; 14564 14565 block_len = -1; 14566 yank_type = MAUTO; 14567 append = FALSE; 14568 14569 strregname = get_tv_string_chk(argvars); 14570 rettv->vval.v_number = 1; /* FAIL is default */ 14571 14572 if (strregname == NULL) 14573 return; /* type error; errmsg already given */ 14574 regname = *strregname; 14575 if (regname == 0 || regname == '@') 14576 regname = '"'; 14577 else if (regname == '=') 14578 return; 14579 14580 if (argvars[2].v_type != VAR_UNKNOWN) 14581 { 14582 stropt = get_tv_string_chk(&argvars[2]); 14583 if (stropt == NULL) 14584 return; /* type error */ 14585 for (; *stropt != NUL; ++stropt) 14586 switch (*stropt) 14587 { 14588 case 'a': case 'A': /* append */ 14589 append = TRUE; 14590 break; 14591 case 'v': case 'c': /* character-wise selection */ 14592 yank_type = MCHAR; 14593 break; 14594 case 'V': case 'l': /* line-wise selection */ 14595 yank_type = MLINE; 14596 break; 14597 #ifdef FEAT_VISUAL 14598 case 'b': case Ctrl_V: /* block-wise selection */ 14599 yank_type = MBLOCK; 14600 if (VIM_ISDIGIT(stropt[1])) 14601 { 14602 ++stropt; 14603 block_len = getdigits(&stropt) - 1; 14604 --stropt; 14605 } 14606 break; 14607 #endif 14608 } 14609 } 14610 14611 strval = get_tv_string_chk(&argvars[1]); 14612 if (strval != NULL) 14613 write_reg_contents_ex(regname, strval, -1, 14614 append, yank_type, block_len); 14615 rettv->vval.v_number = 0; 14616 } 14617 14618 /* 14619 * "settabwinvar()" function 14620 */ 14621 static void 14622 f_settabwinvar(argvars, rettv) 14623 typval_T *argvars; 14624 typval_T *rettv; 14625 { 14626 setwinvar(argvars, rettv, 1); 14627 } 14628 14629 /* 14630 * "setwinvar()" function 14631 */ 14632 static void 14633 f_setwinvar(argvars, rettv) 14634 typval_T *argvars; 14635 typval_T *rettv; 14636 { 14637 setwinvar(argvars, rettv, 0); 14638 } 14639 14640 /* 14641 * "setwinvar()" and "settabwinvar()" functions 14642 */ 14643 static void 14644 setwinvar(argvars, rettv, off) 14645 typval_T *argvars; 14646 typval_T *rettv; 14647 int off; 14648 { 14649 win_T *win; 14650 #ifdef FEAT_WINDOWS 14651 win_T *save_curwin; 14652 tabpage_T *save_curtab; 14653 #endif 14654 char_u *varname, *winvarname; 14655 typval_T *varp; 14656 char_u nbuf[NUMBUFLEN]; 14657 tabpage_T *tp; 14658 14659 rettv->vval.v_number = 0; 14660 14661 if (check_restricted() || check_secure()) 14662 return; 14663 14664 #ifdef FEAT_WINDOWS 14665 if (off == 1) 14666 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); 14667 else 14668 tp = curtab; 14669 #endif 14670 win = find_win_by_nr(&argvars[off], tp); 14671 varname = get_tv_string_chk(&argvars[off + 1]); 14672 varp = &argvars[off + 2]; 14673 14674 if (win != NULL && varname != NULL && varp != NULL) 14675 { 14676 #ifdef FEAT_WINDOWS 14677 /* set curwin to be our win, temporarily */ 14678 save_curwin = curwin; 14679 save_curtab = curtab; 14680 goto_tabpage_tp(tp); 14681 if (!win_valid(win)) 14682 return; 14683 curwin = win; 14684 curbuf = curwin->w_buffer; 14685 #endif 14686 14687 if (*varname == '&') 14688 { 14689 long numval; 14690 char_u *strval; 14691 int error = FALSE; 14692 14693 ++varname; 14694 numval = get_tv_number_chk(varp, &error); 14695 strval = get_tv_string_buf_chk(varp, nbuf); 14696 if (!error && strval != NULL) 14697 set_option_value(varname, numval, strval, OPT_LOCAL); 14698 } 14699 else 14700 { 14701 winvarname = alloc((unsigned)STRLEN(varname) + 3); 14702 if (winvarname != NULL) 14703 { 14704 STRCPY(winvarname, "w:"); 14705 STRCPY(winvarname + 2, varname); 14706 set_var(winvarname, varp, TRUE); 14707 vim_free(winvarname); 14708 } 14709 } 14710 14711 #ifdef FEAT_WINDOWS 14712 /* Restore current tabpage and window, if still valid (autocomands can 14713 * make them invalid). */ 14714 if (valid_tabpage(save_curtab)) 14715 goto_tabpage_tp(save_curtab); 14716 if (win_valid(save_curwin)) 14717 { 14718 curwin = save_curwin; 14719 curbuf = curwin->w_buffer; 14720 } 14721 #endif 14722 } 14723 } 14724 14725 /* 14726 * "shellescape({string})" function 14727 */ 14728 static void 14729 f_shellescape(argvars, rettv) 14730 typval_T *argvars; 14731 typval_T *rettv; 14732 { 14733 rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0])); 14734 rettv->v_type = VAR_STRING; 14735 } 14736 14737 /* 14738 * "simplify()" function 14739 */ 14740 static void 14741 f_simplify(argvars, rettv) 14742 typval_T *argvars; 14743 typval_T *rettv; 14744 { 14745 char_u *p; 14746 14747 p = get_tv_string(&argvars[0]); 14748 rettv->vval.v_string = vim_strsave(p); 14749 simplify_filename(rettv->vval.v_string); /* simplify in place */ 14750 rettv->v_type = VAR_STRING; 14751 } 14752 14753 static int 14754 #ifdef __BORLANDC__ 14755 _RTLENTRYF 14756 #endif 14757 item_compare __ARGS((const void *s1, const void *s2)); 14758 static int 14759 #ifdef __BORLANDC__ 14760 _RTLENTRYF 14761 #endif 14762 item_compare2 __ARGS((const void *s1, const void *s2)); 14763 14764 static int item_compare_ic; 14765 static char_u *item_compare_func; 14766 static int item_compare_func_err; 14767 #define ITEM_COMPARE_FAIL 999 14768 14769 /* 14770 * Compare functions for f_sort() below. 14771 */ 14772 static int 14773 #ifdef __BORLANDC__ 14774 _RTLENTRYF 14775 #endif 14776 item_compare(s1, s2) 14777 const void *s1; 14778 const void *s2; 14779 { 14780 char_u *p1, *p2; 14781 char_u *tofree1, *tofree2; 14782 int res; 14783 char_u numbuf1[NUMBUFLEN]; 14784 char_u numbuf2[NUMBUFLEN]; 14785 14786 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0); 14787 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0); 14788 if (item_compare_ic) 14789 res = STRICMP(p1, p2); 14790 else 14791 res = STRCMP(p1, p2); 14792 vim_free(tofree1); 14793 vim_free(tofree2); 14794 return res; 14795 } 14796 14797 static int 14798 #ifdef __BORLANDC__ 14799 _RTLENTRYF 14800 #endif 14801 item_compare2(s1, s2) 14802 const void *s1; 14803 const void *s2; 14804 { 14805 int res; 14806 typval_T rettv; 14807 typval_T argv[3]; 14808 int dummy; 14809 14810 /* shortcut after failure in previous call; compare all items equal */ 14811 if (item_compare_func_err) 14812 return 0; 14813 14814 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 14815 * in the copy without changing the original list items. */ 14816 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 14817 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 14818 14819 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 14820 res = call_func(item_compare_func, (int)STRLEN(item_compare_func), 14821 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 14822 clear_tv(&argv[0]); 14823 clear_tv(&argv[1]); 14824 14825 if (res == FAIL) 14826 res = ITEM_COMPARE_FAIL; 14827 else 14828 /* return value has wrong type */ 14829 res = get_tv_number_chk(&rettv, &item_compare_func_err); 14830 if (item_compare_func_err) 14831 res = ITEM_COMPARE_FAIL; 14832 clear_tv(&rettv); 14833 return res; 14834 } 14835 14836 /* 14837 * "sort({list})" function 14838 */ 14839 static void 14840 f_sort(argvars, rettv) 14841 typval_T *argvars; 14842 typval_T *rettv; 14843 { 14844 list_T *l; 14845 listitem_T *li; 14846 listitem_T **ptrs; 14847 long len; 14848 long i; 14849 14850 rettv->vval.v_number = 0; 14851 if (argvars[0].v_type != VAR_LIST) 14852 EMSG2(_(e_listarg), "sort()"); 14853 else 14854 { 14855 l = argvars[0].vval.v_list; 14856 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 14857 return; 14858 rettv->vval.v_list = l; 14859 rettv->v_type = VAR_LIST; 14860 ++l->lv_refcount; 14861 14862 len = list_len(l); 14863 if (len <= 1) 14864 return; /* short list sorts pretty quickly */ 14865 14866 item_compare_ic = FALSE; 14867 item_compare_func = NULL; 14868 if (argvars[1].v_type != VAR_UNKNOWN) 14869 { 14870 if (argvars[1].v_type == VAR_FUNC) 14871 item_compare_func = argvars[1].vval.v_string; 14872 else 14873 { 14874 int error = FALSE; 14875 14876 i = get_tv_number_chk(&argvars[1], &error); 14877 if (error) 14878 return; /* type error; errmsg already given */ 14879 if (i == 1) 14880 item_compare_ic = TRUE; 14881 else 14882 item_compare_func = get_tv_string(&argvars[1]); 14883 } 14884 } 14885 14886 /* Make an array with each entry pointing to an item in the List. */ 14887 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 14888 if (ptrs == NULL) 14889 return; 14890 i = 0; 14891 for (li = l->lv_first; li != NULL; li = li->li_next) 14892 ptrs[i++] = li; 14893 14894 item_compare_func_err = FALSE; 14895 /* test the compare function */ 14896 if (item_compare_func != NULL 14897 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 14898 == ITEM_COMPARE_FAIL) 14899 EMSG(_("E702: Sort compare function failed")); 14900 else 14901 { 14902 /* Sort the array with item pointers. */ 14903 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 14904 item_compare_func == NULL ? item_compare : item_compare2); 14905 14906 if (!item_compare_func_err) 14907 { 14908 /* Clear the List and append the items in the sorted order. */ 14909 l->lv_first = l->lv_last = NULL; 14910 l->lv_len = 0; 14911 for (i = 0; i < len; ++i) 14912 list_append(l, ptrs[i]); 14913 } 14914 } 14915 14916 vim_free(ptrs); 14917 } 14918 } 14919 14920 /* 14921 * "soundfold({word})" function 14922 */ 14923 static void 14924 f_soundfold(argvars, rettv) 14925 typval_T *argvars; 14926 typval_T *rettv; 14927 { 14928 char_u *s; 14929 14930 rettv->v_type = VAR_STRING; 14931 s = get_tv_string(&argvars[0]); 14932 #ifdef FEAT_SPELL 14933 rettv->vval.v_string = eval_soundfold(s); 14934 #else 14935 rettv->vval.v_string = vim_strsave(s); 14936 #endif 14937 } 14938 14939 /* 14940 * "spellbadword()" function 14941 */ 14942 /* ARGSUSED */ 14943 static void 14944 f_spellbadword(argvars, rettv) 14945 typval_T *argvars; 14946 typval_T *rettv; 14947 { 14948 char_u *word = (char_u *)""; 14949 hlf_T attr = HLF_COUNT; 14950 int len = 0; 14951 14952 if (rettv_list_alloc(rettv) == FAIL) 14953 return; 14954 14955 #ifdef FEAT_SPELL 14956 if (argvars[0].v_type == VAR_UNKNOWN) 14957 { 14958 /* Find the start and length of the badly spelled word. */ 14959 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr); 14960 if (len != 0) 14961 word = ml_get_cursor(); 14962 } 14963 else if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 14964 { 14965 char_u *str = get_tv_string_chk(&argvars[0]); 14966 int capcol = -1; 14967 14968 if (str != NULL) 14969 { 14970 /* Check the argument for spelling. */ 14971 while (*str != NUL) 14972 { 14973 len = spell_check(curwin, str, &attr, &capcol, FALSE); 14974 if (attr != HLF_COUNT) 14975 { 14976 word = str; 14977 break; 14978 } 14979 str += len; 14980 } 14981 } 14982 } 14983 #endif 14984 14985 list_append_string(rettv->vval.v_list, word, len); 14986 list_append_string(rettv->vval.v_list, (char_u *)( 14987 attr == HLF_SPB ? "bad" : 14988 attr == HLF_SPR ? "rare" : 14989 attr == HLF_SPL ? "local" : 14990 attr == HLF_SPC ? "caps" : 14991 ""), -1); 14992 } 14993 14994 /* 14995 * "spellsuggest()" function 14996 */ 14997 /*ARGSUSED*/ 14998 static void 14999 f_spellsuggest(argvars, rettv) 15000 typval_T *argvars; 15001 typval_T *rettv; 15002 { 15003 #ifdef FEAT_SPELL 15004 char_u *str; 15005 int typeerr = FALSE; 15006 int maxcount; 15007 garray_T ga; 15008 int i; 15009 listitem_T *li; 15010 int need_capital = FALSE; 15011 #endif 15012 15013 if (rettv_list_alloc(rettv) == FAIL) 15014 return; 15015 15016 #ifdef FEAT_SPELL 15017 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 15018 { 15019 str = get_tv_string(&argvars[0]); 15020 if (argvars[1].v_type != VAR_UNKNOWN) 15021 { 15022 maxcount = get_tv_number_chk(&argvars[1], &typeerr); 15023 if (maxcount <= 0) 15024 return; 15025 if (argvars[2].v_type != VAR_UNKNOWN) 15026 { 15027 need_capital = get_tv_number_chk(&argvars[2], &typeerr); 15028 if (typeerr) 15029 return; 15030 } 15031 } 15032 else 15033 maxcount = 25; 15034 15035 spell_suggest_list(&ga, str, maxcount, need_capital, FALSE); 15036 15037 for (i = 0; i < ga.ga_len; ++i) 15038 { 15039 str = ((char_u **)ga.ga_data)[i]; 15040 15041 li = listitem_alloc(); 15042 if (li == NULL) 15043 vim_free(str); 15044 else 15045 { 15046 li->li_tv.v_type = VAR_STRING; 15047 li->li_tv.v_lock = 0; 15048 li->li_tv.vval.v_string = str; 15049 list_append(rettv->vval.v_list, li); 15050 } 15051 } 15052 ga_clear(&ga); 15053 } 15054 #endif 15055 } 15056 15057 static void 15058 f_split(argvars, rettv) 15059 typval_T *argvars; 15060 typval_T *rettv; 15061 { 15062 char_u *str; 15063 char_u *end; 15064 char_u *pat = NULL; 15065 regmatch_T regmatch; 15066 char_u patbuf[NUMBUFLEN]; 15067 char_u *save_cpo; 15068 int match; 15069 colnr_T col = 0; 15070 int keepempty = FALSE; 15071 int typeerr = FALSE; 15072 15073 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 15074 save_cpo = p_cpo; 15075 p_cpo = (char_u *)""; 15076 15077 str = get_tv_string(&argvars[0]); 15078 if (argvars[1].v_type != VAR_UNKNOWN) 15079 { 15080 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15081 if (pat == NULL) 15082 typeerr = TRUE; 15083 if (argvars[2].v_type != VAR_UNKNOWN) 15084 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 15085 } 15086 if (pat == NULL || *pat == NUL) 15087 pat = (char_u *)"[\\x01- ]\\+"; 15088 15089 if (rettv_list_alloc(rettv) == FAIL) 15090 return; 15091 if (typeerr) 15092 return; 15093 15094 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 15095 if (regmatch.regprog != NULL) 15096 { 15097 regmatch.rm_ic = FALSE; 15098 while (*str != NUL || keepempty) 15099 { 15100 if (*str == NUL) 15101 match = FALSE; /* empty item at the end */ 15102 else 15103 match = vim_regexec_nl(®match, str, col); 15104 if (match) 15105 end = regmatch.startp[0]; 15106 else 15107 end = str + STRLEN(str); 15108 if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0 15109 && *str != NUL && match && end < regmatch.endp[0])) 15110 { 15111 if (list_append_string(rettv->vval.v_list, str, 15112 (int)(end - str)) == FAIL) 15113 break; 15114 } 15115 if (!match) 15116 break; 15117 /* Advance to just after the match. */ 15118 if (regmatch.endp[0] > str) 15119 col = 0; 15120 else 15121 { 15122 /* Don't get stuck at the same match. */ 15123 #ifdef FEAT_MBYTE 15124 col = (*mb_ptr2len)(regmatch.endp[0]); 15125 #else 15126 col = 1; 15127 #endif 15128 } 15129 str = regmatch.endp[0]; 15130 } 15131 15132 vim_free(regmatch.regprog); 15133 } 15134 15135 p_cpo = save_cpo; 15136 } 15137 15138 /* 15139 * "str2nr()" function 15140 */ 15141 static void 15142 f_str2nr(argvars, rettv) 15143 typval_T *argvars; 15144 typval_T *rettv; 15145 { 15146 int base = 10; 15147 char_u *p; 15148 long n; 15149 15150 if (argvars[1].v_type != VAR_UNKNOWN) 15151 { 15152 base = get_tv_number(&argvars[1]); 15153 if (base != 8 && base != 10 && base != 16) 15154 { 15155 EMSG(_(e_invarg)); 15156 return; 15157 } 15158 } 15159 15160 p = skipwhite(get_tv_string(&argvars[0])); 15161 vim_str2nr(p, NULL, NULL, base == 8 ? 2 : 0, base == 16 ? 2 : 0, &n, NULL); 15162 rettv->vval.v_number = n; 15163 } 15164 15165 #ifdef HAVE_STRFTIME 15166 /* 15167 * "strftime({format}[, {time}])" function 15168 */ 15169 static void 15170 f_strftime(argvars, rettv) 15171 typval_T *argvars; 15172 typval_T *rettv; 15173 { 15174 char_u result_buf[256]; 15175 struct tm *curtime; 15176 time_t seconds; 15177 char_u *p; 15178 15179 rettv->v_type = VAR_STRING; 15180 15181 p = get_tv_string(&argvars[0]); 15182 if (argvars[1].v_type == VAR_UNKNOWN) 15183 seconds = time(NULL); 15184 else 15185 seconds = (time_t)get_tv_number(&argvars[1]); 15186 curtime = localtime(&seconds); 15187 /* MSVC returns NULL for an invalid value of seconds. */ 15188 if (curtime == NULL) 15189 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 15190 else 15191 { 15192 # ifdef FEAT_MBYTE 15193 vimconv_T conv; 15194 char_u *enc; 15195 15196 conv.vc_type = CONV_NONE; 15197 enc = enc_locale(); 15198 convert_setup(&conv, p_enc, enc); 15199 if (conv.vc_type != CONV_NONE) 15200 p = string_convert(&conv, p, NULL); 15201 # endif 15202 if (p != NULL) 15203 (void)strftime((char *)result_buf, sizeof(result_buf), 15204 (char *)p, curtime); 15205 else 15206 result_buf[0] = NUL; 15207 15208 # ifdef FEAT_MBYTE 15209 if (conv.vc_type != CONV_NONE) 15210 vim_free(p); 15211 convert_setup(&conv, enc, p_enc); 15212 if (conv.vc_type != CONV_NONE) 15213 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 15214 else 15215 # endif 15216 rettv->vval.v_string = vim_strsave(result_buf); 15217 15218 # ifdef FEAT_MBYTE 15219 /* Release conversion descriptors */ 15220 convert_setup(&conv, NULL, NULL); 15221 vim_free(enc); 15222 # endif 15223 } 15224 } 15225 #endif 15226 15227 /* 15228 * "stridx()" function 15229 */ 15230 static void 15231 f_stridx(argvars, rettv) 15232 typval_T *argvars; 15233 typval_T *rettv; 15234 { 15235 char_u buf[NUMBUFLEN]; 15236 char_u *needle; 15237 char_u *haystack; 15238 char_u *save_haystack; 15239 char_u *pos; 15240 int start_idx; 15241 15242 needle = get_tv_string_chk(&argvars[1]); 15243 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 15244 rettv->vval.v_number = -1; 15245 if (needle == NULL || haystack == NULL) 15246 return; /* type error; errmsg already given */ 15247 15248 if (argvars[2].v_type != VAR_UNKNOWN) 15249 { 15250 int error = FALSE; 15251 15252 start_idx = get_tv_number_chk(&argvars[2], &error); 15253 if (error || start_idx >= (int)STRLEN(haystack)) 15254 return; 15255 if (start_idx >= 0) 15256 haystack += start_idx; 15257 } 15258 15259 pos = (char_u *)strstr((char *)haystack, (char *)needle); 15260 if (pos != NULL) 15261 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 15262 } 15263 15264 /* 15265 * "string()" function 15266 */ 15267 static void 15268 f_string(argvars, rettv) 15269 typval_T *argvars; 15270 typval_T *rettv; 15271 { 15272 char_u *tofree; 15273 char_u numbuf[NUMBUFLEN]; 15274 15275 rettv->v_type = VAR_STRING; 15276 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0); 15277 if (tofree == NULL) 15278 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 15279 } 15280 15281 /* 15282 * "strlen()" function 15283 */ 15284 static void 15285 f_strlen(argvars, rettv) 15286 typval_T *argvars; 15287 typval_T *rettv; 15288 { 15289 rettv->vval.v_number = (varnumber_T)(STRLEN( 15290 get_tv_string(&argvars[0]))); 15291 } 15292 15293 /* 15294 * "strpart()" function 15295 */ 15296 static void 15297 f_strpart(argvars, rettv) 15298 typval_T *argvars; 15299 typval_T *rettv; 15300 { 15301 char_u *p; 15302 int n; 15303 int len; 15304 int slen; 15305 int error = FALSE; 15306 15307 p = get_tv_string(&argvars[0]); 15308 slen = (int)STRLEN(p); 15309 15310 n = get_tv_number_chk(&argvars[1], &error); 15311 if (error) 15312 len = 0; 15313 else if (argvars[2].v_type != VAR_UNKNOWN) 15314 len = get_tv_number(&argvars[2]); 15315 else 15316 len = slen - n; /* default len: all bytes that are available. */ 15317 15318 /* 15319 * Only return the overlap between the specified part and the actual 15320 * string. 15321 */ 15322 if (n < 0) 15323 { 15324 len += n; 15325 n = 0; 15326 } 15327 else if (n > slen) 15328 n = slen; 15329 if (len < 0) 15330 len = 0; 15331 else if (n + len > slen) 15332 len = slen - n; 15333 15334 rettv->v_type = VAR_STRING; 15335 rettv->vval.v_string = vim_strnsave(p + n, len); 15336 } 15337 15338 /* 15339 * "strridx()" function 15340 */ 15341 static void 15342 f_strridx(argvars, rettv) 15343 typval_T *argvars; 15344 typval_T *rettv; 15345 { 15346 char_u buf[NUMBUFLEN]; 15347 char_u *needle; 15348 char_u *haystack; 15349 char_u *rest; 15350 char_u *lastmatch = NULL; 15351 int haystack_len, end_idx; 15352 15353 needle = get_tv_string_chk(&argvars[1]); 15354 haystack = get_tv_string_buf_chk(&argvars[0], buf); 15355 15356 rettv->vval.v_number = -1; 15357 if (needle == NULL || haystack == NULL) 15358 return; /* type error; errmsg already given */ 15359 15360 haystack_len = (int)STRLEN(haystack); 15361 if (argvars[2].v_type != VAR_UNKNOWN) 15362 { 15363 /* Third argument: upper limit for index */ 15364 end_idx = get_tv_number_chk(&argvars[2], NULL); 15365 if (end_idx < 0) 15366 return; /* can never find a match */ 15367 } 15368 else 15369 end_idx = haystack_len; 15370 15371 if (*needle == NUL) 15372 { 15373 /* Empty string matches past the end. */ 15374 lastmatch = haystack + end_idx; 15375 } 15376 else 15377 { 15378 for (rest = haystack; *rest != '\0'; ++rest) 15379 { 15380 rest = (char_u *)strstr((char *)rest, (char *)needle); 15381 if (rest == NULL || rest > haystack + end_idx) 15382 break; 15383 lastmatch = rest; 15384 } 15385 } 15386 15387 if (lastmatch == NULL) 15388 rettv->vval.v_number = -1; 15389 else 15390 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 15391 } 15392 15393 /* 15394 * "strtrans()" function 15395 */ 15396 static void 15397 f_strtrans(argvars, rettv) 15398 typval_T *argvars; 15399 typval_T *rettv; 15400 { 15401 rettv->v_type = VAR_STRING; 15402 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 15403 } 15404 15405 /* 15406 * "submatch()" function 15407 */ 15408 static void 15409 f_submatch(argvars, rettv) 15410 typval_T *argvars; 15411 typval_T *rettv; 15412 { 15413 rettv->v_type = VAR_STRING; 15414 rettv->vval.v_string = 15415 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 15416 } 15417 15418 /* 15419 * "substitute()" function 15420 */ 15421 static void 15422 f_substitute(argvars, rettv) 15423 typval_T *argvars; 15424 typval_T *rettv; 15425 { 15426 char_u patbuf[NUMBUFLEN]; 15427 char_u subbuf[NUMBUFLEN]; 15428 char_u flagsbuf[NUMBUFLEN]; 15429 15430 char_u *str = get_tv_string_chk(&argvars[0]); 15431 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 15432 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 15433 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 15434 15435 rettv->v_type = VAR_STRING; 15436 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 15437 rettv->vval.v_string = NULL; 15438 else 15439 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 15440 } 15441 15442 /* 15443 * "synID(lnum, col, trans)" function 15444 */ 15445 /*ARGSUSED*/ 15446 static void 15447 f_synID(argvars, rettv) 15448 typval_T *argvars; 15449 typval_T *rettv; 15450 { 15451 int id = 0; 15452 #ifdef FEAT_SYN_HL 15453 long lnum; 15454 long col; 15455 int trans; 15456 int transerr = FALSE; 15457 15458 lnum = get_tv_lnum(argvars); /* -1 on type error */ 15459 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 15460 trans = get_tv_number_chk(&argvars[2], &transerr); 15461 15462 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 15463 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 15464 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 15465 #endif 15466 15467 rettv->vval.v_number = id; 15468 } 15469 15470 /* 15471 * "synIDattr(id, what [, mode])" function 15472 */ 15473 /*ARGSUSED*/ 15474 static void 15475 f_synIDattr(argvars, rettv) 15476 typval_T *argvars; 15477 typval_T *rettv; 15478 { 15479 char_u *p = NULL; 15480 #ifdef FEAT_SYN_HL 15481 int id; 15482 char_u *what; 15483 char_u *mode; 15484 char_u modebuf[NUMBUFLEN]; 15485 int modec; 15486 15487 id = get_tv_number(&argvars[0]); 15488 what = get_tv_string(&argvars[1]); 15489 if (argvars[2].v_type != VAR_UNKNOWN) 15490 { 15491 mode = get_tv_string_buf(&argvars[2], modebuf); 15492 modec = TOLOWER_ASC(mode[0]); 15493 if (modec != 't' && modec != 'c' 15494 #ifdef FEAT_GUI 15495 && modec != 'g' 15496 #endif 15497 ) 15498 modec = 0; /* replace invalid with current */ 15499 } 15500 else 15501 { 15502 #ifdef FEAT_GUI 15503 if (gui.in_use) 15504 modec = 'g'; 15505 else 15506 #endif 15507 if (t_colors > 1) 15508 modec = 'c'; 15509 else 15510 modec = 't'; 15511 } 15512 15513 15514 switch (TOLOWER_ASC(what[0])) 15515 { 15516 case 'b': 15517 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 15518 p = highlight_color(id, what, modec); 15519 else /* bold */ 15520 p = highlight_has_attr(id, HL_BOLD, modec); 15521 break; 15522 15523 case 'f': /* fg[#] */ 15524 p = highlight_color(id, what, modec); 15525 break; 15526 15527 case 'i': 15528 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 15529 p = highlight_has_attr(id, HL_INVERSE, modec); 15530 else /* italic */ 15531 p = highlight_has_attr(id, HL_ITALIC, modec); 15532 break; 15533 15534 case 'n': /* name */ 15535 p = get_highlight_name(NULL, id - 1); 15536 break; 15537 15538 case 'r': /* reverse */ 15539 p = highlight_has_attr(id, HL_INVERSE, modec); 15540 break; 15541 15542 case 's': /* standout */ 15543 p = highlight_has_attr(id, HL_STANDOUT, modec); 15544 break; 15545 15546 case 'u': 15547 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 15548 /* underline */ 15549 p = highlight_has_attr(id, HL_UNDERLINE, modec); 15550 else 15551 /* undercurl */ 15552 p = highlight_has_attr(id, HL_UNDERCURL, modec); 15553 break; 15554 } 15555 15556 if (p != NULL) 15557 p = vim_strsave(p); 15558 #endif 15559 rettv->v_type = VAR_STRING; 15560 rettv->vval.v_string = p; 15561 } 15562 15563 /* 15564 * "synIDtrans(id)" function 15565 */ 15566 /*ARGSUSED*/ 15567 static void 15568 f_synIDtrans(argvars, rettv) 15569 typval_T *argvars; 15570 typval_T *rettv; 15571 { 15572 int id; 15573 15574 #ifdef FEAT_SYN_HL 15575 id = get_tv_number(&argvars[0]); 15576 15577 if (id > 0) 15578 id = syn_get_final_id(id); 15579 else 15580 #endif 15581 id = 0; 15582 15583 rettv->vval.v_number = id; 15584 } 15585 15586 /* 15587 * "system()" function 15588 */ 15589 static void 15590 f_system(argvars, rettv) 15591 typval_T *argvars; 15592 typval_T *rettv; 15593 { 15594 char_u *res = NULL; 15595 char_u *p; 15596 char_u *infile = NULL; 15597 char_u buf[NUMBUFLEN]; 15598 int err = FALSE; 15599 FILE *fd; 15600 15601 if (check_restricted() || check_secure()) 15602 return; 15603 15604 if (argvars[1].v_type != VAR_UNKNOWN) 15605 { 15606 /* 15607 * Write the string to a temp file, to be used for input of the shell 15608 * command. 15609 */ 15610 if ((infile = vim_tempname('i')) == NULL) 15611 { 15612 EMSG(_(e_notmp)); 15613 return; 15614 } 15615 15616 fd = mch_fopen((char *)infile, WRITEBIN); 15617 if (fd == NULL) 15618 { 15619 EMSG2(_(e_notopen), infile); 15620 goto done; 15621 } 15622 p = get_tv_string_buf_chk(&argvars[1], buf); 15623 if (p == NULL) 15624 { 15625 fclose(fd); 15626 goto done; /* type error; errmsg already given */ 15627 } 15628 if (fwrite(p, STRLEN(p), 1, fd) != 1) 15629 err = TRUE; 15630 if (fclose(fd) != 0) 15631 err = TRUE; 15632 if (err) 15633 { 15634 EMSG(_("E677: Error writing temp file")); 15635 goto done; 15636 } 15637 } 15638 15639 res = get_cmd_output(get_tv_string(&argvars[0]), infile, 15640 SHELL_SILENT | SHELL_COOKED); 15641 15642 #ifdef USE_CR 15643 /* translate <CR> into <NL> */ 15644 if (res != NULL) 15645 { 15646 char_u *s; 15647 15648 for (s = res; *s; ++s) 15649 { 15650 if (*s == CAR) 15651 *s = NL; 15652 } 15653 } 15654 #else 15655 # ifdef USE_CRNL 15656 /* translate <CR><NL> into <NL> */ 15657 if (res != NULL) 15658 { 15659 char_u *s, *d; 15660 15661 d = res; 15662 for (s = res; *s; ++s) 15663 { 15664 if (s[0] == CAR && s[1] == NL) 15665 ++s; 15666 *d++ = *s; 15667 } 15668 *d = NUL; 15669 } 15670 # endif 15671 #endif 15672 15673 done: 15674 if (infile != NULL) 15675 { 15676 mch_remove(infile); 15677 vim_free(infile); 15678 } 15679 rettv->v_type = VAR_STRING; 15680 rettv->vval.v_string = res; 15681 } 15682 15683 /* 15684 * "tabpagebuflist()" function 15685 */ 15686 /* ARGSUSED */ 15687 static void 15688 f_tabpagebuflist(argvars, rettv) 15689 typval_T *argvars; 15690 typval_T *rettv; 15691 { 15692 #ifndef FEAT_WINDOWS 15693 rettv->vval.v_number = 0; 15694 #else 15695 tabpage_T *tp; 15696 win_T *wp = NULL; 15697 15698 if (argvars[0].v_type == VAR_UNKNOWN) 15699 wp = firstwin; 15700 else 15701 { 15702 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15703 if (tp != NULL) 15704 wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15705 } 15706 if (wp == NULL) 15707 rettv->vval.v_number = 0; 15708 else 15709 { 15710 if (rettv_list_alloc(rettv) == FAIL) 15711 rettv->vval.v_number = 0; 15712 else 15713 { 15714 for (; wp != NULL; wp = wp->w_next) 15715 if (list_append_number(rettv->vval.v_list, 15716 wp->w_buffer->b_fnum) == FAIL) 15717 break; 15718 } 15719 } 15720 #endif 15721 } 15722 15723 15724 /* 15725 * "tabpagenr()" function 15726 */ 15727 /* ARGSUSED */ 15728 static void 15729 f_tabpagenr(argvars, rettv) 15730 typval_T *argvars; 15731 typval_T *rettv; 15732 { 15733 int nr = 1; 15734 #ifdef FEAT_WINDOWS 15735 char_u *arg; 15736 15737 if (argvars[0].v_type != VAR_UNKNOWN) 15738 { 15739 arg = get_tv_string_chk(&argvars[0]); 15740 nr = 0; 15741 if (arg != NULL) 15742 { 15743 if (STRCMP(arg, "$") == 0) 15744 nr = tabpage_index(NULL) - 1; 15745 else 15746 EMSG2(_(e_invexpr2), arg); 15747 } 15748 } 15749 else 15750 nr = tabpage_index(curtab); 15751 #endif 15752 rettv->vval.v_number = nr; 15753 } 15754 15755 15756 #ifdef FEAT_WINDOWS 15757 static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar)); 15758 15759 /* 15760 * Common code for tabpagewinnr() and winnr(). 15761 */ 15762 static int 15763 get_winnr(tp, argvar) 15764 tabpage_T *tp; 15765 typval_T *argvar; 15766 { 15767 win_T *twin; 15768 int nr = 1; 15769 win_T *wp; 15770 char_u *arg; 15771 15772 twin = (tp == curtab) ? curwin : tp->tp_curwin; 15773 if (argvar->v_type != VAR_UNKNOWN) 15774 { 15775 arg = get_tv_string_chk(argvar); 15776 if (arg == NULL) 15777 nr = 0; /* type error; errmsg already given */ 15778 else if (STRCMP(arg, "$") == 0) 15779 twin = (tp == curtab) ? lastwin : tp->tp_lastwin; 15780 else if (STRCMP(arg, "#") == 0) 15781 { 15782 twin = (tp == curtab) ? prevwin : tp->tp_prevwin; 15783 if (twin == NULL) 15784 nr = 0; 15785 } 15786 else 15787 { 15788 EMSG2(_(e_invexpr2), arg); 15789 nr = 0; 15790 } 15791 } 15792 15793 if (nr > 0) 15794 for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; 15795 wp != twin; wp = wp->w_next) 15796 { 15797 if (wp == NULL) 15798 { 15799 /* didn't find it in this tabpage */ 15800 nr = 0; 15801 break; 15802 } 15803 ++nr; 15804 } 15805 return nr; 15806 } 15807 #endif 15808 15809 /* 15810 * "tabpagewinnr()" function 15811 */ 15812 /* ARGSUSED */ 15813 static void 15814 f_tabpagewinnr(argvars, rettv) 15815 typval_T *argvars; 15816 typval_T *rettv; 15817 { 15818 int nr = 1; 15819 #ifdef FEAT_WINDOWS 15820 tabpage_T *tp; 15821 15822 tp = find_tabpage((int)get_tv_number(&argvars[0])); 15823 if (tp == NULL) 15824 nr = 0; 15825 else 15826 nr = get_winnr(tp, &argvars[1]); 15827 #endif 15828 rettv->vval.v_number = nr; 15829 } 15830 15831 15832 /* 15833 * "tagfiles()" function 15834 */ 15835 /*ARGSUSED*/ 15836 static void 15837 f_tagfiles(argvars, rettv) 15838 typval_T *argvars; 15839 typval_T *rettv; 15840 { 15841 char_u fname[MAXPATHL + 1]; 15842 tagname_T tn; 15843 int first; 15844 15845 if (rettv_list_alloc(rettv) == FAIL) 15846 { 15847 rettv->vval.v_number = 0; 15848 return; 15849 } 15850 15851 for (first = TRUE; ; first = FALSE) 15852 if (get_tagfname(&tn, first, fname) == FAIL 15853 || list_append_string(rettv->vval.v_list, fname, -1) == FAIL) 15854 break; 15855 tagname_free(&tn); 15856 } 15857 15858 /* 15859 * "taglist()" function 15860 */ 15861 static void 15862 f_taglist(argvars, rettv) 15863 typval_T *argvars; 15864 typval_T *rettv; 15865 { 15866 char_u *tag_pattern; 15867 15868 tag_pattern = get_tv_string(&argvars[0]); 15869 15870 rettv->vval.v_number = FALSE; 15871 if (*tag_pattern == NUL) 15872 return; 15873 15874 if (rettv_list_alloc(rettv) == OK) 15875 (void)get_tags(rettv->vval.v_list, tag_pattern); 15876 } 15877 15878 /* 15879 * "tempname()" function 15880 */ 15881 /*ARGSUSED*/ 15882 static void 15883 f_tempname(argvars, rettv) 15884 typval_T *argvars; 15885 typval_T *rettv; 15886 { 15887 static int x = 'A'; 15888 15889 rettv->v_type = VAR_STRING; 15890 rettv->vval.v_string = vim_tempname(x); 15891 15892 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 15893 * names. Skip 'I' and 'O', they are used for shell redirection. */ 15894 do 15895 { 15896 if (x == 'Z') 15897 x = '0'; 15898 else if (x == '9') 15899 x = 'A'; 15900 else 15901 { 15902 #ifdef EBCDIC 15903 if (x == 'I') 15904 x = 'J'; 15905 else if (x == 'R') 15906 x = 'S'; 15907 else 15908 #endif 15909 ++x; 15910 } 15911 } while (x == 'I' || x == 'O'); 15912 } 15913 15914 /* 15915 * "test(list)" function: Just checking the walls... 15916 */ 15917 /*ARGSUSED*/ 15918 static void 15919 f_test(argvars, rettv) 15920 typval_T *argvars; 15921 typval_T *rettv; 15922 { 15923 /* Used for unit testing. Change the code below to your liking. */ 15924 #if 0 15925 listitem_T *li; 15926 list_T *l; 15927 char_u *bad, *good; 15928 15929 if (argvars[0].v_type != VAR_LIST) 15930 return; 15931 l = argvars[0].vval.v_list; 15932 if (l == NULL) 15933 return; 15934 li = l->lv_first; 15935 if (li == NULL) 15936 return; 15937 bad = get_tv_string(&li->li_tv); 15938 li = li->li_next; 15939 if (li == NULL) 15940 return; 15941 good = get_tv_string(&li->li_tv); 15942 rettv->vval.v_number = test_edit_score(bad, good); 15943 #endif 15944 } 15945 15946 /* 15947 * "tolower(string)" function 15948 */ 15949 static void 15950 f_tolower(argvars, rettv) 15951 typval_T *argvars; 15952 typval_T *rettv; 15953 { 15954 char_u *p; 15955 15956 p = vim_strsave(get_tv_string(&argvars[0])); 15957 rettv->v_type = VAR_STRING; 15958 rettv->vval.v_string = p; 15959 15960 if (p != NULL) 15961 while (*p != NUL) 15962 { 15963 #ifdef FEAT_MBYTE 15964 int l; 15965 15966 if (enc_utf8) 15967 { 15968 int c, lc; 15969 15970 c = utf_ptr2char(p); 15971 lc = utf_tolower(c); 15972 l = utf_ptr2len(p); 15973 /* TODO: reallocate string when byte count changes. */ 15974 if (utf_char2len(lc) == l) 15975 utf_char2bytes(lc, p); 15976 p += l; 15977 } 15978 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 15979 p += l; /* skip multi-byte character */ 15980 else 15981 #endif 15982 { 15983 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 15984 ++p; 15985 } 15986 } 15987 } 15988 15989 /* 15990 * "toupper(string)" function 15991 */ 15992 static void 15993 f_toupper(argvars, rettv) 15994 typval_T *argvars; 15995 typval_T *rettv; 15996 { 15997 rettv->v_type = VAR_STRING; 15998 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 15999 } 16000 16001 /* 16002 * "tr(string, fromstr, tostr)" function 16003 */ 16004 static void 16005 f_tr(argvars, rettv) 16006 typval_T *argvars; 16007 typval_T *rettv; 16008 { 16009 char_u *instr; 16010 char_u *fromstr; 16011 char_u *tostr; 16012 char_u *p; 16013 #ifdef FEAT_MBYTE 16014 int inlen; 16015 int fromlen; 16016 int tolen; 16017 int idx; 16018 char_u *cpstr; 16019 int cplen; 16020 int first = TRUE; 16021 #endif 16022 char_u buf[NUMBUFLEN]; 16023 char_u buf2[NUMBUFLEN]; 16024 garray_T ga; 16025 16026 instr = get_tv_string(&argvars[0]); 16027 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 16028 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 16029 16030 /* Default return value: empty string. */ 16031 rettv->v_type = VAR_STRING; 16032 rettv->vval.v_string = NULL; 16033 if (fromstr == NULL || tostr == NULL) 16034 return; /* type error; errmsg already given */ 16035 ga_init2(&ga, (int)sizeof(char), 80); 16036 16037 #ifdef FEAT_MBYTE 16038 if (!has_mbyte) 16039 #endif 16040 /* not multi-byte: fromstr and tostr must be the same length */ 16041 if (STRLEN(fromstr) != STRLEN(tostr)) 16042 { 16043 #ifdef FEAT_MBYTE 16044 error: 16045 #endif 16046 EMSG2(_(e_invarg2), fromstr); 16047 ga_clear(&ga); 16048 return; 16049 } 16050 16051 /* fromstr and tostr have to contain the same number of chars */ 16052 while (*instr != NUL) 16053 { 16054 #ifdef FEAT_MBYTE 16055 if (has_mbyte) 16056 { 16057 inlen = (*mb_ptr2len)(instr); 16058 cpstr = instr; 16059 cplen = inlen; 16060 idx = 0; 16061 for (p = fromstr; *p != NUL; p += fromlen) 16062 { 16063 fromlen = (*mb_ptr2len)(p); 16064 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 16065 { 16066 for (p = tostr; *p != NUL; p += tolen) 16067 { 16068 tolen = (*mb_ptr2len)(p); 16069 if (idx-- == 0) 16070 { 16071 cplen = tolen; 16072 cpstr = p; 16073 break; 16074 } 16075 } 16076 if (*p == NUL) /* tostr is shorter than fromstr */ 16077 goto error; 16078 break; 16079 } 16080 ++idx; 16081 } 16082 16083 if (first && cpstr == instr) 16084 { 16085 /* Check that fromstr and tostr have the same number of 16086 * (multi-byte) characters. Done only once when a character 16087 * of instr doesn't appear in fromstr. */ 16088 first = FALSE; 16089 for (p = tostr; *p != NUL; p += tolen) 16090 { 16091 tolen = (*mb_ptr2len)(p); 16092 --idx; 16093 } 16094 if (idx != 0) 16095 goto error; 16096 } 16097 16098 ga_grow(&ga, cplen); 16099 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 16100 ga.ga_len += cplen; 16101 16102 instr += inlen; 16103 } 16104 else 16105 #endif 16106 { 16107 /* When not using multi-byte chars we can do it faster. */ 16108 p = vim_strchr(fromstr, *instr); 16109 if (p != NULL) 16110 ga_append(&ga, tostr[p - fromstr]); 16111 else 16112 ga_append(&ga, *instr); 16113 ++instr; 16114 } 16115 } 16116 16117 /* add a terminating NUL */ 16118 ga_grow(&ga, 1); 16119 ga_append(&ga, NUL); 16120 16121 rettv->vval.v_string = ga.ga_data; 16122 } 16123 16124 /* 16125 * "type(expr)" function 16126 */ 16127 static void 16128 f_type(argvars, rettv) 16129 typval_T *argvars; 16130 typval_T *rettv; 16131 { 16132 int n; 16133 16134 switch (argvars[0].v_type) 16135 { 16136 case VAR_NUMBER: n = 0; break; 16137 case VAR_STRING: n = 1; break; 16138 case VAR_FUNC: n = 2; break; 16139 case VAR_LIST: n = 3; break; 16140 case VAR_DICT: n = 4; break; 16141 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 16142 } 16143 rettv->vval.v_number = n; 16144 } 16145 16146 /* 16147 * "values(dict)" function 16148 */ 16149 static void 16150 f_values(argvars, rettv) 16151 typval_T *argvars; 16152 typval_T *rettv; 16153 { 16154 dict_list(argvars, rettv, 1); 16155 } 16156 16157 /* 16158 * "virtcol(string)" function 16159 */ 16160 static void 16161 f_virtcol(argvars, rettv) 16162 typval_T *argvars; 16163 typval_T *rettv; 16164 { 16165 colnr_T vcol = 0; 16166 pos_T *fp; 16167 int fnum = curbuf->b_fnum; 16168 16169 fp = var2fpos(&argvars[0], FALSE, &fnum); 16170 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count 16171 && fnum == curbuf->b_fnum) 16172 { 16173 getvvcol(curwin, fp, NULL, NULL, &vcol); 16174 ++vcol; 16175 } 16176 16177 rettv->vval.v_number = vcol; 16178 } 16179 16180 /* 16181 * "visualmode()" function 16182 */ 16183 /*ARGSUSED*/ 16184 static void 16185 f_visualmode(argvars, rettv) 16186 typval_T *argvars; 16187 typval_T *rettv; 16188 { 16189 #ifdef FEAT_VISUAL 16190 char_u str[2]; 16191 16192 rettv->v_type = VAR_STRING; 16193 str[0] = curbuf->b_visual_mode_eval; 16194 str[1] = NUL; 16195 rettv->vval.v_string = vim_strsave(str); 16196 16197 /* A non-zero number or non-empty string argument: reset mode. */ 16198 if ((argvars[0].v_type == VAR_NUMBER 16199 && argvars[0].vval.v_number != 0) 16200 || (argvars[0].v_type == VAR_STRING 16201 && *get_tv_string(&argvars[0]) != NUL)) 16202 curbuf->b_visual_mode_eval = NUL; 16203 #else 16204 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 16205 #endif 16206 } 16207 16208 /* 16209 * "winbufnr(nr)" function 16210 */ 16211 static void 16212 f_winbufnr(argvars, rettv) 16213 typval_T *argvars; 16214 typval_T *rettv; 16215 { 16216 win_T *wp; 16217 16218 wp = find_win_by_nr(&argvars[0], NULL); 16219 if (wp == NULL) 16220 rettv->vval.v_number = -1; 16221 else 16222 rettv->vval.v_number = wp->w_buffer->b_fnum; 16223 } 16224 16225 /* 16226 * "wincol()" function 16227 */ 16228 /*ARGSUSED*/ 16229 static void 16230 f_wincol(argvars, rettv) 16231 typval_T *argvars; 16232 typval_T *rettv; 16233 { 16234 validate_cursor(); 16235 rettv->vval.v_number = curwin->w_wcol + 1; 16236 } 16237 16238 /* 16239 * "winheight(nr)" function 16240 */ 16241 static void 16242 f_winheight(argvars, rettv) 16243 typval_T *argvars; 16244 typval_T *rettv; 16245 { 16246 win_T *wp; 16247 16248 wp = find_win_by_nr(&argvars[0], NULL); 16249 if (wp == NULL) 16250 rettv->vval.v_number = -1; 16251 else 16252 rettv->vval.v_number = wp->w_height; 16253 } 16254 16255 /* 16256 * "winline()" function 16257 */ 16258 /*ARGSUSED*/ 16259 static void 16260 f_winline(argvars, rettv) 16261 typval_T *argvars; 16262 typval_T *rettv; 16263 { 16264 validate_cursor(); 16265 rettv->vval.v_number = curwin->w_wrow + 1; 16266 } 16267 16268 /* 16269 * "winnr()" function 16270 */ 16271 /* ARGSUSED */ 16272 static void 16273 f_winnr(argvars, rettv) 16274 typval_T *argvars; 16275 typval_T *rettv; 16276 { 16277 int nr = 1; 16278 16279 #ifdef FEAT_WINDOWS 16280 nr = get_winnr(curtab, &argvars[0]); 16281 #endif 16282 rettv->vval.v_number = nr; 16283 } 16284 16285 /* 16286 * "winrestcmd()" function 16287 */ 16288 /* ARGSUSED */ 16289 static void 16290 f_winrestcmd(argvars, rettv) 16291 typval_T *argvars; 16292 typval_T *rettv; 16293 { 16294 #ifdef FEAT_WINDOWS 16295 win_T *wp; 16296 int winnr = 1; 16297 garray_T ga; 16298 char_u buf[50]; 16299 16300 ga_init2(&ga, (int)sizeof(char), 70); 16301 for (wp = firstwin; wp != NULL; wp = wp->w_next) 16302 { 16303 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 16304 ga_concat(&ga, buf); 16305 # ifdef FEAT_VERTSPLIT 16306 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 16307 ga_concat(&ga, buf); 16308 # endif 16309 ++winnr; 16310 } 16311 ga_append(&ga, NUL); 16312 16313 rettv->vval.v_string = ga.ga_data; 16314 #else 16315 rettv->vval.v_string = NULL; 16316 #endif 16317 rettv->v_type = VAR_STRING; 16318 } 16319 16320 /* 16321 * "winrestview()" function 16322 */ 16323 /* ARGSUSED */ 16324 static void 16325 f_winrestview(argvars, rettv) 16326 typval_T *argvars; 16327 typval_T *rettv; 16328 { 16329 dict_T *dict; 16330 16331 if (argvars[0].v_type != VAR_DICT 16332 || (dict = argvars[0].vval.v_dict) == NULL) 16333 EMSG(_(e_invarg)); 16334 else 16335 { 16336 curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum"); 16337 curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col"); 16338 #ifdef FEAT_VIRTUALEDIT 16339 curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd"); 16340 #endif 16341 curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant"); 16342 curwin->w_set_curswant = FALSE; 16343 16344 set_topline(curwin, get_dict_number(dict, (char_u *)"topline")); 16345 #ifdef FEAT_DIFF 16346 curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill"); 16347 #endif 16348 curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol"); 16349 curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol"); 16350 16351 check_cursor(); 16352 changed_cline_bef_curs(); 16353 invalidate_botline(); 16354 redraw_later(VALID); 16355 16356 if (curwin->w_topline == 0) 16357 curwin->w_topline = 1; 16358 if (curwin->w_topline > curbuf->b_ml.ml_line_count) 16359 curwin->w_topline = curbuf->b_ml.ml_line_count; 16360 #ifdef FEAT_DIFF 16361 check_topfill(curwin, TRUE); 16362 #endif 16363 } 16364 } 16365 16366 /* 16367 * "winsaveview()" function 16368 */ 16369 /* ARGSUSED */ 16370 static void 16371 f_winsaveview(argvars, rettv) 16372 typval_T *argvars; 16373 typval_T *rettv; 16374 { 16375 dict_T *dict; 16376 16377 dict = dict_alloc(); 16378 if (dict == NULL) 16379 return; 16380 rettv->v_type = VAR_DICT; 16381 rettv->vval.v_dict = dict; 16382 ++dict->dv_refcount; 16383 16384 dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL); 16385 dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL); 16386 #ifdef FEAT_VIRTUALEDIT 16387 dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL); 16388 #endif 16389 update_curswant(); 16390 dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL); 16391 16392 dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL); 16393 #ifdef FEAT_DIFF 16394 dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL); 16395 #endif 16396 dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL); 16397 dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL); 16398 } 16399 16400 /* 16401 * "winwidth(nr)" function 16402 */ 16403 static void 16404 f_winwidth(argvars, rettv) 16405 typval_T *argvars; 16406 typval_T *rettv; 16407 { 16408 win_T *wp; 16409 16410 wp = find_win_by_nr(&argvars[0], NULL); 16411 if (wp == NULL) 16412 rettv->vval.v_number = -1; 16413 else 16414 #ifdef FEAT_VERTSPLIT 16415 rettv->vval.v_number = wp->w_width; 16416 #else 16417 rettv->vval.v_number = Columns; 16418 #endif 16419 } 16420 16421 /* 16422 * "writefile()" function 16423 */ 16424 static void 16425 f_writefile(argvars, rettv) 16426 typval_T *argvars; 16427 typval_T *rettv; 16428 { 16429 int binary = FALSE; 16430 char_u *fname; 16431 FILE *fd; 16432 listitem_T *li; 16433 char_u *s; 16434 int ret = 0; 16435 int c; 16436 16437 if (check_restricted() || check_secure()) 16438 return; 16439 16440 if (argvars[0].v_type != VAR_LIST) 16441 { 16442 EMSG2(_(e_listarg), "writefile()"); 16443 return; 16444 } 16445 if (argvars[0].vval.v_list == NULL) 16446 return; 16447 16448 if (argvars[2].v_type != VAR_UNKNOWN 16449 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 16450 binary = TRUE; 16451 16452 /* Always open the file in binary mode, library functions have a mind of 16453 * their own about CR-LF conversion. */ 16454 fname = get_tv_string(&argvars[1]); 16455 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 16456 { 16457 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 16458 ret = -1; 16459 } 16460 else 16461 { 16462 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 16463 li = li->li_next) 16464 { 16465 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 16466 { 16467 if (*s == '\n') 16468 c = putc(NUL, fd); 16469 else 16470 c = putc(*s, fd); 16471 if (c == EOF) 16472 { 16473 ret = -1; 16474 break; 16475 } 16476 } 16477 if (!binary || li->li_next != NULL) 16478 if (putc('\n', fd) == EOF) 16479 { 16480 ret = -1; 16481 break; 16482 } 16483 if (ret < 0) 16484 { 16485 EMSG(_(e_write)); 16486 break; 16487 } 16488 } 16489 fclose(fd); 16490 } 16491 16492 rettv->vval.v_number = ret; 16493 } 16494 16495 /* 16496 * Translate a String variable into a position. 16497 * Returns NULL when there is an error. 16498 */ 16499 static pos_T * 16500 var2fpos(varp, lnum, fnum) 16501 typval_T *varp; 16502 int lnum; /* TRUE when $ is last line */ 16503 int *fnum; /* set to fnum for '0, 'A, etc. */ 16504 { 16505 char_u *name; 16506 static pos_T pos; 16507 pos_T *pp; 16508 16509 /* Argument can be [lnum, col, coladd]. */ 16510 if (varp->v_type == VAR_LIST) 16511 { 16512 list_T *l; 16513 int len; 16514 int error = FALSE; 16515 16516 l = varp->vval.v_list; 16517 if (l == NULL) 16518 return NULL; 16519 16520 /* Get the line number */ 16521 pos.lnum = list_find_nr(l, 0L, &error); 16522 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) 16523 return NULL; /* invalid line number */ 16524 16525 /* Get the column number */ 16526 pos.col = list_find_nr(l, 1L, &error); 16527 if (error) 16528 return NULL; 16529 len = (long)STRLEN(ml_get(pos.lnum)); 16530 /* Accept a position up to the NUL after the line. */ 16531 if (pos.col == 0 || (int)pos.col > len + 1) 16532 return NULL; /* invalid column number */ 16533 --pos.col; 16534 16535 #ifdef FEAT_VIRTUALEDIT 16536 /* Get the virtual offset. Defaults to zero. */ 16537 pos.coladd = list_find_nr(l, 2L, &error); 16538 if (error) 16539 pos.coladd = 0; 16540 #endif 16541 16542 return &pos; 16543 } 16544 16545 name = get_tv_string_chk(varp); 16546 if (name == NULL) 16547 return NULL; 16548 if (name[0] == '.') /* cursor */ 16549 return &curwin->w_cursor; 16550 if (name[0] == '\'') /* mark */ 16551 { 16552 pp = getmark_fnum(name[1], FALSE, fnum); 16553 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 16554 return NULL; 16555 return pp; 16556 } 16557 16558 #ifdef FEAT_VIRTUALEDIT 16559 pos.coladd = 0; 16560 #endif 16561 16562 if (name[0] == 'w' && lnum) 16563 { 16564 pos.col = 0; 16565 if (name[1] == '0') /* "w0": first visible line */ 16566 { 16567 update_topline(); 16568 pos.lnum = curwin->w_topline; 16569 return &pos; 16570 } 16571 else if (name[1] == '$') /* "w$": last visible line */ 16572 { 16573 validate_botline(); 16574 pos.lnum = curwin->w_botline - 1; 16575 return &pos; 16576 } 16577 } 16578 else if (name[0] == '$') /* last column or line */ 16579 { 16580 if (lnum) 16581 { 16582 pos.lnum = curbuf->b_ml.ml_line_count; 16583 pos.col = 0; 16584 } 16585 else 16586 { 16587 pos.lnum = curwin->w_cursor.lnum; 16588 pos.col = (colnr_T)STRLEN(ml_get_curline()); 16589 } 16590 return &pos; 16591 } 16592 return NULL; 16593 } 16594 16595 /* 16596 * Convert list in "arg" into a position and optional file number. 16597 * When "fnump" is NULL there is no file number, only 3 items. 16598 * Note that the column is passed on as-is, the caller may want to decrement 16599 * it to use 1 for the first column. 16600 * Return FAIL when conversion is not possible, doesn't check the position for 16601 * validity. 16602 */ 16603 static int 16604 list2fpos(arg, posp, fnump) 16605 typval_T *arg; 16606 pos_T *posp; 16607 int *fnump; 16608 { 16609 list_T *l = arg->vval.v_list; 16610 long i = 0; 16611 long n; 16612 16613 /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there 16614 * when "fnump" isn't NULL and "coladd" is optional. */ 16615 if (arg->v_type != VAR_LIST 16616 || l == NULL 16617 || l->lv_len < (fnump == NULL ? 2 : 3) 16618 || l->lv_len > (fnump == NULL ? 3 : 4)) 16619 return FAIL; 16620 16621 if (fnump != NULL) 16622 { 16623 n = list_find_nr(l, i++, NULL); /* fnum */ 16624 if (n < 0) 16625 return FAIL; 16626 if (n == 0) 16627 n = curbuf->b_fnum; /* current buffer */ 16628 *fnump = n; 16629 } 16630 16631 n = list_find_nr(l, i++, NULL); /* lnum */ 16632 if (n < 0) 16633 return FAIL; 16634 posp->lnum = n; 16635 16636 n = list_find_nr(l, i++, NULL); /* col */ 16637 if (n < 0) 16638 return FAIL; 16639 posp->col = n; 16640 16641 #ifdef FEAT_VIRTUALEDIT 16642 n = list_find_nr(l, i, NULL); 16643 if (n < 0) 16644 posp->coladd = 0; 16645 else 16646 posp->coladd = n; 16647 #endif 16648 16649 return OK; 16650 } 16651 16652 /* 16653 * Get the length of an environment variable name. 16654 * Advance "arg" to the first character after the name. 16655 * Return 0 for error. 16656 */ 16657 static int 16658 get_env_len(arg) 16659 char_u **arg; 16660 { 16661 char_u *p; 16662 int len; 16663 16664 for (p = *arg; vim_isIDc(*p); ++p) 16665 ; 16666 if (p == *arg) /* no name found */ 16667 return 0; 16668 16669 len = (int)(p - *arg); 16670 *arg = p; 16671 return len; 16672 } 16673 16674 /* 16675 * Get the length of the name of a function or internal variable. 16676 * "arg" is advanced to the first non-white character after the name. 16677 * Return 0 if something is wrong. 16678 */ 16679 static int 16680 get_id_len(arg) 16681 char_u **arg; 16682 { 16683 char_u *p; 16684 int len; 16685 16686 /* Find the end of the name. */ 16687 for (p = *arg; eval_isnamec(*p); ++p) 16688 ; 16689 if (p == *arg) /* no name found */ 16690 return 0; 16691 16692 len = (int)(p - *arg); 16693 *arg = skipwhite(p); 16694 16695 return len; 16696 } 16697 16698 /* 16699 * Get the length of the name of a variable or function. 16700 * Only the name is recognized, does not handle ".key" or "[idx]". 16701 * "arg" is advanced to the first non-white character after the name. 16702 * Return -1 if curly braces expansion failed. 16703 * Return 0 if something else is wrong. 16704 * If the name contains 'magic' {}'s, expand them and return the 16705 * expanded name in an allocated string via 'alias' - caller must free. 16706 */ 16707 static int 16708 get_name_len(arg, alias, evaluate, verbose) 16709 char_u **arg; 16710 char_u **alias; 16711 int evaluate; 16712 int verbose; 16713 { 16714 int len; 16715 char_u *p; 16716 char_u *expr_start; 16717 char_u *expr_end; 16718 16719 *alias = NULL; /* default to no alias */ 16720 16721 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 16722 && (*arg)[2] == (int)KE_SNR) 16723 { 16724 /* hard coded <SNR>, already translated */ 16725 *arg += 3; 16726 return get_id_len(arg) + 3; 16727 } 16728 len = eval_fname_script(*arg); 16729 if (len > 0) 16730 { 16731 /* literal "<SID>", "s:" or "<SNR>" */ 16732 *arg += len; 16733 } 16734 16735 /* 16736 * Find the end of the name; check for {} construction. 16737 */ 16738 p = find_name_end(*arg, &expr_start, &expr_end, 16739 len > 0 ? 0 : FNE_CHECK_START); 16740 if (expr_start != NULL) 16741 { 16742 char_u *temp_string; 16743 16744 if (!evaluate) 16745 { 16746 len += (int)(p - *arg); 16747 *arg = skipwhite(p); 16748 return len; 16749 } 16750 16751 /* 16752 * Include any <SID> etc in the expanded string: 16753 * Thus the -len here. 16754 */ 16755 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 16756 if (temp_string == NULL) 16757 return -1; 16758 *alias = temp_string; 16759 *arg = skipwhite(p); 16760 return (int)STRLEN(temp_string); 16761 } 16762 16763 len += get_id_len(arg); 16764 if (len == 0 && verbose) 16765 EMSG2(_(e_invexpr2), *arg); 16766 16767 return len; 16768 } 16769 16770 /* 16771 * Find the end of a variable or function name, taking care of magic braces. 16772 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 16773 * start and end of the first magic braces item. 16774 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 16775 * Return a pointer to just after the name. Equal to "arg" if there is no 16776 * valid name. 16777 */ 16778 static char_u * 16779 find_name_end(arg, expr_start, expr_end, flags) 16780 char_u *arg; 16781 char_u **expr_start; 16782 char_u **expr_end; 16783 int flags; 16784 { 16785 int mb_nest = 0; 16786 int br_nest = 0; 16787 char_u *p; 16788 16789 if (expr_start != NULL) 16790 { 16791 *expr_start = NULL; 16792 *expr_end = NULL; 16793 } 16794 16795 /* Quick check for valid starting character. */ 16796 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 16797 return arg; 16798 16799 for (p = arg; *p != NUL 16800 && (eval_isnamec(*p) 16801 || *p == '{' 16802 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 16803 || mb_nest != 0 16804 || br_nest != 0); mb_ptr_adv(p)) 16805 { 16806 if (*p == '\'') 16807 { 16808 /* skip over 'string' to avoid counting [ and ] inside it. */ 16809 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 16810 ; 16811 if (*p == NUL) 16812 break; 16813 } 16814 else if (*p == '"') 16815 { 16816 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 16817 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 16818 if (*p == '\\' && p[1] != NUL) 16819 ++p; 16820 if (*p == NUL) 16821 break; 16822 } 16823 16824 if (mb_nest == 0) 16825 { 16826 if (*p == '[') 16827 ++br_nest; 16828 else if (*p == ']') 16829 --br_nest; 16830 } 16831 16832 if (br_nest == 0) 16833 { 16834 if (*p == '{') 16835 { 16836 mb_nest++; 16837 if (expr_start != NULL && *expr_start == NULL) 16838 *expr_start = p; 16839 } 16840 else if (*p == '}') 16841 { 16842 mb_nest--; 16843 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 16844 *expr_end = p; 16845 } 16846 } 16847 } 16848 16849 return p; 16850 } 16851 16852 /* 16853 * Expands out the 'magic' {}'s in a variable/function name. 16854 * Note that this can call itself recursively, to deal with 16855 * constructs like foo{bar}{baz}{bam} 16856 * The four pointer arguments point to "foo{expre}ss{ion}bar" 16857 * "in_start" ^ 16858 * "expr_start" ^ 16859 * "expr_end" ^ 16860 * "in_end" ^ 16861 * 16862 * Returns a new allocated string, which the caller must free. 16863 * Returns NULL for failure. 16864 */ 16865 static char_u * 16866 make_expanded_name(in_start, expr_start, expr_end, in_end) 16867 char_u *in_start; 16868 char_u *expr_start; 16869 char_u *expr_end; 16870 char_u *in_end; 16871 { 16872 char_u c1; 16873 char_u *retval = NULL; 16874 char_u *temp_result; 16875 char_u *nextcmd = NULL; 16876 16877 if (expr_end == NULL || in_end == NULL) 16878 return NULL; 16879 *expr_start = NUL; 16880 *expr_end = NUL; 16881 c1 = *in_end; 16882 *in_end = NUL; 16883 16884 temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); 16885 if (temp_result != NULL && nextcmd == NULL) 16886 { 16887 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 16888 + (in_end - expr_end) + 1)); 16889 if (retval != NULL) 16890 { 16891 STRCPY(retval, in_start); 16892 STRCAT(retval, temp_result); 16893 STRCAT(retval, expr_end + 1); 16894 } 16895 } 16896 vim_free(temp_result); 16897 16898 *in_end = c1; /* put char back for error messages */ 16899 *expr_start = '{'; 16900 *expr_end = '}'; 16901 16902 if (retval != NULL) 16903 { 16904 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 16905 if (expr_start != NULL) 16906 { 16907 /* Further expansion! */ 16908 temp_result = make_expanded_name(retval, expr_start, 16909 expr_end, temp_result); 16910 vim_free(retval); 16911 retval = temp_result; 16912 } 16913 } 16914 16915 return retval; 16916 } 16917 16918 /* 16919 * Return TRUE if character "c" can be used in a variable or function name. 16920 * Does not include '{' or '}' for magic braces. 16921 */ 16922 static int 16923 eval_isnamec(c) 16924 int c; 16925 { 16926 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 16927 } 16928 16929 /* 16930 * Return TRUE if character "c" can be used as the first character in a 16931 * variable or function name (excluding '{' and '}'). 16932 */ 16933 static int 16934 eval_isnamec1(c) 16935 int c; 16936 { 16937 return (ASCII_ISALPHA(c) || c == '_'); 16938 } 16939 16940 /* 16941 * Set number v: variable to "val". 16942 */ 16943 void 16944 set_vim_var_nr(idx, val) 16945 int idx; 16946 long val; 16947 { 16948 vimvars[idx].vv_nr = val; 16949 } 16950 16951 /* 16952 * Get number v: variable value. 16953 */ 16954 long 16955 get_vim_var_nr(idx) 16956 int idx; 16957 { 16958 return vimvars[idx].vv_nr; 16959 } 16960 16961 #if defined(FEAT_AUTOCMD) || defined(PROTO) 16962 /* 16963 * Get string v: variable value. Uses a static buffer, can only be used once. 16964 */ 16965 char_u * 16966 get_vim_var_str(idx) 16967 int idx; 16968 { 16969 return get_tv_string(&vimvars[idx].vv_tv); 16970 } 16971 #endif 16972 16973 /* 16974 * Set v:count, v:count1 and v:prevcount. 16975 */ 16976 void 16977 set_vcount(count, count1) 16978 long count; 16979 long count1; 16980 { 16981 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 16982 vimvars[VV_COUNT].vv_nr = count; 16983 vimvars[VV_COUNT1].vv_nr = count1; 16984 } 16985 16986 /* 16987 * Set string v: variable to a copy of "val". 16988 */ 16989 void 16990 set_vim_var_string(idx, val, len) 16991 int idx; 16992 char_u *val; 16993 int len; /* length of "val" to use or -1 (whole string) */ 16994 { 16995 /* Need to do this (at least) once, since we can't initialize a union. 16996 * Will always be invoked when "v:progname" is set. */ 16997 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 16998 16999 vim_free(vimvars[idx].vv_str); 17000 if (val == NULL) 17001 vimvars[idx].vv_str = NULL; 17002 else if (len == -1) 17003 vimvars[idx].vv_str = vim_strsave(val); 17004 else 17005 vimvars[idx].vv_str = vim_strnsave(val, len); 17006 } 17007 17008 /* 17009 * Set v:register if needed. 17010 */ 17011 void 17012 set_reg_var(c) 17013 int c; 17014 { 17015 char_u regname; 17016 17017 if (c == 0 || c == ' ') 17018 regname = '"'; 17019 else 17020 regname = c; 17021 /* Avoid free/alloc when the value is already right. */ 17022 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 17023 set_vim_var_string(VV_REG, ®name, 1); 17024 } 17025 17026 /* 17027 * Get or set v:exception. If "oldval" == NULL, return the current value. 17028 * Otherwise, restore the value to "oldval" and return NULL. 17029 * Must always be called in pairs to save and restore v:exception! Does not 17030 * take care of memory allocations. 17031 */ 17032 char_u * 17033 v_exception(oldval) 17034 char_u *oldval; 17035 { 17036 if (oldval == NULL) 17037 return vimvars[VV_EXCEPTION].vv_str; 17038 17039 vimvars[VV_EXCEPTION].vv_str = oldval; 17040 return NULL; 17041 } 17042 17043 /* 17044 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 17045 * Otherwise, restore the value to "oldval" and return NULL. 17046 * Must always be called in pairs to save and restore v:throwpoint! Does not 17047 * take care of memory allocations. 17048 */ 17049 char_u * 17050 v_throwpoint(oldval) 17051 char_u *oldval; 17052 { 17053 if (oldval == NULL) 17054 return vimvars[VV_THROWPOINT].vv_str; 17055 17056 vimvars[VV_THROWPOINT].vv_str = oldval; 17057 return NULL; 17058 } 17059 17060 #if defined(FEAT_AUTOCMD) || defined(PROTO) 17061 /* 17062 * Set v:cmdarg. 17063 * If "eap" != NULL, use "eap" to generate the value and return the old value. 17064 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 17065 * Must always be called in pairs! 17066 */ 17067 char_u * 17068 set_cmdarg(eap, oldarg) 17069 exarg_T *eap; 17070 char_u *oldarg; 17071 { 17072 char_u *oldval; 17073 char_u *newval; 17074 unsigned len; 17075 17076 oldval = vimvars[VV_CMDARG].vv_str; 17077 if (eap == NULL) 17078 { 17079 vim_free(oldval); 17080 vimvars[VV_CMDARG].vv_str = oldarg; 17081 return NULL; 17082 } 17083 17084 if (eap->force_bin == FORCE_BIN) 17085 len = 6; 17086 else if (eap->force_bin == FORCE_NOBIN) 17087 len = 8; 17088 else 17089 len = 0; 17090 17091 if (eap->read_edit) 17092 len += 7; 17093 17094 if (eap->force_ff != 0) 17095 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 17096 # ifdef FEAT_MBYTE 17097 if (eap->force_enc != 0) 17098 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 17099 if (eap->bad_char != 0) 17100 len += (unsigned)STRLEN(eap->cmd + eap->bad_char) + 7; 17101 # endif 17102 17103 newval = alloc(len + 1); 17104 if (newval == NULL) 17105 return NULL; 17106 17107 if (eap->force_bin == FORCE_BIN) 17108 sprintf((char *)newval, " ++bin"); 17109 else if (eap->force_bin == FORCE_NOBIN) 17110 sprintf((char *)newval, " ++nobin"); 17111 else 17112 *newval = NUL; 17113 17114 if (eap->read_edit) 17115 STRCAT(newval, " ++edit"); 17116 17117 if (eap->force_ff != 0) 17118 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 17119 eap->cmd + eap->force_ff); 17120 # ifdef FEAT_MBYTE 17121 if (eap->force_enc != 0) 17122 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 17123 eap->cmd + eap->force_enc); 17124 if (eap->bad_char != 0) 17125 sprintf((char *)newval + STRLEN(newval), " ++bad=%s", 17126 eap->cmd + eap->bad_char); 17127 # endif 17128 vimvars[VV_CMDARG].vv_str = newval; 17129 return oldval; 17130 } 17131 #endif 17132 17133 /* 17134 * Get the value of internal variable "name". 17135 * Return OK or FAIL. 17136 */ 17137 static int 17138 get_var_tv(name, len, rettv, verbose) 17139 char_u *name; 17140 int len; /* length of "name" */ 17141 typval_T *rettv; /* NULL when only checking existence */ 17142 int verbose; /* may give error message */ 17143 { 17144 int ret = OK; 17145 typval_T *tv = NULL; 17146 typval_T atv; 17147 dictitem_T *v; 17148 int cc; 17149 17150 /* truncate the name, so that we can use strcmp() */ 17151 cc = name[len]; 17152 name[len] = NUL; 17153 17154 /* 17155 * Check for "b:changedtick". 17156 */ 17157 if (STRCMP(name, "b:changedtick") == 0) 17158 { 17159 atv.v_type = VAR_NUMBER; 17160 atv.vval.v_number = curbuf->b_changedtick; 17161 tv = &atv; 17162 } 17163 17164 /* 17165 * Check for user-defined variables. 17166 */ 17167 else 17168 { 17169 v = find_var(name, NULL); 17170 if (v != NULL) 17171 tv = &v->di_tv; 17172 } 17173 17174 if (tv == NULL) 17175 { 17176 if (rettv != NULL && verbose) 17177 EMSG2(_(e_undefvar), name); 17178 ret = FAIL; 17179 } 17180 else if (rettv != NULL) 17181 copy_tv(tv, rettv); 17182 17183 name[len] = cc; 17184 17185 return ret; 17186 } 17187 17188 /* 17189 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 17190 * Also handle function call with Funcref variable: func(expr) 17191 * Can all be combined: dict.func(expr)[idx]['func'](expr) 17192 */ 17193 static int 17194 handle_subscript(arg, rettv, evaluate, verbose) 17195 char_u **arg; 17196 typval_T *rettv; 17197 int evaluate; /* do more than finding the end */ 17198 int verbose; /* give error messages */ 17199 { 17200 int ret = OK; 17201 dict_T *selfdict = NULL; 17202 char_u *s; 17203 int len; 17204 typval_T functv; 17205 17206 while (ret == OK 17207 && (**arg == '[' 17208 || (**arg == '.' && rettv->v_type == VAR_DICT) 17209 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 17210 && !vim_iswhite(*(*arg - 1))) 17211 { 17212 if (**arg == '(') 17213 { 17214 /* need to copy the funcref so that we can clear rettv */ 17215 functv = *rettv; 17216 rettv->v_type = VAR_UNKNOWN; 17217 17218 /* Invoke the function. Recursive! */ 17219 s = functv.vval.v_string; 17220 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, 17221 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 17222 &len, evaluate, selfdict); 17223 17224 /* Clear the funcref afterwards, so that deleting it while 17225 * evaluating the arguments is possible (see test55). */ 17226 clear_tv(&functv); 17227 17228 /* Stop the expression evaluation when immediately aborting on 17229 * error, or when an interrupt occurred or an exception was thrown 17230 * but not caught. */ 17231 if (aborting()) 17232 { 17233 if (ret == OK) 17234 clear_tv(rettv); 17235 ret = FAIL; 17236 } 17237 dict_unref(selfdict); 17238 selfdict = NULL; 17239 } 17240 else /* **arg == '[' || **arg == '.' */ 17241 { 17242 dict_unref(selfdict); 17243 if (rettv->v_type == VAR_DICT) 17244 { 17245 selfdict = rettv->vval.v_dict; 17246 if (selfdict != NULL) 17247 ++selfdict->dv_refcount; 17248 } 17249 else 17250 selfdict = NULL; 17251 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 17252 { 17253 clear_tv(rettv); 17254 ret = FAIL; 17255 } 17256 } 17257 } 17258 dict_unref(selfdict); 17259 return ret; 17260 } 17261 17262 /* 17263 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 17264 * value). 17265 */ 17266 static typval_T * 17267 alloc_tv() 17268 { 17269 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 17270 } 17271 17272 /* 17273 * Allocate memory for a variable type-value, and assign a string to it. 17274 * The string "s" must have been allocated, it is consumed. 17275 * Return NULL for out of memory, the variable otherwise. 17276 */ 17277 static typval_T * 17278 alloc_string_tv(s) 17279 char_u *s; 17280 { 17281 typval_T *rettv; 17282 17283 rettv = alloc_tv(); 17284 if (rettv != NULL) 17285 { 17286 rettv->v_type = VAR_STRING; 17287 rettv->vval.v_string = s; 17288 } 17289 else 17290 vim_free(s); 17291 return rettv; 17292 } 17293 17294 /* 17295 * Free the memory for a variable type-value. 17296 */ 17297 void 17298 free_tv(varp) 17299 typval_T *varp; 17300 { 17301 if (varp != NULL) 17302 { 17303 switch (varp->v_type) 17304 { 17305 case VAR_FUNC: 17306 func_unref(varp->vval.v_string); 17307 /*FALLTHROUGH*/ 17308 case VAR_STRING: 17309 vim_free(varp->vval.v_string); 17310 break; 17311 case VAR_LIST: 17312 list_unref(varp->vval.v_list); 17313 break; 17314 case VAR_DICT: 17315 dict_unref(varp->vval.v_dict); 17316 break; 17317 case VAR_NUMBER: 17318 case VAR_UNKNOWN: 17319 break; 17320 default: 17321 EMSG2(_(e_intern2), "free_tv()"); 17322 break; 17323 } 17324 vim_free(varp); 17325 } 17326 } 17327 17328 /* 17329 * Free the memory for a variable value and set the value to NULL or 0. 17330 */ 17331 void 17332 clear_tv(varp) 17333 typval_T *varp; 17334 { 17335 if (varp != NULL) 17336 { 17337 switch (varp->v_type) 17338 { 17339 case VAR_FUNC: 17340 func_unref(varp->vval.v_string); 17341 /*FALLTHROUGH*/ 17342 case VAR_STRING: 17343 vim_free(varp->vval.v_string); 17344 varp->vval.v_string = NULL; 17345 break; 17346 case VAR_LIST: 17347 list_unref(varp->vval.v_list); 17348 varp->vval.v_list = NULL; 17349 break; 17350 case VAR_DICT: 17351 dict_unref(varp->vval.v_dict); 17352 varp->vval.v_dict = NULL; 17353 break; 17354 case VAR_NUMBER: 17355 varp->vval.v_number = 0; 17356 break; 17357 case VAR_UNKNOWN: 17358 break; 17359 default: 17360 EMSG2(_(e_intern2), "clear_tv()"); 17361 } 17362 varp->v_lock = 0; 17363 } 17364 } 17365 17366 /* 17367 * Set the value of a variable to NULL without freeing items. 17368 */ 17369 static void 17370 init_tv(varp) 17371 typval_T *varp; 17372 { 17373 if (varp != NULL) 17374 vim_memset(varp, 0, sizeof(typval_T)); 17375 } 17376 17377 /* 17378 * Get the number value of a variable. 17379 * If it is a String variable, uses vim_str2nr(). 17380 * For incompatible types, return 0. 17381 * get_tv_number_chk() is similar to get_tv_number(), but informs the 17382 * caller of incompatible types: it sets *denote to TRUE if "denote" 17383 * is not NULL or returns -1 otherwise. 17384 */ 17385 static long 17386 get_tv_number(varp) 17387 typval_T *varp; 17388 { 17389 int error = FALSE; 17390 17391 return get_tv_number_chk(varp, &error); /* return 0L on error */ 17392 } 17393 17394 long 17395 get_tv_number_chk(varp, denote) 17396 typval_T *varp; 17397 int *denote; 17398 { 17399 long n = 0L; 17400 17401 switch (varp->v_type) 17402 { 17403 case VAR_NUMBER: 17404 return (long)(varp->vval.v_number); 17405 case VAR_FUNC: 17406 EMSG(_("E703: Using a Funcref as a number")); 17407 break; 17408 case VAR_STRING: 17409 if (varp->vval.v_string != NULL) 17410 vim_str2nr(varp->vval.v_string, NULL, NULL, 17411 TRUE, TRUE, &n, NULL); 17412 return n; 17413 case VAR_LIST: 17414 EMSG(_("E745: Using a List as a number")); 17415 break; 17416 case VAR_DICT: 17417 EMSG(_("E728: Using a Dictionary as a number")); 17418 break; 17419 default: 17420 EMSG2(_(e_intern2), "get_tv_number()"); 17421 break; 17422 } 17423 if (denote == NULL) /* useful for values that must be unsigned */ 17424 n = -1; 17425 else 17426 *denote = TRUE; 17427 return n; 17428 } 17429 17430 /* 17431 * Get the lnum from the first argument. 17432 * Also accepts ".", "$", etc., but that only works for the current buffer. 17433 * Returns -1 on error. 17434 */ 17435 static linenr_T 17436 get_tv_lnum(argvars) 17437 typval_T *argvars; 17438 { 17439 typval_T rettv; 17440 linenr_T lnum; 17441 17442 lnum = get_tv_number_chk(&argvars[0], NULL); 17443 if (lnum == 0) /* no valid number, try using line() */ 17444 { 17445 rettv.v_type = VAR_NUMBER; 17446 f_line(argvars, &rettv); 17447 lnum = rettv.vval.v_number; 17448 clear_tv(&rettv); 17449 } 17450 return lnum; 17451 } 17452 17453 /* 17454 * Get the lnum from the first argument. 17455 * Also accepts "$", then "buf" is used. 17456 * Returns 0 on error. 17457 */ 17458 static linenr_T 17459 get_tv_lnum_buf(argvars, buf) 17460 typval_T *argvars; 17461 buf_T *buf; 17462 { 17463 if (argvars[0].v_type == VAR_STRING 17464 && argvars[0].vval.v_string != NULL 17465 && argvars[0].vval.v_string[0] == '$' 17466 && buf != NULL) 17467 return buf->b_ml.ml_line_count; 17468 return get_tv_number_chk(&argvars[0], NULL); 17469 } 17470 17471 /* 17472 * Get the string value of a variable. 17473 * If it is a Number variable, the number is converted into a string. 17474 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 17475 * get_tv_string_buf() uses a given buffer. 17476 * If the String variable has never been set, return an empty string. 17477 * Never returns NULL; 17478 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 17479 * NULL on error. 17480 */ 17481 static char_u * 17482 get_tv_string(varp) 17483 typval_T *varp; 17484 { 17485 static char_u mybuf[NUMBUFLEN]; 17486 17487 return get_tv_string_buf(varp, mybuf); 17488 } 17489 17490 static char_u * 17491 get_tv_string_buf(varp, buf) 17492 typval_T *varp; 17493 char_u *buf; 17494 { 17495 char_u *res = get_tv_string_buf_chk(varp, buf); 17496 17497 return res != NULL ? res : (char_u *)""; 17498 } 17499 17500 char_u * 17501 get_tv_string_chk(varp) 17502 typval_T *varp; 17503 { 17504 static char_u mybuf[NUMBUFLEN]; 17505 17506 return get_tv_string_buf_chk(varp, mybuf); 17507 } 17508 17509 static char_u * 17510 get_tv_string_buf_chk(varp, buf) 17511 typval_T *varp; 17512 char_u *buf; 17513 { 17514 switch (varp->v_type) 17515 { 17516 case VAR_NUMBER: 17517 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 17518 return buf; 17519 case VAR_FUNC: 17520 EMSG(_("E729: using Funcref as a String")); 17521 break; 17522 case VAR_LIST: 17523 EMSG(_("E730: using List as a String")); 17524 break; 17525 case VAR_DICT: 17526 EMSG(_("E731: using Dictionary as a String")); 17527 break; 17528 case VAR_STRING: 17529 if (varp->vval.v_string != NULL) 17530 return varp->vval.v_string; 17531 return (char_u *)""; 17532 default: 17533 EMSG2(_(e_intern2), "get_tv_string_buf()"); 17534 break; 17535 } 17536 return NULL; 17537 } 17538 17539 /* 17540 * Find variable "name" in the list of variables. 17541 * Return a pointer to it if found, NULL if not found. 17542 * Careful: "a:0" variables don't have a name. 17543 * When "htp" is not NULL we are writing to the variable, set "htp" to the 17544 * hashtab_T used. 17545 */ 17546 static dictitem_T * 17547 find_var(name, htp) 17548 char_u *name; 17549 hashtab_T **htp; 17550 { 17551 char_u *varname; 17552 hashtab_T *ht; 17553 17554 ht = find_var_ht(name, &varname); 17555 if (htp != NULL) 17556 *htp = ht; 17557 if (ht == NULL) 17558 return NULL; 17559 return find_var_in_ht(ht, varname, htp != NULL); 17560 } 17561 17562 /* 17563 * Find variable "varname" in hashtab "ht". 17564 * Returns NULL if not found. 17565 */ 17566 static dictitem_T * 17567 find_var_in_ht(ht, varname, writing) 17568 hashtab_T *ht; 17569 char_u *varname; 17570 int writing; 17571 { 17572 hashitem_T *hi; 17573 17574 if (*varname == NUL) 17575 { 17576 /* Must be something like "s:", otherwise "ht" would be NULL. */ 17577 switch (varname[-2]) 17578 { 17579 case 's': return &SCRIPT_SV(current_SID).sv_var; 17580 case 'g': return &globvars_var; 17581 case 'v': return &vimvars_var; 17582 case 'b': return &curbuf->b_bufvar; 17583 case 'w': return &curwin->w_winvar; 17584 #ifdef FEAT_WINDOWS 17585 case 't': return &curtab->tp_winvar; 17586 #endif 17587 case 'l': return current_funccal == NULL 17588 ? NULL : ¤t_funccal->l_vars_var; 17589 case 'a': return current_funccal == NULL 17590 ? NULL : ¤t_funccal->l_avars_var; 17591 } 17592 return NULL; 17593 } 17594 17595 hi = hash_find(ht, varname); 17596 if (HASHITEM_EMPTY(hi)) 17597 { 17598 /* For global variables we may try auto-loading the script. If it 17599 * worked find the variable again. Don't auto-load a script if it was 17600 * loaded already, otherwise it would be loaded every time when 17601 * checking if a function name is a Funcref variable. */ 17602 if (ht == &globvarht && !writing 17603 && script_autoload(varname, FALSE) && !aborting()) 17604 hi = hash_find(ht, varname); 17605 if (HASHITEM_EMPTY(hi)) 17606 return NULL; 17607 } 17608 return HI2DI(hi); 17609 } 17610 17611 /* 17612 * Find the hashtab used for a variable name. 17613 * Set "varname" to the start of name without ':'. 17614 */ 17615 static hashtab_T * 17616 find_var_ht(name, varname) 17617 char_u *name; 17618 char_u **varname; 17619 { 17620 hashitem_T *hi; 17621 17622 if (name[1] != ':') 17623 { 17624 /* The name must not start with a colon or #. */ 17625 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 17626 return NULL; 17627 *varname = name; 17628 17629 /* "version" is "v:version" in all scopes */ 17630 hi = hash_find(&compat_hashtab, name); 17631 if (!HASHITEM_EMPTY(hi)) 17632 return &compat_hashtab; 17633 17634 if (current_funccal == NULL) 17635 return &globvarht; /* global variable */ 17636 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 17637 } 17638 *varname = name + 2; 17639 if (*name == 'g') /* global variable */ 17640 return &globvarht; 17641 /* There must be no ':' or '#' in the rest of the name, unless g: is used 17642 */ 17643 if (vim_strchr(name + 2, ':') != NULL 17644 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 17645 return NULL; 17646 if (*name == 'b') /* buffer variable */ 17647 return &curbuf->b_vars.dv_hashtab; 17648 if (*name == 'w') /* window variable */ 17649 return &curwin->w_vars.dv_hashtab; 17650 #ifdef FEAT_WINDOWS 17651 if (*name == 't') /* tab page variable */ 17652 return &curtab->tp_vars.dv_hashtab; 17653 #endif 17654 if (*name == 'v') /* v: variable */ 17655 return &vimvarht; 17656 if (*name == 'a' && current_funccal != NULL) /* function argument */ 17657 return ¤t_funccal->l_avars.dv_hashtab; 17658 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 17659 return ¤t_funccal->l_vars.dv_hashtab; 17660 if (*name == 's' /* script variable */ 17661 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 17662 return &SCRIPT_VARS(current_SID); 17663 return NULL; 17664 } 17665 17666 /* 17667 * Get the string value of a (global/local) variable. 17668 * Returns NULL when it doesn't exist. 17669 */ 17670 char_u * 17671 get_var_value(name) 17672 char_u *name; 17673 { 17674 dictitem_T *v; 17675 17676 v = find_var(name, NULL); 17677 if (v == NULL) 17678 return NULL; 17679 return get_tv_string(&v->di_tv); 17680 } 17681 17682 /* 17683 * Allocate a new hashtab for a sourced script. It will be used while 17684 * sourcing this script and when executing functions defined in the script. 17685 */ 17686 void 17687 new_script_vars(id) 17688 scid_T id; 17689 { 17690 int i; 17691 hashtab_T *ht; 17692 scriptvar_T *sv; 17693 17694 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 17695 { 17696 /* Re-allocating ga_data means that an ht_array pointing to 17697 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 17698 * at its init value. Also reset "v_dict", it's always the same. */ 17699 for (i = 1; i <= ga_scripts.ga_len; ++i) 17700 { 17701 ht = &SCRIPT_VARS(i); 17702 if (ht->ht_mask == HT_INIT_SIZE - 1) 17703 ht->ht_array = ht->ht_smallarray; 17704 sv = &SCRIPT_SV(i); 17705 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 17706 } 17707 17708 while (ga_scripts.ga_len < id) 17709 { 17710 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 17711 init_var_dict(&sv->sv_dict, &sv->sv_var); 17712 ++ga_scripts.ga_len; 17713 } 17714 } 17715 } 17716 17717 /* 17718 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 17719 * point to it. 17720 */ 17721 void 17722 init_var_dict(dict, dict_var) 17723 dict_T *dict; 17724 dictitem_T *dict_var; 17725 { 17726 hash_init(&dict->dv_hashtab); 17727 dict->dv_refcount = 99999; 17728 dict_var->di_tv.vval.v_dict = dict; 17729 dict_var->di_tv.v_type = VAR_DICT; 17730 dict_var->di_tv.v_lock = VAR_FIXED; 17731 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 17732 dict_var->di_key[0] = NUL; 17733 } 17734 17735 /* 17736 * Clean up a list of internal variables. 17737 * Frees all allocated variables and the value they contain. 17738 * Clears hashtab "ht", does not free it. 17739 */ 17740 void 17741 vars_clear(ht) 17742 hashtab_T *ht; 17743 { 17744 vars_clear_ext(ht, TRUE); 17745 } 17746 17747 /* 17748 * Like vars_clear(), but only free the value if "free_val" is TRUE. 17749 */ 17750 static void 17751 vars_clear_ext(ht, free_val) 17752 hashtab_T *ht; 17753 int free_val; 17754 { 17755 int todo; 17756 hashitem_T *hi; 17757 dictitem_T *v; 17758 17759 hash_lock(ht); 17760 todo = (int)ht->ht_used; 17761 for (hi = ht->ht_array; todo > 0; ++hi) 17762 { 17763 if (!HASHITEM_EMPTY(hi)) 17764 { 17765 --todo; 17766 17767 /* Free the variable. Don't remove it from the hashtab, 17768 * ht_array might change then. hash_clear() takes care of it 17769 * later. */ 17770 v = HI2DI(hi); 17771 if (free_val) 17772 clear_tv(&v->di_tv); 17773 if ((v->di_flags & DI_FLAGS_FIX) == 0) 17774 vim_free(v); 17775 } 17776 } 17777 hash_clear(ht); 17778 ht->ht_used = 0; 17779 } 17780 17781 /* 17782 * Delete a variable from hashtab "ht" at item "hi". 17783 * Clear the variable value and free the dictitem. 17784 */ 17785 static void 17786 delete_var(ht, hi) 17787 hashtab_T *ht; 17788 hashitem_T *hi; 17789 { 17790 dictitem_T *di = HI2DI(hi); 17791 17792 hash_remove(ht, hi); 17793 clear_tv(&di->di_tv); 17794 vim_free(di); 17795 } 17796 17797 /* 17798 * List the value of one internal variable. 17799 */ 17800 static void 17801 list_one_var(v, prefix) 17802 dictitem_T *v; 17803 char_u *prefix; 17804 { 17805 char_u *tofree; 17806 char_u *s; 17807 char_u numbuf[NUMBUFLEN]; 17808 17809 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID); 17810 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 17811 s == NULL ? (char_u *)"" : s); 17812 vim_free(tofree); 17813 } 17814 17815 static void 17816 list_one_var_a(prefix, name, type, string) 17817 char_u *prefix; 17818 char_u *name; 17819 int type; 17820 char_u *string; 17821 { 17822 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 17823 if (name != NULL) /* "a:" vars don't have a name stored */ 17824 msg_puts(name); 17825 msg_putchar(' '); 17826 msg_advance(22); 17827 if (type == VAR_NUMBER) 17828 msg_putchar('#'); 17829 else if (type == VAR_FUNC) 17830 msg_putchar('*'); 17831 else if (type == VAR_LIST) 17832 { 17833 msg_putchar('['); 17834 if (*string == '[') 17835 ++string; 17836 } 17837 else if (type == VAR_DICT) 17838 { 17839 msg_putchar('{'); 17840 if (*string == '{') 17841 ++string; 17842 } 17843 else 17844 msg_putchar(' '); 17845 17846 msg_outtrans(string); 17847 17848 if (type == VAR_FUNC) 17849 msg_puts((char_u *)"()"); 17850 } 17851 17852 /* 17853 * Set variable "name" to value in "tv". 17854 * If the variable already exists, the value is updated. 17855 * Otherwise the variable is created. 17856 */ 17857 static void 17858 set_var(name, tv, copy) 17859 char_u *name; 17860 typval_T *tv; 17861 int copy; /* make copy of value in "tv" */ 17862 { 17863 dictitem_T *v; 17864 char_u *varname; 17865 hashtab_T *ht; 17866 char_u *p; 17867 17868 if (tv->v_type == VAR_FUNC) 17869 { 17870 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 17871 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 17872 ? name[2] : name[0])) 17873 { 17874 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 17875 return; 17876 } 17877 if (function_exists(name)) 17878 { 17879 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 17880 name); 17881 return; 17882 } 17883 } 17884 17885 ht = find_var_ht(name, &varname); 17886 if (ht == NULL || *varname == NUL) 17887 { 17888 EMSG2(_(e_illvar), name); 17889 return; 17890 } 17891 17892 v = find_var_in_ht(ht, varname, TRUE); 17893 if (v != NULL) 17894 { 17895 /* existing variable, need to clear the value */ 17896 if (var_check_ro(v->di_flags, name) 17897 || tv_check_lock(v->di_tv.v_lock, name)) 17898 return; 17899 if (v->di_tv.v_type != tv->v_type 17900 && !((v->di_tv.v_type == VAR_STRING 17901 || v->di_tv.v_type == VAR_NUMBER) 17902 && (tv->v_type == VAR_STRING 17903 || tv->v_type == VAR_NUMBER))) 17904 { 17905 EMSG2(_("E706: Variable type mismatch for: %s"), name); 17906 return; 17907 } 17908 17909 /* 17910 * Handle setting internal v: variables separately: we don't change 17911 * the type. 17912 */ 17913 if (ht == &vimvarht) 17914 { 17915 if (v->di_tv.v_type == VAR_STRING) 17916 { 17917 vim_free(v->di_tv.vval.v_string); 17918 if (copy || tv->v_type != VAR_STRING) 17919 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 17920 else 17921 { 17922 /* Take over the string to avoid an extra alloc/free. */ 17923 v->di_tv.vval.v_string = tv->vval.v_string; 17924 tv->vval.v_string = NULL; 17925 } 17926 } 17927 else if (v->di_tv.v_type != VAR_NUMBER) 17928 EMSG2(_(e_intern2), "set_var()"); 17929 else 17930 v->di_tv.vval.v_number = get_tv_number(tv); 17931 return; 17932 } 17933 17934 clear_tv(&v->di_tv); 17935 } 17936 else /* add a new variable */ 17937 { 17938 /* Can't add "v:" variable. */ 17939 if (ht == &vimvarht) 17940 { 17941 EMSG2(_(e_illvar), name); 17942 return; 17943 } 17944 17945 /* Make sure the variable name is valid. */ 17946 for (p = varname; *p != NUL; ++p) 17947 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) 17948 && *p != AUTOLOAD_CHAR) 17949 { 17950 EMSG2(_(e_illvar), varname); 17951 return; 17952 } 17953 17954 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 17955 + STRLEN(varname))); 17956 if (v == NULL) 17957 return; 17958 STRCPY(v->di_key, varname); 17959 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 17960 { 17961 vim_free(v); 17962 return; 17963 } 17964 v->di_flags = 0; 17965 } 17966 17967 if (copy || tv->v_type == VAR_NUMBER) 17968 copy_tv(tv, &v->di_tv); 17969 else 17970 { 17971 v->di_tv = *tv; 17972 v->di_tv.v_lock = 0; 17973 init_tv(tv); 17974 } 17975 } 17976 17977 /* 17978 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 17979 * Also give an error message. 17980 */ 17981 static int 17982 var_check_ro(flags, name) 17983 int flags; 17984 char_u *name; 17985 { 17986 if (flags & DI_FLAGS_RO) 17987 { 17988 EMSG2(_(e_readonlyvar), name); 17989 return TRUE; 17990 } 17991 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 17992 { 17993 EMSG2(_(e_readonlysbx), name); 17994 return TRUE; 17995 } 17996 return FALSE; 17997 } 17998 17999 /* 18000 * Return TRUE if di_flags "flags" indicates variable "name" is fixed. 18001 * Also give an error message. 18002 */ 18003 static int 18004 var_check_fixed(flags, name) 18005 int flags; 18006 char_u *name; 18007 { 18008 if (flags & DI_FLAGS_FIX) 18009 { 18010 EMSG2(_("E795: Cannot delete variable %s"), name); 18011 return TRUE; 18012 } 18013 return FALSE; 18014 } 18015 18016 /* 18017 * Return TRUE if typeval "tv" is set to be locked (immutable). 18018 * Also give an error message, using "name". 18019 */ 18020 static int 18021 tv_check_lock(lock, name) 18022 int lock; 18023 char_u *name; 18024 { 18025 if (lock & VAR_LOCKED) 18026 { 18027 EMSG2(_("E741: Value is locked: %s"), 18028 name == NULL ? (char_u *)_("Unknown") : name); 18029 return TRUE; 18030 } 18031 if (lock & VAR_FIXED) 18032 { 18033 EMSG2(_("E742: Cannot change value of %s"), 18034 name == NULL ? (char_u *)_("Unknown") : name); 18035 return TRUE; 18036 } 18037 return FALSE; 18038 } 18039 18040 /* 18041 * Copy the values from typval_T "from" to typval_T "to". 18042 * When needed allocates string or increases reference count. 18043 * Does not make a copy of a list or dict but copies the reference! 18044 */ 18045 static void 18046 copy_tv(from, to) 18047 typval_T *from; 18048 typval_T *to; 18049 { 18050 to->v_type = from->v_type; 18051 to->v_lock = 0; 18052 switch (from->v_type) 18053 { 18054 case VAR_NUMBER: 18055 to->vval.v_number = from->vval.v_number; 18056 break; 18057 case VAR_STRING: 18058 case VAR_FUNC: 18059 if (from->vval.v_string == NULL) 18060 to->vval.v_string = NULL; 18061 else 18062 { 18063 to->vval.v_string = vim_strsave(from->vval.v_string); 18064 if (from->v_type == VAR_FUNC) 18065 func_ref(to->vval.v_string); 18066 } 18067 break; 18068 case VAR_LIST: 18069 if (from->vval.v_list == NULL) 18070 to->vval.v_list = NULL; 18071 else 18072 { 18073 to->vval.v_list = from->vval.v_list; 18074 ++to->vval.v_list->lv_refcount; 18075 } 18076 break; 18077 case VAR_DICT: 18078 if (from->vval.v_dict == NULL) 18079 to->vval.v_dict = NULL; 18080 else 18081 { 18082 to->vval.v_dict = from->vval.v_dict; 18083 ++to->vval.v_dict->dv_refcount; 18084 } 18085 break; 18086 default: 18087 EMSG2(_(e_intern2), "copy_tv()"); 18088 break; 18089 } 18090 } 18091 18092 /* 18093 * Make a copy of an item. 18094 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 18095 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 18096 * reference to an already copied list/dict can be used. 18097 * Returns FAIL or OK. 18098 */ 18099 static int 18100 item_copy(from, to, deep, copyID) 18101 typval_T *from; 18102 typval_T *to; 18103 int deep; 18104 int copyID; 18105 { 18106 static int recurse = 0; 18107 int ret = OK; 18108 18109 if (recurse >= DICT_MAXNEST) 18110 { 18111 EMSG(_("E698: variable nested too deep for making a copy")); 18112 return FAIL; 18113 } 18114 ++recurse; 18115 18116 switch (from->v_type) 18117 { 18118 case VAR_NUMBER: 18119 case VAR_STRING: 18120 case VAR_FUNC: 18121 copy_tv(from, to); 18122 break; 18123 case VAR_LIST: 18124 to->v_type = VAR_LIST; 18125 to->v_lock = 0; 18126 if (from->vval.v_list == NULL) 18127 to->vval.v_list = NULL; 18128 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 18129 { 18130 /* use the copy made earlier */ 18131 to->vval.v_list = from->vval.v_list->lv_copylist; 18132 ++to->vval.v_list->lv_refcount; 18133 } 18134 else 18135 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 18136 if (to->vval.v_list == NULL) 18137 ret = FAIL; 18138 break; 18139 case VAR_DICT: 18140 to->v_type = VAR_DICT; 18141 to->v_lock = 0; 18142 if (from->vval.v_dict == NULL) 18143 to->vval.v_dict = NULL; 18144 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 18145 { 18146 /* use the copy made earlier */ 18147 to->vval.v_dict = from->vval.v_dict->dv_copydict; 18148 ++to->vval.v_dict->dv_refcount; 18149 } 18150 else 18151 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 18152 if (to->vval.v_dict == NULL) 18153 ret = FAIL; 18154 break; 18155 default: 18156 EMSG2(_(e_intern2), "item_copy()"); 18157 ret = FAIL; 18158 } 18159 --recurse; 18160 return ret; 18161 } 18162 18163 /* 18164 * ":echo expr1 ..." print each argument separated with a space, add a 18165 * newline at the end. 18166 * ":echon expr1 ..." print each argument plain. 18167 */ 18168 void 18169 ex_echo(eap) 18170 exarg_T *eap; 18171 { 18172 char_u *arg = eap->arg; 18173 typval_T rettv; 18174 char_u *tofree; 18175 char_u *p; 18176 int needclr = TRUE; 18177 int atstart = TRUE; 18178 char_u numbuf[NUMBUFLEN]; 18179 18180 if (eap->skip) 18181 ++emsg_skip; 18182 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 18183 { 18184 p = arg; 18185 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 18186 { 18187 /* 18188 * Report the invalid expression unless the expression evaluation 18189 * has been cancelled due to an aborting error, an interrupt, or an 18190 * exception. 18191 */ 18192 if (!aborting()) 18193 EMSG2(_(e_invexpr2), p); 18194 break; 18195 } 18196 if (!eap->skip) 18197 { 18198 if (atstart) 18199 { 18200 atstart = FALSE; 18201 /* Call msg_start() after eval1(), evaluating the expression 18202 * may cause a message to appear. */ 18203 if (eap->cmdidx == CMD_echo) 18204 msg_start(); 18205 } 18206 else if (eap->cmdidx == CMD_echo) 18207 msg_puts_attr((char_u *)" ", echo_attr); 18208 p = echo_string(&rettv, &tofree, numbuf, ++current_copyID); 18209 if (p != NULL) 18210 for ( ; *p != NUL && !got_int; ++p) 18211 { 18212 if (*p == '\n' || *p == '\r' || *p == TAB) 18213 { 18214 if (*p != TAB && needclr) 18215 { 18216 /* remove any text still there from the command */ 18217 msg_clr_eos(); 18218 needclr = FALSE; 18219 } 18220 msg_putchar_attr(*p, echo_attr); 18221 } 18222 else 18223 { 18224 #ifdef FEAT_MBYTE 18225 if (has_mbyte) 18226 { 18227 int i = (*mb_ptr2len)(p); 18228 18229 (void)msg_outtrans_len_attr(p, i, echo_attr); 18230 p += i - 1; 18231 } 18232 else 18233 #endif 18234 (void)msg_outtrans_len_attr(p, 1, echo_attr); 18235 } 18236 } 18237 vim_free(tofree); 18238 } 18239 clear_tv(&rettv); 18240 arg = skipwhite(arg); 18241 } 18242 eap->nextcmd = check_nextcmd(arg); 18243 18244 if (eap->skip) 18245 --emsg_skip; 18246 else 18247 { 18248 /* remove text that may still be there from the command */ 18249 if (needclr) 18250 msg_clr_eos(); 18251 if (eap->cmdidx == CMD_echo) 18252 msg_end(); 18253 } 18254 } 18255 18256 /* 18257 * ":echohl {name}". 18258 */ 18259 void 18260 ex_echohl(eap) 18261 exarg_T *eap; 18262 { 18263 int id; 18264 18265 id = syn_name2id(eap->arg); 18266 if (id == 0) 18267 echo_attr = 0; 18268 else 18269 echo_attr = syn_id2attr(id); 18270 } 18271 18272 /* 18273 * ":execute expr1 ..." execute the result of an expression. 18274 * ":echomsg expr1 ..." Print a message 18275 * ":echoerr expr1 ..." Print an error 18276 * Each gets spaces around each argument and a newline at the end for 18277 * echo commands 18278 */ 18279 void 18280 ex_execute(eap) 18281 exarg_T *eap; 18282 { 18283 char_u *arg = eap->arg; 18284 typval_T rettv; 18285 int ret = OK; 18286 char_u *p; 18287 garray_T ga; 18288 int len; 18289 int save_did_emsg; 18290 18291 ga_init2(&ga, 1, 80); 18292 18293 if (eap->skip) 18294 ++emsg_skip; 18295 while (*arg != NUL && *arg != '|' && *arg != '\n') 18296 { 18297 p = arg; 18298 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 18299 { 18300 /* 18301 * Report the invalid expression unless the expression evaluation 18302 * has been cancelled due to an aborting error, an interrupt, or an 18303 * exception. 18304 */ 18305 if (!aborting()) 18306 EMSG2(_(e_invexpr2), p); 18307 ret = FAIL; 18308 break; 18309 } 18310 18311 if (!eap->skip) 18312 { 18313 p = get_tv_string(&rettv); 18314 len = (int)STRLEN(p); 18315 if (ga_grow(&ga, len + 2) == FAIL) 18316 { 18317 clear_tv(&rettv); 18318 ret = FAIL; 18319 break; 18320 } 18321 if (ga.ga_len) 18322 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 18323 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 18324 ga.ga_len += len; 18325 } 18326 18327 clear_tv(&rettv); 18328 arg = skipwhite(arg); 18329 } 18330 18331 if (ret != FAIL && ga.ga_data != NULL) 18332 { 18333 if (eap->cmdidx == CMD_echomsg) 18334 { 18335 MSG_ATTR(ga.ga_data, echo_attr); 18336 out_flush(); 18337 } 18338 else if (eap->cmdidx == CMD_echoerr) 18339 { 18340 /* We don't want to abort following commands, restore did_emsg. */ 18341 save_did_emsg = did_emsg; 18342 EMSG((char_u *)ga.ga_data); 18343 if (!force_abort) 18344 did_emsg = save_did_emsg; 18345 } 18346 else if (eap->cmdidx == CMD_execute) 18347 do_cmdline((char_u *)ga.ga_data, 18348 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 18349 } 18350 18351 ga_clear(&ga); 18352 18353 if (eap->skip) 18354 --emsg_skip; 18355 18356 eap->nextcmd = check_nextcmd(arg); 18357 } 18358 18359 /* 18360 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 18361 * "arg" points to the "&" or '+' when called, to "option" when returning. 18362 * Returns NULL when no option name found. Otherwise pointer to the char 18363 * after the option name. 18364 */ 18365 static char_u * 18366 find_option_end(arg, opt_flags) 18367 char_u **arg; 18368 int *opt_flags; 18369 { 18370 char_u *p = *arg; 18371 18372 ++p; 18373 if (*p == 'g' && p[1] == ':') 18374 { 18375 *opt_flags = OPT_GLOBAL; 18376 p += 2; 18377 } 18378 else if (*p == 'l' && p[1] == ':') 18379 { 18380 *opt_flags = OPT_LOCAL; 18381 p += 2; 18382 } 18383 else 18384 *opt_flags = 0; 18385 18386 if (!ASCII_ISALPHA(*p)) 18387 return NULL; 18388 *arg = p; 18389 18390 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 18391 p += 4; /* termcap option */ 18392 else 18393 while (ASCII_ISALPHA(*p)) 18394 ++p; 18395 return p; 18396 } 18397 18398 /* 18399 * ":function" 18400 */ 18401 void 18402 ex_function(eap) 18403 exarg_T *eap; 18404 { 18405 char_u *theline; 18406 int j; 18407 int c; 18408 int saved_did_emsg; 18409 char_u *name = NULL; 18410 char_u *p; 18411 char_u *arg; 18412 char_u *line_arg = NULL; 18413 garray_T newargs; 18414 garray_T newlines; 18415 int varargs = FALSE; 18416 int mustend = FALSE; 18417 int flags = 0; 18418 ufunc_T *fp; 18419 int indent; 18420 int nesting; 18421 char_u *skip_until = NULL; 18422 dictitem_T *v; 18423 funcdict_T fudi; 18424 static int func_nr = 0; /* number for nameless function */ 18425 int paren; 18426 hashtab_T *ht; 18427 int todo; 18428 hashitem_T *hi; 18429 int sourcing_lnum_off; 18430 18431 /* 18432 * ":function" without argument: list functions. 18433 */ 18434 if (ends_excmd(*eap->arg)) 18435 { 18436 if (!eap->skip) 18437 { 18438 todo = (int)func_hashtab.ht_used; 18439 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18440 { 18441 if (!HASHITEM_EMPTY(hi)) 18442 { 18443 --todo; 18444 fp = HI2UF(hi); 18445 if (!isdigit(*fp->uf_name)) 18446 list_func_head(fp, FALSE); 18447 } 18448 } 18449 } 18450 eap->nextcmd = check_nextcmd(eap->arg); 18451 return; 18452 } 18453 18454 /* 18455 * ":function /pat": list functions matching pattern. 18456 */ 18457 if (*eap->arg == '/') 18458 { 18459 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 18460 if (!eap->skip) 18461 { 18462 regmatch_T regmatch; 18463 18464 c = *p; 18465 *p = NUL; 18466 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 18467 *p = c; 18468 if (regmatch.regprog != NULL) 18469 { 18470 regmatch.rm_ic = p_ic; 18471 18472 todo = (int)func_hashtab.ht_used; 18473 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 18474 { 18475 if (!HASHITEM_EMPTY(hi)) 18476 { 18477 --todo; 18478 fp = HI2UF(hi); 18479 if (!isdigit(*fp->uf_name) 18480 && vim_regexec(®match, fp->uf_name, 0)) 18481 list_func_head(fp, FALSE); 18482 } 18483 } 18484 } 18485 } 18486 if (*p == '/') 18487 ++p; 18488 eap->nextcmd = check_nextcmd(p); 18489 return; 18490 } 18491 18492 /* 18493 * Get the function name. There are these situations: 18494 * func normal function name 18495 * "name" == func, "fudi.fd_dict" == NULL 18496 * dict.func new dictionary entry 18497 * "name" == NULL, "fudi.fd_dict" set, 18498 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 18499 * dict.func existing dict entry with a Funcref 18500 * "name" == func, "fudi.fd_dict" set, 18501 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18502 * dict.func existing dict entry that's not a Funcref 18503 * "name" == NULL, "fudi.fd_dict" set, 18504 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 18505 */ 18506 p = eap->arg; 18507 name = trans_function_name(&p, eap->skip, 0, &fudi); 18508 paren = (vim_strchr(p, '(') != NULL); 18509 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 18510 { 18511 /* 18512 * Return on an invalid expression in braces, unless the expression 18513 * evaluation has been cancelled due to an aborting error, an 18514 * interrupt, or an exception. 18515 */ 18516 if (!aborting()) 18517 { 18518 if (!eap->skip && fudi.fd_newkey != NULL) 18519 EMSG2(_(e_dictkey), fudi.fd_newkey); 18520 vim_free(fudi.fd_newkey); 18521 return; 18522 } 18523 else 18524 eap->skip = TRUE; 18525 } 18526 18527 /* An error in a function call during evaluation of an expression in magic 18528 * braces should not cause the function not to be defined. */ 18529 saved_did_emsg = did_emsg; 18530 did_emsg = FALSE; 18531 18532 /* 18533 * ":function func" with only function name: list function. 18534 */ 18535 if (!paren) 18536 { 18537 if (!ends_excmd(*skipwhite(p))) 18538 { 18539 EMSG(_(e_trailing)); 18540 goto ret_free; 18541 } 18542 eap->nextcmd = check_nextcmd(p); 18543 if (eap->nextcmd != NULL) 18544 *p = NUL; 18545 if (!eap->skip && !got_int) 18546 { 18547 fp = find_func(name); 18548 if (fp != NULL) 18549 { 18550 list_func_head(fp, TRUE); 18551 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 18552 { 18553 if (FUNCLINE(fp, j) == NULL) 18554 continue; 18555 msg_putchar('\n'); 18556 msg_outnum((long)(j + 1)); 18557 if (j < 9) 18558 msg_putchar(' '); 18559 if (j < 99) 18560 msg_putchar(' '); 18561 msg_prt_line(FUNCLINE(fp, j), FALSE); 18562 out_flush(); /* show a line at a time */ 18563 ui_breakcheck(); 18564 } 18565 if (!got_int) 18566 { 18567 msg_putchar('\n'); 18568 msg_puts((char_u *)" endfunction"); 18569 } 18570 } 18571 else 18572 emsg_funcname("E123: Undefined function: %s", name); 18573 } 18574 goto ret_free; 18575 } 18576 18577 /* 18578 * ":function name(arg1, arg2)" Define function. 18579 */ 18580 p = skipwhite(p); 18581 if (*p != '(') 18582 { 18583 if (!eap->skip) 18584 { 18585 EMSG2(_("E124: Missing '(': %s"), eap->arg); 18586 goto ret_free; 18587 } 18588 /* attempt to continue by skipping some text */ 18589 if (vim_strchr(p, '(') != NULL) 18590 p = vim_strchr(p, '('); 18591 } 18592 p = skipwhite(p + 1); 18593 18594 ga_init2(&newargs, (int)sizeof(char_u *), 3); 18595 ga_init2(&newlines, (int)sizeof(char_u *), 3); 18596 18597 if (!eap->skip) 18598 { 18599 /* Check the name of the function. Unless it's a dictionary function 18600 * (that we are overwriting). */ 18601 if (name != NULL) 18602 arg = name; 18603 else 18604 arg = fudi.fd_newkey; 18605 if (arg != NULL && (fudi.fd_di == NULL 18606 || fudi.fd_di->di_tv.v_type != VAR_FUNC)) 18607 { 18608 if (*arg == K_SPECIAL) 18609 j = 3; 18610 else 18611 j = 0; 18612 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 18613 : eval_isnamec(arg[j]))) 18614 ++j; 18615 if (arg[j] != NUL) 18616 emsg_funcname(_(e_invarg2), arg); 18617 } 18618 } 18619 18620 /* 18621 * Isolate the arguments: "arg1, arg2, ...)" 18622 */ 18623 while (*p != ')') 18624 { 18625 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 18626 { 18627 varargs = TRUE; 18628 p += 3; 18629 mustend = TRUE; 18630 } 18631 else 18632 { 18633 arg = p; 18634 while (ASCII_ISALNUM(*p) || *p == '_') 18635 ++p; 18636 if (arg == p || isdigit(*arg) 18637 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 18638 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 18639 { 18640 if (!eap->skip) 18641 EMSG2(_("E125: Illegal argument: %s"), arg); 18642 break; 18643 } 18644 if (ga_grow(&newargs, 1) == FAIL) 18645 goto erret; 18646 c = *p; 18647 *p = NUL; 18648 arg = vim_strsave(arg); 18649 if (arg == NULL) 18650 goto erret; 18651 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 18652 *p = c; 18653 newargs.ga_len++; 18654 if (*p == ',') 18655 ++p; 18656 else 18657 mustend = TRUE; 18658 } 18659 p = skipwhite(p); 18660 if (mustend && *p != ')') 18661 { 18662 if (!eap->skip) 18663 EMSG2(_(e_invarg2), eap->arg); 18664 break; 18665 } 18666 } 18667 ++p; /* skip the ')' */ 18668 18669 /* find extra arguments "range", "dict" and "abort" */ 18670 for (;;) 18671 { 18672 p = skipwhite(p); 18673 if (STRNCMP(p, "range", 5) == 0) 18674 { 18675 flags |= FC_RANGE; 18676 p += 5; 18677 } 18678 else if (STRNCMP(p, "dict", 4) == 0) 18679 { 18680 flags |= FC_DICT; 18681 p += 4; 18682 } 18683 else if (STRNCMP(p, "abort", 5) == 0) 18684 { 18685 flags |= FC_ABORT; 18686 p += 5; 18687 } 18688 else 18689 break; 18690 } 18691 18692 /* When there is a line break use what follows for the function body. 18693 * Makes 'exe "func Test()\n...\nendfunc"' work. */ 18694 if (*p == '\n') 18695 line_arg = p + 1; 18696 else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) 18697 EMSG(_(e_trailing)); 18698 18699 /* 18700 * Read the body of the function, until ":endfunction" is found. 18701 */ 18702 if (KeyTyped) 18703 { 18704 /* Check if the function already exists, don't let the user type the 18705 * whole function before telling him it doesn't work! For a script we 18706 * need to skip the body to be able to find what follows. */ 18707 if (!eap->skip && !eap->forceit) 18708 { 18709 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 18710 EMSG(_(e_funcdict)); 18711 else if (name != NULL && find_func(name) != NULL) 18712 emsg_funcname(e_funcexts, name); 18713 } 18714 18715 if (!eap->skip && did_emsg) 18716 goto erret; 18717 18718 msg_putchar('\n'); /* don't overwrite the function name */ 18719 cmdline_row = msg_row; 18720 } 18721 18722 indent = 2; 18723 nesting = 0; 18724 for (;;) 18725 { 18726 msg_scroll = TRUE; 18727 need_wait_return = FALSE; 18728 sourcing_lnum_off = sourcing_lnum; 18729 18730 if (line_arg != NULL) 18731 { 18732 /* Use eap->arg, split up in parts by line breaks. */ 18733 theline = line_arg; 18734 p = vim_strchr(theline, '\n'); 18735 if (p == NULL) 18736 line_arg += STRLEN(line_arg); 18737 else 18738 { 18739 *p = NUL; 18740 line_arg = p + 1; 18741 } 18742 } 18743 else if (eap->getline == NULL) 18744 theline = getcmdline(':', 0L, indent); 18745 else 18746 theline = eap->getline(':', eap->cookie, indent); 18747 if (KeyTyped) 18748 lines_left = Rows - 1; 18749 if (theline == NULL) 18750 { 18751 EMSG(_("E126: Missing :endfunction")); 18752 goto erret; 18753 } 18754 18755 /* Detect line continuation: sourcing_lnum increased more than one. */ 18756 if (sourcing_lnum > sourcing_lnum_off + 1) 18757 sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; 18758 else 18759 sourcing_lnum_off = 0; 18760 18761 if (skip_until != NULL) 18762 { 18763 /* between ":append" and "." and between ":python <<EOF" and "EOF" 18764 * don't check for ":endfunc". */ 18765 if (STRCMP(theline, skip_until) == 0) 18766 { 18767 vim_free(skip_until); 18768 skip_until = NULL; 18769 } 18770 } 18771 else 18772 { 18773 /* skip ':' and blanks*/ 18774 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 18775 ; 18776 18777 /* Check for "endfunction". */ 18778 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 18779 { 18780 if (line_arg == NULL) 18781 vim_free(theline); 18782 break; 18783 } 18784 18785 /* Increase indent inside "if", "while", "for" and "try", decrease 18786 * at "end". */ 18787 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 18788 indent -= 2; 18789 else if (STRNCMP(p, "if", 2) == 0 18790 || STRNCMP(p, "wh", 2) == 0 18791 || STRNCMP(p, "for", 3) == 0 18792 || STRNCMP(p, "try", 3) == 0) 18793 indent += 2; 18794 18795 /* Check for defining a function inside this function. */ 18796 if (checkforcmd(&p, "function", 2)) 18797 { 18798 if (*p == '!') 18799 p = skipwhite(p + 1); 18800 p += eval_fname_script(p); 18801 if (ASCII_ISALPHA(*p)) 18802 { 18803 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 18804 if (*skipwhite(p) == '(') 18805 { 18806 ++nesting; 18807 indent += 2; 18808 } 18809 } 18810 } 18811 18812 /* Check for ":append" or ":insert". */ 18813 p = skip_range(p, NULL); 18814 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 18815 || (p[0] == 'i' 18816 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 18817 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 18818 skip_until = vim_strsave((char_u *)"."); 18819 18820 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 18821 arg = skipwhite(skiptowhite(p)); 18822 if (arg[0] == '<' && arg[1] =='<' 18823 && ((p[0] == 'p' && p[1] == 'y' 18824 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 18825 || (p[0] == 'p' && p[1] == 'e' 18826 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 18827 || (p[0] == 't' && p[1] == 'c' 18828 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 18829 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 18830 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 18831 || (p[0] == 'm' && p[1] == 'z' 18832 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 18833 )) 18834 { 18835 /* ":python <<" continues until a dot, like ":append" */ 18836 p = skipwhite(arg + 2); 18837 if (*p == NUL) 18838 skip_until = vim_strsave((char_u *)"."); 18839 else 18840 skip_until = vim_strsave(p); 18841 } 18842 } 18843 18844 /* Add the line to the function. */ 18845 if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL) 18846 { 18847 if (line_arg == NULL) 18848 vim_free(theline); 18849 goto erret; 18850 } 18851 18852 /* Copy the line to newly allocated memory. get_one_sourceline() 18853 * allocates 250 bytes per line, this saves 80% on average. The cost 18854 * is an extra alloc/free. */ 18855 p = vim_strsave(theline); 18856 if (p != NULL) 18857 { 18858 if (line_arg == NULL) 18859 vim_free(theline); 18860 theline = p; 18861 } 18862 18863 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline; 18864 18865 /* Add NULL lines for continuation lines, so that the line count is 18866 * equal to the index in the growarray. */ 18867 while (sourcing_lnum_off-- > 0) 18868 ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; 18869 18870 /* Check for end of eap->arg. */ 18871 if (line_arg != NULL && *line_arg == NUL) 18872 line_arg = NULL; 18873 } 18874 18875 /* Don't define the function when skipping commands or when an error was 18876 * detected. */ 18877 if (eap->skip || did_emsg) 18878 goto erret; 18879 18880 /* 18881 * If there are no errors, add the function 18882 */ 18883 if (fudi.fd_dict == NULL) 18884 { 18885 v = find_var(name, &ht); 18886 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 18887 { 18888 emsg_funcname("E707: Function name conflicts with variable: %s", 18889 name); 18890 goto erret; 18891 } 18892 18893 fp = find_func(name); 18894 if (fp != NULL) 18895 { 18896 if (!eap->forceit) 18897 { 18898 emsg_funcname(e_funcexts, name); 18899 goto erret; 18900 } 18901 if (fp->uf_calls > 0) 18902 { 18903 emsg_funcname("E127: Cannot redefine function %s: It is in use", 18904 name); 18905 goto erret; 18906 } 18907 /* redefine existing function */ 18908 ga_clear_strings(&(fp->uf_args)); 18909 ga_clear_strings(&(fp->uf_lines)); 18910 vim_free(name); 18911 name = NULL; 18912 } 18913 } 18914 else 18915 { 18916 char numbuf[20]; 18917 18918 fp = NULL; 18919 if (fudi.fd_newkey == NULL && !eap->forceit) 18920 { 18921 EMSG(_(e_funcdict)); 18922 goto erret; 18923 } 18924 if (fudi.fd_di == NULL) 18925 { 18926 /* Can't add a function to a locked dictionary */ 18927 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 18928 goto erret; 18929 } 18930 /* Can't change an existing function if it is locked */ 18931 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 18932 goto erret; 18933 18934 /* Give the function a sequential number. Can only be used with a 18935 * Funcref! */ 18936 vim_free(name); 18937 sprintf(numbuf, "%d", ++func_nr); 18938 name = vim_strsave((char_u *)numbuf); 18939 if (name == NULL) 18940 goto erret; 18941 } 18942 18943 if (fp == NULL) 18944 { 18945 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 18946 { 18947 int slen, plen; 18948 char_u *scriptname; 18949 18950 /* Check that the autoload name matches the script name. */ 18951 j = FAIL; 18952 if (sourcing_name != NULL) 18953 { 18954 scriptname = autoload_name(name); 18955 if (scriptname != NULL) 18956 { 18957 p = vim_strchr(scriptname, '/'); 18958 plen = (int)STRLEN(p); 18959 slen = (int)STRLEN(sourcing_name); 18960 if (slen > plen && fnamecmp(p, 18961 sourcing_name + slen - plen) == 0) 18962 j = OK; 18963 vim_free(scriptname); 18964 } 18965 } 18966 if (j == FAIL) 18967 { 18968 EMSG2(_("E746: Function name does not match script file name: %s"), name); 18969 goto erret; 18970 } 18971 } 18972 18973 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 18974 if (fp == NULL) 18975 goto erret; 18976 18977 if (fudi.fd_dict != NULL) 18978 { 18979 if (fudi.fd_di == NULL) 18980 { 18981 /* add new dict entry */ 18982 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 18983 if (fudi.fd_di == NULL) 18984 { 18985 vim_free(fp); 18986 goto erret; 18987 } 18988 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 18989 { 18990 vim_free(fudi.fd_di); 18991 vim_free(fp); 18992 goto erret; 18993 } 18994 } 18995 else 18996 /* overwrite existing dict entry */ 18997 clear_tv(&fudi.fd_di->di_tv); 18998 fudi.fd_di->di_tv.v_type = VAR_FUNC; 18999 fudi.fd_di->di_tv.v_lock = 0; 19000 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 19001 fp->uf_refcount = 1; 19002 19003 /* behave like "dict" was used */ 19004 flags |= FC_DICT; 19005 } 19006 19007 /* insert the new function in the function list */ 19008 STRCPY(fp->uf_name, name); 19009 hash_add(&func_hashtab, UF2HIKEY(fp)); 19010 } 19011 fp->uf_args = newargs; 19012 fp->uf_lines = newlines; 19013 #ifdef FEAT_PROFILE 19014 fp->uf_tml_count = NULL; 19015 fp->uf_tml_total = NULL; 19016 fp->uf_tml_self = NULL; 19017 fp->uf_profiling = FALSE; 19018 if (prof_def_func()) 19019 func_do_profile(fp); 19020 #endif 19021 fp->uf_varargs = varargs; 19022 fp->uf_flags = flags; 19023 fp->uf_calls = 0; 19024 fp->uf_script_ID = current_SID; 19025 goto ret_free; 19026 19027 erret: 19028 ga_clear_strings(&newargs); 19029 ga_clear_strings(&newlines); 19030 ret_free: 19031 vim_free(skip_until); 19032 vim_free(fudi.fd_newkey); 19033 vim_free(name); 19034 did_emsg |= saved_did_emsg; 19035 } 19036 19037 /* 19038 * Get a function name, translating "<SID>" and "<SNR>". 19039 * Also handles a Funcref in a List or Dictionary. 19040 * Returns the function name in allocated memory, or NULL for failure. 19041 * flags: 19042 * TFN_INT: internal function name OK 19043 * TFN_QUIET: be quiet 19044 * Advances "pp" to just after the function name (if no error). 19045 */ 19046 static char_u * 19047 trans_function_name(pp, skip, flags, fdp) 19048 char_u **pp; 19049 int skip; /* only find the end, don't evaluate */ 19050 int flags; 19051 funcdict_T *fdp; /* return: info about dictionary used */ 19052 { 19053 char_u *name = NULL; 19054 char_u *start; 19055 char_u *end; 19056 int lead; 19057 char_u sid_buf[20]; 19058 int len; 19059 lval_T lv; 19060 19061 if (fdp != NULL) 19062 vim_memset(fdp, 0, sizeof(funcdict_T)); 19063 start = *pp; 19064 19065 /* Check for hard coded <SNR>: already translated function ID (from a user 19066 * command). */ 19067 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 19068 && (*pp)[2] == (int)KE_SNR) 19069 { 19070 *pp += 3; 19071 len = get_id_len(pp) + 3; 19072 return vim_strnsave(start, len); 19073 } 19074 19075 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 19076 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 19077 lead = eval_fname_script(start); 19078 if (lead > 2) 19079 start += lead; 19080 19081 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 19082 lead > 2 ? 0 : FNE_CHECK_START); 19083 if (end == start) 19084 { 19085 if (!skip) 19086 EMSG(_("E129: Function name required")); 19087 goto theend; 19088 } 19089 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 19090 { 19091 /* 19092 * Report an invalid expression in braces, unless the expression 19093 * evaluation has been cancelled due to an aborting error, an 19094 * interrupt, or an exception. 19095 */ 19096 if (!aborting()) 19097 { 19098 if (end != NULL) 19099 EMSG2(_(e_invarg2), start); 19100 } 19101 else 19102 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 19103 goto theend; 19104 } 19105 19106 if (lv.ll_tv != NULL) 19107 { 19108 if (fdp != NULL) 19109 { 19110 fdp->fd_dict = lv.ll_dict; 19111 fdp->fd_newkey = lv.ll_newkey; 19112 lv.ll_newkey = NULL; 19113 fdp->fd_di = lv.ll_di; 19114 } 19115 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 19116 { 19117 name = vim_strsave(lv.ll_tv->vval.v_string); 19118 *pp = end; 19119 } 19120 else 19121 { 19122 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 19123 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 19124 EMSG(_(e_funcref)); 19125 else 19126 *pp = end; 19127 name = NULL; 19128 } 19129 goto theend; 19130 } 19131 19132 if (lv.ll_name == NULL) 19133 { 19134 /* Error found, but continue after the function name. */ 19135 *pp = end; 19136 goto theend; 19137 } 19138 19139 if (lv.ll_exp_name != NULL) 19140 { 19141 len = (int)STRLEN(lv.ll_exp_name); 19142 if (lead <= 2 && lv.ll_name == lv.ll_exp_name 19143 && STRNCMP(lv.ll_name, "s:", 2) == 0) 19144 { 19145 /* When there was "s:" already or the name expanded to get a 19146 * leading "s:" then remove it. */ 19147 lv.ll_name += 2; 19148 len -= 2; 19149 lead = 2; 19150 } 19151 } 19152 else 19153 { 19154 if (lead == 2) /* skip over "s:" */ 19155 lv.ll_name += 2; 19156 len = (int)(end - lv.ll_name); 19157 } 19158 19159 /* 19160 * Copy the function name to allocated memory. 19161 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 19162 * Accept <SNR>123_name() outside a script. 19163 */ 19164 if (skip) 19165 lead = 0; /* do nothing */ 19166 else if (lead > 0) 19167 { 19168 lead = 3; 19169 if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) 19170 || eval_fname_sid(*pp)) 19171 { 19172 /* It's "s:" or "<SID>" */ 19173 if (current_SID <= 0) 19174 { 19175 EMSG(_(e_usingsid)); 19176 goto theend; 19177 } 19178 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 19179 lead += (int)STRLEN(sid_buf); 19180 } 19181 } 19182 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 19183 { 19184 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 19185 goto theend; 19186 } 19187 name = alloc((unsigned)(len + lead + 1)); 19188 if (name != NULL) 19189 { 19190 if (lead > 0) 19191 { 19192 name[0] = K_SPECIAL; 19193 name[1] = KS_EXTRA; 19194 name[2] = (int)KE_SNR; 19195 if (lead > 3) /* If it's "<SID>" */ 19196 STRCPY(name + 3, sid_buf); 19197 } 19198 mch_memmove(name + lead, lv.ll_name, (size_t)len); 19199 name[len + lead] = NUL; 19200 } 19201 *pp = end; 19202 19203 theend: 19204 clear_lval(&lv); 19205 return name; 19206 } 19207 19208 /* 19209 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 19210 * Return 2 if "p" starts with "s:". 19211 * Return 0 otherwise. 19212 */ 19213 static int 19214 eval_fname_script(p) 19215 char_u *p; 19216 { 19217 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 19218 || STRNICMP(p + 1, "SNR>", 4) == 0)) 19219 return 5; 19220 if (p[0] == 's' && p[1] == ':') 19221 return 2; 19222 return 0; 19223 } 19224 19225 /* 19226 * Return TRUE if "p" starts with "<SID>" or "s:". 19227 * Only works if eval_fname_script() returned non-zero for "p"! 19228 */ 19229 static int 19230 eval_fname_sid(p) 19231 char_u *p; 19232 { 19233 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 19234 } 19235 19236 /* 19237 * List the head of the function: "name(arg1, arg2)". 19238 */ 19239 static void 19240 list_func_head(fp, indent) 19241 ufunc_T *fp; 19242 int indent; 19243 { 19244 int j; 19245 19246 msg_start(); 19247 if (indent) 19248 MSG_PUTS(" "); 19249 MSG_PUTS("function "); 19250 if (fp->uf_name[0] == K_SPECIAL) 19251 { 19252 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 19253 msg_puts(fp->uf_name + 3); 19254 } 19255 else 19256 msg_puts(fp->uf_name); 19257 msg_putchar('('); 19258 for (j = 0; j < fp->uf_args.ga_len; ++j) 19259 { 19260 if (j) 19261 MSG_PUTS(", "); 19262 msg_puts(FUNCARG(fp, j)); 19263 } 19264 if (fp->uf_varargs) 19265 { 19266 if (j) 19267 MSG_PUTS(", "); 19268 MSG_PUTS("..."); 19269 } 19270 msg_putchar(')'); 19271 msg_clr_eos(); 19272 if (p_verbose > 0) 19273 last_set_msg(fp->uf_script_ID); 19274 } 19275 19276 /* 19277 * Find a function by name, return pointer to it in ufuncs. 19278 * Return NULL for unknown function. 19279 */ 19280 static ufunc_T * 19281 find_func(name) 19282 char_u *name; 19283 { 19284 hashitem_T *hi; 19285 19286 hi = hash_find(&func_hashtab, name); 19287 if (!HASHITEM_EMPTY(hi)) 19288 return HI2UF(hi); 19289 return NULL; 19290 } 19291 19292 #if defined(EXITFREE) || defined(PROTO) 19293 void 19294 free_all_functions() 19295 { 19296 hashitem_T *hi; 19297 19298 /* Need to start all over every time, because func_free() may change the 19299 * hash table. */ 19300 while (func_hashtab.ht_used > 0) 19301 for (hi = func_hashtab.ht_array; ; ++hi) 19302 if (!HASHITEM_EMPTY(hi)) 19303 { 19304 func_free(HI2UF(hi)); 19305 break; 19306 } 19307 } 19308 #endif 19309 19310 /* 19311 * Return TRUE if a function "name" exists. 19312 */ 19313 static int 19314 function_exists(name) 19315 char_u *name; 19316 { 19317 char_u *nm = name; 19318 char_u *p; 19319 int n = FALSE; 19320 19321 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); 19322 nm = skipwhite(nm); 19323 19324 /* Only accept "funcname", "funcname ", "funcname (..." and 19325 * "funcname(...", not "funcname!...". */ 19326 if (p != NULL && (*nm == NUL || *nm == '(')) 19327 { 19328 if (builtin_function(p)) 19329 n = (find_internal_func(p) >= 0); 19330 else 19331 n = (find_func(p) != NULL); 19332 } 19333 vim_free(p); 19334 return n; 19335 } 19336 19337 /* 19338 * Return TRUE if "name" looks like a builtin function name: starts with a 19339 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 19340 */ 19341 static int 19342 builtin_function(name) 19343 char_u *name; 19344 { 19345 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 19346 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 19347 } 19348 19349 #if defined(FEAT_PROFILE) || defined(PROTO) 19350 /* 19351 * Start profiling function "fp". 19352 */ 19353 static void 19354 func_do_profile(fp) 19355 ufunc_T *fp; 19356 { 19357 fp->uf_tm_count = 0; 19358 profile_zero(&fp->uf_tm_self); 19359 profile_zero(&fp->uf_tm_total); 19360 if (fp->uf_tml_count == NULL) 19361 fp->uf_tml_count = (int *)alloc_clear((unsigned) 19362 (sizeof(int) * fp->uf_lines.ga_len)); 19363 if (fp->uf_tml_total == NULL) 19364 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 19365 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19366 if (fp->uf_tml_self == NULL) 19367 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 19368 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 19369 fp->uf_tml_idx = -1; 19370 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 19371 || fp->uf_tml_self == NULL) 19372 return; /* out of memory */ 19373 19374 fp->uf_profiling = TRUE; 19375 } 19376 19377 /* 19378 * Dump the profiling results for all functions in file "fd". 19379 */ 19380 void 19381 func_dump_profile(fd) 19382 FILE *fd; 19383 { 19384 hashitem_T *hi; 19385 int todo; 19386 ufunc_T *fp; 19387 int i; 19388 ufunc_T **sorttab; 19389 int st_len = 0; 19390 19391 todo = (int)func_hashtab.ht_used; 19392 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 19393 19394 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 19395 { 19396 if (!HASHITEM_EMPTY(hi)) 19397 { 19398 --todo; 19399 fp = HI2UF(hi); 19400 if (fp->uf_profiling) 19401 { 19402 if (sorttab != NULL) 19403 sorttab[st_len++] = fp; 19404 19405 if (fp->uf_name[0] == K_SPECIAL) 19406 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 19407 else 19408 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 19409 if (fp->uf_tm_count == 1) 19410 fprintf(fd, "Called 1 time\n"); 19411 else 19412 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 19413 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 19414 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 19415 fprintf(fd, "\n"); 19416 fprintf(fd, "count total (s) self (s)\n"); 19417 19418 for (i = 0; i < fp->uf_lines.ga_len; ++i) 19419 { 19420 if (FUNCLINE(fp, i) == NULL) 19421 continue; 19422 prof_func_line(fd, fp->uf_tml_count[i], 19423 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 19424 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 19425 } 19426 fprintf(fd, "\n"); 19427 } 19428 } 19429 } 19430 19431 if (sorttab != NULL && st_len > 0) 19432 { 19433 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19434 prof_total_cmp); 19435 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 19436 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 19437 prof_self_cmp); 19438 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 19439 } 19440 } 19441 19442 static void 19443 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 19444 FILE *fd; 19445 ufunc_T **sorttab; 19446 int st_len; 19447 char *title; 19448 int prefer_self; /* when equal print only self time */ 19449 { 19450 int i; 19451 ufunc_T *fp; 19452 19453 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 19454 fprintf(fd, "count total (s) self (s) function\n"); 19455 for (i = 0; i < 20 && i < st_len; ++i) 19456 { 19457 fp = sorttab[i]; 19458 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 19459 prefer_self); 19460 if (fp->uf_name[0] == K_SPECIAL) 19461 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 19462 else 19463 fprintf(fd, " %s()\n", fp->uf_name); 19464 } 19465 fprintf(fd, "\n"); 19466 } 19467 19468 /* 19469 * Print the count and times for one function or function line. 19470 */ 19471 static void 19472 prof_func_line(fd, count, total, self, prefer_self) 19473 FILE *fd; 19474 int count; 19475 proftime_T *total; 19476 proftime_T *self; 19477 int prefer_self; /* when equal print only self time */ 19478 { 19479 if (count > 0) 19480 { 19481 fprintf(fd, "%5d ", count); 19482 if (prefer_self && profile_equal(total, self)) 19483 fprintf(fd, " "); 19484 else 19485 fprintf(fd, "%s ", profile_msg(total)); 19486 if (!prefer_self && profile_equal(total, self)) 19487 fprintf(fd, " "); 19488 else 19489 fprintf(fd, "%s ", profile_msg(self)); 19490 } 19491 else 19492 fprintf(fd, " "); 19493 } 19494 19495 /* 19496 * Compare function for total time sorting. 19497 */ 19498 static int 19499 #ifdef __BORLANDC__ 19500 _RTLENTRYF 19501 #endif 19502 prof_total_cmp(s1, s2) 19503 const void *s1; 19504 const void *s2; 19505 { 19506 ufunc_T *p1, *p2; 19507 19508 p1 = *(ufunc_T **)s1; 19509 p2 = *(ufunc_T **)s2; 19510 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 19511 } 19512 19513 /* 19514 * Compare function for self time sorting. 19515 */ 19516 static int 19517 #ifdef __BORLANDC__ 19518 _RTLENTRYF 19519 #endif 19520 prof_self_cmp(s1, s2) 19521 const void *s1; 19522 const void *s2; 19523 { 19524 ufunc_T *p1, *p2; 19525 19526 p1 = *(ufunc_T **)s1; 19527 p2 = *(ufunc_T **)s2; 19528 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 19529 } 19530 19531 #endif 19532 19533 /* 19534 * If "name" has a package name try autoloading the script for it. 19535 * Return TRUE if a package was loaded. 19536 */ 19537 static int 19538 script_autoload(name, reload) 19539 char_u *name; 19540 int reload; /* load script again when already loaded */ 19541 { 19542 char_u *p; 19543 char_u *scriptname, *tofree; 19544 int ret = FALSE; 19545 int i; 19546 19547 /* If there is no '#' after name[0] there is no package name. */ 19548 p = vim_strchr(name, AUTOLOAD_CHAR); 19549 if (p == NULL || p == name) 19550 return FALSE; 19551 19552 tofree = scriptname = autoload_name(name); 19553 19554 /* Find the name in the list of previously loaded package names. Skip 19555 * "autoload/", it's always the same. */ 19556 for (i = 0; i < ga_loaded.ga_len; ++i) 19557 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 19558 break; 19559 if (!reload && i < ga_loaded.ga_len) 19560 ret = FALSE; /* was loaded already */ 19561 else 19562 { 19563 /* Remember the name if it wasn't loaded already. */ 19564 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 19565 { 19566 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 19567 tofree = NULL; 19568 } 19569 19570 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 19571 if (source_runtime(scriptname, FALSE) == OK) 19572 ret = TRUE; 19573 } 19574 19575 vim_free(tofree); 19576 return ret; 19577 } 19578 19579 /* 19580 * Return the autoload script name for a function or variable name. 19581 * Returns NULL when out of memory. 19582 */ 19583 static char_u * 19584 autoload_name(name) 19585 char_u *name; 19586 { 19587 char_u *p; 19588 char_u *scriptname; 19589 19590 /* Get the script file name: replace '#' with '/', append ".vim". */ 19591 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 19592 if (scriptname == NULL) 19593 return FALSE; 19594 STRCPY(scriptname, "autoload/"); 19595 STRCAT(scriptname, name); 19596 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 19597 STRCAT(scriptname, ".vim"); 19598 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 19599 *p = '/'; 19600 return scriptname; 19601 } 19602 19603 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 19604 19605 /* 19606 * Function given to ExpandGeneric() to obtain the list of user defined 19607 * function names. 19608 */ 19609 char_u * 19610 get_user_func_name(xp, idx) 19611 expand_T *xp; 19612 int idx; 19613 { 19614 static long_u done; 19615 static hashitem_T *hi; 19616 ufunc_T *fp; 19617 19618 if (idx == 0) 19619 { 19620 done = 0; 19621 hi = func_hashtab.ht_array; 19622 } 19623 if (done < func_hashtab.ht_used) 19624 { 19625 if (done++ > 0) 19626 ++hi; 19627 while (HASHITEM_EMPTY(hi)) 19628 ++hi; 19629 fp = HI2UF(hi); 19630 19631 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 19632 return fp->uf_name; /* prevents overflow */ 19633 19634 cat_func_name(IObuff, fp); 19635 if (xp->xp_context != EXPAND_USER_FUNC) 19636 { 19637 STRCAT(IObuff, "("); 19638 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 19639 STRCAT(IObuff, ")"); 19640 } 19641 return IObuff; 19642 } 19643 return NULL; 19644 } 19645 19646 #endif /* FEAT_CMDL_COMPL */ 19647 19648 /* 19649 * Copy the function name of "fp" to buffer "buf". 19650 * "buf" must be able to hold the function name plus three bytes. 19651 * Takes care of script-local function names. 19652 */ 19653 static void 19654 cat_func_name(buf, fp) 19655 char_u *buf; 19656 ufunc_T *fp; 19657 { 19658 if (fp->uf_name[0] == K_SPECIAL) 19659 { 19660 STRCPY(buf, "<SNR>"); 19661 STRCAT(buf, fp->uf_name + 3); 19662 } 19663 else 19664 STRCPY(buf, fp->uf_name); 19665 } 19666 19667 /* 19668 * ":delfunction {name}" 19669 */ 19670 void 19671 ex_delfunction(eap) 19672 exarg_T *eap; 19673 { 19674 ufunc_T *fp = NULL; 19675 char_u *p; 19676 char_u *name; 19677 funcdict_T fudi; 19678 19679 p = eap->arg; 19680 name = trans_function_name(&p, eap->skip, 0, &fudi); 19681 vim_free(fudi.fd_newkey); 19682 if (name == NULL) 19683 { 19684 if (fudi.fd_dict != NULL && !eap->skip) 19685 EMSG(_(e_funcref)); 19686 return; 19687 } 19688 if (!ends_excmd(*skipwhite(p))) 19689 { 19690 vim_free(name); 19691 EMSG(_(e_trailing)); 19692 return; 19693 } 19694 eap->nextcmd = check_nextcmd(p); 19695 if (eap->nextcmd != NULL) 19696 *p = NUL; 19697 19698 if (!eap->skip) 19699 fp = find_func(name); 19700 vim_free(name); 19701 19702 if (!eap->skip) 19703 { 19704 if (fp == NULL) 19705 { 19706 EMSG2(_(e_nofunc), eap->arg); 19707 return; 19708 } 19709 if (fp->uf_calls > 0) 19710 { 19711 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 19712 return; 19713 } 19714 19715 if (fudi.fd_dict != NULL) 19716 { 19717 /* Delete the dict item that refers to the function, it will 19718 * invoke func_unref() and possibly delete the function. */ 19719 dictitem_remove(fudi.fd_dict, fudi.fd_di); 19720 } 19721 else 19722 func_free(fp); 19723 } 19724 } 19725 19726 /* 19727 * Free a function and remove it from the list of functions. 19728 */ 19729 static void 19730 func_free(fp) 19731 ufunc_T *fp; 19732 { 19733 hashitem_T *hi; 19734 19735 /* clear this function */ 19736 ga_clear_strings(&(fp->uf_args)); 19737 ga_clear_strings(&(fp->uf_lines)); 19738 #ifdef FEAT_PROFILE 19739 vim_free(fp->uf_tml_count); 19740 vim_free(fp->uf_tml_total); 19741 vim_free(fp->uf_tml_self); 19742 #endif 19743 19744 /* remove the function from the function hashtable */ 19745 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 19746 if (HASHITEM_EMPTY(hi)) 19747 EMSG2(_(e_intern2), "func_free()"); 19748 else 19749 hash_remove(&func_hashtab, hi); 19750 19751 vim_free(fp); 19752 } 19753 19754 /* 19755 * Unreference a Function: decrement the reference count and free it when it 19756 * becomes zero. Only for numbered functions. 19757 */ 19758 static void 19759 func_unref(name) 19760 char_u *name; 19761 { 19762 ufunc_T *fp; 19763 19764 if (name != NULL && isdigit(*name)) 19765 { 19766 fp = find_func(name); 19767 if (fp == NULL) 19768 EMSG2(_(e_intern2), "func_unref()"); 19769 else if (--fp->uf_refcount <= 0) 19770 { 19771 /* Only delete it when it's not being used. Otherwise it's done 19772 * when "uf_calls" becomes zero. */ 19773 if (fp->uf_calls == 0) 19774 func_free(fp); 19775 } 19776 } 19777 } 19778 19779 /* 19780 * Count a reference to a Function. 19781 */ 19782 static void 19783 func_ref(name) 19784 char_u *name; 19785 { 19786 ufunc_T *fp; 19787 19788 if (name != NULL && isdigit(*name)) 19789 { 19790 fp = find_func(name); 19791 if (fp == NULL) 19792 EMSG2(_(e_intern2), "func_ref()"); 19793 else 19794 ++fp->uf_refcount; 19795 } 19796 } 19797 19798 /* 19799 * Call a user function. 19800 */ 19801 static void 19802 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 19803 ufunc_T *fp; /* pointer to function */ 19804 int argcount; /* nr of args */ 19805 typval_T *argvars; /* arguments */ 19806 typval_T *rettv; /* return value */ 19807 linenr_T firstline; /* first line of range */ 19808 linenr_T lastline; /* last line of range */ 19809 dict_T *selfdict; /* Dictionary for "self" */ 19810 { 19811 char_u *save_sourcing_name; 19812 linenr_T save_sourcing_lnum; 19813 scid_T save_current_SID; 19814 funccall_T fc; 19815 int save_did_emsg; 19816 static int depth = 0; 19817 dictitem_T *v; 19818 int fixvar_idx = 0; /* index in fixvar[] */ 19819 int i; 19820 int ai; 19821 char_u numbuf[NUMBUFLEN]; 19822 char_u *name; 19823 #ifdef FEAT_PROFILE 19824 proftime_T wait_start; 19825 proftime_T call_start; 19826 #endif 19827 19828 /* If depth of calling is getting too high, don't execute the function */ 19829 if (depth >= p_mfd) 19830 { 19831 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 19832 rettv->v_type = VAR_NUMBER; 19833 rettv->vval.v_number = -1; 19834 return; 19835 } 19836 ++depth; 19837 19838 line_breakcheck(); /* check for CTRL-C hit */ 19839 19840 fc.caller = current_funccal; 19841 current_funccal = &fc; 19842 fc.func = fp; 19843 fc.rettv = rettv; 19844 rettv->vval.v_number = 0; 19845 fc.linenr = 0; 19846 fc.returned = FALSE; 19847 fc.level = ex_nesting_level; 19848 /* Check if this function has a breakpoint. */ 19849 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 19850 fc.dbg_tick = debug_tick; 19851 19852 /* 19853 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 19854 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 19855 * each argument variable and saves a lot of time. 19856 */ 19857 /* 19858 * Init l: variables. 19859 */ 19860 init_var_dict(&fc.l_vars, &fc.l_vars_var); 19861 if (selfdict != NULL) 19862 { 19863 /* Set l:self to "selfdict". Use "name" to avoid a warning from 19864 * some compiler that checks the destination size. */ 19865 v = &fc.fixvar[fixvar_idx++].var; 19866 name = v->di_key; 19867 STRCPY(name, "self"); 19868 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 19869 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 19870 v->di_tv.v_type = VAR_DICT; 19871 v->di_tv.v_lock = 0; 19872 v->di_tv.vval.v_dict = selfdict; 19873 ++selfdict->dv_refcount; 19874 } 19875 19876 /* 19877 * Init a: variables. 19878 * Set a:0 to "argcount". 19879 * Set a:000 to a list with room for the "..." arguments. 19880 */ 19881 init_var_dict(&fc.l_avars, &fc.l_avars_var); 19882 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 19883 (varnumber_T)(argcount - fp->uf_args.ga_len)); 19884 v = &fc.fixvar[fixvar_idx++].var; 19885 STRCPY(v->di_key, "000"); 19886 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19887 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19888 v->di_tv.v_type = VAR_LIST; 19889 v->di_tv.v_lock = VAR_FIXED; 19890 v->di_tv.vval.v_list = &fc.l_varlist; 19891 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 19892 fc.l_varlist.lv_refcount = 99999; 19893 fc.l_varlist.lv_lock = VAR_FIXED; 19894 19895 /* 19896 * Set a:firstline to "firstline" and a:lastline to "lastline". 19897 * Set a:name to named arguments. 19898 * Set a:N to the "..." arguments. 19899 */ 19900 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 19901 (varnumber_T)firstline); 19902 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 19903 (varnumber_T)lastline); 19904 for (i = 0; i < argcount; ++i) 19905 { 19906 ai = i - fp->uf_args.ga_len; 19907 if (ai < 0) 19908 /* named argument a:name */ 19909 name = FUNCARG(fp, i); 19910 else 19911 { 19912 /* "..." argument a:1, a:2, etc. */ 19913 sprintf((char *)numbuf, "%d", ai + 1); 19914 name = numbuf; 19915 } 19916 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 19917 { 19918 v = &fc.fixvar[fixvar_idx++].var; 19919 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 19920 } 19921 else 19922 { 19923 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 19924 + STRLEN(name))); 19925 if (v == NULL) 19926 break; 19927 v->di_flags = DI_FLAGS_RO; 19928 } 19929 STRCPY(v->di_key, name); 19930 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 19931 19932 /* Note: the values are copied directly to avoid alloc/free. 19933 * "argvars" must have VAR_FIXED for v_lock. */ 19934 v->di_tv = argvars[i]; 19935 v->di_tv.v_lock = VAR_FIXED; 19936 19937 if (ai >= 0 && ai < MAX_FUNC_ARGS) 19938 { 19939 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 19940 fc.l_listitems[ai].li_tv = argvars[i]; 19941 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 19942 } 19943 } 19944 19945 /* Don't redraw while executing the function. */ 19946 ++RedrawingDisabled; 19947 save_sourcing_name = sourcing_name; 19948 save_sourcing_lnum = sourcing_lnum; 19949 sourcing_lnum = 1; 19950 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 19951 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 19952 if (sourcing_name != NULL) 19953 { 19954 if (save_sourcing_name != NULL 19955 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 19956 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 19957 else 19958 STRCPY(sourcing_name, "function "); 19959 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 19960 19961 if (p_verbose >= 12) 19962 { 19963 ++no_wait_return; 19964 verbose_enter_scroll(); 19965 19966 smsg((char_u *)_("calling %s"), sourcing_name); 19967 if (p_verbose >= 14) 19968 { 19969 char_u buf[MSG_BUF_LEN]; 19970 char_u numbuf2[NUMBUFLEN]; 19971 char_u *tofree; 19972 19973 msg_puts((char_u *)"("); 19974 for (i = 0; i < argcount; ++i) 19975 { 19976 if (i > 0) 19977 msg_puts((char_u *)", "); 19978 if (argvars[i].v_type == VAR_NUMBER) 19979 msg_outnum((long)argvars[i].vval.v_number); 19980 else 19981 { 19982 trunc_string(tv2string(&argvars[i], &tofree, 19983 numbuf2, 0), buf, MSG_BUF_CLEN); 19984 msg_puts(buf); 19985 vim_free(tofree); 19986 } 19987 } 19988 msg_puts((char_u *)")"); 19989 } 19990 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 19991 19992 verbose_leave_scroll(); 19993 --no_wait_return; 19994 } 19995 } 19996 #ifdef FEAT_PROFILE 19997 if (do_profiling == PROF_YES) 19998 { 19999 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 20000 func_do_profile(fp); 20001 if (fp->uf_profiling 20002 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 20003 { 20004 ++fp->uf_tm_count; 20005 profile_start(&call_start); 20006 profile_zero(&fp->uf_tm_children); 20007 } 20008 script_prof_save(&wait_start); 20009 } 20010 #endif 20011 20012 save_current_SID = current_SID; 20013 current_SID = fp->uf_script_ID; 20014 save_did_emsg = did_emsg; 20015 did_emsg = FALSE; 20016 20017 /* call do_cmdline() to execute the lines */ 20018 do_cmdline(NULL, get_func_line, (void *)&fc, 20019 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 20020 20021 --RedrawingDisabled; 20022 20023 /* when the function was aborted because of an error, return -1 */ 20024 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 20025 { 20026 clear_tv(rettv); 20027 rettv->v_type = VAR_NUMBER; 20028 rettv->vval.v_number = -1; 20029 } 20030 20031 #ifdef FEAT_PROFILE 20032 if (do_profiling == PROF_YES && (fp->uf_profiling 20033 || (fc.caller != NULL && &fc.caller->func->uf_profiling))) 20034 { 20035 profile_end(&call_start); 20036 profile_sub_wait(&wait_start, &call_start); 20037 profile_add(&fp->uf_tm_total, &call_start); 20038 profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); 20039 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 20040 { 20041 profile_add(&fc.caller->func->uf_tm_children, &call_start); 20042 profile_add(&fc.caller->func->uf_tml_children, &call_start); 20043 } 20044 } 20045 #endif 20046 20047 /* when being verbose, mention the return value */ 20048 if (p_verbose >= 12) 20049 { 20050 ++no_wait_return; 20051 verbose_enter_scroll(); 20052 20053 if (aborting()) 20054 smsg((char_u *)_("%s aborted"), sourcing_name); 20055 else if (fc.rettv->v_type == VAR_NUMBER) 20056 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 20057 (long)fc.rettv->vval.v_number); 20058 else 20059 { 20060 char_u buf[MSG_BUF_LEN]; 20061 char_u numbuf2[NUMBUFLEN]; 20062 char_u *tofree; 20063 20064 /* The value may be very long. Skip the middle part, so that we 20065 * have some idea how it starts and ends. smsg() would always 20066 * truncate it at the end. */ 20067 trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0), 20068 buf, MSG_BUF_CLEN); 20069 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 20070 vim_free(tofree); 20071 } 20072 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 20073 20074 verbose_leave_scroll(); 20075 --no_wait_return; 20076 } 20077 20078 vim_free(sourcing_name); 20079 sourcing_name = save_sourcing_name; 20080 sourcing_lnum = save_sourcing_lnum; 20081 current_SID = save_current_SID; 20082 #ifdef FEAT_PROFILE 20083 if (do_profiling == PROF_YES) 20084 script_prof_restore(&wait_start); 20085 #endif 20086 20087 if (p_verbose >= 12 && sourcing_name != NULL) 20088 { 20089 ++no_wait_return; 20090 verbose_enter_scroll(); 20091 20092 smsg((char_u *)_("continuing in %s"), sourcing_name); 20093 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 20094 20095 verbose_leave_scroll(); 20096 --no_wait_return; 20097 } 20098 20099 did_emsg |= save_did_emsg; 20100 current_funccal = fc.caller; 20101 20102 /* The a: variables typevals were not alloced, only free the allocated 20103 * variables. */ 20104 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 20105 20106 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 20107 --depth; 20108 } 20109 20110 /* 20111 * Add a number variable "name" to dict "dp" with value "nr". 20112 */ 20113 static void 20114 add_nr_var(dp, v, name, nr) 20115 dict_T *dp; 20116 dictitem_T *v; 20117 char *name; 20118 varnumber_T nr; 20119 { 20120 STRCPY(v->di_key, name); 20121 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 20122 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 20123 v->di_tv.v_type = VAR_NUMBER; 20124 v->di_tv.v_lock = VAR_FIXED; 20125 v->di_tv.vval.v_number = nr; 20126 } 20127 20128 /* 20129 * ":return [expr]" 20130 */ 20131 void 20132 ex_return(eap) 20133 exarg_T *eap; 20134 { 20135 char_u *arg = eap->arg; 20136 typval_T rettv; 20137 int returning = FALSE; 20138 20139 if (current_funccal == NULL) 20140 { 20141 EMSG(_("E133: :return not inside a function")); 20142 return; 20143 } 20144 20145 if (eap->skip) 20146 ++emsg_skip; 20147 20148 eap->nextcmd = NULL; 20149 if ((*arg != NUL && *arg != '|' && *arg != '\n') 20150 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 20151 { 20152 if (!eap->skip) 20153 returning = do_return(eap, FALSE, TRUE, &rettv); 20154 else 20155 clear_tv(&rettv); 20156 } 20157 /* It's safer to return also on error. */ 20158 else if (!eap->skip) 20159 { 20160 /* 20161 * Return unless the expression evaluation has been cancelled due to an 20162 * aborting error, an interrupt, or an exception. 20163 */ 20164 if (!aborting()) 20165 returning = do_return(eap, FALSE, TRUE, NULL); 20166 } 20167 20168 /* When skipping or the return gets pending, advance to the next command 20169 * in this line (!returning). Otherwise, ignore the rest of the line. 20170 * Following lines will be ignored by get_func_line(). */ 20171 if (returning) 20172 eap->nextcmd = NULL; 20173 else if (eap->nextcmd == NULL) /* no argument */ 20174 eap->nextcmd = check_nextcmd(arg); 20175 20176 if (eap->skip) 20177 --emsg_skip; 20178 } 20179 20180 /* 20181 * Return from a function. Possibly makes the return pending. Also called 20182 * for a pending return at the ":endtry" or after returning from an extra 20183 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 20184 * when called due to a ":return" command. "rettv" may point to a typval_T 20185 * with the return rettv. Returns TRUE when the return can be carried out, 20186 * FALSE when the return gets pending. 20187 */ 20188 int 20189 do_return(eap, reanimate, is_cmd, rettv) 20190 exarg_T *eap; 20191 int reanimate; 20192 int is_cmd; 20193 void *rettv; 20194 { 20195 int idx; 20196 struct condstack *cstack = eap->cstack; 20197 20198 if (reanimate) 20199 /* Undo the return. */ 20200 current_funccal->returned = FALSE; 20201 20202 /* 20203 * Cleanup (and inactivate) conditionals, but stop when a try conditional 20204 * not in its finally clause (which then is to be executed next) is found. 20205 * In this case, make the ":return" pending for execution at the ":endtry". 20206 * Otherwise, return normally. 20207 */ 20208 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 20209 if (idx >= 0) 20210 { 20211 cstack->cs_pending[idx] = CSTP_RETURN; 20212 20213 if (!is_cmd && !reanimate) 20214 /* A pending return again gets pending. "rettv" points to an 20215 * allocated variable with the rettv of the original ":return"'s 20216 * argument if present or is NULL else. */ 20217 cstack->cs_rettv[idx] = rettv; 20218 else 20219 { 20220 /* When undoing a return in order to make it pending, get the stored 20221 * return rettv. */ 20222 if (reanimate) 20223 rettv = current_funccal->rettv; 20224 20225 if (rettv != NULL) 20226 { 20227 /* Store the value of the pending return. */ 20228 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 20229 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 20230 else 20231 EMSG(_(e_outofmem)); 20232 } 20233 else 20234 cstack->cs_rettv[idx] = NULL; 20235 20236 if (reanimate) 20237 { 20238 /* The pending return value could be overwritten by a ":return" 20239 * without argument in a finally clause; reset the default 20240 * return value. */ 20241 current_funccal->rettv->v_type = VAR_NUMBER; 20242 current_funccal->rettv->vval.v_number = 0; 20243 } 20244 } 20245 report_make_pending(CSTP_RETURN, rettv); 20246 } 20247 else 20248 { 20249 current_funccal->returned = TRUE; 20250 20251 /* If the return is carried out now, store the return value. For 20252 * a return immediately after reanimation, the value is already 20253 * there. */ 20254 if (!reanimate && rettv != NULL) 20255 { 20256 clear_tv(current_funccal->rettv); 20257 *current_funccal->rettv = *(typval_T *)rettv; 20258 if (!is_cmd) 20259 vim_free(rettv); 20260 } 20261 } 20262 20263 return idx < 0; 20264 } 20265 20266 /* 20267 * Free the variable with a pending return value. 20268 */ 20269 void 20270 discard_pending_return(rettv) 20271 void *rettv; 20272 { 20273 free_tv((typval_T *)rettv); 20274 } 20275 20276 /* 20277 * Generate a return command for producing the value of "rettv". The result 20278 * is an allocated string. Used by report_pending() for verbose messages. 20279 */ 20280 char_u * 20281 get_return_cmd(rettv) 20282 void *rettv; 20283 { 20284 char_u *s = NULL; 20285 char_u *tofree = NULL; 20286 char_u numbuf[NUMBUFLEN]; 20287 20288 if (rettv != NULL) 20289 s = echo_string((typval_T *)rettv, &tofree, numbuf, 0); 20290 if (s == NULL) 20291 s = (char_u *)""; 20292 20293 STRCPY(IObuff, ":return "); 20294 STRNCPY(IObuff + 8, s, IOSIZE - 8); 20295 if (STRLEN(s) + 8 >= IOSIZE) 20296 STRCPY(IObuff + IOSIZE - 4, "..."); 20297 vim_free(tofree); 20298 return vim_strsave(IObuff); 20299 } 20300 20301 /* 20302 * Get next function line. 20303 * Called by do_cmdline() to get the next line. 20304 * Returns allocated string, or NULL for end of function. 20305 */ 20306 /* ARGSUSED */ 20307 char_u * 20308 get_func_line(c, cookie, indent) 20309 int c; /* not used */ 20310 void *cookie; 20311 int indent; /* not used */ 20312 { 20313 funccall_T *fcp = (funccall_T *)cookie; 20314 ufunc_T *fp = fcp->func; 20315 char_u *retval; 20316 garray_T *gap; /* growarray with function lines */ 20317 20318 /* If breakpoints have been added/deleted need to check for it. */ 20319 if (fcp->dbg_tick != debug_tick) 20320 { 20321 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20322 sourcing_lnum); 20323 fcp->dbg_tick = debug_tick; 20324 } 20325 #ifdef FEAT_PROFILE 20326 if (do_profiling == PROF_YES) 20327 func_line_end(cookie); 20328 #endif 20329 20330 gap = &fp->uf_lines; 20331 if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20332 || fcp->returned) 20333 retval = NULL; 20334 else 20335 { 20336 /* Skip NULL lines (continuation lines). */ 20337 while (fcp->linenr < gap->ga_len 20338 && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) 20339 ++fcp->linenr; 20340 if (fcp->linenr >= gap->ga_len) 20341 retval = NULL; 20342 else 20343 { 20344 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 20345 sourcing_lnum = fcp->linenr; 20346 #ifdef FEAT_PROFILE 20347 if (do_profiling == PROF_YES) 20348 func_line_start(cookie); 20349 #endif 20350 } 20351 } 20352 20353 /* Did we encounter a breakpoint? */ 20354 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 20355 { 20356 dbg_breakpoint(fp->uf_name, sourcing_lnum); 20357 /* Find next breakpoint. */ 20358 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 20359 sourcing_lnum); 20360 fcp->dbg_tick = debug_tick; 20361 } 20362 20363 return retval; 20364 } 20365 20366 #if defined(FEAT_PROFILE) || defined(PROTO) 20367 /* 20368 * Called when starting to read a function line. 20369 * "sourcing_lnum" must be correct! 20370 * When skipping lines it may not actually be executed, but we won't find out 20371 * until later and we need to store the time now. 20372 */ 20373 void 20374 func_line_start(cookie) 20375 void *cookie; 20376 { 20377 funccall_T *fcp = (funccall_T *)cookie; 20378 ufunc_T *fp = fcp->func; 20379 20380 if (fp->uf_profiling && sourcing_lnum >= 1 20381 && sourcing_lnum <= fp->uf_lines.ga_len) 20382 { 20383 fp->uf_tml_idx = sourcing_lnum - 1; 20384 /* Skip continuation lines. */ 20385 while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) 20386 --fp->uf_tml_idx; 20387 fp->uf_tml_execed = FALSE; 20388 profile_start(&fp->uf_tml_start); 20389 profile_zero(&fp->uf_tml_children); 20390 profile_get_wait(&fp->uf_tml_wait); 20391 } 20392 } 20393 20394 /* 20395 * Called when actually executing a function line. 20396 */ 20397 void 20398 func_line_exec(cookie) 20399 void *cookie; 20400 { 20401 funccall_T *fcp = (funccall_T *)cookie; 20402 ufunc_T *fp = fcp->func; 20403 20404 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20405 fp->uf_tml_execed = TRUE; 20406 } 20407 20408 /* 20409 * Called when done with a function line. 20410 */ 20411 void 20412 func_line_end(cookie) 20413 void *cookie; 20414 { 20415 funccall_T *fcp = (funccall_T *)cookie; 20416 ufunc_T *fp = fcp->func; 20417 20418 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 20419 { 20420 if (fp->uf_tml_execed) 20421 { 20422 ++fp->uf_tml_count[fp->uf_tml_idx]; 20423 profile_end(&fp->uf_tml_start); 20424 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 20425 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 20426 profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start, 20427 &fp->uf_tml_children); 20428 } 20429 fp->uf_tml_idx = -1; 20430 } 20431 } 20432 #endif 20433 20434 /* 20435 * Return TRUE if the currently active function should be ended, because a 20436 * return was encountered or an error occured. Used inside a ":while". 20437 */ 20438 int 20439 func_has_ended(cookie) 20440 void *cookie; 20441 { 20442 funccall_T *fcp = (funccall_T *)cookie; 20443 20444 /* Ignore the "abort" flag if the abortion behavior has been changed due to 20445 * an error inside a try conditional. */ 20446 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 20447 || fcp->returned); 20448 } 20449 20450 /* 20451 * return TRUE if cookie indicates a function which "abort"s on errors. 20452 */ 20453 int 20454 func_has_abort(cookie) 20455 void *cookie; 20456 { 20457 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 20458 } 20459 20460 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 20461 typedef enum 20462 { 20463 VAR_FLAVOUR_DEFAULT, 20464 VAR_FLAVOUR_SESSION, 20465 VAR_FLAVOUR_VIMINFO 20466 } var_flavour_T; 20467 20468 static var_flavour_T var_flavour __ARGS((char_u *varname)); 20469 20470 static var_flavour_T 20471 var_flavour(varname) 20472 char_u *varname; 20473 { 20474 char_u *p = varname; 20475 20476 if (ASCII_ISUPPER(*p)) 20477 { 20478 while (*(++p)) 20479 if (ASCII_ISLOWER(*p)) 20480 return VAR_FLAVOUR_SESSION; 20481 return VAR_FLAVOUR_VIMINFO; 20482 } 20483 else 20484 return VAR_FLAVOUR_DEFAULT; 20485 } 20486 #endif 20487 20488 #if defined(FEAT_VIMINFO) || defined(PROTO) 20489 /* 20490 * Restore global vars that start with a capital from the viminfo file 20491 */ 20492 int 20493 read_viminfo_varlist(virp, writing) 20494 vir_T *virp; 20495 int writing; 20496 { 20497 char_u *tab; 20498 int is_string = FALSE; 20499 typval_T tv; 20500 20501 if (!writing && (find_viminfo_parameter('!') != NULL)) 20502 { 20503 tab = vim_strchr(virp->vir_line + 1, '\t'); 20504 if (tab != NULL) 20505 { 20506 *tab++ = '\0'; /* isolate the variable name */ 20507 if (*tab == 'S') /* string var */ 20508 is_string = TRUE; 20509 20510 tab = vim_strchr(tab, '\t'); 20511 if (tab != NULL) 20512 { 20513 if (is_string) 20514 { 20515 tv.v_type = VAR_STRING; 20516 tv.vval.v_string = viminfo_readstring(virp, 20517 (int)(tab - virp->vir_line + 1), TRUE); 20518 } 20519 else 20520 { 20521 tv.v_type = VAR_NUMBER; 20522 tv.vval.v_number = atol((char *)tab + 1); 20523 } 20524 set_var(virp->vir_line + 1, &tv, FALSE); 20525 if (is_string) 20526 vim_free(tv.vval.v_string); 20527 } 20528 } 20529 } 20530 20531 return viminfo_readline(virp); 20532 } 20533 20534 /* 20535 * Write global vars that start with a capital to the viminfo file 20536 */ 20537 void 20538 write_viminfo_varlist(fp) 20539 FILE *fp; 20540 { 20541 hashitem_T *hi; 20542 dictitem_T *this_var; 20543 int todo; 20544 char *s; 20545 char_u *p; 20546 char_u *tofree; 20547 char_u numbuf[NUMBUFLEN]; 20548 20549 if (find_viminfo_parameter('!') == NULL) 20550 return; 20551 20552 fprintf(fp, _("\n# global variables:\n")); 20553 20554 todo = (int)globvarht.ht_used; 20555 for (hi = globvarht.ht_array; todo > 0; ++hi) 20556 { 20557 if (!HASHITEM_EMPTY(hi)) 20558 { 20559 --todo; 20560 this_var = HI2DI(hi); 20561 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 20562 { 20563 switch (this_var->di_tv.v_type) 20564 { 20565 case VAR_STRING: s = "STR"; break; 20566 case VAR_NUMBER: s = "NUM"; break; 20567 default: continue; 20568 } 20569 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 20570 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); 20571 if (p != NULL) 20572 viminfo_writestring(fp, p); 20573 vim_free(tofree); 20574 } 20575 } 20576 } 20577 } 20578 #endif 20579 20580 #if defined(FEAT_SESSION) || defined(PROTO) 20581 int 20582 store_session_globals(fd) 20583 FILE *fd; 20584 { 20585 hashitem_T *hi; 20586 dictitem_T *this_var; 20587 int todo; 20588 char_u *p, *t; 20589 20590 todo = (int)globvarht.ht_used; 20591 for (hi = globvarht.ht_array; todo > 0; ++hi) 20592 { 20593 if (!HASHITEM_EMPTY(hi)) 20594 { 20595 --todo; 20596 this_var = HI2DI(hi); 20597 if ((this_var->di_tv.v_type == VAR_NUMBER 20598 || this_var->di_tv.v_type == VAR_STRING) 20599 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 20600 { 20601 /* Escape special characters with a backslash. Turn a LF and 20602 * CR into \n and \r. */ 20603 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 20604 (char_u *)"\\\"\n\r"); 20605 if (p == NULL) /* out of memory */ 20606 break; 20607 for (t = p; *t != NUL; ++t) 20608 if (*t == '\n') 20609 *t = 'n'; 20610 else if (*t == '\r') 20611 *t = 'r'; 20612 if ((fprintf(fd, "let %s = %c%s%c", 20613 this_var->di_key, 20614 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20615 : ' ', 20616 p, 20617 (this_var->di_tv.v_type == VAR_STRING) ? '"' 20618 : ' ') < 0) 20619 || put_eol(fd) == FAIL) 20620 { 20621 vim_free(p); 20622 return FAIL; 20623 } 20624 vim_free(p); 20625 } 20626 } 20627 } 20628 return OK; 20629 } 20630 #endif 20631 20632 /* 20633 * Display script name where an item was last set. 20634 * Should only be invoked when 'verbose' is non-zero. 20635 */ 20636 void 20637 last_set_msg(scriptID) 20638 scid_T scriptID; 20639 { 20640 char_u *p; 20641 20642 if (scriptID != 0) 20643 { 20644 p = home_replace_save(NULL, get_scriptname(scriptID)); 20645 if (p != NULL) 20646 { 20647 verbose_enter(); 20648 MSG_PUTS(_("\n\tLast set from ")); 20649 MSG_PUTS(p); 20650 vim_free(p); 20651 verbose_leave(); 20652 } 20653 } 20654 } 20655 20656 #endif /* FEAT_EVAL */ 20657 20658 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 20659 20660 20661 #ifdef WIN3264 20662 /* 20663 * Functions for ":8" filename modifier: get 8.3 version of a filename. 20664 */ 20665 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20666 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 20667 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 20668 20669 /* 20670 * Get the short pathname of a file. 20671 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 20672 */ 20673 static int 20674 get_short_pathname(fnamep, bufp, fnamelen) 20675 char_u **fnamep; 20676 char_u **bufp; 20677 int *fnamelen; 20678 { 20679 int l,len; 20680 char_u *newbuf; 20681 20682 len = *fnamelen; 20683 20684 l = GetShortPathName(*fnamep, *fnamep, len); 20685 if (l > len - 1) 20686 { 20687 /* If that doesn't work (not enough space), then save the string 20688 * and try again with a new buffer big enough 20689 */ 20690 newbuf = vim_strnsave(*fnamep, l); 20691 if (newbuf == NULL) 20692 return 0; 20693 20694 vim_free(*bufp); 20695 *fnamep = *bufp = newbuf; 20696 20697 l = GetShortPathName(*fnamep,*fnamep,l+1); 20698 20699 /* Really should always succeed, as the buffer is big enough */ 20700 } 20701 20702 *fnamelen = l; 20703 return 1; 20704 } 20705 20706 /* 20707 * Create a short path name. Returns the length of the buffer it needs. 20708 * Doesn't copy over the end of the buffer passed in. 20709 */ 20710 static int 20711 shortpath_for_invalid_fname(fname, bufp, fnamelen) 20712 char_u **fname; 20713 char_u **bufp; 20714 int *fnamelen; 20715 { 20716 char_u *s, *p, *pbuf2, *pbuf3; 20717 char_u ch; 20718 int len, len2, plen, slen; 20719 20720 /* Make a copy */ 20721 len2 = *fnamelen; 20722 pbuf2 = vim_strnsave(*fname, len2); 20723 pbuf3 = NULL; 20724 20725 s = pbuf2 + len2 - 1; /* Find the end */ 20726 slen = 1; 20727 plen = len2; 20728 20729 if (after_pathsep(pbuf2, s + 1)) 20730 { 20731 --s; 20732 ++slen; 20733 --plen; 20734 } 20735 20736 do 20737 { 20738 /* Go back one path-seperator */ 20739 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 20740 { 20741 --s; 20742 ++slen; 20743 --plen; 20744 } 20745 if (s <= pbuf2) 20746 break; 20747 20748 /* Remeber the character that is about to be blatted */ 20749 ch = *s; 20750 *s = 0; /* get_short_pathname requires a null-terminated string */ 20751 20752 /* Try it in situ */ 20753 p = pbuf2; 20754 if (!get_short_pathname(&p, &pbuf3, &plen)) 20755 { 20756 vim_free(pbuf2); 20757 return -1; 20758 } 20759 *s = ch; /* Preserve the string */ 20760 } while (plen == 0); 20761 20762 if (plen > 0) 20763 { 20764 /* Remeber the length of the new string. */ 20765 *fnamelen = len = plen + slen; 20766 vim_free(*bufp); 20767 if (len > len2) 20768 { 20769 /* If there's not enough space in the currently allocated string, 20770 * then copy it to a buffer big enough. 20771 */ 20772 *fname= *bufp = vim_strnsave(p, len); 20773 if (*fname == NULL) 20774 return -1; 20775 } 20776 else 20777 { 20778 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 20779 *fname = *bufp = pbuf2; 20780 if (p != pbuf2) 20781 strncpy(*fname, p, plen); 20782 pbuf2 = NULL; 20783 } 20784 /* Concat the next bit */ 20785 strncpy(*fname + plen, s, slen); 20786 (*fname)[len] = '\0'; 20787 } 20788 vim_free(pbuf3); 20789 vim_free(pbuf2); 20790 return 0; 20791 } 20792 20793 /* 20794 * Get a pathname for a partial path. 20795 */ 20796 static int 20797 shortpath_for_partial(fnamep, bufp, fnamelen) 20798 char_u **fnamep; 20799 char_u **bufp; 20800 int *fnamelen; 20801 { 20802 int sepcount, len, tflen; 20803 char_u *p; 20804 char_u *pbuf, *tfname; 20805 int hasTilde; 20806 20807 /* Count up the path seperators from the RHS.. so we know which part 20808 * of the path to return. 20809 */ 20810 sepcount = 0; 20811 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 20812 if (vim_ispathsep(*p)) 20813 ++sepcount; 20814 20815 /* Need full path first (use expand_env() to remove a "~/") */ 20816 hasTilde = (**fnamep == '~'); 20817 if (hasTilde) 20818 pbuf = tfname = expand_env_save(*fnamep); 20819 else 20820 pbuf = tfname = FullName_save(*fnamep, FALSE); 20821 20822 len = tflen = (int)STRLEN(tfname); 20823 20824 if (!get_short_pathname(&tfname, &pbuf, &len)) 20825 return -1; 20826 20827 if (len == 0) 20828 { 20829 /* Don't have a valid filename, so shorten the rest of the 20830 * path if we can. This CAN give us invalid 8.3 filenames, but 20831 * there's not a lot of point in guessing what it might be. 20832 */ 20833 len = tflen; 20834 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 20835 return -1; 20836 } 20837 20838 /* Count the paths backward to find the beginning of the desired string. */ 20839 for (p = tfname + len - 1; p >= tfname; --p) 20840 { 20841 #ifdef FEAT_MBYTE 20842 if (has_mbyte) 20843 p -= mb_head_off(tfname, p); 20844 #endif 20845 if (vim_ispathsep(*p)) 20846 { 20847 if (sepcount == 0 || (hasTilde && sepcount == 1)) 20848 break; 20849 else 20850 sepcount --; 20851 } 20852 } 20853 if (hasTilde) 20854 { 20855 --p; 20856 if (p >= tfname) 20857 *p = '~'; 20858 else 20859 return -1; 20860 } 20861 else 20862 ++p; 20863 20864 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 20865 vim_free(*bufp); 20866 *fnamelen = (int)STRLEN(p); 20867 *bufp = pbuf; 20868 *fnamep = p; 20869 20870 return 0; 20871 } 20872 #endif /* WIN3264 */ 20873 20874 /* 20875 * Adjust a filename, according to a string of modifiers. 20876 * *fnamep must be NUL terminated when called. When returning, the length is 20877 * determined by *fnamelen. 20878 * Returns valid flags. 20879 * When there is an error, *fnamep is set to NULL. 20880 */ 20881 int 20882 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 20883 char_u *src; /* string with modifiers */ 20884 int *usedlen; /* characters after src that are used */ 20885 char_u **fnamep; /* file name so far */ 20886 char_u **bufp; /* buffer for allocated file name or NULL */ 20887 int *fnamelen; /* length of fnamep */ 20888 { 20889 int valid = 0; 20890 char_u *tail; 20891 char_u *s, *p, *pbuf; 20892 char_u dirname[MAXPATHL]; 20893 int c; 20894 int has_fullname = 0; 20895 #ifdef WIN3264 20896 int has_shortname = 0; 20897 #endif 20898 20899 repeat: 20900 /* ":p" - full path/file_name */ 20901 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 20902 { 20903 has_fullname = 1; 20904 20905 valid |= VALID_PATH; 20906 *usedlen += 2; 20907 20908 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 20909 if ((*fnamep)[0] == '~' 20910 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 20911 && ((*fnamep)[1] == '/' 20912 # ifdef BACKSLASH_IN_FILENAME 20913 || (*fnamep)[1] == '\\' 20914 # endif 20915 || (*fnamep)[1] == NUL) 20916 20917 #endif 20918 ) 20919 { 20920 *fnamep = expand_env_save(*fnamep); 20921 vim_free(*bufp); /* free any allocated file name */ 20922 *bufp = *fnamep; 20923 if (*fnamep == NULL) 20924 return -1; 20925 } 20926 20927 /* When "/." or "/.." is used: force expansion to get rid of it. */ 20928 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 20929 { 20930 if (vim_ispathsep(*p) 20931 && p[1] == '.' 20932 && (p[2] == NUL 20933 || vim_ispathsep(p[2]) 20934 || (p[2] == '.' 20935 && (p[3] == NUL || vim_ispathsep(p[3]))))) 20936 break; 20937 } 20938 20939 /* FullName_save() is slow, don't use it when not needed. */ 20940 if (*p != NUL || !vim_isAbsName(*fnamep)) 20941 { 20942 *fnamep = FullName_save(*fnamep, *p != NUL); 20943 vim_free(*bufp); /* free any allocated file name */ 20944 *bufp = *fnamep; 20945 if (*fnamep == NULL) 20946 return -1; 20947 } 20948 20949 /* Append a path separator to a directory. */ 20950 if (mch_isdir(*fnamep)) 20951 { 20952 /* Make room for one or two extra characters. */ 20953 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 20954 vim_free(*bufp); /* free any allocated file name */ 20955 *bufp = *fnamep; 20956 if (*fnamep == NULL) 20957 return -1; 20958 add_pathsep(*fnamep); 20959 } 20960 } 20961 20962 /* ":." - path relative to the current directory */ 20963 /* ":~" - path relative to the home directory */ 20964 /* ":8" - shortname path - postponed till after */ 20965 while (src[*usedlen] == ':' 20966 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 20967 { 20968 *usedlen += 2; 20969 if (c == '8') 20970 { 20971 #ifdef WIN3264 20972 has_shortname = 1; /* Postpone this. */ 20973 #endif 20974 continue; 20975 } 20976 pbuf = NULL; 20977 /* Need full path first (use expand_env() to remove a "~/") */ 20978 if (!has_fullname) 20979 { 20980 if (c == '.' && **fnamep == '~') 20981 p = pbuf = expand_env_save(*fnamep); 20982 else 20983 p = pbuf = FullName_save(*fnamep, FALSE); 20984 } 20985 else 20986 p = *fnamep; 20987 20988 has_fullname = 0; 20989 20990 if (p != NULL) 20991 { 20992 if (c == '.') 20993 { 20994 mch_dirname(dirname, MAXPATHL); 20995 s = shorten_fname(p, dirname); 20996 if (s != NULL) 20997 { 20998 *fnamep = s; 20999 if (pbuf != NULL) 21000 { 21001 vim_free(*bufp); /* free any allocated file name */ 21002 *bufp = pbuf; 21003 pbuf = NULL; 21004 } 21005 } 21006 } 21007 else 21008 { 21009 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 21010 /* Only replace it when it starts with '~' */ 21011 if (*dirname == '~') 21012 { 21013 s = vim_strsave(dirname); 21014 if (s != NULL) 21015 { 21016 *fnamep = s; 21017 vim_free(*bufp); 21018 *bufp = s; 21019 } 21020 } 21021 } 21022 vim_free(pbuf); 21023 } 21024 } 21025 21026 tail = gettail(*fnamep); 21027 *fnamelen = (int)STRLEN(*fnamep); 21028 21029 /* ":h" - head, remove "/file_name", can be repeated */ 21030 /* Don't remove the first "/" or "c:\" */ 21031 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 21032 { 21033 valid |= VALID_HEAD; 21034 *usedlen += 2; 21035 s = get_past_head(*fnamep); 21036 while (tail > s && after_pathsep(s, tail)) 21037 --tail; 21038 *fnamelen = (int)(tail - *fnamep); 21039 #ifdef VMS 21040 if (*fnamelen > 0) 21041 *fnamelen += 1; /* the path separator is part of the path */ 21042 #endif 21043 while (tail > s && !after_pathsep(s, tail)) 21044 mb_ptr_back(*fnamep, tail); 21045 } 21046 21047 /* ":8" - shortname */ 21048 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 21049 { 21050 *usedlen += 2; 21051 #ifdef WIN3264 21052 has_shortname = 1; 21053 #endif 21054 } 21055 21056 #ifdef WIN3264 21057 /* Check shortname after we have done 'heads' and before we do 'tails' 21058 */ 21059 if (has_shortname) 21060 { 21061 pbuf = NULL; 21062 /* Copy the string if it is shortened by :h */ 21063 if (*fnamelen < (int)STRLEN(*fnamep)) 21064 { 21065 p = vim_strnsave(*fnamep, *fnamelen); 21066 if (p == 0) 21067 return -1; 21068 vim_free(*bufp); 21069 *bufp = *fnamep = p; 21070 } 21071 21072 /* Split into two implementations - makes it easier. First is where 21073 * there isn't a full name already, second is where there is. 21074 */ 21075 if (!has_fullname && !vim_isAbsName(*fnamep)) 21076 { 21077 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 21078 return -1; 21079 } 21080 else 21081 { 21082 int l; 21083 21084 /* Simple case, already have the full-name 21085 * Nearly always shorter, so try first time. */ 21086 l = *fnamelen; 21087 if (!get_short_pathname(fnamep, bufp, &l)) 21088 return -1; 21089 21090 if (l == 0) 21091 { 21092 /* Couldn't find the filename.. search the paths. 21093 */ 21094 l = *fnamelen; 21095 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 21096 return -1; 21097 } 21098 *fnamelen = l; 21099 } 21100 } 21101 #endif /* WIN3264 */ 21102 21103 /* ":t" - tail, just the basename */ 21104 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 21105 { 21106 *usedlen += 2; 21107 *fnamelen -= (int)(tail - *fnamep); 21108 *fnamep = tail; 21109 } 21110 21111 /* ":e" - extension, can be repeated */ 21112 /* ":r" - root, without extension, can be repeated */ 21113 while (src[*usedlen] == ':' 21114 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 21115 { 21116 /* find a '.' in the tail: 21117 * - for second :e: before the current fname 21118 * - otherwise: The last '.' 21119 */ 21120 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 21121 s = *fnamep - 2; 21122 else 21123 s = *fnamep + *fnamelen - 1; 21124 for ( ; s > tail; --s) 21125 if (s[0] == '.') 21126 break; 21127 if (src[*usedlen + 1] == 'e') /* :e */ 21128 { 21129 if (s > tail) 21130 { 21131 *fnamelen += (int)(*fnamep - (s + 1)); 21132 *fnamep = s + 1; 21133 #ifdef VMS 21134 /* cut version from the extension */ 21135 s = *fnamep + *fnamelen - 1; 21136 for ( ; s > *fnamep; --s) 21137 if (s[0] == ';') 21138 break; 21139 if (s > *fnamep) 21140 *fnamelen = s - *fnamep; 21141 #endif 21142 } 21143 else if (*fnamep <= tail) 21144 *fnamelen = 0; 21145 } 21146 else /* :r */ 21147 { 21148 if (s > tail) /* remove one extension */ 21149 *fnamelen = (int)(s - *fnamep); 21150 } 21151 *usedlen += 2; 21152 } 21153 21154 /* ":s?pat?foo?" - substitute */ 21155 /* ":gs?pat?foo?" - global substitute */ 21156 if (src[*usedlen] == ':' 21157 && (src[*usedlen + 1] == 's' 21158 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 21159 { 21160 char_u *str; 21161 char_u *pat; 21162 char_u *sub; 21163 int sep; 21164 char_u *flags; 21165 int didit = FALSE; 21166 21167 flags = (char_u *)""; 21168 s = src + *usedlen + 2; 21169 if (src[*usedlen + 1] == 'g') 21170 { 21171 flags = (char_u *)"g"; 21172 ++s; 21173 } 21174 21175 sep = *s++; 21176 if (sep) 21177 { 21178 /* find end of pattern */ 21179 p = vim_strchr(s, sep); 21180 if (p != NULL) 21181 { 21182 pat = vim_strnsave(s, (int)(p - s)); 21183 if (pat != NULL) 21184 { 21185 s = p + 1; 21186 /* find end of substitution */ 21187 p = vim_strchr(s, sep); 21188 if (p != NULL) 21189 { 21190 sub = vim_strnsave(s, (int)(p - s)); 21191 str = vim_strnsave(*fnamep, *fnamelen); 21192 if (sub != NULL && str != NULL) 21193 { 21194 *usedlen = (int)(p + 1 - src); 21195 s = do_string_sub(str, pat, sub, flags); 21196 if (s != NULL) 21197 { 21198 *fnamep = s; 21199 *fnamelen = (int)STRLEN(s); 21200 vim_free(*bufp); 21201 *bufp = s; 21202 didit = TRUE; 21203 } 21204 } 21205 vim_free(sub); 21206 vim_free(str); 21207 } 21208 vim_free(pat); 21209 } 21210 } 21211 /* after using ":s", repeat all the modifiers */ 21212 if (didit) 21213 goto repeat; 21214 } 21215 } 21216 21217 return valid; 21218 } 21219 21220 /* 21221 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 21222 * "flags" can be "g" to do a global substitute. 21223 * Returns an allocated string, NULL for error. 21224 */ 21225 char_u * 21226 do_string_sub(str, pat, sub, flags) 21227 char_u *str; 21228 char_u *pat; 21229 char_u *sub; 21230 char_u *flags; 21231 { 21232 int sublen; 21233 regmatch_T regmatch; 21234 int i; 21235 int do_all; 21236 char_u *tail; 21237 garray_T ga; 21238 char_u *ret; 21239 char_u *save_cpo; 21240 21241 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 21242 save_cpo = p_cpo; 21243 p_cpo = (char_u *)""; 21244 21245 ga_init2(&ga, 1, 200); 21246 21247 do_all = (flags[0] == 'g'); 21248 21249 regmatch.rm_ic = p_ic; 21250 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 21251 if (regmatch.regprog != NULL) 21252 { 21253 tail = str; 21254 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 21255 { 21256 /* 21257 * Get some space for a temporary buffer to do the substitution 21258 * into. It will contain: 21259 * - The text up to where the match is. 21260 * - The substituted text. 21261 * - The text after the match. 21262 */ 21263 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 21264 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 21265 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 21266 { 21267 ga_clear(&ga); 21268 break; 21269 } 21270 21271 /* copy the text up to where the match is */ 21272 i = (int)(regmatch.startp[0] - tail); 21273 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 21274 /* add the substituted text */ 21275 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 21276 + ga.ga_len + i, TRUE, TRUE, FALSE); 21277 ga.ga_len += i + sublen - 1; 21278 /* avoid getting stuck on a match with an empty string */ 21279 if (tail == regmatch.endp[0]) 21280 { 21281 if (*tail == NUL) 21282 break; 21283 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 21284 ++ga.ga_len; 21285 } 21286 else 21287 { 21288 tail = regmatch.endp[0]; 21289 if (*tail == NUL) 21290 break; 21291 } 21292 if (!do_all) 21293 break; 21294 } 21295 21296 if (ga.ga_data != NULL) 21297 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 21298 21299 vim_free(regmatch.regprog); 21300 } 21301 21302 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 21303 ga_clear(&ga); 21304 p_cpo = save_cpo; 21305 21306 return ret; 21307 } 21308 21309 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 21310