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 <io.h> /* for mch_open(), must be before vim.h */ 15 #endif 16 17 #include "vim.h" 18 19 #ifdef AMIGA 20 # include <time.h> /* for strftime() */ 21 #endif 22 23 #ifdef MACOS 24 # include <time.h> /* for time_t */ 25 #endif 26 27 #ifdef HAVE_FCNTL_H 28 # include <fcntl.h> 29 #endif 30 31 #if defined(FEAT_EVAL) || defined(PROTO) 32 33 #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ 34 35 /* 36 * In a hashtab item "hi_key" points to "di_key" in a dictitem. 37 * This avoids adding a pointer to the hashtab item. 38 * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. 39 * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. 40 * HI2DI() converts a hashitem pointer to a dictitem pointer. 41 */ 42 static dictitem_T dumdi; 43 #define DI2HIKEY(di) ((di)->di_key) 44 #define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) 45 #define HI2DI(hi) HIKEY2DI((hi)->hi_key) 46 47 /* 48 * Structure returned by get_lval() and used by set_var_lval(). 49 * For a plain name: 50 * "name" points to the variable name. 51 * "exp_name" is NULL. 52 * "tv" is NULL 53 * For a magic braces name: 54 * "name" points to the expanded variable name. 55 * "exp_name" is non-NULL, to be freed later. 56 * "tv" is NULL 57 * For an index in a list: 58 * "name" points to the (expanded) variable name. 59 * "exp_name" NULL or non-NULL, to be freed later. 60 * "tv" points to the (first) list item value 61 * "li" points to the (first) list item 62 * "range", "n1", "n2" and "empty2" indicate what items are used. 63 * For an existing Dict item: 64 * "name" points to the (expanded) variable name. 65 * "exp_name" NULL or non-NULL, to be freed later. 66 * "tv" points to the dict item value 67 * "newkey" is NULL 68 * For a non-existing Dict item: 69 * "name" points to the (expanded) variable name. 70 * "exp_name" NULL or non-NULL, to be freed later. 71 * "tv" points to the Dictionary typval_T 72 * "newkey" is the key for the new item. 73 */ 74 typedef struct lval_S 75 { 76 char_u *ll_name; /* start of variable name (can be NULL) */ 77 char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ 78 typval_T *ll_tv; /* Typeval of item being used. If "newkey" 79 isn't NULL it's the Dict to which to add 80 the item. */ 81 listitem_T *ll_li; /* The list item or NULL. */ 82 list_T *ll_list; /* The list or NULL. */ 83 int ll_range; /* TRUE when a [i:j] range was used */ 84 long ll_n1; /* First index for list */ 85 long ll_n2; /* Second index for list range */ 86 int ll_empty2; /* Second index is empty: [i:] */ 87 dict_T *ll_dict; /* The Dictionary or NULL */ 88 dictitem_T *ll_di; /* The dictitem or NULL */ 89 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ 90 } lval_T; 91 92 93 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 94 static char *e_listidx = N_("E684: list index out of range: %ld"); 95 static char *e_undefvar = N_("E121: Undefined variable: %s"); 96 static char *e_missbrac = N_("E111: Missing ']'"); 97 static char *e_listarg = N_("E686: Argument of %s must be a List"); 98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); 99 static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary"); 100 static char *e_listreq = N_("E714: List required"); 101 static char *e_dictreq = N_("E715: Dictionary required"); 102 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s"); 103 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s"); 104 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it"); 105 static char *e_funcdict = N_("E717: Dictionary entry already exists"); 106 static char *e_funcref = N_("E718: Funcref required"); 107 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); 108 static char *e_letwrong = N_("E734: Wrong variable type for %s="); 109 static char *e_nofunc = N_("E130: Unknown function: %s"); 110 static char *e_illvar = N_("E461: Illegal variable name: %s"); 111 /* 112 * All user-defined global variables are stored in dictionary "globvardict". 113 * "globvars_var" is the variable that is used for "g:". 114 */ 115 static dict_T globvardict; 116 static dictitem_T globvars_var; 117 #define globvarht globvardict.dv_hashtab 118 119 /* 120 * Old Vim variables such as "v:version" are also available without the "v:". 121 * Also in functions. We need a special hashtable for them. 122 */ 123 static hashtab_T compat_hashtab; 124 125 /* 126 * When recursively copying lists and dicts we need to remember which ones we 127 * have done to avoid endless recursiveness. This unique ID is used for that. 128 */ 129 static int current_copyID = 0; 130 131 /* 132 * Array to hold the hashtab with variables local to each sourced script. 133 * Each item holds a variable (nameless) that points to the dict_T. 134 */ 135 typedef struct 136 { 137 dictitem_T sv_var; 138 dict_T sv_dict; 139 } scriptvar_T; 140 141 static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL}; 142 #define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1]) 143 #define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab) 144 145 static int echo_attr = 0; /* attributes used for ":echo" */ 146 147 /* Values for trans_function_name() argument: */ 148 #define TFN_INT 1 /* internal function name OK */ 149 #define TFN_QUIET 2 /* no error messages */ 150 151 /* 152 * Structure to hold info for a user function. 153 */ 154 typedef struct ufunc ufunc_T; 155 156 struct ufunc 157 { 158 int uf_varargs; /* variable nr of arguments */ 159 int uf_flags; 160 int uf_calls; /* nr of active calls */ 161 garray_T uf_args; /* arguments */ 162 garray_T uf_lines; /* function lines */ 163 #ifdef FEAT_PROFILE 164 int uf_profiling; /* TRUE when func is being profiled */ 165 /* profiling the function as a whole */ 166 int uf_tm_count; /* nr of calls */ 167 proftime_T uf_tm_total; /* time spend in function + children */ 168 proftime_T uf_tm_self; /* time spend in function itself */ 169 proftime_T uf_tm_start; /* time at function call */ 170 proftime_T uf_tm_children; /* time spent in children this call */ 171 /* profiling the function per line */ 172 int *uf_tml_count; /* nr of times line was executed */ 173 proftime_T *uf_tml_total; /* time spend in a line + children */ 174 proftime_T *uf_tml_self; /* time spend in a line itself */ 175 proftime_T uf_tml_start; /* start time for current line */ 176 proftime_T uf_tml_children; /* time spent in children for this line */ 177 proftime_T uf_tml_wait; /* start wait time for current line */ 178 int uf_tml_idx; /* index of line being timed; -1 if none */ 179 int uf_tml_execed; /* line being timed was executed */ 180 #endif 181 scid_T uf_script_ID; /* ID of script where function was defined, 182 used for s: variables */ 183 int uf_refcount; /* for numbered function: reference count */ 184 char_u uf_name[1]; /* name of function (actually longer); can 185 start with <SNR>123_ (<SNR> is K_SPECIAL 186 KS_EXTRA KE_SNR) */ 187 }; 188 189 /* function flags */ 190 #define FC_ABORT 1 /* abort function on error */ 191 #define FC_RANGE 2 /* function accepts range */ 192 #define FC_DICT 4 /* Dict function, uses "self" */ 193 194 #define DEL_REFCOUNT 999999 /* list/dict is being deleted */ 195 196 /* 197 * All user-defined functions are found in this hashtable. 198 */ 199 static hashtab_T func_hashtab; 200 201 /* list heads for garbage collection */ 202 static dict_T *first_dict = NULL; /* list of all dicts */ 203 static list_T *first_list = NULL; /* list of all lists */ 204 205 /* From user function to hashitem and back. */ 206 static ufunc_T dumuf; 207 #define UF2HIKEY(fp) ((fp)->uf_name) 208 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) 209 #define HI2UF(hi) HIKEY2UF((hi)->hi_key) 210 211 #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] 212 #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] 213 214 #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ 215 #define VAR_SHORT_LEN 20 /* short variable name length */ 216 #define FIXVAR_CNT 12 /* number of fixed variables */ 217 218 /* structure to hold info for a function that is currently being executed. */ 219 typedef struct funccall_S funccall_T; 220 221 struct funccall_S 222 { 223 ufunc_T *func; /* function being called */ 224 int linenr; /* next line to be executed */ 225 int returned; /* ":return" used */ 226 struct /* fixed variables for arguments */ 227 { 228 dictitem_T var; /* variable (without room for name) */ 229 char_u room[VAR_SHORT_LEN]; /* room for the name */ 230 } fixvar[FIXVAR_CNT]; 231 dict_T l_vars; /* l: local function variables */ 232 dictitem_T l_vars_var; /* variable for l: scope */ 233 dict_T l_avars; /* a: argument variables */ 234 dictitem_T l_avars_var; /* variable for a: scope */ 235 list_T l_varlist; /* list for a:000 */ 236 listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ 237 typval_T *rettv; /* return value */ 238 linenr_T breakpoint; /* next line with breakpoint or zero */ 239 int dbg_tick; /* debug_tick when breakpoint was set */ 240 int level; /* top nesting level of executed function */ 241 #ifdef FEAT_PROFILE 242 proftime_T prof_child; /* time spent in a child */ 243 #endif 244 funccall_T *caller; /* calling function or NULL */ 245 }; 246 247 /* 248 * Info used by a ":for" loop. 249 */ 250 typedef struct 251 { 252 int fi_semicolon; /* TRUE if ending in '; var]' */ 253 int fi_varcount; /* nr of variables in the list */ 254 listwatch_T fi_lw; /* keep an eye on the item used. */ 255 list_T *fi_list; /* list being used */ 256 } forinfo_T; 257 258 /* 259 * Struct used by trans_function_name() 260 */ 261 typedef struct 262 { 263 dict_T *fd_dict; /* Dictionary used */ 264 char_u *fd_newkey; /* new key in "dict" in allocated memory */ 265 dictitem_T *fd_di; /* Dictionary item used */ 266 } funcdict_T; 267 268 269 /* 270 * Array to hold the value of v: variables. 271 * The value is in a dictitem, so that it can also be used in the v: scope. 272 * The reason to use this table anyway is for very quick access to the 273 * variables with the VV_ defines. 274 */ 275 #include "version.h" 276 277 /* values for vv_flags: */ 278 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 279 #define VV_RO 2 /* read-only */ 280 #define VV_RO_SBX 4 /* read-only in the sandbox */ 281 282 #define VV_NAME(s, t) s, {{t}}, {0} 283 284 static struct vimvar 285 { 286 char *vv_name; /* name of variable, without v: */ 287 dictitem_T vv_di; /* value and name for key */ 288 char vv_filler[16]; /* space for LONGEST name below!!! */ 289 char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ 290 } vimvars[VV_LEN] = 291 { 292 /* 293 * The order here must match the VV_ defines in vim.h! 294 * Initializing a union does not work, leave tv.vval empty to get zero's. 295 */ 296 {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, 297 {VV_NAME("count1", VAR_NUMBER), VV_RO}, 298 {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, 299 {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, 300 {VV_NAME("warningmsg", VAR_STRING), 0}, 301 {VV_NAME("statusmsg", VAR_STRING), 0}, 302 {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, 303 {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, 304 {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, 305 {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, 306 {VV_NAME("termresponse", VAR_STRING), VV_RO}, 307 {VV_NAME("fname", VAR_STRING), VV_RO}, 308 {VV_NAME("lang", VAR_STRING), VV_RO}, 309 {VV_NAME("lc_time", VAR_STRING), VV_RO}, 310 {VV_NAME("ctype", VAR_STRING), VV_RO}, 311 {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, 312 {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, 313 {VV_NAME("fname_in", VAR_STRING), VV_RO}, 314 {VV_NAME("fname_out", VAR_STRING), VV_RO}, 315 {VV_NAME("fname_new", VAR_STRING), VV_RO}, 316 {VV_NAME("fname_diff", VAR_STRING), VV_RO}, 317 {VV_NAME("cmdarg", VAR_STRING), VV_RO}, 318 {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, 319 {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, 320 {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, 321 {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, 322 {VV_NAME("progname", VAR_STRING), VV_RO}, 323 {VV_NAME("servername", VAR_STRING), VV_RO}, 324 {VV_NAME("dying", VAR_NUMBER), VV_RO}, 325 {VV_NAME("exception", VAR_STRING), VV_RO}, 326 {VV_NAME("throwpoint", VAR_STRING), VV_RO}, 327 {VV_NAME("register", VAR_STRING), VV_RO}, 328 {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, 329 {VV_NAME("insertmode", VAR_STRING), VV_RO}, 330 {VV_NAME("val", VAR_UNKNOWN), VV_RO}, 331 {VV_NAME("key", VAR_UNKNOWN), VV_RO}, 332 {VV_NAME("profiling", VAR_NUMBER), VV_RO}, 333 {VV_NAME("fcs_reason", VAR_STRING), VV_RO}, 334 {VV_NAME("fcs_choice", VAR_STRING), 0}, 335 {VV_NAME("beval_bufnr", VAR_NUMBER), VV_RO}, 336 {VV_NAME("beval_winnr", VAR_NUMBER), VV_RO}, 337 {VV_NAME("beval_lnum", VAR_NUMBER), VV_RO}, 338 {VV_NAME("beval_col", VAR_NUMBER), VV_RO}, 339 {VV_NAME("beval_text", VAR_STRING), VV_RO}, 340 }; 341 342 /* shorthand */ 343 #define vv_type vv_di.di_tv.v_type 344 #define vv_nr vv_di.di_tv.vval.v_number 345 #define vv_str vv_di.di_tv.vval.v_string 346 #define vv_tv vv_di.di_tv 347 348 /* 349 * The v: variables are stored in dictionary "vimvardict". 350 * "vimvars_var" is the variable that is used for the "l:" scope. 351 */ 352 static dict_T vimvardict; 353 static dictitem_T vimvars_var; 354 #define vimvarht vimvardict.dv_hashtab 355 356 static void prepare_vimvar __ARGS((int idx, typval_T *save_tv)); 357 static void restore_vimvar __ARGS((int idx, typval_T *save_tv)); 358 #if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL) 359 static int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, typval_T *rettv)); 360 #endif 361 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); 362 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); 363 static char_u *skip_var_one __ARGS((char_u *arg)); 364 static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); 365 static void list_glob_vars __ARGS((void)); 366 static void list_buf_vars __ARGS((void)); 367 static void list_win_vars __ARGS((void)); 368 static void list_vim_vars __ARGS((void)); 369 static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); 370 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); 371 static int check_changedtick __ARGS((char_u *arg)); 372 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); 373 static void clear_lval __ARGS((lval_T *lp)); 374 static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); 375 static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); 376 static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); 377 static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); 378 static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); 379 static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep)); 380 static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); 381 static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); 382 static void item_lock __ARGS((typval_T *tv, int deep, int lock)); 383 static int tv_islocked __ARGS((typval_T *tv)); 384 385 static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); 386 static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 387 static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 388 static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 389 static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 390 static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 391 static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 392 static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 393 394 static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 395 static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 396 static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 397 static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 398 static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 399 static list_T *list_alloc __ARGS((void)); 400 static void list_free __ARGS((list_T *l)); 401 static listitem_T *listitem_alloc __ARGS((void)); 402 static void listitem_free __ARGS((listitem_T *item)); 403 static void listitem_remove __ARGS((list_T *l, listitem_T *item)); 404 static long list_len __ARGS((list_T *l)); 405 static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); 406 static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); 407 static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); 408 static listitem_T *list_find __ARGS((list_T *l, long n)); 409 static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); 410 static void list_append __ARGS((list_T *l, listitem_T *item)); 411 static int list_append_tv __ARGS((list_T *l, typval_T *tv)); 412 static int list_append_string __ARGS((list_T *l, char_u *str)); 413 static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); 414 static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); 415 static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); 416 static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); 417 static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); 418 static char_u *list2string __ARGS((typval_T *tv)); 419 static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); 420 static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); 421 static void set_ref_in_list __ARGS((list_T *l, int copyID)); 422 static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); 423 static void dict_unref __ARGS((dict_T *d)); 424 static void dict_free __ARGS((dict_T *d)); 425 static dictitem_T *dictitem_alloc __ARGS((char_u *key)); 426 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); 427 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); 428 static void dictitem_free __ARGS((dictitem_T *item)); 429 static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID)); 430 static int dict_add __ARGS((dict_T *d, dictitem_T *item)); 431 static long dict_len __ARGS((dict_T *d)); 432 static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); 433 static char_u *dict2string __ARGS((typval_T *tv)); 434 static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 435 static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 436 static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); 437 static char_u *string_quote __ARGS((char_u *str, int function)); 438 static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); 439 static int find_internal_func __ARGS((char_u *name)); 440 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 441 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)); 442 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)); 443 static void emsg_funcname __ARGS((char *msg, char_u *name)); 444 445 static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); 446 static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); 447 static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); 448 static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); 449 static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); 450 static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); 451 static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); 452 static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); 453 static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); 454 static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); 455 static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); 456 static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); 457 static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); 458 static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); 459 static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); 460 static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); 461 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); 462 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); 463 static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); 464 #if defined(FEAT_INS_EXPAND) 465 static void f_complete_add __ARGS((typval_T *argvars, typval_T *rettv)); 466 static void f_complete_check __ARGS((typval_T *argvars, typval_T *rettv)); 467 #endif 468 static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); 469 static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); 470 static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); 471 static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); 472 static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); 473 static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); 474 static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); 475 static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); 476 static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); 477 static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 478 static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); 479 static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); 480 static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); 481 static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); 482 static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); 483 static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); 484 static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); 485 static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); 486 static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); 487 static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); 488 static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); 489 static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); 490 static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); 491 static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); 492 static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); 493 static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); 494 static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); 495 static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); 496 static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); 497 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 498 static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); 499 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv)); 500 static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); 501 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv)); 502 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 503 static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); 504 static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); 505 static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); 506 static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 507 static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); 508 static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); 509 static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); 510 static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); 511 static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); 512 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); 513 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); 514 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); 515 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv)); 516 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); 517 static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); 518 static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); 519 static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); 520 static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 521 static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); 522 static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); 523 static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); 524 static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); 525 static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); 526 static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); 527 static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); 528 static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); 529 static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); 530 static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); 531 static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); 532 static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); 533 static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); 534 static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); 535 static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); 536 static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); 537 static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); 538 static void f_inputlist __ARGS((typval_T *argvars, typval_T *rettv)); 539 static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); 540 static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); 541 static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); 542 static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); 543 static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); 544 static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); 545 static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); 546 static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); 547 static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); 548 static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); 549 static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); 550 static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); 551 static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); 552 static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); 553 static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); 554 static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); 555 static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); 556 static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); 557 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); 558 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); 559 static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); 560 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); 561 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv)); 562 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); 563 static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); 564 static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); 565 #ifdef vim_mkdir 566 static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv)); 567 #endif 568 static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 594 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 595 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 596 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 597 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 602 #ifdef HAVE_STRFTIME 603 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 604 #endif 605 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_tagfiles __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_test __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 626 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 627 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 628 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 629 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 630 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 631 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 632 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 633 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 634 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 635 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 636 637 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 638 static int get_env_len __ARGS((char_u **arg)); 639 static int get_id_len __ARGS((char_u **arg)); 640 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 641 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 642 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 643 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 644 valid character */ 645 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 646 static int eval_isnamec __ARGS((int c)); 647 static int eval_isnamec1 __ARGS((int c)); 648 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 649 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 650 static typval_T *alloc_tv __ARGS((void)); 651 static typval_T *alloc_string_tv __ARGS((char_u *string)); 652 static void free_tv __ARGS((typval_T *varp)); 653 static void init_tv __ARGS((typval_T *varp)); 654 static long get_tv_number __ARGS((typval_T *varp)); 655 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 656 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 657 static char_u *get_tv_string __ARGS((typval_T *varp)); 658 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 659 static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); 660 static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); 661 static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing)); 662 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); 663 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); 664 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); 665 static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); 666 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 667 static void set_var __ARGS((char_u *name, typval_T *varp, int copy)); 668 static int var_check_ro __ARGS((int flags, char_u *name)); 669 static int tv_check_lock __ARGS((int lock, char_u *name)); 670 static void copy_tv __ARGS((typval_T *from, typval_T *to)); 671 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID)); 672 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 673 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int flags, funcdict_T *fd)); 674 static int eval_fname_script __ARGS((char_u *p)); 675 static int eval_fname_sid __ARGS((char_u *p)); 676 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 677 static ufunc_T *find_func __ARGS((char_u *name)); 678 static int function_exists __ARGS((char_u *name)); 679 static int builtin_function __ARGS((char_u *name)); 680 #ifdef FEAT_PROFILE 681 static void func_do_profile __ARGS((ufunc_T *fp)); 682 static void prof_sort_list __ARGS((FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self)); 683 static void prof_func_line __ARGS((FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self)); 684 static int 685 # ifdef __BORLANDC__ 686 _RTLENTRYF 687 # endif 688 prof_total_cmp __ARGS((const void *s1, const void *s2)); 689 static int 690 # ifdef __BORLANDC__ 691 _RTLENTRYF 692 # endif 693 prof_self_cmp __ARGS((const void *s1, const void *s2)); 694 #endif 695 static int script_autoload __ARGS((char_u *name, int reload)); 696 static char_u *autoload_name __ARGS((char_u *name)); 697 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 698 static void func_free __ARGS((ufunc_T *fp)); 699 static void func_unref __ARGS((char_u *name)); 700 static void func_ref __ARGS((char_u *name)); 701 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)); 702 static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); 703 704 /* Character used as separated in autoload function/variable names. */ 705 #define AUTOLOAD_CHAR '#' 706 707 /* 708 * Initialize the global and v: variables. 709 */ 710 void 711 eval_init() 712 { 713 int i; 714 struct vimvar *p; 715 716 init_var_dict(&globvardict, &globvars_var); 717 init_var_dict(&vimvardict, &vimvars_var); 718 hash_init(&compat_hashtab); 719 hash_init(&func_hashtab); 720 721 for (i = 0; i < VV_LEN; ++i) 722 { 723 p = &vimvars[i]; 724 STRCPY(p->vv_di.di_key, p->vv_name); 725 if (p->vv_flags & VV_RO) 726 p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 727 else if (p->vv_flags & VV_RO_SBX) 728 p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; 729 else 730 p->vv_di.di_flags = DI_FLAGS_FIX; 731 732 /* add to v: scope dict, unless the value is not always available */ 733 if (p->vv_type != VAR_UNKNOWN) 734 hash_add(&vimvarht, p->vv_di.di_key); 735 if (p->vv_flags & VV_COMPAT) 736 /* add to compat scope dict */ 737 hash_add(&compat_hashtab, p->vv_di.di_key); 738 } 739 } 740 741 #if defined(EXITFREE) || defined(PROTO) 742 void 743 eval_clear() 744 { 745 int i; 746 struct vimvar *p; 747 748 for (i = 0; i < VV_LEN; ++i) 749 { 750 p = &vimvars[i]; 751 if (p->vv_di.di_tv.v_type == VAR_STRING) 752 { 753 vim_free(p->vv_di.di_tv.vval.v_string); 754 p->vv_di.di_tv.vval.v_string = NULL; 755 } 756 } 757 hash_clear(&vimvarht); 758 hash_clear(&compat_hashtab); 759 760 /* script-local variables */ 761 for (i = 1; i <= ga_scripts.ga_len; ++i) 762 vars_clear(&SCRIPT_VARS(i)); 763 ga_clear(&ga_scripts); 764 free_scriptnames(); 765 766 /* global variables */ 767 vars_clear(&globvarht); 768 769 /* functions */ 770 free_all_functions(); 771 hash_clear(&func_hashtab); 772 773 /* unreferenced lists and dicts */ 774 (void)garbage_collect(); 775 } 776 #endif 777 778 /* 779 * Return the name of the executed function. 780 */ 781 char_u * 782 func_name(cookie) 783 void *cookie; 784 { 785 return ((funccall_T *)cookie)->func->uf_name; 786 } 787 788 /* 789 * Return the address holding the next breakpoint line for a funccall cookie. 790 */ 791 linenr_T * 792 func_breakpoint(cookie) 793 void *cookie; 794 { 795 return &((funccall_T *)cookie)->breakpoint; 796 } 797 798 /* 799 * Return the address holding the debug tick for a funccall cookie. 800 */ 801 int * 802 func_dbg_tick(cookie) 803 void *cookie; 804 { 805 return &((funccall_T *)cookie)->dbg_tick; 806 } 807 808 /* 809 * Return the nesting level for a funccall cookie. 810 */ 811 int 812 func_level(cookie) 813 void *cookie; 814 { 815 return ((funccall_T *)cookie)->level; 816 } 817 818 /* pointer to funccal for currently active function */ 819 funccall_T *current_funccal = NULL; 820 821 /* 822 * Return TRUE when a function was ended by a ":return" command. 823 */ 824 int 825 current_func_returned() 826 { 827 return current_funccal->returned; 828 } 829 830 831 /* 832 * Set an internal variable to a string value. Creates the variable if it does 833 * not already exist. 834 */ 835 void 836 set_internal_string_var(name, value) 837 char_u *name; 838 char_u *value; 839 { 840 char_u *val; 841 typval_T *tvp; 842 843 val = vim_strsave(value); 844 if (val != NULL) 845 { 846 tvp = alloc_string_tv(val); 847 if (tvp != NULL) 848 { 849 set_var(name, tvp, FALSE); 850 free_tv(tvp); 851 } 852 } 853 } 854 855 static lval_T *redir_lval = NULL; 856 static char_u *redir_endp = NULL; 857 static char_u *redir_varname = NULL; 858 859 /* 860 * Start recording command output to a variable 861 * Returns OK if successfully completed the setup. FAIL otherwise. 862 */ 863 int 864 var_redir_start(name, append) 865 char_u *name; 866 int append; /* append to an existing variable */ 867 { 868 int save_emsg; 869 int err; 870 typval_T tv; 871 872 /* Make sure a valid variable name is specified */ 873 if (!eval_isnamec1(*name)) 874 { 875 EMSG(_(e_invarg)); 876 return FAIL; 877 } 878 879 redir_varname = vim_strsave(name); 880 if (redir_varname == NULL) 881 return FAIL; 882 883 redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T)); 884 if (redir_lval == NULL) 885 { 886 var_redir_stop(); 887 return FAIL; 888 } 889 890 /* Parse the variable name (can be a dict or list entry). */ 891 redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, 892 FNE_CHECK_START); 893 if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) 894 { 895 if (redir_endp != NULL && *redir_endp != NUL) 896 /* Trailing characters are present after the variable name */ 897 EMSG(_(e_trailing)); 898 else 899 EMSG(_(e_invarg)); 900 var_redir_stop(); 901 return FAIL; 902 } 903 904 /* check if we can write to the variable: set it to or append an empty 905 * string */ 906 save_emsg = did_emsg; 907 did_emsg = FALSE; 908 tv.v_type = VAR_STRING; 909 tv.vval.v_string = (char_u *)""; 910 if (append) 911 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"."); 912 else 913 set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"="); 914 err = did_emsg; 915 did_emsg += save_emsg; 916 if (err) 917 { 918 var_redir_stop(); 919 return FAIL; 920 } 921 if (redir_lval->ll_newkey != NULL) 922 { 923 /* Dictionary item was created, don't do it again. */ 924 vim_free(redir_lval->ll_newkey); 925 redir_lval->ll_newkey = NULL; 926 } 927 928 return OK; 929 } 930 931 /* 932 * Append "value[len]" to the variable set by var_redir_start(). 933 */ 934 void 935 var_redir_str(value, len) 936 char_u *value; 937 int len; 938 { 939 char_u *val; 940 typval_T tv; 941 int save_emsg; 942 int err; 943 944 if (redir_lval == NULL) 945 return; 946 947 if (len == -1) 948 /* Append the entire string */ 949 val = vim_strsave(value); 950 else 951 /* Append only the specified number of characters */ 952 val = vim_strnsave(value, len); 953 if (val == NULL) 954 return; 955 956 tv.v_type = VAR_STRING; 957 tv.vval.v_string = val; 958 959 save_emsg = did_emsg; 960 did_emsg = FALSE; 961 set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); 962 err = did_emsg; 963 did_emsg += save_emsg; 964 if (err) 965 var_redir_stop(); 966 967 vim_free(tv.vval.v_string); 968 } 969 970 /* 971 * Stop redirecting command output to a variable. 972 */ 973 void 974 var_redir_stop() 975 { 976 if (redir_lval != NULL) 977 { 978 clear_lval(redir_lval); 979 vim_free(redir_lval); 980 redir_lval = NULL; 981 } 982 vim_free(redir_varname); 983 redir_varname = NULL; 984 } 985 986 # if defined(FEAT_MBYTE) || defined(PROTO) 987 int 988 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 989 char_u *enc_from; 990 char_u *enc_to; 991 char_u *fname_from; 992 char_u *fname_to; 993 { 994 int err = FALSE; 995 996 set_vim_var_string(VV_CC_FROM, enc_from, -1); 997 set_vim_var_string(VV_CC_TO, enc_to, -1); 998 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 999 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 1000 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 1001 err = TRUE; 1002 set_vim_var_string(VV_CC_FROM, NULL, -1); 1003 set_vim_var_string(VV_CC_TO, NULL, -1); 1004 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1005 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1006 1007 if (err) 1008 return FAIL; 1009 return OK; 1010 } 1011 # endif 1012 1013 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 1014 int 1015 eval_printexpr(fname, args) 1016 char_u *fname; 1017 char_u *args; 1018 { 1019 int err = FALSE; 1020 1021 set_vim_var_string(VV_FNAME_IN, fname, -1); 1022 set_vim_var_string(VV_CMDARG, args, -1); 1023 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 1024 err = TRUE; 1025 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1026 set_vim_var_string(VV_CMDARG, NULL, -1); 1027 1028 if (err) 1029 { 1030 mch_remove(fname); 1031 return FAIL; 1032 } 1033 return OK; 1034 } 1035 # endif 1036 1037 # if defined(FEAT_DIFF) || defined(PROTO) 1038 void 1039 eval_diff(origfile, newfile, outfile) 1040 char_u *origfile; 1041 char_u *newfile; 1042 char_u *outfile; 1043 { 1044 int err = FALSE; 1045 1046 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1047 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 1048 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1049 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 1050 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1051 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 1052 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1053 } 1054 1055 void 1056 eval_patch(origfile, difffile, outfile) 1057 char_u *origfile; 1058 char_u *difffile; 1059 char_u *outfile; 1060 { 1061 int err; 1062 1063 set_vim_var_string(VV_FNAME_IN, origfile, -1); 1064 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 1065 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 1066 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 1067 set_vim_var_string(VV_FNAME_IN, NULL, -1); 1068 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 1069 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 1070 } 1071 # endif 1072 1073 /* 1074 * Top level evaluation function, returning a boolean. 1075 * Sets "error" to TRUE if there was an error. 1076 * Return TRUE or FALSE. 1077 */ 1078 int 1079 eval_to_bool(arg, error, nextcmd, skip) 1080 char_u *arg; 1081 int *error; 1082 char_u **nextcmd; 1083 int skip; /* only parse, don't execute */ 1084 { 1085 typval_T tv; 1086 int retval = FALSE; 1087 1088 if (skip) 1089 ++emsg_skip; 1090 if (eval0(arg, &tv, nextcmd, !skip) == FAIL) 1091 *error = TRUE; 1092 else 1093 { 1094 *error = FALSE; 1095 if (!skip) 1096 { 1097 retval = (get_tv_number_chk(&tv, error) != 0); 1098 clear_tv(&tv); 1099 } 1100 } 1101 if (skip) 1102 --emsg_skip; 1103 1104 return retval; 1105 } 1106 1107 /* 1108 * Top level evaluation function, returning a string. If "skip" is TRUE, 1109 * only parsing to "nextcmd" is done, without reporting errors. Return 1110 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 1111 */ 1112 char_u * 1113 eval_to_string_skip(arg, nextcmd, skip) 1114 char_u *arg; 1115 char_u **nextcmd; 1116 int skip; /* only parse, don't execute */ 1117 { 1118 typval_T tv; 1119 char_u *retval; 1120 1121 if (skip) 1122 ++emsg_skip; 1123 if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip) 1124 retval = NULL; 1125 else 1126 { 1127 retval = vim_strsave(get_tv_string(&tv)); 1128 clear_tv(&tv); 1129 } 1130 if (skip) 1131 --emsg_skip; 1132 1133 return retval; 1134 } 1135 1136 /* 1137 * Skip over an expression at "*pp". 1138 * Return FAIL for an error, OK otherwise. 1139 */ 1140 int 1141 skip_expr(pp) 1142 char_u **pp; 1143 { 1144 typval_T rettv; 1145 1146 *pp = skipwhite(*pp); 1147 return eval1(pp, &rettv, FALSE); 1148 } 1149 1150 /* 1151 * Top level evaluation function, returning a string. 1152 * Return pointer to allocated memory, or NULL for failure. 1153 */ 1154 char_u * 1155 eval_to_string(arg, nextcmd) 1156 char_u *arg; 1157 char_u **nextcmd; 1158 { 1159 typval_T tv; 1160 char_u *retval; 1161 1162 if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) 1163 retval = NULL; 1164 else 1165 { 1166 retval = vim_strsave(get_tv_string(&tv)); 1167 clear_tv(&tv); 1168 } 1169 1170 return retval; 1171 } 1172 1173 /* 1174 * Call eval_to_string() with "sandbox" set and not using local variables. 1175 */ 1176 char_u * 1177 eval_to_string_safe(arg, nextcmd) 1178 char_u *arg; 1179 char_u **nextcmd; 1180 { 1181 char_u *retval; 1182 void *save_funccalp; 1183 1184 save_funccalp = save_funccal(); 1185 ++sandbox; 1186 retval = eval_to_string(arg, nextcmd); 1187 --sandbox; 1188 restore_funccal(save_funccalp); 1189 return retval; 1190 } 1191 1192 /* 1193 * Top level evaluation function, returning a number. 1194 * Evaluates "expr" silently. 1195 * Returns -1 for an error. 1196 */ 1197 int 1198 eval_to_number(expr) 1199 char_u *expr; 1200 { 1201 typval_T rettv; 1202 int retval; 1203 char_u *p = skipwhite(expr); 1204 1205 ++emsg_off; 1206 1207 if (eval1(&p, &rettv, TRUE) == FAIL) 1208 retval = -1; 1209 else 1210 { 1211 retval = get_tv_number_chk(&rettv, NULL); 1212 clear_tv(&rettv); 1213 } 1214 --emsg_off; 1215 1216 return retval; 1217 } 1218 1219 /* 1220 * Prepare v: variable "idx" to be used. 1221 * Save the current typeval in "save_tv". 1222 * When not used yet add the variable to the v: hashtable. 1223 */ 1224 static void 1225 prepare_vimvar(idx, save_tv) 1226 int idx; 1227 typval_T *save_tv; 1228 { 1229 *save_tv = vimvars[idx].vv_tv; 1230 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1231 hash_add(&vimvarht, vimvars[idx].vv_di.di_key); 1232 } 1233 1234 /* 1235 * Restore v: variable "idx" to typeval "save_tv". 1236 * When no longer defined, remove the variable from the v: hashtable. 1237 */ 1238 static void 1239 restore_vimvar(idx, save_tv) 1240 int idx; 1241 typval_T *save_tv; 1242 { 1243 hashitem_T *hi; 1244 1245 clear_tv(&vimvars[idx].vv_tv); 1246 vimvars[idx].vv_tv = *save_tv; 1247 if (vimvars[idx].vv_type == VAR_UNKNOWN) 1248 { 1249 hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key); 1250 if (HASHITEM_EMPTY(hi)) 1251 EMSG2(_(e_intern2), "restore_vimvar()"); 1252 else 1253 hash_remove(&vimvarht, hi); 1254 } 1255 } 1256 1257 #if defined(FEAT_SYN_HL) || defined(PROTO) 1258 /* 1259 * Evaluate an expression to a list with suggestions. 1260 * For the "expr:" part of 'spellsuggest'. 1261 */ 1262 list_T * 1263 eval_spell_expr(badword, expr) 1264 char_u *badword; 1265 char_u *expr; 1266 { 1267 typval_T save_val; 1268 typval_T rettv; 1269 list_T *list = NULL; 1270 char_u *p = skipwhite(expr); 1271 1272 /* Set "v:val" to the bad word. */ 1273 prepare_vimvar(VV_VAL, &save_val); 1274 vimvars[VV_VAL].vv_type = VAR_STRING; 1275 vimvars[VV_VAL].vv_str = badword; 1276 if (p_verbose == 0) 1277 ++emsg_off; 1278 1279 if (eval1(&p, &rettv, TRUE) == OK) 1280 { 1281 if (rettv.v_type != VAR_LIST) 1282 clear_tv(&rettv); 1283 else 1284 list = rettv.vval.v_list; 1285 } 1286 1287 if (p_verbose == 0) 1288 --emsg_off; 1289 vimvars[VV_VAL].vv_str = NULL; 1290 restore_vimvar(VV_VAL, &save_val); 1291 1292 return list; 1293 } 1294 1295 /* 1296 * "list" is supposed to contain two items: a word and a number. Return the 1297 * word in "pp" and the number as the return value. 1298 * Return -1 if anything isn't right. 1299 * Used to get the good word and score from the eval_spell_expr() result. 1300 */ 1301 int 1302 get_spellword(list, pp) 1303 list_T *list; 1304 char_u **pp; 1305 { 1306 listitem_T *li; 1307 1308 li = list->lv_first; 1309 if (li == NULL) 1310 return -1; 1311 *pp = get_tv_string(&li->li_tv); 1312 1313 li = li->li_next; 1314 if (li == NULL) 1315 return -1; 1316 return get_tv_number(&li->li_tv); 1317 } 1318 #endif 1319 1320 /* 1321 * Top level evaluation function, 1322 */ 1323 typval_T * 1324 eval_expr(arg, nextcmd) 1325 char_u *arg; 1326 char_u **nextcmd; 1327 { 1328 typval_T *tv; 1329 1330 tv = (typval_T *)alloc(sizeof(typval_T)); 1331 if (!tv) 1332 return NULL; 1333 1334 if (eval0(arg, tv, nextcmd, TRUE) == FAIL) 1335 { 1336 vim_free(tv); 1337 return NULL; 1338 } 1339 1340 return tv; 1341 } 1342 1343 1344 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 1345 /* 1346 * Call some vimL function and return the result in "*rettv". 1347 * Uses argv[argc] for the function arguments. 1348 * Returns OK or FAIL. 1349 */ 1350 static int 1351 call_vim_function(func, argc, argv, safe, rettv) 1352 char_u *func; 1353 int argc; 1354 char_u **argv; 1355 int safe; /* use the sandbox */ 1356 typval_T *rettv; 1357 { 1358 typval_T *argvars; 1359 long n; 1360 int len; 1361 int i; 1362 int doesrange; 1363 void *save_funccalp = NULL; 1364 int ret; 1365 1366 argvars = (typval_T *)alloc((unsigned)(argc * sizeof(typval_T))); 1367 if (argvars == NULL) 1368 return FAIL; 1369 1370 for (i = 0; i < argc; i++) 1371 { 1372 /* Pass a NULL or empty argument as an empty string */ 1373 if (argv[i] == NULL || *argv[i] == NUL) 1374 { 1375 argvars[i].v_type = VAR_STRING; 1376 argvars[i].vval.v_string = (char_u *)""; 1377 continue; 1378 } 1379 1380 /* Recognize a number argument, the others must be strings. */ 1381 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 1382 if (len != 0 && len == (int)STRLEN(argv[i])) 1383 { 1384 argvars[i].v_type = VAR_NUMBER; 1385 argvars[i].vval.v_number = n; 1386 } 1387 else 1388 { 1389 argvars[i].v_type = VAR_STRING; 1390 argvars[i].vval.v_string = argv[i]; 1391 } 1392 } 1393 1394 if (safe) 1395 { 1396 save_funccalp = save_funccal(); 1397 ++sandbox; 1398 } 1399 1400 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1401 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, 1402 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1403 &doesrange, TRUE, NULL); 1404 if (safe) 1405 { 1406 --sandbox; 1407 restore_funccal(save_funccalp); 1408 } 1409 vim_free(argvars); 1410 1411 if (ret == FAIL) 1412 clear_tv(rettv); 1413 1414 return ret; 1415 } 1416 1417 /* 1418 * Call vimL function "func" and return the result as a string. 1419 * Returns NULL when calling the function fails. 1420 * Uses argv[argc] for the function arguments. 1421 */ 1422 void * 1423 call_func_retstr(func, argc, argv, safe) 1424 char_u *func; 1425 int argc; 1426 char_u **argv; 1427 int safe; /* use the sandbox */ 1428 { 1429 typval_T rettv; 1430 char_u *retval; 1431 1432 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1433 return NULL; 1434 1435 retval = vim_strsave(get_tv_string(&rettv)); 1436 clear_tv(&rettv); 1437 return retval; 1438 } 1439 1440 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1441 /* 1442 * Call vimL function "func" and return the result as a number. 1443 * Returns -1 when calling the function fails. 1444 * Uses argv[argc] for the function arguments. 1445 */ 1446 long 1447 call_func_retnr(func, argc, argv, safe) 1448 char_u *func; 1449 int argc; 1450 char_u **argv; 1451 int safe; /* use the sandbox */ 1452 { 1453 typval_T rettv; 1454 long retval; 1455 1456 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1457 return -1; 1458 1459 retval = get_tv_number_chk(&rettv, NULL); 1460 clear_tv(&rettv); 1461 return retval; 1462 } 1463 #endif 1464 1465 /* 1466 * Call vimL function "func" and return the result as a list 1467 * Uses argv[argc] for the function arguments. 1468 */ 1469 void * 1470 call_func_retlist(func, argc, argv, safe) 1471 char_u *func; 1472 int argc; 1473 char_u **argv; 1474 int safe; /* use the sandbox */ 1475 { 1476 typval_T rettv; 1477 1478 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1479 return NULL; 1480 1481 if (rettv.v_type != VAR_LIST) 1482 { 1483 clear_tv(&rettv); 1484 return NULL; 1485 } 1486 1487 return rettv.vval.v_list; 1488 } 1489 1490 #endif 1491 1492 /* 1493 * Save the current function call pointer, and set it to NULL. 1494 * Used when executing autocommands and for ":source". 1495 */ 1496 void * 1497 save_funccal() 1498 { 1499 funccall_T *fc = current_funccal; 1500 1501 current_funccal = NULL; 1502 return (void *)fc; 1503 } 1504 1505 void 1506 restore_funccal(vfc) 1507 void *vfc; 1508 { 1509 funccall_T *fc = (funccall_T *)vfc; 1510 1511 current_funccal = fc; 1512 } 1513 1514 #if defined(FEAT_PROFILE) || defined(PROTO) 1515 /* 1516 * Prepare profiling for entering a child or something else that is not 1517 * counted for the script/function itself. 1518 * Should always be called in pair with prof_child_exit(). 1519 */ 1520 void 1521 prof_child_enter(tm) 1522 proftime_T *tm; /* place to store waittime */ 1523 { 1524 funccall_T *fc = current_funccal; 1525 1526 if (fc != NULL && fc->func->uf_profiling) 1527 profile_start(&fc->prof_child); 1528 script_prof_save(tm); 1529 } 1530 1531 /* 1532 * Take care of time spent in a child. 1533 * Should always be called after prof_child_enter(). 1534 */ 1535 void 1536 prof_child_exit(tm) 1537 proftime_T *tm; /* where waittime was stored */ 1538 { 1539 funccall_T *fc = current_funccal; 1540 1541 if (fc != NULL && fc->func->uf_profiling) 1542 { 1543 profile_end(&fc->prof_child); 1544 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1545 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1546 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1547 } 1548 script_prof_restore(tm); 1549 } 1550 #endif 1551 1552 1553 #ifdef FEAT_FOLDING 1554 /* 1555 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1556 * it in "*cp". Doesn't give error messages. 1557 */ 1558 int 1559 eval_foldexpr(arg, cp) 1560 char_u *arg; 1561 int *cp; 1562 { 1563 typval_T tv; 1564 int retval; 1565 char_u *s; 1566 1567 ++emsg_off; 1568 ++sandbox; 1569 *cp = NUL; 1570 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1571 retval = 0; 1572 else 1573 { 1574 /* If the result is a number, just return the number. */ 1575 if (tv.v_type == VAR_NUMBER) 1576 retval = tv.vval.v_number; 1577 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1578 retval = 0; 1579 else 1580 { 1581 /* If the result is a string, check if there is a non-digit before 1582 * the number. */ 1583 s = tv.vval.v_string; 1584 if (!VIM_ISDIGIT(*s) && *s != '-') 1585 *cp = *s++; 1586 retval = atol((char *)s); 1587 } 1588 clear_tv(&tv); 1589 } 1590 --emsg_off; 1591 --sandbox; 1592 1593 return retval; 1594 } 1595 #endif 1596 1597 /* 1598 * ":let" list all variable values 1599 * ":let var1 var2" list variable values 1600 * ":let var = expr" assignment command. 1601 * ":let var += expr" assignment command. 1602 * ":let var -= expr" assignment command. 1603 * ":let var .= expr" assignment command. 1604 * ":let [var1, var2] = expr" unpack list. 1605 */ 1606 void 1607 ex_let(eap) 1608 exarg_T *eap; 1609 { 1610 char_u *arg = eap->arg; 1611 char_u *expr = NULL; 1612 typval_T rettv; 1613 int i; 1614 int var_count = 0; 1615 int semicolon = 0; 1616 char_u op[2]; 1617 1618 expr = skip_var_list(arg, &var_count, &semicolon); 1619 if (expr == NULL) 1620 return; 1621 expr = vim_strchr(expr, '='); 1622 if (expr == NULL) 1623 { 1624 /* 1625 * ":let" without "=": list variables 1626 */ 1627 if (*arg == '[') 1628 EMSG(_(e_invarg)); 1629 else if (!ends_excmd(*arg)) 1630 /* ":let var1 var2" */ 1631 arg = list_arg_vars(eap, arg); 1632 else if (!eap->skip) 1633 { 1634 /* ":let" */ 1635 list_glob_vars(); 1636 list_buf_vars(); 1637 list_win_vars(); 1638 list_vim_vars(); 1639 } 1640 eap->nextcmd = check_nextcmd(arg); 1641 } 1642 else 1643 { 1644 op[0] = '='; 1645 op[1] = NUL; 1646 if (expr > arg) 1647 { 1648 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1649 op[0] = expr[-1]; /* +=, -= or .= */ 1650 } 1651 expr = skipwhite(expr + 1); 1652 1653 if (eap->skip) 1654 ++emsg_skip; 1655 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1656 if (eap->skip) 1657 { 1658 if (i != FAIL) 1659 clear_tv(&rettv); 1660 --emsg_skip; 1661 } 1662 else if (i != FAIL) 1663 { 1664 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1665 op); 1666 clear_tv(&rettv); 1667 } 1668 } 1669 } 1670 1671 /* 1672 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1673 * Handles both "var" with any type and "[var, var; var]" with a list type. 1674 * When "nextchars" is not NULL it points to a string with characters that 1675 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1676 * or concatenate. 1677 * Returns OK or FAIL; 1678 */ 1679 static int 1680 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1681 char_u *arg_start; 1682 typval_T *tv; 1683 int copy; /* copy values from "tv", don't move */ 1684 int semicolon; /* from skip_var_list() */ 1685 int var_count; /* from skip_var_list() */ 1686 char_u *nextchars; 1687 { 1688 char_u *arg = arg_start; 1689 list_T *l; 1690 int i; 1691 listitem_T *item; 1692 typval_T ltv; 1693 1694 if (*arg != '[') 1695 { 1696 /* 1697 * ":let var = expr" or ":for var in list" 1698 */ 1699 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1700 return FAIL; 1701 return OK; 1702 } 1703 1704 /* 1705 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1706 */ 1707 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1708 { 1709 EMSG(_(e_listreq)); 1710 return FAIL; 1711 } 1712 1713 i = list_len(l); 1714 if (semicolon == 0 && var_count < i) 1715 { 1716 EMSG(_("E687: Less targets than List items")); 1717 return FAIL; 1718 } 1719 if (var_count - semicolon > i) 1720 { 1721 EMSG(_("E688: More targets than List items")); 1722 return FAIL; 1723 } 1724 1725 item = l->lv_first; 1726 while (*arg != ']') 1727 { 1728 arg = skipwhite(arg + 1); 1729 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1730 item = item->li_next; 1731 if (arg == NULL) 1732 return FAIL; 1733 1734 arg = skipwhite(arg); 1735 if (*arg == ';') 1736 { 1737 /* Put the rest of the list (may be empty) in the var after ';'. 1738 * Create a new list for this. */ 1739 l = list_alloc(); 1740 if (l == NULL) 1741 return FAIL; 1742 while (item != NULL) 1743 { 1744 list_append_tv(l, &item->li_tv); 1745 item = item->li_next; 1746 } 1747 1748 ltv.v_type = VAR_LIST; 1749 ltv.v_lock = 0; 1750 ltv.vval.v_list = l; 1751 l->lv_refcount = 1; 1752 1753 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1754 (char_u *)"]", nextchars); 1755 clear_tv(<v); 1756 if (arg == NULL) 1757 return FAIL; 1758 break; 1759 } 1760 else if (*arg != ',' && *arg != ']') 1761 { 1762 EMSG2(_(e_intern2), "ex_let_vars()"); 1763 return FAIL; 1764 } 1765 } 1766 1767 return OK; 1768 } 1769 1770 /* 1771 * Skip over assignable variable "var" or list of variables "[var, var]". 1772 * Used for ":let varvar = expr" and ":for varvar in expr". 1773 * For "[var, var]" increment "*var_count" for each variable. 1774 * for "[var, var; var]" set "semicolon". 1775 * Return NULL for an error. 1776 */ 1777 static char_u * 1778 skip_var_list(arg, var_count, semicolon) 1779 char_u *arg; 1780 int *var_count; 1781 int *semicolon; 1782 { 1783 char_u *p, *s; 1784 1785 if (*arg == '[') 1786 { 1787 /* "[var, var]": find the matching ']'. */ 1788 p = arg; 1789 for (;;) 1790 { 1791 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1792 s = skip_var_one(p); 1793 if (s == p) 1794 { 1795 EMSG2(_(e_invarg2), p); 1796 return NULL; 1797 } 1798 ++*var_count; 1799 1800 p = skipwhite(s); 1801 if (*p == ']') 1802 break; 1803 else if (*p == ';') 1804 { 1805 if (*semicolon == 1) 1806 { 1807 EMSG(_("Double ; in list of variables")); 1808 return NULL; 1809 } 1810 *semicolon = 1; 1811 } 1812 else if (*p != ',') 1813 { 1814 EMSG2(_(e_invarg2), p); 1815 return NULL; 1816 } 1817 } 1818 return p + 1; 1819 } 1820 else 1821 return skip_var_one(arg); 1822 } 1823 1824 /* 1825 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1826 * l[idx]. 1827 */ 1828 static char_u * 1829 skip_var_one(arg) 1830 char_u *arg; 1831 { 1832 if (*arg == '@' && arg[1] != NUL) 1833 return arg + 2; 1834 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1835 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1836 } 1837 1838 /* 1839 * List variables for hashtab "ht" with prefix "prefix". 1840 * If "empty" is TRUE also list NULL strings as empty strings. 1841 */ 1842 static void 1843 list_hashtable_vars(ht, prefix, empty) 1844 hashtab_T *ht; 1845 char_u *prefix; 1846 int empty; 1847 { 1848 hashitem_T *hi; 1849 dictitem_T *di; 1850 int todo; 1851 1852 todo = ht->ht_used; 1853 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1854 { 1855 if (!HASHITEM_EMPTY(hi)) 1856 { 1857 --todo; 1858 di = HI2DI(hi); 1859 if (empty || di->di_tv.v_type != VAR_STRING 1860 || di->di_tv.vval.v_string != NULL) 1861 list_one_var(di, prefix); 1862 } 1863 } 1864 } 1865 1866 /* 1867 * List global variables. 1868 */ 1869 static void 1870 list_glob_vars() 1871 { 1872 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1873 } 1874 1875 /* 1876 * List buffer variables. 1877 */ 1878 static void 1879 list_buf_vars() 1880 { 1881 char_u numbuf[NUMBUFLEN]; 1882 1883 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1884 1885 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1886 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1887 } 1888 1889 /* 1890 * List window variables. 1891 */ 1892 static void 1893 list_win_vars() 1894 { 1895 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1896 } 1897 1898 /* 1899 * List Vim variables. 1900 */ 1901 static void 1902 list_vim_vars() 1903 { 1904 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1905 } 1906 1907 /* 1908 * List variables in "arg". 1909 */ 1910 static char_u * 1911 list_arg_vars(eap, arg) 1912 exarg_T *eap; 1913 char_u *arg; 1914 { 1915 int error = FALSE; 1916 int len; 1917 char_u *name; 1918 char_u *name_start; 1919 char_u *arg_subsc; 1920 char_u *tofree; 1921 typval_T tv; 1922 1923 while (!ends_excmd(*arg) && !got_int) 1924 { 1925 if (error || eap->skip) 1926 { 1927 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1928 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1929 { 1930 emsg_severe = TRUE; 1931 EMSG(_(e_trailing)); 1932 break; 1933 } 1934 } 1935 else 1936 { 1937 /* get_name_len() takes care of expanding curly braces */ 1938 name_start = name = arg; 1939 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1940 if (len <= 0) 1941 { 1942 /* This is mainly to keep test 49 working: when expanding 1943 * curly braces fails overrule the exception error message. */ 1944 if (len < 0 && !aborting()) 1945 { 1946 emsg_severe = TRUE; 1947 EMSG2(_(e_invarg2), arg); 1948 break; 1949 } 1950 error = TRUE; 1951 } 1952 else 1953 { 1954 if (tofree != NULL) 1955 name = tofree; 1956 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1957 error = TRUE; 1958 else 1959 { 1960 /* handle d.key, l[idx], f(expr) */ 1961 arg_subsc = arg; 1962 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1963 error = TRUE; 1964 else 1965 { 1966 if (arg == arg_subsc && len == 2 && name[1] == ':') 1967 { 1968 switch (*name) 1969 { 1970 case 'g': list_glob_vars(); break; 1971 case 'b': list_buf_vars(); break; 1972 case 'w': list_win_vars(); break; 1973 case 'v': list_vim_vars(); break; 1974 default: 1975 EMSG2(_("E738: Can't list variables for %s"), name); 1976 } 1977 } 1978 else 1979 { 1980 char_u numbuf[NUMBUFLEN]; 1981 char_u *tf; 1982 int c; 1983 char_u *s; 1984 1985 s = echo_string(&tv, &tf, numbuf); 1986 c = *arg; 1987 *arg = NUL; 1988 list_one_var_a((char_u *)"", 1989 arg == arg_subsc ? name : name_start, 1990 tv.v_type, s == NULL ? (char_u *)"" : s); 1991 *arg = c; 1992 vim_free(tf); 1993 } 1994 clear_tv(&tv); 1995 } 1996 } 1997 } 1998 1999 vim_free(tofree); 2000 } 2001 2002 arg = skipwhite(arg); 2003 } 2004 2005 return arg; 2006 } 2007 2008 /* 2009 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2010 * Returns a pointer to the char just after the var name. 2011 * Returns NULL if there is an error. 2012 */ 2013 static char_u * 2014 ex_let_one(arg, tv, copy, endchars, op) 2015 char_u *arg; /* points to variable name */ 2016 typval_T *tv; /* value to assign to variable */ 2017 int copy; /* copy value from "tv" */ 2018 char_u *endchars; /* valid chars after variable name or NULL */ 2019 char_u *op; /* "+", "-", "." or NULL*/ 2020 { 2021 int c1; 2022 char_u *name; 2023 char_u *p; 2024 char_u *arg_end = NULL; 2025 int len; 2026 int opt_flags; 2027 char_u *tofree = NULL; 2028 2029 /* 2030 * ":let $VAR = expr": Set environment variable. 2031 */ 2032 if (*arg == '$') 2033 { 2034 /* Find the end of the name. */ 2035 ++arg; 2036 name = arg; 2037 len = get_env_len(&arg); 2038 if (len == 0) 2039 EMSG2(_(e_invarg2), name - 1); 2040 else 2041 { 2042 if (op != NULL && (*op == '+' || *op == '-')) 2043 EMSG2(_(e_letwrong), op); 2044 else if (endchars != NULL 2045 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2046 EMSG(_(e_letunexp)); 2047 else 2048 { 2049 c1 = name[len]; 2050 name[len] = NUL; 2051 p = get_tv_string_chk(tv); 2052 if (p != NULL && op != NULL && *op == '.') 2053 { 2054 int mustfree = FALSE; 2055 char_u *s = vim_getenv(name, &mustfree); 2056 2057 if (s != NULL) 2058 { 2059 p = tofree = concat_str(s, p); 2060 if (mustfree) 2061 vim_free(s); 2062 } 2063 } 2064 if (p != NULL) 2065 { 2066 vim_setenv(name, p); 2067 if (STRICMP(name, "HOME") == 0) 2068 init_homedir(); 2069 else if (didset_vim && STRICMP(name, "VIM") == 0) 2070 didset_vim = FALSE; 2071 else if (didset_vimruntime 2072 && STRICMP(name, "VIMRUNTIME") == 0) 2073 didset_vimruntime = FALSE; 2074 arg_end = arg; 2075 } 2076 name[len] = c1; 2077 vim_free(tofree); 2078 } 2079 } 2080 } 2081 2082 /* 2083 * ":let &option = expr": Set option value. 2084 * ":let &l:option = expr": Set local option value. 2085 * ":let &g:option = expr": Set global option value. 2086 */ 2087 else if (*arg == '&') 2088 { 2089 /* Find the end of the name. */ 2090 p = find_option_end(&arg, &opt_flags); 2091 if (p == NULL || (endchars != NULL 2092 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2093 EMSG(_(e_letunexp)); 2094 else 2095 { 2096 long n; 2097 int opt_type; 2098 long numval; 2099 char_u *stringval = NULL; 2100 char_u *s; 2101 2102 c1 = *p; 2103 *p = NUL; 2104 2105 n = get_tv_number(tv); 2106 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2107 if (s != NULL && op != NULL && *op != '=') 2108 { 2109 opt_type = get_option_value(arg, &numval, 2110 &stringval, opt_flags); 2111 if ((opt_type == 1 && *op == '.') 2112 || (opt_type == 0 && *op != '.')) 2113 EMSG2(_(e_letwrong), op); 2114 else 2115 { 2116 if (opt_type == 1) /* number */ 2117 { 2118 if (*op == '+') 2119 n = numval + n; 2120 else 2121 n = numval - n; 2122 } 2123 else if (opt_type == 0 && stringval != NULL) /* string */ 2124 { 2125 s = concat_str(stringval, s); 2126 vim_free(stringval); 2127 stringval = s; 2128 } 2129 } 2130 } 2131 if (s != NULL) 2132 { 2133 set_option_value(arg, n, s, opt_flags); 2134 arg_end = p; 2135 } 2136 *p = c1; 2137 vim_free(stringval); 2138 } 2139 } 2140 2141 /* 2142 * ":let @r = expr": Set register contents. 2143 */ 2144 else if (*arg == '@') 2145 { 2146 ++arg; 2147 if (op != NULL && (*op == '+' || *op == '-')) 2148 EMSG2(_(e_letwrong), op); 2149 else if (endchars != NULL 2150 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2151 EMSG(_(e_letunexp)); 2152 else 2153 { 2154 char_u *tofree = NULL; 2155 char_u *s; 2156 2157 p = get_tv_string_chk(tv); 2158 if (p != NULL && op != NULL && *op == '.') 2159 { 2160 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2161 if (s != NULL) 2162 { 2163 p = tofree = concat_str(s, p); 2164 vim_free(s); 2165 } 2166 } 2167 if (p != NULL) 2168 { 2169 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2170 arg_end = arg + 1; 2171 } 2172 vim_free(tofree); 2173 } 2174 } 2175 2176 /* 2177 * ":let var = expr": Set internal variable. 2178 * ":let {expr} = expr": Idem, name made with curly braces 2179 */ 2180 else if (eval_isnamec1(*arg) || *arg == '{') 2181 { 2182 lval_T lv; 2183 2184 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2185 if (p != NULL && lv.ll_name != NULL) 2186 { 2187 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2188 EMSG(_(e_letunexp)); 2189 else 2190 { 2191 set_var_lval(&lv, p, tv, copy, op); 2192 arg_end = p; 2193 } 2194 } 2195 clear_lval(&lv); 2196 } 2197 2198 else 2199 EMSG2(_(e_invarg2), arg); 2200 2201 return arg_end; 2202 } 2203 2204 /* 2205 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2206 */ 2207 static int 2208 check_changedtick(arg) 2209 char_u *arg; 2210 { 2211 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2212 { 2213 EMSG2(_(e_readonlyvar), arg); 2214 return TRUE; 2215 } 2216 return FALSE; 2217 } 2218 2219 /* 2220 * Get an lval: variable, Dict item or List item that can be assigned a value 2221 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2222 * "name.key", "name.key[expr]" etc. 2223 * Indexing only works if "name" is an existing List or Dictionary. 2224 * "name" points to the start of the name. 2225 * If "rettv" is not NULL it points to the value to be assigned. 2226 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2227 * wrong; must end in space or cmd separator. 2228 * 2229 * Returns a pointer to just after the name, including indexes. 2230 * When an evaluation error occurs "lp->ll_name" is NULL; 2231 * Returns NULL for a parsing error. Still need to free items in "lp"! 2232 */ 2233 static char_u * 2234 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2235 char_u *name; 2236 typval_T *rettv; 2237 lval_T *lp; 2238 int unlet; 2239 int skip; 2240 int quiet; /* don't give error messages */ 2241 int fne_flags; /* flags for find_name_end() */ 2242 { 2243 char_u *p; 2244 char_u *expr_start, *expr_end; 2245 int cc; 2246 dictitem_T *v; 2247 typval_T var1; 2248 typval_T var2; 2249 int empty1 = FALSE; 2250 listitem_T *ni; 2251 char_u *key = NULL; 2252 int len; 2253 hashtab_T *ht; 2254 2255 /* Clear everything in "lp". */ 2256 vim_memset(lp, 0, sizeof(lval_T)); 2257 2258 if (skip) 2259 { 2260 /* When skipping just find the end of the name. */ 2261 lp->ll_name = name; 2262 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2263 } 2264 2265 /* Find the end of the name. */ 2266 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2267 if (expr_start != NULL) 2268 { 2269 /* Don't expand the name when we already know there is an error. */ 2270 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2271 && *p != '[' && *p != '.') 2272 { 2273 EMSG(_(e_trailing)); 2274 return NULL; 2275 } 2276 2277 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2278 if (lp->ll_exp_name == NULL) 2279 { 2280 /* Report an invalid expression in braces, unless the 2281 * expression evaluation has been cancelled due to an 2282 * aborting error, an interrupt, or an exception. */ 2283 if (!aborting() && !quiet) 2284 { 2285 emsg_severe = TRUE; 2286 EMSG2(_(e_invarg2), name); 2287 return NULL; 2288 } 2289 } 2290 lp->ll_name = lp->ll_exp_name; 2291 } 2292 else 2293 lp->ll_name = name; 2294 2295 /* Without [idx] or .key we are done. */ 2296 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2297 return p; 2298 2299 cc = *p; 2300 *p = NUL; 2301 v = find_var(lp->ll_name, &ht); 2302 if (v == NULL && !quiet) 2303 EMSG2(_(e_undefvar), lp->ll_name); 2304 *p = cc; 2305 if (v == NULL) 2306 return NULL; 2307 2308 /* 2309 * Loop until no more [idx] or .key is following. 2310 */ 2311 lp->ll_tv = &v->di_tv; 2312 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2313 { 2314 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2315 && !(lp->ll_tv->v_type == VAR_DICT 2316 && lp->ll_tv->vval.v_dict != NULL)) 2317 { 2318 if (!quiet) 2319 EMSG(_("E689: Can only index a List or Dictionary")); 2320 return NULL; 2321 } 2322 if (lp->ll_range) 2323 { 2324 if (!quiet) 2325 EMSG(_("E708: [:] must come last")); 2326 return NULL; 2327 } 2328 2329 len = -1; 2330 if (*p == '.') 2331 { 2332 key = p + 1; 2333 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2334 ; 2335 if (len == 0) 2336 { 2337 if (!quiet) 2338 EMSG(_(e_emptykey)); 2339 return NULL; 2340 } 2341 p = key + len; 2342 } 2343 else 2344 { 2345 /* Get the index [expr] or the first index [expr: ]. */ 2346 p = skipwhite(p + 1); 2347 if (*p == ':') 2348 empty1 = TRUE; 2349 else 2350 { 2351 empty1 = FALSE; 2352 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2353 return NULL; 2354 if (get_tv_string_chk(&var1) == NULL) 2355 { 2356 /* not a number or string */ 2357 clear_tv(&var1); 2358 return NULL; 2359 } 2360 } 2361 2362 /* Optionally get the second index [ :expr]. */ 2363 if (*p == ':') 2364 { 2365 if (lp->ll_tv->v_type == VAR_DICT) 2366 { 2367 if (!quiet) 2368 EMSG(_(e_dictrange)); 2369 if (!empty1) 2370 clear_tv(&var1); 2371 return NULL; 2372 } 2373 if (rettv != NULL && (rettv->v_type != VAR_LIST 2374 || rettv->vval.v_list == NULL)) 2375 { 2376 if (!quiet) 2377 EMSG(_("E709: [:] requires a List value")); 2378 if (!empty1) 2379 clear_tv(&var1); 2380 return NULL; 2381 } 2382 p = skipwhite(p + 1); 2383 if (*p == ']') 2384 lp->ll_empty2 = TRUE; 2385 else 2386 { 2387 lp->ll_empty2 = FALSE; 2388 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2389 { 2390 if (!empty1) 2391 clear_tv(&var1); 2392 return NULL; 2393 } 2394 if (get_tv_string_chk(&var2) == NULL) 2395 { 2396 /* not a number or string */ 2397 if (!empty1) 2398 clear_tv(&var1); 2399 clear_tv(&var2); 2400 return NULL; 2401 } 2402 } 2403 lp->ll_range = TRUE; 2404 } 2405 else 2406 lp->ll_range = FALSE; 2407 2408 if (*p != ']') 2409 { 2410 if (!quiet) 2411 EMSG(_(e_missbrac)); 2412 if (!empty1) 2413 clear_tv(&var1); 2414 if (lp->ll_range && !lp->ll_empty2) 2415 clear_tv(&var2); 2416 return NULL; 2417 } 2418 2419 /* Skip to past ']'. */ 2420 ++p; 2421 } 2422 2423 if (lp->ll_tv->v_type == VAR_DICT) 2424 { 2425 if (len == -1) 2426 { 2427 /* "[key]": get key from "var1" */ 2428 key = get_tv_string(&var1); /* is number or string */ 2429 if (*key == NUL) 2430 { 2431 if (!quiet) 2432 EMSG(_(e_emptykey)); 2433 clear_tv(&var1); 2434 return NULL; 2435 } 2436 } 2437 lp->ll_list = NULL; 2438 lp->ll_dict = lp->ll_tv->vval.v_dict; 2439 lp->ll_di = dict_find(lp->ll_dict, key, len); 2440 if (lp->ll_di == NULL) 2441 { 2442 /* Key does not exist in dict: may need to add it. */ 2443 if (*p == '[' || *p == '.' || unlet) 2444 { 2445 if (!quiet) 2446 EMSG2(_(e_dictkey), key); 2447 if (len == -1) 2448 clear_tv(&var1); 2449 return NULL; 2450 } 2451 if (len == -1) 2452 lp->ll_newkey = vim_strsave(key); 2453 else 2454 lp->ll_newkey = vim_strnsave(key, len); 2455 if (len == -1) 2456 clear_tv(&var1); 2457 if (lp->ll_newkey == NULL) 2458 p = NULL; 2459 break; 2460 } 2461 if (len == -1) 2462 clear_tv(&var1); 2463 lp->ll_tv = &lp->ll_di->di_tv; 2464 } 2465 else 2466 { 2467 /* 2468 * Get the number and item for the only or first index of the List. 2469 */ 2470 if (empty1) 2471 lp->ll_n1 = 0; 2472 else 2473 { 2474 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2475 clear_tv(&var1); 2476 } 2477 lp->ll_dict = NULL; 2478 lp->ll_list = lp->ll_tv->vval.v_list; 2479 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2480 if (lp->ll_li == NULL) 2481 { 2482 if (!quiet) 2483 EMSGN(_(e_listidx), lp->ll_n1); 2484 if (lp->ll_range && !lp->ll_empty2) 2485 clear_tv(&var2); 2486 return NULL; 2487 } 2488 2489 /* 2490 * May need to find the item or absolute index for the second 2491 * index of a range. 2492 * When no index given: "lp->ll_empty2" is TRUE. 2493 * Otherwise "lp->ll_n2" is set to the second index. 2494 */ 2495 if (lp->ll_range && !lp->ll_empty2) 2496 { 2497 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2498 clear_tv(&var2); 2499 if (lp->ll_n2 < 0) 2500 { 2501 ni = list_find(lp->ll_list, lp->ll_n2); 2502 if (ni == NULL) 2503 { 2504 if (!quiet) 2505 EMSGN(_(e_listidx), lp->ll_n2); 2506 return NULL; 2507 } 2508 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2509 } 2510 2511 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2512 if (lp->ll_n1 < 0) 2513 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2514 if (lp->ll_n2 < lp->ll_n1) 2515 { 2516 if (!quiet) 2517 EMSGN(_(e_listidx), lp->ll_n2); 2518 return NULL; 2519 } 2520 } 2521 2522 lp->ll_tv = &lp->ll_li->li_tv; 2523 } 2524 } 2525 2526 return p; 2527 } 2528 2529 /* 2530 * Clear lval "lp" that was filled by get_lval(). 2531 */ 2532 static void 2533 clear_lval(lp) 2534 lval_T *lp; 2535 { 2536 vim_free(lp->ll_exp_name); 2537 vim_free(lp->ll_newkey); 2538 } 2539 2540 /* 2541 * Set a variable that was parsed by get_lval() to "rettv". 2542 * "endp" points to just after the parsed name. 2543 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2544 */ 2545 static void 2546 set_var_lval(lp, endp, rettv, copy, op) 2547 lval_T *lp; 2548 char_u *endp; 2549 typval_T *rettv; 2550 int copy; 2551 char_u *op; 2552 { 2553 int cc; 2554 listitem_T *ni; 2555 listitem_T *ri; 2556 dictitem_T *di; 2557 2558 if (lp->ll_tv == NULL) 2559 { 2560 if (!check_changedtick(lp->ll_name)) 2561 { 2562 cc = *endp; 2563 *endp = NUL; 2564 if (op != NULL && *op != '=') 2565 { 2566 typval_T tv; 2567 2568 /* handle +=, -= and .= */ 2569 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2570 &tv, TRUE) == OK) 2571 { 2572 if (tv_op(&tv, rettv, op) == OK) 2573 set_var(lp->ll_name, &tv, FALSE); 2574 clear_tv(&tv); 2575 } 2576 } 2577 else 2578 set_var(lp->ll_name, rettv, copy); 2579 *endp = cc; 2580 } 2581 } 2582 else if (tv_check_lock(lp->ll_newkey == NULL 2583 ? lp->ll_tv->v_lock 2584 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2585 ; 2586 else if (lp->ll_range) 2587 { 2588 /* 2589 * Assign the List values to the list items. 2590 */ 2591 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2592 { 2593 if (op != NULL && *op != '=') 2594 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2595 else 2596 { 2597 clear_tv(&lp->ll_li->li_tv); 2598 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2599 } 2600 ri = ri->li_next; 2601 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2602 break; 2603 if (lp->ll_li->li_next == NULL) 2604 { 2605 /* Need to add an empty item. */ 2606 ni = listitem_alloc(); 2607 if (ni == NULL) 2608 { 2609 ri = NULL; 2610 break; 2611 } 2612 ni->li_tv.v_type = VAR_NUMBER; 2613 ni->li_tv.v_lock = 0; 2614 ni->li_tv.vval.v_number = 0; 2615 list_append(lp->ll_list, ni); 2616 } 2617 lp->ll_li = lp->ll_li->li_next; 2618 ++lp->ll_n1; 2619 } 2620 if (ri != NULL) 2621 EMSG(_("E710: List value has more items than target")); 2622 else if (lp->ll_empty2 2623 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2624 : lp->ll_n1 != lp->ll_n2) 2625 EMSG(_("E711: List value has not enough items")); 2626 } 2627 else 2628 { 2629 /* 2630 * Assign to a List or Dictionary item. 2631 */ 2632 if (lp->ll_newkey != NULL) 2633 { 2634 if (op != NULL && *op != '=') 2635 { 2636 EMSG2(_(e_letwrong), op); 2637 return; 2638 } 2639 2640 /* Need to add an item to the Dictionary. */ 2641 di = dictitem_alloc(lp->ll_newkey); 2642 if (di == NULL) 2643 return; 2644 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2645 { 2646 vim_free(di); 2647 return; 2648 } 2649 lp->ll_tv = &di->di_tv; 2650 } 2651 else if (op != NULL && *op != '=') 2652 { 2653 tv_op(lp->ll_tv, rettv, op); 2654 return; 2655 } 2656 else 2657 clear_tv(lp->ll_tv); 2658 2659 /* 2660 * Assign the value to the variable or list item. 2661 */ 2662 if (copy) 2663 copy_tv(rettv, lp->ll_tv); 2664 else 2665 { 2666 *lp->ll_tv = *rettv; 2667 lp->ll_tv->v_lock = 0; 2668 init_tv(rettv); 2669 } 2670 } 2671 } 2672 2673 /* 2674 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2675 * Returns OK or FAIL. 2676 */ 2677 static int 2678 tv_op(tv1, tv2, op) 2679 typval_T *tv1; 2680 typval_T *tv2; 2681 char_u *op; 2682 { 2683 long n; 2684 char_u numbuf[NUMBUFLEN]; 2685 char_u *s; 2686 2687 /* Can't do anything with a Funcref or a Dict on the right. */ 2688 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2689 { 2690 switch (tv1->v_type) 2691 { 2692 case VAR_DICT: 2693 case VAR_FUNC: 2694 break; 2695 2696 case VAR_LIST: 2697 if (*op != '+' || tv2->v_type != VAR_LIST) 2698 break; 2699 /* List += List */ 2700 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2701 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2702 return OK; 2703 2704 case VAR_NUMBER: 2705 case VAR_STRING: 2706 if (tv2->v_type == VAR_LIST) 2707 break; 2708 if (*op == '+' || *op == '-') 2709 { 2710 /* nr += nr or nr -= nr*/ 2711 n = get_tv_number(tv1); 2712 if (*op == '+') 2713 n += get_tv_number(tv2); 2714 else 2715 n -= get_tv_number(tv2); 2716 clear_tv(tv1); 2717 tv1->v_type = VAR_NUMBER; 2718 tv1->vval.v_number = n; 2719 } 2720 else 2721 { 2722 /* str .= str */ 2723 s = get_tv_string(tv1); 2724 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2725 clear_tv(tv1); 2726 tv1->v_type = VAR_STRING; 2727 tv1->vval.v_string = s; 2728 } 2729 return OK; 2730 } 2731 } 2732 2733 EMSG2(_(e_letwrong), op); 2734 return FAIL; 2735 } 2736 2737 /* 2738 * Add a watcher to a list. 2739 */ 2740 static void 2741 list_add_watch(l, lw) 2742 list_T *l; 2743 listwatch_T *lw; 2744 { 2745 lw->lw_next = l->lv_watch; 2746 l->lv_watch = lw; 2747 } 2748 2749 /* 2750 * Remove a watcher from a list. 2751 * No warning when it isn't found... 2752 */ 2753 static void 2754 list_rem_watch(l, lwrem) 2755 list_T *l; 2756 listwatch_T *lwrem; 2757 { 2758 listwatch_T *lw, **lwp; 2759 2760 lwp = &l->lv_watch; 2761 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2762 { 2763 if (lw == lwrem) 2764 { 2765 *lwp = lw->lw_next; 2766 break; 2767 } 2768 lwp = &lw->lw_next; 2769 } 2770 } 2771 2772 /* 2773 * Just before removing an item from a list: advance watchers to the next 2774 * item. 2775 */ 2776 static void 2777 list_fix_watch(l, item) 2778 list_T *l; 2779 listitem_T *item; 2780 { 2781 listwatch_T *lw; 2782 2783 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2784 if (lw->lw_item == item) 2785 lw->lw_item = item->li_next; 2786 } 2787 2788 /* 2789 * Evaluate the expression used in a ":for var in expr" command. 2790 * "arg" points to "var". 2791 * Set "*errp" to TRUE for an error, FALSE otherwise; 2792 * Return a pointer that holds the info. Null when there is an error. 2793 */ 2794 void * 2795 eval_for_line(arg, errp, nextcmdp, skip) 2796 char_u *arg; 2797 int *errp; 2798 char_u **nextcmdp; 2799 int skip; 2800 { 2801 forinfo_T *fi; 2802 char_u *expr; 2803 typval_T tv; 2804 list_T *l; 2805 2806 *errp = TRUE; /* default: there is an error */ 2807 2808 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2809 if (fi == NULL) 2810 return NULL; 2811 2812 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2813 if (expr == NULL) 2814 return fi; 2815 2816 expr = skipwhite(expr); 2817 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2818 { 2819 EMSG(_("E690: Missing \"in\" after :for")); 2820 return fi; 2821 } 2822 2823 if (skip) 2824 ++emsg_skip; 2825 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2826 { 2827 *errp = FALSE; 2828 if (!skip) 2829 { 2830 l = tv.vval.v_list; 2831 if (tv.v_type != VAR_LIST || l == NULL) 2832 { 2833 EMSG(_(e_listreq)); 2834 clear_tv(&tv); 2835 } 2836 else 2837 { 2838 /* No need to increment the refcount, it's already set for the 2839 * list being used in "tv". */ 2840 fi->fi_list = l; 2841 list_add_watch(l, &fi->fi_lw); 2842 fi->fi_lw.lw_item = l->lv_first; 2843 } 2844 } 2845 } 2846 if (skip) 2847 --emsg_skip; 2848 2849 return fi; 2850 } 2851 2852 /* 2853 * Use the first item in a ":for" list. Advance to the next. 2854 * Assign the values to the variable (list). "arg" points to the first one. 2855 * Return TRUE when a valid item was found, FALSE when at end of list or 2856 * something wrong. 2857 */ 2858 int 2859 next_for_item(fi_void, arg) 2860 void *fi_void; 2861 char_u *arg; 2862 { 2863 forinfo_T *fi = (forinfo_T *)fi_void; 2864 int result; 2865 listitem_T *item; 2866 2867 item = fi->fi_lw.lw_item; 2868 if (item == NULL) 2869 result = FALSE; 2870 else 2871 { 2872 fi->fi_lw.lw_item = item->li_next; 2873 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2874 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2875 } 2876 return result; 2877 } 2878 2879 /* 2880 * Free the structure used to store info used by ":for". 2881 */ 2882 void 2883 free_for_info(fi_void) 2884 void *fi_void; 2885 { 2886 forinfo_T *fi = (forinfo_T *)fi_void; 2887 2888 if (fi != NULL && fi->fi_list != NULL) 2889 { 2890 list_rem_watch(fi->fi_list, &fi->fi_lw); 2891 list_unref(fi->fi_list); 2892 } 2893 vim_free(fi); 2894 } 2895 2896 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2897 2898 void 2899 set_context_for_expression(xp, arg, cmdidx) 2900 expand_T *xp; 2901 char_u *arg; 2902 cmdidx_T cmdidx; 2903 { 2904 int got_eq = FALSE; 2905 int c; 2906 char_u *p; 2907 2908 if (cmdidx == CMD_let) 2909 { 2910 xp->xp_context = EXPAND_USER_VARS; 2911 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2912 { 2913 /* ":let var1 var2 ...": find last space. */ 2914 for (p = arg + STRLEN(arg); p >= arg; ) 2915 { 2916 xp->xp_pattern = p; 2917 mb_ptr_back(arg, p); 2918 if (vim_iswhite(*p)) 2919 break; 2920 } 2921 return; 2922 } 2923 } 2924 else 2925 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2926 : EXPAND_EXPRESSION; 2927 while ((xp->xp_pattern = vim_strpbrk(arg, 2928 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2929 { 2930 c = *xp->xp_pattern; 2931 if (c == '&') 2932 { 2933 c = xp->xp_pattern[1]; 2934 if (c == '&') 2935 { 2936 ++xp->xp_pattern; 2937 xp->xp_context = cmdidx != CMD_let || got_eq 2938 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2939 } 2940 else if (c != ' ') 2941 { 2942 xp->xp_context = EXPAND_SETTINGS; 2943 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2944 xp->xp_pattern += 2; 2945 2946 } 2947 } 2948 else if (c == '$') 2949 { 2950 /* environment variable */ 2951 xp->xp_context = EXPAND_ENV_VARS; 2952 } 2953 else if (c == '=') 2954 { 2955 got_eq = TRUE; 2956 xp->xp_context = EXPAND_EXPRESSION; 2957 } 2958 else if (c == '<' 2959 && xp->xp_context == EXPAND_FUNCTIONS 2960 && vim_strchr(xp->xp_pattern, '(') == NULL) 2961 { 2962 /* Function name can start with "<SNR>" */ 2963 break; 2964 } 2965 else if (cmdidx != CMD_let || got_eq) 2966 { 2967 if (c == '"') /* string */ 2968 { 2969 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2970 if (c == '\\' && xp->xp_pattern[1] != NUL) 2971 ++xp->xp_pattern; 2972 xp->xp_context = EXPAND_NOTHING; 2973 } 2974 else if (c == '\'') /* literal string */ 2975 { 2976 /* Trick: '' is like stopping and starting a literal string. */ 2977 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2978 /* skip */ ; 2979 xp->xp_context = EXPAND_NOTHING; 2980 } 2981 else if (c == '|') 2982 { 2983 if (xp->xp_pattern[1] == '|') 2984 { 2985 ++xp->xp_pattern; 2986 xp->xp_context = EXPAND_EXPRESSION; 2987 } 2988 else 2989 xp->xp_context = EXPAND_COMMANDS; 2990 } 2991 else 2992 xp->xp_context = EXPAND_EXPRESSION; 2993 } 2994 else 2995 /* Doesn't look like something valid, expand as an expression 2996 * anyway. */ 2997 xp->xp_context = EXPAND_EXPRESSION; 2998 arg = xp->xp_pattern; 2999 if (*arg != NUL) 3000 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 3001 /* skip */ ; 3002 } 3003 xp->xp_pattern = arg; 3004 } 3005 3006 #endif /* FEAT_CMDL_COMPL */ 3007 3008 /* 3009 * ":1,25call func(arg1, arg2)" function call. 3010 */ 3011 void 3012 ex_call(eap) 3013 exarg_T *eap; 3014 { 3015 char_u *arg = eap->arg; 3016 char_u *startarg; 3017 char_u *name; 3018 char_u *tofree; 3019 int len; 3020 typval_T rettv; 3021 linenr_T lnum; 3022 int doesrange; 3023 int failed = FALSE; 3024 funcdict_T fudi; 3025 3026 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3027 vim_free(fudi.fd_newkey); 3028 if (tofree == NULL) 3029 return; 3030 3031 /* Increase refcount on dictionary, it could get deleted when evaluating 3032 * the arguments. */ 3033 if (fudi.fd_dict != NULL) 3034 ++fudi.fd_dict->dv_refcount; 3035 3036 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3037 len = STRLEN(tofree); 3038 name = deref_func_name(tofree, &len); 3039 3040 /* Skip white space to allow ":call func ()". Not good, but required for 3041 * backward compatibility. */ 3042 startarg = skipwhite(arg); 3043 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3044 3045 if (*startarg != '(') 3046 { 3047 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3048 goto end; 3049 } 3050 3051 /* 3052 * When skipping, evaluate the function once, to find the end of the 3053 * arguments. 3054 * When the function takes a range, this is discovered after the first 3055 * call, and the loop is broken. 3056 */ 3057 if (eap->skip) 3058 { 3059 ++emsg_skip; 3060 lnum = eap->line2; /* do it once, also with an invalid range */ 3061 } 3062 else 3063 lnum = eap->line1; 3064 for ( ; lnum <= eap->line2; ++lnum) 3065 { 3066 if (!eap->skip && eap->addr_count > 0) 3067 { 3068 curwin->w_cursor.lnum = lnum; 3069 curwin->w_cursor.col = 0; 3070 } 3071 arg = startarg; 3072 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3073 eap->line1, eap->line2, &doesrange, 3074 !eap->skip, fudi.fd_dict) == FAIL) 3075 { 3076 failed = TRUE; 3077 break; 3078 } 3079 clear_tv(&rettv); 3080 if (doesrange || eap->skip) 3081 break; 3082 /* Stop when immediately aborting on error, or when an interrupt 3083 * occurred or an exception was thrown but not caught. 3084 * get_func_tv() returned OK, so that the check for trailing 3085 * characters below is executed. */ 3086 if (aborting()) 3087 break; 3088 } 3089 if (eap->skip) 3090 --emsg_skip; 3091 3092 if (!failed) 3093 { 3094 /* Check for trailing illegal characters and a following command. */ 3095 if (!ends_excmd(*arg)) 3096 { 3097 emsg_severe = TRUE; 3098 EMSG(_(e_trailing)); 3099 } 3100 else 3101 eap->nextcmd = check_nextcmd(arg); 3102 } 3103 3104 end: 3105 dict_unref(fudi.fd_dict); 3106 vim_free(tofree); 3107 } 3108 3109 /* 3110 * ":unlet[!] var1 ... " command. 3111 */ 3112 void 3113 ex_unlet(eap) 3114 exarg_T *eap; 3115 { 3116 ex_unletlock(eap, eap->arg, 0); 3117 } 3118 3119 /* 3120 * ":lockvar" and ":unlockvar" commands 3121 */ 3122 void 3123 ex_lockvar(eap) 3124 exarg_T *eap; 3125 { 3126 char_u *arg = eap->arg; 3127 int deep = 2; 3128 3129 if (eap->forceit) 3130 deep = -1; 3131 else if (vim_isdigit(*arg)) 3132 { 3133 deep = getdigits(&arg); 3134 arg = skipwhite(arg); 3135 } 3136 3137 ex_unletlock(eap, arg, deep); 3138 } 3139 3140 /* 3141 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3142 */ 3143 static void 3144 ex_unletlock(eap, argstart, deep) 3145 exarg_T *eap; 3146 char_u *argstart; 3147 int deep; 3148 { 3149 char_u *arg = argstart; 3150 char_u *name_end; 3151 int error = FALSE; 3152 lval_T lv; 3153 3154 do 3155 { 3156 /* Parse the name and find the end. */ 3157 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3158 FNE_CHECK_START); 3159 if (lv.ll_name == NULL) 3160 error = TRUE; /* error but continue parsing */ 3161 if (name_end == NULL || (!vim_iswhite(*name_end) 3162 && !ends_excmd(*name_end))) 3163 { 3164 if (name_end != NULL) 3165 { 3166 emsg_severe = TRUE; 3167 EMSG(_(e_trailing)); 3168 } 3169 if (!(eap->skip || error)) 3170 clear_lval(&lv); 3171 break; 3172 } 3173 3174 if (!error && !eap->skip) 3175 { 3176 if (eap->cmdidx == CMD_unlet) 3177 { 3178 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3179 error = TRUE; 3180 } 3181 else 3182 { 3183 if (do_lock_var(&lv, name_end, deep, 3184 eap->cmdidx == CMD_lockvar) == FAIL) 3185 error = TRUE; 3186 } 3187 } 3188 3189 if (!eap->skip) 3190 clear_lval(&lv); 3191 3192 arg = skipwhite(name_end); 3193 } while (!ends_excmd(*arg)); 3194 3195 eap->nextcmd = check_nextcmd(arg); 3196 } 3197 3198 static int 3199 do_unlet_var(lp, name_end, forceit) 3200 lval_T *lp; 3201 char_u *name_end; 3202 int forceit; 3203 { 3204 int ret = OK; 3205 int cc; 3206 3207 if (lp->ll_tv == NULL) 3208 { 3209 cc = *name_end; 3210 *name_end = NUL; 3211 3212 /* Normal name or expanded name. */ 3213 if (check_changedtick(lp->ll_name)) 3214 ret = FAIL; 3215 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3216 ret = FAIL; 3217 *name_end = cc; 3218 } 3219 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3220 return FAIL; 3221 else if (lp->ll_range) 3222 { 3223 listitem_T *li; 3224 3225 /* Delete a range of List items. */ 3226 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3227 { 3228 li = lp->ll_li->li_next; 3229 listitem_remove(lp->ll_list, lp->ll_li); 3230 lp->ll_li = li; 3231 ++lp->ll_n1; 3232 } 3233 } 3234 else 3235 { 3236 if (lp->ll_list != NULL) 3237 /* unlet a List item. */ 3238 listitem_remove(lp->ll_list, lp->ll_li); 3239 else 3240 /* unlet a Dictionary item. */ 3241 dictitem_remove(lp->ll_dict, lp->ll_di); 3242 } 3243 3244 return ret; 3245 } 3246 3247 /* 3248 * "unlet" a variable. Return OK if it existed, FAIL if not. 3249 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3250 */ 3251 int 3252 do_unlet(name, forceit) 3253 char_u *name; 3254 int forceit; 3255 { 3256 hashtab_T *ht; 3257 hashitem_T *hi; 3258 char_u *varname; 3259 3260 ht = find_var_ht(name, &varname); 3261 if (ht != NULL && *varname != NUL) 3262 { 3263 hi = hash_find(ht, varname); 3264 if (!HASHITEM_EMPTY(hi)) 3265 { 3266 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3267 return FAIL; 3268 delete_var(ht, hi); 3269 return OK; 3270 } 3271 } 3272 if (forceit) 3273 return OK; 3274 EMSG2(_("E108: No such variable: \"%s\""), name); 3275 return FAIL; 3276 } 3277 3278 /* 3279 * Lock or unlock variable indicated by "lp". 3280 * "deep" is the levels to go (-1 for unlimited); 3281 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3282 */ 3283 static int 3284 do_lock_var(lp, name_end, deep, lock) 3285 lval_T *lp; 3286 char_u *name_end; 3287 int deep; 3288 int lock; 3289 { 3290 int ret = OK; 3291 int cc; 3292 dictitem_T *di; 3293 3294 if (deep == 0) /* nothing to do */ 3295 return OK; 3296 3297 if (lp->ll_tv == NULL) 3298 { 3299 cc = *name_end; 3300 *name_end = NUL; 3301 3302 /* Normal name or expanded name. */ 3303 if (check_changedtick(lp->ll_name)) 3304 ret = FAIL; 3305 else 3306 { 3307 di = find_var(lp->ll_name, NULL); 3308 if (di == NULL) 3309 ret = FAIL; 3310 else 3311 { 3312 if (lock) 3313 di->di_flags |= DI_FLAGS_LOCK; 3314 else 3315 di->di_flags &= ~DI_FLAGS_LOCK; 3316 item_lock(&di->di_tv, deep, lock); 3317 } 3318 } 3319 *name_end = cc; 3320 } 3321 else if (lp->ll_range) 3322 { 3323 listitem_T *li = lp->ll_li; 3324 3325 /* (un)lock a range of List items. */ 3326 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3327 { 3328 item_lock(&li->li_tv, deep, lock); 3329 li = li->li_next; 3330 ++lp->ll_n1; 3331 } 3332 } 3333 else if (lp->ll_list != NULL) 3334 /* (un)lock a List item. */ 3335 item_lock(&lp->ll_li->li_tv, deep, lock); 3336 else 3337 /* un(lock) a Dictionary item. */ 3338 item_lock(&lp->ll_di->di_tv, deep, lock); 3339 3340 return ret; 3341 } 3342 3343 /* 3344 * Lock or unlock an item. "deep" is nr of levels to go. 3345 */ 3346 static void 3347 item_lock(tv, deep, lock) 3348 typval_T *tv; 3349 int deep; 3350 int lock; 3351 { 3352 static int recurse = 0; 3353 list_T *l; 3354 listitem_T *li; 3355 dict_T *d; 3356 hashitem_T *hi; 3357 int todo; 3358 3359 if (recurse >= DICT_MAXNEST) 3360 { 3361 EMSG(_("E743: variable nested too deep for (un)lock")); 3362 return; 3363 } 3364 if (deep == 0) 3365 return; 3366 ++recurse; 3367 3368 /* lock/unlock the item itself */ 3369 if (lock) 3370 tv->v_lock |= VAR_LOCKED; 3371 else 3372 tv->v_lock &= ~VAR_LOCKED; 3373 3374 switch (tv->v_type) 3375 { 3376 case VAR_LIST: 3377 if ((l = tv->vval.v_list) != NULL) 3378 { 3379 if (lock) 3380 l->lv_lock |= VAR_LOCKED; 3381 else 3382 l->lv_lock &= ~VAR_LOCKED; 3383 if (deep < 0 || deep > 1) 3384 /* recursive: lock/unlock the items the List contains */ 3385 for (li = l->lv_first; li != NULL; li = li->li_next) 3386 item_lock(&li->li_tv, deep - 1, lock); 3387 } 3388 break; 3389 case VAR_DICT: 3390 if ((d = tv->vval.v_dict) != NULL) 3391 { 3392 if (lock) 3393 d->dv_lock |= VAR_LOCKED; 3394 else 3395 d->dv_lock &= ~VAR_LOCKED; 3396 if (deep < 0 || deep > 1) 3397 { 3398 /* recursive: lock/unlock the items the List contains */ 3399 todo = d->dv_hashtab.ht_used; 3400 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3401 { 3402 if (!HASHITEM_EMPTY(hi)) 3403 { 3404 --todo; 3405 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3406 } 3407 } 3408 } 3409 } 3410 } 3411 --recurse; 3412 } 3413 3414 /* 3415 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3416 * it refers to a List or Dictionary that is locked. 3417 */ 3418 static int 3419 tv_islocked(tv) 3420 typval_T *tv; 3421 { 3422 return (tv->v_lock & VAR_LOCKED) 3423 || (tv->v_type == VAR_LIST 3424 && tv->vval.v_list != NULL 3425 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3426 || (tv->v_type == VAR_DICT 3427 && tv->vval.v_dict != NULL 3428 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3429 } 3430 3431 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3432 /* 3433 * Delete all "menutrans_" variables. 3434 */ 3435 void 3436 del_menutrans_vars() 3437 { 3438 hashitem_T *hi; 3439 int todo; 3440 3441 hash_lock(&globvarht); 3442 todo = globvarht.ht_used; 3443 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3444 { 3445 if (!HASHITEM_EMPTY(hi)) 3446 { 3447 --todo; 3448 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3449 delete_var(&globvarht, hi); 3450 } 3451 } 3452 hash_unlock(&globvarht); 3453 } 3454 #endif 3455 3456 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3457 3458 /* 3459 * Local string buffer for the next two functions to store a variable name 3460 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3461 * get_user_var_name(). 3462 */ 3463 3464 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3465 3466 static char_u *varnamebuf = NULL; 3467 static int varnamebuflen = 0; 3468 3469 /* 3470 * Function to concatenate a prefix and a variable name. 3471 */ 3472 static char_u * 3473 cat_prefix_varname(prefix, name) 3474 int prefix; 3475 char_u *name; 3476 { 3477 int len; 3478 3479 len = (int)STRLEN(name) + 3; 3480 if (len > varnamebuflen) 3481 { 3482 vim_free(varnamebuf); 3483 len += 10; /* some additional space */ 3484 varnamebuf = alloc(len); 3485 if (varnamebuf == NULL) 3486 { 3487 varnamebuflen = 0; 3488 return NULL; 3489 } 3490 varnamebuflen = len; 3491 } 3492 *varnamebuf = prefix; 3493 varnamebuf[1] = ':'; 3494 STRCPY(varnamebuf + 2, name); 3495 return varnamebuf; 3496 } 3497 3498 /* 3499 * Function given to ExpandGeneric() to obtain the list of user defined 3500 * (global/buffer/window/built-in) variable names. 3501 */ 3502 /*ARGSUSED*/ 3503 char_u * 3504 get_user_var_name(xp, idx) 3505 expand_T *xp; 3506 int idx; 3507 { 3508 static long_u gdone; 3509 static long_u bdone; 3510 static long_u wdone; 3511 static int vidx; 3512 static hashitem_T *hi; 3513 hashtab_T *ht; 3514 3515 if (idx == 0) 3516 gdone = bdone = wdone = vidx = 0; 3517 3518 /* Global variables */ 3519 if (gdone < globvarht.ht_used) 3520 { 3521 if (gdone++ == 0) 3522 hi = globvarht.ht_array; 3523 else 3524 ++hi; 3525 while (HASHITEM_EMPTY(hi)) 3526 ++hi; 3527 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3528 return cat_prefix_varname('g', hi->hi_key); 3529 return hi->hi_key; 3530 } 3531 3532 /* b: variables */ 3533 ht = &curbuf->b_vars.dv_hashtab; 3534 if (bdone < ht->ht_used) 3535 { 3536 if (bdone++ == 0) 3537 hi = ht->ht_array; 3538 else 3539 ++hi; 3540 while (HASHITEM_EMPTY(hi)) 3541 ++hi; 3542 return cat_prefix_varname('b', hi->hi_key); 3543 } 3544 if (bdone == ht->ht_used) 3545 { 3546 ++bdone; 3547 return (char_u *)"b:changedtick"; 3548 } 3549 3550 /* w: variables */ 3551 ht = &curwin->w_vars.dv_hashtab; 3552 if (wdone < ht->ht_used) 3553 { 3554 if (wdone++ == 0) 3555 hi = ht->ht_array; 3556 else 3557 ++hi; 3558 while (HASHITEM_EMPTY(hi)) 3559 ++hi; 3560 return cat_prefix_varname('w', hi->hi_key); 3561 } 3562 3563 /* v: variables */ 3564 if (vidx < VV_LEN) 3565 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3566 3567 vim_free(varnamebuf); 3568 varnamebuf = NULL; 3569 varnamebuflen = 0; 3570 return NULL; 3571 } 3572 3573 #endif /* FEAT_CMDL_COMPL */ 3574 3575 /* 3576 * types for expressions. 3577 */ 3578 typedef enum 3579 { 3580 TYPE_UNKNOWN = 0 3581 , TYPE_EQUAL /* == */ 3582 , TYPE_NEQUAL /* != */ 3583 , TYPE_GREATER /* > */ 3584 , TYPE_GEQUAL /* >= */ 3585 , TYPE_SMALLER /* < */ 3586 , TYPE_SEQUAL /* <= */ 3587 , TYPE_MATCH /* =~ */ 3588 , TYPE_NOMATCH /* !~ */ 3589 } exptype_T; 3590 3591 /* 3592 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3593 * executed. The function may return OK, but the rettv will be of type 3594 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3595 */ 3596 3597 /* 3598 * Handle zero level expression. 3599 * This calls eval1() and handles error message and nextcmd. 3600 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3601 * Return OK or FAIL. 3602 */ 3603 static int 3604 eval0(arg, rettv, nextcmd, evaluate) 3605 char_u *arg; 3606 typval_T *rettv; 3607 char_u **nextcmd; 3608 int evaluate; 3609 { 3610 int ret; 3611 char_u *p; 3612 3613 p = skipwhite(arg); 3614 ret = eval1(&p, rettv, evaluate); 3615 if (ret == FAIL || !ends_excmd(*p)) 3616 { 3617 if (ret != FAIL) 3618 clear_tv(rettv); 3619 /* 3620 * Report the invalid expression unless the expression evaluation has 3621 * been cancelled due to an aborting error, an interrupt, or an 3622 * exception. 3623 */ 3624 if (!aborting()) 3625 EMSG2(_(e_invexpr2), arg); 3626 ret = FAIL; 3627 } 3628 if (nextcmd != NULL) 3629 *nextcmd = check_nextcmd(p); 3630 3631 return ret; 3632 } 3633 3634 /* 3635 * Handle top level expression: 3636 * expr1 ? expr0 : expr0 3637 * 3638 * "arg" must point to the first non-white of the expression. 3639 * "arg" is advanced to the next non-white after the recognized expression. 3640 * 3641 * Return OK or FAIL. 3642 */ 3643 static int 3644 eval1(arg, rettv, evaluate) 3645 char_u **arg; 3646 typval_T *rettv; 3647 int evaluate; 3648 { 3649 int result; 3650 typval_T var2; 3651 3652 /* 3653 * Get the first variable. 3654 */ 3655 if (eval2(arg, rettv, evaluate) == FAIL) 3656 return FAIL; 3657 3658 if ((*arg)[0] == '?') 3659 { 3660 result = FALSE; 3661 if (evaluate) 3662 { 3663 int error = FALSE; 3664 3665 if (get_tv_number_chk(rettv, &error) != 0) 3666 result = TRUE; 3667 clear_tv(rettv); 3668 if (error) 3669 return FAIL; 3670 } 3671 3672 /* 3673 * Get the second variable. 3674 */ 3675 *arg = skipwhite(*arg + 1); 3676 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3677 return FAIL; 3678 3679 /* 3680 * Check for the ":". 3681 */ 3682 if ((*arg)[0] != ':') 3683 { 3684 EMSG(_("E109: Missing ':' after '?'")); 3685 if (evaluate && result) 3686 clear_tv(rettv); 3687 return FAIL; 3688 } 3689 3690 /* 3691 * Get the third variable. 3692 */ 3693 *arg = skipwhite(*arg + 1); 3694 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3695 { 3696 if (evaluate && result) 3697 clear_tv(rettv); 3698 return FAIL; 3699 } 3700 if (evaluate && !result) 3701 *rettv = var2; 3702 } 3703 3704 return OK; 3705 } 3706 3707 /* 3708 * Handle first level expression: 3709 * expr2 || expr2 || expr2 logical OR 3710 * 3711 * "arg" must point to the first non-white of the expression. 3712 * "arg" is advanced to the next non-white after the recognized expression. 3713 * 3714 * Return OK or FAIL. 3715 */ 3716 static int 3717 eval2(arg, rettv, evaluate) 3718 char_u **arg; 3719 typval_T *rettv; 3720 int evaluate; 3721 { 3722 typval_T var2; 3723 long result; 3724 int first; 3725 int error = FALSE; 3726 3727 /* 3728 * Get the first variable. 3729 */ 3730 if (eval3(arg, rettv, evaluate) == FAIL) 3731 return FAIL; 3732 3733 /* 3734 * Repeat until there is no following "||". 3735 */ 3736 first = TRUE; 3737 result = FALSE; 3738 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3739 { 3740 if (evaluate && first) 3741 { 3742 if (get_tv_number_chk(rettv, &error) != 0) 3743 result = TRUE; 3744 clear_tv(rettv); 3745 if (error) 3746 return FAIL; 3747 first = FALSE; 3748 } 3749 3750 /* 3751 * Get the second variable. 3752 */ 3753 *arg = skipwhite(*arg + 2); 3754 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3755 return FAIL; 3756 3757 /* 3758 * Compute the result. 3759 */ 3760 if (evaluate && !result) 3761 { 3762 if (get_tv_number_chk(&var2, &error) != 0) 3763 result = TRUE; 3764 clear_tv(&var2); 3765 if (error) 3766 return FAIL; 3767 } 3768 if (evaluate) 3769 { 3770 rettv->v_type = VAR_NUMBER; 3771 rettv->vval.v_number = result; 3772 } 3773 } 3774 3775 return OK; 3776 } 3777 3778 /* 3779 * Handle second level expression: 3780 * expr3 && expr3 && expr3 logical AND 3781 * 3782 * "arg" must point to the first non-white of the expression. 3783 * "arg" is advanced to the next non-white after the recognized expression. 3784 * 3785 * Return OK or FAIL. 3786 */ 3787 static int 3788 eval3(arg, rettv, evaluate) 3789 char_u **arg; 3790 typval_T *rettv; 3791 int evaluate; 3792 { 3793 typval_T var2; 3794 long result; 3795 int first; 3796 int error = FALSE; 3797 3798 /* 3799 * Get the first variable. 3800 */ 3801 if (eval4(arg, rettv, evaluate) == FAIL) 3802 return FAIL; 3803 3804 /* 3805 * Repeat until there is no following "&&". 3806 */ 3807 first = TRUE; 3808 result = TRUE; 3809 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3810 { 3811 if (evaluate && first) 3812 { 3813 if (get_tv_number_chk(rettv, &error) == 0) 3814 result = FALSE; 3815 clear_tv(rettv); 3816 if (error) 3817 return FAIL; 3818 first = FALSE; 3819 } 3820 3821 /* 3822 * Get the second variable. 3823 */ 3824 *arg = skipwhite(*arg + 2); 3825 if (eval4(arg, &var2, evaluate && result) == FAIL) 3826 return FAIL; 3827 3828 /* 3829 * Compute the result. 3830 */ 3831 if (evaluate && result) 3832 { 3833 if (get_tv_number_chk(&var2, &error) == 0) 3834 result = FALSE; 3835 clear_tv(&var2); 3836 if (error) 3837 return FAIL; 3838 } 3839 if (evaluate) 3840 { 3841 rettv->v_type = VAR_NUMBER; 3842 rettv->vval.v_number = result; 3843 } 3844 } 3845 3846 return OK; 3847 } 3848 3849 /* 3850 * Handle third level expression: 3851 * var1 == var2 3852 * var1 =~ var2 3853 * var1 != var2 3854 * var1 !~ var2 3855 * var1 > var2 3856 * var1 >= var2 3857 * var1 < var2 3858 * var1 <= var2 3859 * var1 is var2 3860 * var1 isnot var2 3861 * 3862 * "arg" must point to the first non-white of the expression. 3863 * "arg" is advanced to the next non-white after the recognized expression. 3864 * 3865 * Return OK or FAIL. 3866 */ 3867 static int 3868 eval4(arg, rettv, evaluate) 3869 char_u **arg; 3870 typval_T *rettv; 3871 int evaluate; 3872 { 3873 typval_T var2; 3874 char_u *p; 3875 int i; 3876 exptype_T type = TYPE_UNKNOWN; 3877 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3878 int len = 2; 3879 long n1, n2; 3880 char_u *s1, *s2; 3881 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3882 regmatch_T regmatch; 3883 int ic; 3884 char_u *save_cpo; 3885 3886 /* 3887 * Get the first variable. 3888 */ 3889 if (eval5(arg, rettv, evaluate) == FAIL) 3890 return FAIL; 3891 3892 p = *arg; 3893 switch (p[0]) 3894 { 3895 case '=': if (p[1] == '=') 3896 type = TYPE_EQUAL; 3897 else if (p[1] == '~') 3898 type = TYPE_MATCH; 3899 break; 3900 case '!': if (p[1] == '=') 3901 type = TYPE_NEQUAL; 3902 else if (p[1] == '~') 3903 type = TYPE_NOMATCH; 3904 break; 3905 case '>': if (p[1] != '=') 3906 { 3907 type = TYPE_GREATER; 3908 len = 1; 3909 } 3910 else 3911 type = TYPE_GEQUAL; 3912 break; 3913 case '<': if (p[1] != '=') 3914 { 3915 type = TYPE_SMALLER; 3916 len = 1; 3917 } 3918 else 3919 type = TYPE_SEQUAL; 3920 break; 3921 case 'i': if (p[1] == 's') 3922 { 3923 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3924 len = 5; 3925 if (!vim_isIDc(p[len])) 3926 { 3927 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3928 type_is = TRUE; 3929 } 3930 } 3931 break; 3932 } 3933 3934 /* 3935 * If there is a comparitive operator, use it. 3936 */ 3937 if (type != TYPE_UNKNOWN) 3938 { 3939 /* extra question mark appended: ignore case */ 3940 if (p[len] == '?') 3941 { 3942 ic = TRUE; 3943 ++len; 3944 } 3945 /* extra '#' appended: match case */ 3946 else if (p[len] == '#') 3947 { 3948 ic = FALSE; 3949 ++len; 3950 } 3951 /* nothing appened: use 'ignorecase' */ 3952 else 3953 ic = p_ic; 3954 3955 /* 3956 * Get the second variable. 3957 */ 3958 *arg = skipwhite(p + len); 3959 if (eval5(arg, &var2, evaluate) == FAIL) 3960 { 3961 clear_tv(rettv); 3962 return FAIL; 3963 } 3964 3965 if (evaluate) 3966 { 3967 if (type_is && rettv->v_type != var2.v_type) 3968 { 3969 /* For "is" a different type always means FALSE, for "notis" 3970 * it means TRUE. */ 3971 n1 = (type == TYPE_NEQUAL); 3972 } 3973 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3974 { 3975 if (type_is) 3976 { 3977 n1 = (rettv->v_type == var2.v_type 3978 && rettv->vval.v_list == var2.vval.v_list); 3979 if (type == TYPE_NEQUAL) 3980 n1 = !n1; 3981 } 3982 else if (rettv->v_type != var2.v_type 3983 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3984 { 3985 if (rettv->v_type != var2.v_type) 3986 EMSG(_("E691: Can only compare List with List")); 3987 else 3988 EMSG(_("E692: Invalid operation for Lists")); 3989 clear_tv(rettv); 3990 clear_tv(&var2); 3991 return FAIL; 3992 } 3993 else 3994 { 3995 /* Compare two Lists for being equal or unequal. */ 3996 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3997 if (type == TYPE_NEQUAL) 3998 n1 = !n1; 3999 } 4000 } 4001 4002 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 4003 { 4004 if (type_is) 4005 { 4006 n1 = (rettv->v_type == var2.v_type 4007 && rettv->vval.v_dict == var2.vval.v_dict); 4008 if (type == TYPE_NEQUAL) 4009 n1 = !n1; 4010 } 4011 else if (rettv->v_type != var2.v_type 4012 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4013 { 4014 if (rettv->v_type != var2.v_type) 4015 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4016 else 4017 EMSG(_("E736: Invalid operation for Dictionary")); 4018 clear_tv(rettv); 4019 clear_tv(&var2); 4020 return FAIL; 4021 } 4022 else 4023 { 4024 /* Compare two Dictionaries for being equal or unequal. */ 4025 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4026 if (type == TYPE_NEQUAL) 4027 n1 = !n1; 4028 } 4029 } 4030 4031 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4032 { 4033 if (rettv->v_type != var2.v_type 4034 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4035 { 4036 if (rettv->v_type != var2.v_type) 4037 EMSG(_("E693: Can only compare Funcref with Funcref")); 4038 else 4039 EMSG(_("E694: Invalid operation for Funcrefs")); 4040 clear_tv(rettv); 4041 clear_tv(&var2); 4042 return FAIL; 4043 } 4044 else 4045 { 4046 /* Compare two Funcrefs for being equal or unequal. */ 4047 if (rettv->vval.v_string == NULL 4048 || var2.vval.v_string == NULL) 4049 n1 = FALSE; 4050 else 4051 n1 = STRCMP(rettv->vval.v_string, 4052 var2.vval.v_string) == 0; 4053 if (type == TYPE_NEQUAL) 4054 n1 = !n1; 4055 } 4056 } 4057 4058 /* 4059 * If one of the two variables is a number, compare as a number. 4060 * When using "=~" or "!~", always compare as string. 4061 */ 4062 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4063 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4064 { 4065 n1 = get_tv_number(rettv); 4066 n2 = get_tv_number(&var2); 4067 switch (type) 4068 { 4069 case TYPE_EQUAL: n1 = (n1 == n2); break; 4070 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4071 case TYPE_GREATER: n1 = (n1 > n2); break; 4072 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4073 case TYPE_SMALLER: n1 = (n1 < n2); break; 4074 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4075 case TYPE_UNKNOWN: 4076 case TYPE_MATCH: 4077 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4078 } 4079 } 4080 else 4081 { 4082 s1 = get_tv_string_buf(rettv, buf1); 4083 s2 = get_tv_string_buf(&var2, buf2); 4084 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4085 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4086 else 4087 i = 0; 4088 n1 = FALSE; 4089 switch (type) 4090 { 4091 case TYPE_EQUAL: n1 = (i == 0); break; 4092 case TYPE_NEQUAL: n1 = (i != 0); break; 4093 case TYPE_GREATER: n1 = (i > 0); break; 4094 case TYPE_GEQUAL: n1 = (i >= 0); break; 4095 case TYPE_SMALLER: n1 = (i < 0); break; 4096 case TYPE_SEQUAL: n1 = (i <= 0); break; 4097 4098 case TYPE_MATCH: 4099 case TYPE_NOMATCH: 4100 /* avoid 'l' flag in 'cpoptions' */ 4101 save_cpo = p_cpo; 4102 p_cpo = (char_u *)""; 4103 regmatch.regprog = vim_regcomp(s2, 4104 RE_MAGIC + RE_STRING); 4105 regmatch.rm_ic = ic; 4106 if (regmatch.regprog != NULL) 4107 { 4108 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4109 vim_free(regmatch.regprog); 4110 if (type == TYPE_NOMATCH) 4111 n1 = !n1; 4112 } 4113 p_cpo = save_cpo; 4114 break; 4115 4116 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4117 } 4118 } 4119 clear_tv(rettv); 4120 clear_tv(&var2); 4121 rettv->v_type = VAR_NUMBER; 4122 rettv->vval.v_number = n1; 4123 } 4124 } 4125 4126 return OK; 4127 } 4128 4129 /* 4130 * Handle fourth level expression: 4131 * + number addition 4132 * - number subtraction 4133 * . string concatenation 4134 * 4135 * "arg" must point to the first non-white of the expression. 4136 * "arg" is advanced to the next non-white after the recognized expression. 4137 * 4138 * Return OK or FAIL. 4139 */ 4140 static int 4141 eval5(arg, rettv, evaluate) 4142 char_u **arg; 4143 typval_T *rettv; 4144 int evaluate; 4145 { 4146 typval_T var2; 4147 typval_T var3; 4148 int op; 4149 long n1, n2; 4150 char_u *s1, *s2; 4151 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4152 char_u *p; 4153 4154 /* 4155 * Get the first variable. 4156 */ 4157 if (eval6(arg, rettv, evaluate) == FAIL) 4158 return FAIL; 4159 4160 /* 4161 * Repeat computing, until no '+', '-' or '.' is following. 4162 */ 4163 for (;;) 4164 { 4165 op = **arg; 4166 if (op != '+' && op != '-' && op != '.') 4167 break; 4168 4169 if (op != '+' || rettv->v_type != VAR_LIST) 4170 { 4171 /* For "list + ...", an illegal use of the first operand as 4172 * a number cannot be determined before evaluating the 2nd 4173 * operand: if this is also a list, all is ok. 4174 * For "something . ...", "something - ..." or "non-list + ...", 4175 * we know that the first operand needs to be a string or number 4176 * without evaluating the 2nd operand. So check before to avoid 4177 * side effects after an error. */ 4178 if (evaluate && get_tv_string_chk(rettv) == NULL) 4179 { 4180 clear_tv(rettv); 4181 return FAIL; 4182 } 4183 } 4184 4185 /* 4186 * Get the second variable. 4187 */ 4188 *arg = skipwhite(*arg + 1); 4189 if (eval6(arg, &var2, evaluate) == FAIL) 4190 { 4191 clear_tv(rettv); 4192 return FAIL; 4193 } 4194 4195 if (evaluate) 4196 { 4197 /* 4198 * Compute the result. 4199 */ 4200 if (op == '.') 4201 { 4202 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4203 s2 = get_tv_string_buf_chk(&var2, buf2); 4204 if (s2 == NULL) /* type error ? */ 4205 { 4206 clear_tv(rettv); 4207 clear_tv(&var2); 4208 return FAIL; 4209 } 4210 p = concat_str(s1, s2); 4211 clear_tv(rettv); 4212 rettv->v_type = VAR_STRING; 4213 rettv->vval.v_string = p; 4214 } 4215 else if (op == '+' && rettv->v_type == VAR_LIST 4216 && var2.v_type == VAR_LIST) 4217 { 4218 /* concatenate Lists */ 4219 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4220 &var3) == FAIL) 4221 { 4222 clear_tv(rettv); 4223 clear_tv(&var2); 4224 return FAIL; 4225 } 4226 clear_tv(rettv); 4227 *rettv = var3; 4228 } 4229 else 4230 { 4231 int error = FALSE; 4232 4233 n1 = get_tv_number_chk(rettv, &error); 4234 if (error) 4235 { 4236 /* This can only happen for "list + non-list". 4237 * For "non-list + ..." or "something - ...", we returned 4238 * before evaluating the 2nd operand. */ 4239 clear_tv(rettv); 4240 return FAIL; 4241 } 4242 n2 = get_tv_number_chk(&var2, &error); 4243 if (error) 4244 { 4245 clear_tv(rettv); 4246 clear_tv(&var2); 4247 return FAIL; 4248 } 4249 clear_tv(rettv); 4250 if (op == '+') 4251 n1 = n1 + n2; 4252 else 4253 n1 = n1 - n2; 4254 rettv->v_type = VAR_NUMBER; 4255 rettv->vval.v_number = n1; 4256 } 4257 clear_tv(&var2); 4258 } 4259 } 4260 return OK; 4261 } 4262 4263 /* 4264 * Handle fifth level expression: 4265 * * number multiplication 4266 * / number division 4267 * % number modulo 4268 * 4269 * "arg" must point to the first non-white of the expression. 4270 * "arg" is advanced to the next non-white after the recognized expression. 4271 * 4272 * Return OK or FAIL. 4273 */ 4274 static int 4275 eval6(arg, rettv, evaluate) 4276 char_u **arg; 4277 typval_T *rettv; 4278 int evaluate; 4279 { 4280 typval_T var2; 4281 int op; 4282 long n1, n2; 4283 int error = FALSE; 4284 4285 /* 4286 * Get the first variable. 4287 */ 4288 if (eval7(arg, rettv, evaluate) == FAIL) 4289 return FAIL; 4290 4291 /* 4292 * Repeat computing, until no '*', '/' or '%' is following. 4293 */ 4294 for (;;) 4295 { 4296 op = **arg; 4297 if (op != '*' && op != '/' && op != '%') 4298 break; 4299 4300 if (evaluate) 4301 { 4302 n1 = get_tv_number_chk(rettv, &error); 4303 clear_tv(rettv); 4304 if (error) 4305 return FAIL; 4306 } 4307 else 4308 n1 = 0; 4309 4310 /* 4311 * Get the second variable. 4312 */ 4313 *arg = skipwhite(*arg + 1); 4314 if (eval7(arg, &var2, evaluate) == FAIL) 4315 return FAIL; 4316 4317 if (evaluate) 4318 { 4319 n2 = get_tv_number_chk(&var2, &error); 4320 clear_tv(&var2); 4321 if (error) 4322 return FAIL; 4323 4324 /* 4325 * Compute the result. 4326 */ 4327 if (op == '*') 4328 n1 = n1 * n2; 4329 else if (op == '/') 4330 { 4331 if (n2 == 0) /* give an error message? */ 4332 n1 = 0x7fffffffL; 4333 else 4334 n1 = n1 / n2; 4335 } 4336 else 4337 { 4338 if (n2 == 0) /* give an error message? */ 4339 n1 = 0; 4340 else 4341 n1 = n1 % n2; 4342 } 4343 rettv->v_type = VAR_NUMBER; 4344 rettv->vval.v_number = n1; 4345 } 4346 } 4347 4348 return OK; 4349 } 4350 4351 /* 4352 * Handle sixth level expression: 4353 * number number constant 4354 * "string" string contstant 4355 * 'string' literal string contstant 4356 * &option-name option value 4357 * @r register contents 4358 * identifier variable value 4359 * function() function call 4360 * $VAR environment variable 4361 * (expression) nested expression 4362 * [expr, expr] List 4363 * {key: val, key: val} Dictionary 4364 * 4365 * Also handle: 4366 * ! in front logical NOT 4367 * - in front unary minus 4368 * + in front unary plus (ignored) 4369 * trailing [] subscript in String or List 4370 * trailing .name entry in Dictionary 4371 * 4372 * "arg" must point to the first non-white of the expression. 4373 * "arg" is advanced to the next non-white after the recognized expression. 4374 * 4375 * Return OK or FAIL. 4376 */ 4377 static int 4378 eval7(arg, rettv, evaluate) 4379 char_u **arg; 4380 typval_T *rettv; 4381 int evaluate; 4382 { 4383 long n; 4384 int len; 4385 char_u *s; 4386 int val; 4387 char_u *start_leader, *end_leader; 4388 int ret = OK; 4389 char_u *alias; 4390 4391 /* 4392 * Initialise variable so that clear_tv() can't mistake this for a 4393 * string and free a string that isn't there. 4394 */ 4395 rettv->v_type = VAR_UNKNOWN; 4396 4397 /* 4398 * Skip '!' and '-' characters. They are handled later. 4399 */ 4400 start_leader = *arg; 4401 while (**arg == '!' || **arg == '-' || **arg == '+') 4402 *arg = skipwhite(*arg + 1); 4403 end_leader = *arg; 4404 4405 switch (**arg) 4406 { 4407 /* 4408 * Number constant. 4409 */ 4410 case '0': 4411 case '1': 4412 case '2': 4413 case '3': 4414 case '4': 4415 case '5': 4416 case '6': 4417 case '7': 4418 case '8': 4419 case '9': 4420 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4421 *arg += len; 4422 if (evaluate) 4423 { 4424 rettv->v_type = VAR_NUMBER; 4425 rettv->vval.v_number = n; 4426 } 4427 break; 4428 4429 /* 4430 * String constant: "string". 4431 */ 4432 case '"': ret = get_string_tv(arg, rettv, evaluate); 4433 break; 4434 4435 /* 4436 * Literal string constant: 'str''ing'. 4437 */ 4438 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4439 break; 4440 4441 /* 4442 * List: [expr, expr] 4443 */ 4444 case '[': ret = get_list_tv(arg, rettv, evaluate); 4445 break; 4446 4447 /* 4448 * Dictionary: {key: val, key: val} 4449 */ 4450 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4451 break; 4452 4453 /* 4454 * Option value: &name 4455 */ 4456 case '&': ret = get_option_tv(arg, rettv, evaluate); 4457 break; 4458 4459 /* 4460 * Environment variable: $VAR. 4461 */ 4462 case '$': ret = get_env_tv(arg, rettv, evaluate); 4463 break; 4464 4465 /* 4466 * Register contents: @r. 4467 */ 4468 case '@': ++*arg; 4469 if (evaluate) 4470 { 4471 rettv->v_type = VAR_STRING; 4472 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4473 } 4474 if (**arg != NUL) 4475 ++*arg; 4476 break; 4477 4478 /* 4479 * nested expression: (expression). 4480 */ 4481 case '(': *arg = skipwhite(*arg + 1); 4482 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4483 if (**arg == ')') 4484 ++*arg; 4485 else if (ret == OK) 4486 { 4487 EMSG(_("E110: Missing ')'")); 4488 clear_tv(rettv); 4489 ret = FAIL; 4490 } 4491 break; 4492 4493 default: ret = NOTDONE; 4494 break; 4495 } 4496 4497 if (ret == NOTDONE) 4498 { 4499 /* 4500 * Must be a variable or function name. 4501 * Can also be a curly-braces kind of name: {expr}. 4502 */ 4503 s = *arg; 4504 len = get_name_len(arg, &alias, evaluate, TRUE); 4505 if (alias != NULL) 4506 s = alias; 4507 4508 if (len <= 0) 4509 ret = FAIL; 4510 else 4511 { 4512 if (**arg == '(') /* recursive! */ 4513 { 4514 /* If "s" is the name of a variable of type VAR_FUNC 4515 * use its contents. */ 4516 s = deref_func_name(s, &len); 4517 4518 /* Invoke the function. */ 4519 ret = get_func_tv(s, len, rettv, arg, 4520 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4521 &len, evaluate, NULL); 4522 /* Stop the expression evaluation when immediately 4523 * aborting on error, or when an interrupt occurred or 4524 * an exception was thrown but not caught. */ 4525 if (aborting()) 4526 { 4527 if (ret == OK) 4528 clear_tv(rettv); 4529 ret = FAIL; 4530 } 4531 } 4532 else if (evaluate) 4533 ret = get_var_tv(s, len, rettv, TRUE); 4534 else 4535 ret = OK; 4536 } 4537 4538 if (alias != NULL) 4539 vim_free(alias); 4540 } 4541 4542 *arg = skipwhite(*arg); 4543 4544 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4545 * expr(expr). */ 4546 if (ret == OK) 4547 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4548 4549 /* 4550 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4551 */ 4552 if (ret == OK && evaluate && end_leader > start_leader) 4553 { 4554 int error = FALSE; 4555 4556 val = get_tv_number_chk(rettv, &error); 4557 if (error) 4558 { 4559 clear_tv(rettv); 4560 ret = FAIL; 4561 } 4562 else 4563 { 4564 while (end_leader > start_leader) 4565 { 4566 --end_leader; 4567 if (*end_leader == '!') 4568 val = !val; 4569 else if (*end_leader == '-') 4570 val = -val; 4571 } 4572 clear_tv(rettv); 4573 rettv->v_type = VAR_NUMBER; 4574 rettv->vval.v_number = val; 4575 } 4576 } 4577 4578 return ret; 4579 } 4580 4581 /* 4582 * Evaluate an "[expr]" or "[expr:expr]" index. 4583 * "*arg" points to the '['. 4584 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4585 */ 4586 static int 4587 eval_index(arg, rettv, evaluate, verbose) 4588 char_u **arg; 4589 typval_T *rettv; 4590 int evaluate; 4591 int verbose; /* give error messages */ 4592 { 4593 int empty1 = FALSE, empty2 = FALSE; 4594 typval_T var1, var2; 4595 long n1, n2 = 0; 4596 long len = -1; 4597 int range = FALSE; 4598 char_u *s; 4599 char_u *key = NULL; 4600 4601 if (rettv->v_type == VAR_FUNC) 4602 { 4603 if (verbose) 4604 EMSG(_("E695: Cannot index a Funcref")); 4605 return FAIL; 4606 } 4607 4608 if (**arg == '.') 4609 { 4610 /* 4611 * dict.name 4612 */ 4613 key = *arg + 1; 4614 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4615 ; 4616 if (len == 0) 4617 return FAIL; 4618 *arg = skipwhite(key + len); 4619 } 4620 else 4621 { 4622 /* 4623 * something[idx] 4624 * 4625 * Get the (first) variable from inside the []. 4626 */ 4627 *arg = skipwhite(*arg + 1); 4628 if (**arg == ':') 4629 empty1 = TRUE; 4630 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4631 return FAIL; 4632 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4633 { 4634 /* not a number or string */ 4635 clear_tv(&var1); 4636 return FAIL; 4637 } 4638 4639 /* 4640 * Get the second variable from inside the [:]. 4641 */ 4642 if (**arg == ':') 4643 { 4644 range = TRUE; 4645 *arg = skipwhite(*arg + 1); 4646 if (**arg == ']') 4647 empty2 = TRUE; 4648 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4649 { 4650 if (!empty1) 4651 clear_tv(&var1); 4652 return FAIL; 4653 } 4654 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4655 { 4656 /* not a number or string */ 4657 if (!empty1) 4658 clear_tv(&var1); 4659 clear_tv(&var2); 4660 return FAIL; 4661 } 4662 } 4663 4664 /* Check for the ']'. */ 4665 if (**arg != ']') 4666 { 4667 if (verbose) 4668 EMSG(_(e_missbrac)); 4669 clear_tv(&var1); 4670 if (range) 4671 clear_tv(&var2); 4672 return FAIL; 4673 } 4674 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4675 } 4676 4677 if (evaluate) 4678 { 4679 n1 = 0; 4680 if (!empty1 && rettv->v_type != VAR_DICT) 4681 { 4682 n1 = get_tv_number(&var1); 4683 clear_tv(&var1); 4684 } 4685 if (range) 4686 { 4687 if (empty2) 4688 n2 = -1; 4689 else 4690 { 4691 n2 = get_tv_number(&var2); 4692 clear_tv(&var2); 4693 } 4694 } 4695 4696 switch (rettv->v_type) 4697 { 4698 case VAR_NUMBER: 4699 case VAR_STRING: 4700 s = get_tv_string(rettv); 4701 len = (long)STRLEN(s); 4702 if (range) 4703 { 4704 /* The resulting variable is a substring. If the indexes 4705 * are out of range the result is empty. */ 4706 if (n1 < 0) 4707 { 4708 n1 = len + n1; 4709 if (n1 < 0) 4710 n1 = 0; 4711 } 4712 if (n2 < 0) 4713 n2 = len + n2; 4714 else if (n2 >= len) 4715 n2 = len; 4716 if (n1 >= len || n2 < 0 || n1 > n2) 4717 s = NULL; 4718 else 4719 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4720 } 4721 else 4722 { 4723 /* The resulting variable is a string of a single 4724 * character. If the index is too big or negative the 4725 * result is empty. */ 4726 if (n1 >= len || n1 < 0) 4727 s = NULL; 4728 else 4729 s = vim_strnsave(s + n1, 1); 4730 } 4731 clear_tv(rettv); 4732 rettv->v_type = VAR_STRING; 4733 rettv->vval.v_string = s; 4734 break; 4735 4736 case VAR_LIST: 4737 len = list_len(rettv->vval.v_list); 4738 if (n1 < 0) 4739 n1 = len + n1; 4740 if (!empty1 && (n1 < 0 || n1 >= len)) 4741 { 4742 if (verbose) 4743 EMSGN(_(e_listidx), n1); 4744 return FAIL; 4745 } 4746 if (range) 4747 { 4748 list_T *l; 4749 listitem_T *item; 4750 4751 if (n2 < 0) 4752 n2 = len + n2; 4753 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4754 { 4755 if (verbose) 4756 EMSGN(_(e_listidx), n2); 4757 return FAIL; 4758 } 4759 l = list_alloc(); 4760 if (l == NULL) 4761 return FAIL; 4762 for (item = list_find(rettv->vval.v_list, n1); 4763 n1 <= n2; ++n1) 4764 { 4765 if (list_append_tv(l, &item->li_tv) == FAIL) 4766 { 4767 list_free(l); 4768 return FAIL; 4769 } 4770 item = item->li_next; 4771 } 4772 clear_tv(rettv); 4773 rettv->v_type = VAR_LIST; 4774 rettv->vval.v_list = l; 4775 ++l->lv_refcount; 4776 } 4777 else 4778 { 4779 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4780 &var1); 4781 clear_tv(rettv); 4782 *rettv = var1; 4783 } 4784 break; 4785 4786 case VAR_DICT: 4787 if (range) 4788 { 4789 if (verbose) 4790 EMSG(_(e_dictrange)); 4791 if (len == -1) 4792 clear_tv(&var1); 4793 return FAIL; 4794 } 4795 { 4796 dictitem_T *item; 4797 4798 if (len == -1) 4799 { 4800 key = get_tv_string(&var1); 4801 if (*key == NUL) 4802 { 4803 if (verbose) 4804 EMSG(_(e_emptykey)); 4805 clear_tv(&var1); 4806 return FAIL; 4807 } 4808 } 4809 4810 item = dict_find(rettv->vval.v_dict, key, (int)len); 4811 4812 if (item == NULL && verbose) 4813 EMSG2(_(e_dictkey), key); 4814 if (len == -1) 4815 clear_tv(&var1); 4816 if (item == NULL) 4817 return FAIL; 4818 4819 copy_tv(&item->di_tv, &var1); 4820 clear_tv(rettv); 4821 *rettv = var1; 4822 } 4823 break; 4824 } 4825 } 4826 4827 return OK; 4828 } 4829 4830 /* 4831 * Get an option value. 4832 * "arg" points to the '&' or '+' before the option name. 4833 * "arg" is advanced to character after the option name. 4834 * Return OK or FAIL. 4835 */ 4836 static int 4837 get_option_tv(arg, rettv, evaluate) 4838 char_u **arg; 4839 typval_T *rettv; /* when NULL, only check if option exists */ 4840 int evaluate; 4841 { 4842 char_u *option_end; 4843 long numval; 4844 char_u *stringval; 4845 int opt_type; 4846 int c; 4847 int working = (**arg == '+'); /* has("+option") */ 4848 int ret = OK; 4849 int opt_flags; 4850 4851 /* 4852 * Isolate the option name and find its value. 4853 */ 4854 option_end = find_option_end(arg, &opt_flags); 4855 if (option_end == NULL) 4856 { 4857 if (rettv != NULL) 4858 EMSG2(_("E112: Option name missing: %s"), *arg); 4859 return FAIL; 4860 } 4861 4862 if (!evaluate) 4863 { 4864 *arg = option_end; 4865 return OK; 4866 } 4867 4868 c = *option_end; 4869 *option_end = NUL; 4870 opt_type = get_option_value(*arg, &numval, 4871 rettv == NULL ? NULL : &stringval, opt_flags); 4872 4873 if (opt_type == -3) /* invalid name */ 4874 { 4875 if (rettv != NULL) 4876 EMSG2(_("E113: Unknown option: %s"), *arg); 4877 ret = FAIL; 4878 } 4879 else if (rettv != NULL) 4880 { 4881 if (opt_type == -2) /* hidden string option */ 4882 { 4883 rettv->v_type = VAR_STRING; 4884 rettv->vval.v_string = NULL; 4885 } 4886 else if (opt_type == -1) /* hidden number option */ 4887 { 4888 rettv->v_type = VAR_NUMBER; 4889 rettv->vval.v_number = 0; 4890 } 4891 else if (opt_type == 1) /* number option */ 4892 { 4893 rettv->v_type = VAR_NUMBER; 4894 rettv->vval.v_number = numval; 4895 } 4896 else /* string option */ 4897 { 4898 rettv->v_type = VAR_STRING; 4899 rettv->vval.v_string = stringval; 4900 } 4901 } 4902 else if (working && (opt_type == -2 || opt_type == -1)) 4903 ret = FAIL; 4904 4905 *option_end = c; /* put back for error messages */ 4906 *arg = option_end; 4907 4908 return ret; 4909 } 4910 4911 /* 4912 * Allocate a variable for a string constant. 4913 * Return OK or FAIL. 4914 */ 4915 static int 4916 get_string_tv(arg, rettv, evaluate) 4917 char_u **arg; 4918 typval_T *rettv; 4919 int evaluate; 4920 { 4921 char_u *p; 4922 char_u *name; 4923 int extra = 0; 4924 4925 /* 4926 * Find the end of the string, skipping backslashed characters. 4927 */ 4928 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4929 { 4930 if (*p == '\\' && p[1] != NUL) 4931 { 4932 ++p; 4933 /* A "\<x>" form occupies at least 4 characters, and produces up 4934 * to 6 characters: reserve space for 2 extra */ 4935 if (*p == '<') 4936 extra += 2; 4937 } 4938 } 4939 4940 if (*p != '"') 4941 { 4942 EMSG2(_("E114: Missing quote: %s"), *arg); 4943 return FAIL; 4944 } 4945 4946 /* If only parsing, set *arg and return here */ 4947 if (!evaluate) 4948 { 4949 *arg = p + 1; 4950 return OK; 4951 } 4952 4953 /* 4954 * Copy the string into allocated memory, handling backslashed 4955 * characters. 4956 */ 4957 name = alloc((unsigned)(p - *arg + extra)); 4958 if (name == NULL) 4959 return FAIL; 4960 rettv->v_type = VAR_STRING; 4961 rettv->vval.v_string = name; 4962 4963 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4964 { 4965 if (*p == '\\') 4966 { 4967 switch (*++p) 4968 { 4969 case 'b': *name++ = BS; ++p; break; 4970 case 'e': *name++ = ESC; ++p; break; 4971 case 'f': *name++ = FF; ++p; break; 4972 case 'n': *name++ = NL; ++p; break; 4973 case 'r': *name++ = CAR; ++p; break; 4974 case 't': *name++ = TAB; ++p; break; 4975 4976 case 'X': /* hex: "\x1", "\x12" */ 4977 case 'x': 4978 case 'u': /* Unicode: "\u0023" */ 4979 case 'U': 4980 if (vim_isxdigit(p[1])) 4981 { 4982 int n, nr; 4983 int c = toupper(*p); 4984 4985 if (c == 'X') 4986 n = 2; 4987 else 4988 n = 4; 4989 nr = 0; 4990 while (--n >= 0 && vim_isxdigit(p[1])) 4991 { 4992 ++p; 4993 nr = (nr << 4) + hex2nr(*p); 4994 } 4995 ++p; 4996 #ifdef FEAT_MBYTE 4997 /* For "\u" store the number according to 4998 * 'encoding'. */ 4999 if (c != 'X') 5000 name += (*mb_char2bytes)(nr, name); 5001 else 5002 #endif 5003 *name++ = nr; 5004 } 5005 break; 5006 5007 /* octal: "\1", "\12", "\123" */ 5008 case '0': 5009 case '1': 5010 case '2': 5011 case '3': 5012 case '4': 5013 case '5': 5014 case '6': 5015 case '7': *name = *p++ - '0'; 5016 if (*p >= '0' && *p <= '7') 5017 { 5018 *name = (*name << 3) + *p++ - '0'; 5019 if (*p >= '0' && *p <= '7') 5020 *name = (*name << 3) + *p++ - '0'; 5021 } 5022 ++name; 5023 break; 5024 5025 /* Special key, e.g.: "\<C-W>" */ 5026 case '<': extra = trans_special(&p, name, TRUE); 5027 if (extra != 0) 5028 { 5029 name += extra; 5030 break; 5031 } 5032 /* FALLTHROUGH */ 5033 5034 default: MB_COPY_CHAR(p, name); 5035 break; 5036 } 5037 } 5038 else 5039 MB_COPY_CHAR(p, name); 5040 5041 } 5042 *name = NUL; 5043 *arg = p + 1; 5044 5045 return OK; 5046 } 5047 5048 /* 5049 * Allocate a variable for a 'str''ing' constant. 5050 * Return OK or FAIL. 5051 */ 5052 static int 5053 get_lit_string_tv(arg, rettv, evaluate) 5054 char_u **arg; 5055 typval_T *rettv; 5056 int evaluate; 5057 { 5058 char_u *p; 5059 char_u *str; 5060 int reduce = 0; 5061 5062 /* 5063 * Find the end of the string, skipping ''. 5064 */ 5065 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5066 { 5067 if (*p == '\'') 5068 { 5069 if (p[1] != '\'') 5070 break; 5071 ++reduce; 5072 ++p; 5073 } 5074 } 5075 5076 if (*p != '\'') 5077 { 5078 EMSG2(_("E115: Missing quote: %s"), *arg); 5079 return FAIL; 5080 } 5081 5082 /* If only parsing return after setting "*arg" */ 5083 if (!evaluate) 5084 { 5085 *arg = p + 1; 5086 return OK; 5087 } 5088 5089 /* 5090 * Copy the string into allocated memory, handling '' to ' reduction. 5091 */ 5092 str = alloc((unsigned)((p - *arg) - reduce)); 5093 if (str == NULL) 5094 return FAIL; 5095 rettv->v_type = VAR_STRING; 5096 rettv->vval.v_string = str; 5097 5098 for (p = *arg + 1; *p != NUL; ) 5099 { 5100 if (*p == '\'') 5101 { 5102 if (p[1] != '\'') 5103 break; 5104 ++p; 5105 } 5106 MB_COPY_CHAR(p, str); 5107 } 5108 *str = NUL; 5109 *arg = p + 1; 5110 5111 return OK; 5112 } 5113 5114 /* 5115 * Allocate a variable for a List and fill it from "*arg". 5116 * Return OK or FAIL. 5117 */ 5118 static int 5119 get_list_tv(arg, rettv, evaluate) 5120 char_u **arg; 5121 typval_T *rettv; 5122 int evaluate; 5123 { 5124 list_T *l = NULL; 5125 typval_T tv; 5126 listitem_T *item; 5127 5128 if (evaluate) 5129 { 5130 l = list_alloc(); 5131 if (l == NULL) 5132 return FAIL; 5133 } 5134 5135 *arg = skipwhite(*arg + 1); 5136 while (**arg != ']' && **arg != NUL) 5137 { 5138 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5139 goto failret; 5140 if (evaluate) 5141 { 5142 item = listitem_alloc(); 5143 if (item != NULL) 5144 { 5145 item->li_tv = tv; 5146 item->li_tv.v_lock = 0; 5147 list_append(l, item); 5148 } 5149 else 5150 clear_tv(&tv); 5151 } 5152 5153 if (**arg == ']') 5154 break; 5155 if (**arg != ',') 5156 { 5157 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5158 goto failret; 5159 } 5160 *arg = skipwhite(*arg + 1); 5161 } 5162 5163 if (**arg != ']') 5164 { 5165 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5166 failret: 5167 if (evaluate) 5168 list_free(l); 5169 return FAIL; 5170 } 5171 5172 *arg = skipwhite(*arg + 1); 5173 if (evaluate) 5174 { 5175 rettv->v_type = VAR_LIST; 5176 rettv->vval.v_list = l; 5177 ++l->lv_refcount; 5178 } 5179 5180 return OK; 5181 } 5182 5183 /* 5184 * Allocate an empty header for a list. 5185 * Caller should take care of the reference count. 5186 */ 5187 static list_T * 5188 list_alloc() 5189 { 5190 list_T *l; 5191 5192 l = (list_T *)alloc_clear(sizeof(list_T)); 5193 if (l != NULL) 5194 { 5195 /* Prepend the list to the list of lists for garbage collection. */ 5196 if (first_list != NULL) 5197 first_list->lv_used_prev = l; 5198 l->lv_used_prev = NULL; 5199 l->lv_used_next = first_list; 5200 first_list = l; 5201 } 5202 return l; 5203 } 5204 5205 /* 5206 * Unreference a list: decrement the reference count and free it when it 5207 * becomes zero. 5208 */ 5209 void 5210 list_unref(l) 5211 list_T *l; 5212 { 5213 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5214 list_free(l); 5215 } 5216 5217 /* 5218 * Free a list, including all items it points to. 5219 * Ignores the reference count. 5220 */ 5221 static void 5222 list_free(l) 5223 list_T *l; 5224 { 5225 listitem_T *item; 5226 5227 /* Avoid that recursive reference to the list frees us again. */ 5228 l->lv_refcount = DEL_REFCOUNT; 5229 5230 /* Remove the list from the list of lists for garbage collection. */ 5231 if (l->lv_used_prev == NULL) 5232 first_list = l->lv_used_next; 5233 else 5234 l->lv_used_prev->lv_used_next = l->lv_used_next; 5235 if (l->lv_used_next != NULL) 5236 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5237 5238 for (item = l->lv_first; item != NULL; item = l->lv_first) 5239 { 5240 /* Remove the item before deleting it. */ 5241 l->lv_first = item->li_next; 5242 listitem_free(item); 5243 } 5244 vim_free(l); 5245 } 5246 5247 /* 5248 * Allocate a list item. 5249 */ 5250 static listitem_T * 5251 listitem_alloc() 5252 { 5253 return (listitem_T *)alloc(sizeof(listitem_T)); 5254 } 5255 5256 /* 5257 * Free a list item. Also clears the value. Does not notify watchers. 5258 */ 5259 static void 5260 listitem_free(item) 5261 listitem_T *item; 5262 { 5263 clear_tv(&item->li_tv); 5264 vim_free(item); 5265 } 5266 5267 /* 5268 * Remove a list item from a List and free it. Also clears the value. 5269 */ 5270 static void 5271 listitem_remove(l, item) 5272 list_T *l; 5273 listitem_T *item; 5274 { 5275 list_remove(l, item, item); 5276 listitem_free(item); 5277 } 5278 5279 /* 5280 * Get the number of items in a list. 5281 */ 5282 static long 5283 list_len(l) 5284 list_T *l; 5285 { 5286 if (l == NULL) 5287 return 0L; 5288 return l->lv_len; 5289 } 5290 5291 /* 5292 * Return TRUE when two lists have exactly the same values. 5293 */ 5294 static int 5295 list_equal(l1, l2, ic) 5296 list_T *l1; 5297 list_T *l2; 5298 int ic; /* ignore case for strings */ 5299 { 5300 listitem_T *item1, *item2; 5301 5302 if (list_len(l1) != list_len(l2)) 5303 return FALSE; 5304 5305 for (item1 = l1->lv_first, item2 = l2->lv_first; 5306 item1 != NULL && item2 != NULL; 5307 item1 = item1->li_next, item2 = item2->li_next) 5308 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5309 return FALSE; 5310 return item1 == NULL && item2 == NULL; 5311 } 5312 5313 /* 5314 * Return TRUE when two dictionaries have exactly the same key/values. 5315 */ 5316 static int 5317 dict_equal(d1, d2, ic) 5318 dict_T *d1; 5319 dict_T *d2; 5320 int ic; /* ignore case for strings */ 5321 { 5322 hashitem_T *hi; 5323 dictitem_T *item2; 5324 int todo; 5325 5326 if (dict_len(d1) != dict_len(d2)) 5327 return FALSE; 5328 5329 todo = d1->dv_hashtab.ht_used; 5330 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5331 { 5332 if (!HASHITEM_EMPTY(hi)) 5333 { 5334 item2 = dict_find(d2, hi->hi_key, -1); 5335 if (item2 == NULL) 5336 return FALSE; 5337 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5338 return FALSE; 5339 --todo; 5340 } 5341 } 5342 return TRUE; 5343 } 5344 5345 /* 5346 * Return TRUE if "tv1" and "tv2" have the same value. 5347 * Compares the items just like "==" would compare them, but strings and 5348 * numbers are different. 5349 */ 5350 static int 5351 tv_equal(tv1, tv2, ic) 5352 typval_T *tv1; 5353 typval_T *tv2; 5354 int ic; /* ignore case */ 5355 { 5356 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5357 char_u *s1, *s2; 5358 5359 if (tv1->v_type != tv2->v_type) 5360 return FALSE; 5361 5362 switch (tv1->v_type) 5363 { 5364 case VAR_LIST: 5365 /* recursive! */ 5366 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5367 5368 case VAR_DICT: 5369 /* recursive! */ 5370 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5371 5372 case VAR_FUNC: 5373 return (tv1->vval.v_string != NULL 5374 && tv2->vval.v_string != NULL 5375 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5376 5377 case VAR_NUMBER: 5378 return tv1->vval.v_number == tv2->vval.v_number; 5379 5380 case VAR_STRING: 5381 s1 = get_tv_string_buf(tv1, buf1); 5382 s2 = get_tv_string_buf(tv2, buf2); 5383 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5384 } 5385 5386 EMSG2(_(e_intern2), "tv_equal()"); 5387 return TRUE; 5388 } 5389 5390 /* 5391 * Locate item with index "n" in list "l" and return it. 5392 * A negative index is counted from the end; -1 is the last item. 5393 * Returns NULL when "n" is out of range. 5394 */ 5395 static listitem_T * 5396 list_find(l, n) 5397 list_T *l; 5398 long n; 5399 { 5400 listitem_T *item; 5401 long idx; 5402 5403 if (l == NULL) 5404 return NULL; 5405 5406 /* Negative index is relative to the end. */ 5407 if (n < 0) 5408 n = l->lv_len + n; 5409 5410 /* Check for index out of range. */ 5411 if (n < 0 || n >= l->lv_len) 5412 return NULL; 5413 5414 /* When there is a cached index may start search from there. */ 5415 if (l->lv_idx_item != NULL) 5416 { 5417 if (n < l->lv_idx / 2) 5418 { 5419 /* closest to the start of the list */ 5420 item = l->lv_first; 5421 idx = 0; 5422 } 5423 else if (n > (l->lv_idx + l->lv_len) / 2) 5424 { 5425 /* closest to the end of the list */ 5426 item = l->lv_last; 5427 idx = l->lv_len - 1; 5428 } 5429 else 5430 { 5431 /* closest to the cached index */ 5432 item = l->lv_idx_item; 5433 idx = l->lv_idx; 5434 } 5435 } 5436 else 5437 { 5438 if (n < l->lv_len / 2) 5439 { 5440 /* closest to the start of the list */ 5441 item = l->lv_first; 5442 idx = 0; 5443 } 5444 else 5445 { 5446 /* closest to the end of the list */ 5447 item = l->lv_last; 5448 idx = l->lv_len - 1; 5449 } 5450 } 5451 5452 while (n > idx) 5453 { 5454 /* search forward */ 5455 item = item->li_next; 5456 ++idx; 5457 } 5458 while (n < idx) 5459 { 5460 /* search backward */ 5461 item = item->li_prev; 5462 --idx; 5463 } 5464 5465 /* cache the used index */ 5466 l->lv_idx = idx; 5467 l->lv_idx_item = item; 5468 5469 return item; 5470 } 5471 5472 /* 5473 * Locate "item" list "l" and return its index. 5474 * Returns -1 when "item" is not in the list. 5475 */ 5476 static long 5477 list_idx_of_item(l, item) 5478 list_T *l; 5479 listitem_T *item; 5480 { 5481 long idx = 0; 5482 listitem_T *li; 5483 5484 if (l == NULL) 5485 return -1; 5486 idx = 0; 5487 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5488 ++idx; 5489 if (li == NULL) 5490 return -1; 5491 return idx; 5492 } 5493 5494 /* 5495 * Append item "item" to the end of list "l". 5496 */ 5497 static void 5498 list_append(l, item) 5499 list_T *l; 5500 listitem_T *item; 5501 { 5502 if (l->lv_last == NULL) 5503 { 5504 /* empty list */ 5505 l->lv_first = item; 5506 l->lv_last = item; 5507 item->li_prev = NULL; 5508 } 5509 else 5510 { 5511 l->lv_last->li_next = item; 5512 item->li_prev = l->lv_last; 5513 l->lv_last = item; 5514 } 5515 ++l->lv_len; 5516 item->li_next = NULL; 5517 } 5518 5519 /* 5520 * Append typval_T "tv" to the end of list "l". 5521 * Return FAIL when out of memory. 5522 */ 5523 static int 5524 list_append_tv(l, tv) 5525 list_T *l; 5526 typval_T *tv; 5527 { 5528 listitem_T *li = listitem_alloc(); 5529 5530 if (li == NULL) 5531 return FAIL; 5532 copy_tv(tv, &li->li_tv); 5533 list_append(l, li); 5534 return OK; 5535 } 5536 5537 /* 5538 * Add a dictionary to a list. Used by getqflist(). 5539 * Return FAIL when out of memory. 5540 */ 5541 int 5542 list_append_dict(list, dict) 5543 list_T *list; 5544 dict_T *dict; 5545 { 5546 listitem_T *li = listitem_alloc(); 5547 5548 if (li == NULL) 5549 return FAIL; 5550 li->li_tv.v_type = VAR_DICT; 5551 li->li_tv.v_lock = 0; 5552 li->li_tv.vval.v_dict = dict; 5553 list_append(list, li); 5554 ++dict->dv_refcount; 5555 return OK; 5556 } 5557 5558 /* 5559 * Make a copy of "str" and append it as an item to list "l". 5560 * Returns FAIL when out of memory. 5561 */ 5562 static int 5563 list_append_string(l, str) 5564 list_T *l; 5565 char_u *str; 5566 { 5567 listitem_T *li = listitem_alloc(); 5568 5569 if (li == NULL) 5570 return FAIL; 5571 list_append(l, li); 5572 li->li_tv.v_type = VAR_STRING; 5573 li->li_tv.v_lock = 0; 5574 if ((li->li_tv.vval.v_string = vim_strsave(str)) == NULL) 5575 return FAIL; 5576 return OK; 5577 } 5578 5579 /* 5580 * Insert typval_T "tv" in list "l" before "item". 5581 * If "item" is NULL append at the end. 5582 * Return FAIL when out of memory. 5583 */ 5584 static int 5585 list_insert_tv(l, tv, item) 5586 list_T *l; 5587 typval_T *tv; 5588 listitem_T *item; 5589 { 5590 listitem_T *ni = listitem_alloc(); 5591 5592 if (ni == NULL) 5593 return FAIL; 5594 copy_tv(tv, &ni->li_tv); 5595 if (item == NULL) 5596 /* Append new item at end of list. */ 5597 list_append(l, ni); 5598 else 5599 { 5600 /* Insert new item before existing item. */ 5601 ni->li_prev = item->li_prev; 5602 ni->li_next = item; 5603 if (item->li_prev == NULL) 5604 { 5605 l->lv_first = ni; 5606 ++l->lv_idx; 5607 } 5608 else 5609 { 5610 item->li_prev->li_next = ni; 5611 l->lv_idx_item = NULL; 5612 } 5613 item->li_prev = ni; 5614 ++l->lv_len; 5615 } 5616 return OK; 5617 } 5618 5619 /* 5620 * Extend "l1" with "l2". 5621 * If "bef" is NULL append at the end, otherwise insert before this item. 5622 * Returns FAIL when out of memory. 5623 */ 5624 static int 5625 list_extend(l1, l2, bef) 5626 list_T *l1; 5627 list_T *l2; 5628 listitem_T *bef; 5629 { 5630 listitem_T *item; 5631 5632 for (item = l2->lv_first; item != NULL; item = item->li_next) 5633 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5634 return FAIL; 5635 return OK; 5636 } 5637 5638 /* 5639 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5640 * Return FAIL when out of memory. 5641 */ 5642 static int 5643 list_concat(l1, l2, tv) 5644 list_T *l1; 5645 list_T *l2; 5646 typval_T *tv; 5647 { 5648 list_T *l; 5649 5650 /* make a copy of the first list. */ 5651 l = list_copy(l1, FALSE, 0); 5652 if (l == NULL) 5653 return FAIL; 5654 tv->v_type = VAR_LIST; 5655 tv->vval.v_list = l; 5656 5657 /* append all items from the second list */ 5658 return list_extend(l, l2, NULL); 5659 } 5660 5661 /* 5662 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5663 * The refcount of the new list is set to 1. 5664 * See item_copy() for "copyID". 5665 * Returns NULL when out of memory. 5666 */ 5667 static list_T * 5668 list_copy(orig, deep, copyID) 5669 list_T *orig; 5670 int deep; 5671 int copyID; 5672 { 5673 list_T *copy; 5674 listitem_T *item; 5675 listitem_T *ni; 5676 5677 if (orig == NULL) 5678 return NULL; 5679 5680 copy = list_alloc(); 5681 if (copy != NULL) 5682 { 5683 if (copyID != 0) 5684 { 5685 /* Do this before adding the items, because one of the items may 5686 * refer back to this list. */ 5687 orig->lv_copyID = copyID; 5688 orig->lv_copylist = copy; 5689 } 5690 for (item = orig->lv_first; item != NULL && !got_int; 5691 item = item->li_next) 5692 { 5693 ni = listitem_alloc(); 5694 if (ni == NULL) 5695 break; 5696 if (deep) 5697 { 5698 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5699 { 5700 vim_free(ni); 5701 break; 5702 } 5703 } 5704 else 5705 copy_tv(&item->li_tv, &ni->li_tv); 5706 list_append(copy, ni); 5707 } 5708 ++copy->lv_refcount; 5709 if (item != NULL) 5710 { 5711 list_unref(copy); 5712 copy = NULL; 5713 } 5714 } 5715 5716 return copy; 5717 } 5718 5719 /* 5720 * Remove items "item" to "item2" from list "l". 5721 * Does not free the listitem or the value! 5722 */ 5723 static void 5724 list_remove(l, item, item2) 5725 list_T *l; 5726 listitem_T *item; 5727 listitem_T *item2; 5728 { 5729 listitem_T *ip; 5730 5731 /* notify watchers */ 5732 for (ip = item; ip != NULL; ip = ip->li_next) 5733 { 5734 --l->lv_len; 5735 list_fix_watch(l, ip); 5736 if (ip == item2) 5737 break; 5738 } 5739 5740 if (item2->li_next == NULL) 5741 l->lv_last = item->li_prev; 5742 else 5743 item2->li_next->li_prev = item->li_prev; 5744 if (item->li_prev == NULL) 5745 l->lv_first = item2->li_next; 5746 else 5747 item->li_prev->li_next = item2->li_next; 5748 l->lv_idx_item = NULL; 5749 } 5750 5751 /* 5752 * Return an allocated string with the string representation of a list. 5753 * May return NULL. 5754 */ 5755 static char_u * 5756 list2string(tv) 5757 typval_T *tv; 5758 { 5759 garray_T ga; 5760 5761 if (tv->vval.v_list == NULL) 5762 return NULL; 5763 ga_init2(&ga, (int)sizeof(char), 80); 5764 ga_append(&ga, '['); 5765 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5766 { 5767 vim_free(ga.ga_data); 5768 return NULL; 5769 } 5770 ga_append(&ga, ']'); 5771 ga_append(&ga, NUL); 5772 return (char_u *)ga.ga_data; 5773 } 5774 5775 /* 5776 * Join list "l" into a string in "*gap", using separator "sep". 5777 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5778 * Return FAIL or OK. 5779 */ 5780 static int 5781 list_join(gap, l, sep, echo) 5782 garray_T *gap; 5783 list_T *l; 5784 char_u *sep; 5785 int echo; 5786 { 5787 int first = TRUE; 5788 char_u *tofree; 5789 char_u numbuf[NUMBUFLEN]; 5790 listitem_T *item; 5791 char_u *s; 5792 5793 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5794 { 5795 if (first) 5796 first = FALSE; 5797 else 5798 ga_concat(gap, sep); 5799 5800 if (echo) 5801 s = echo_string(&item->li_tv, &tofree, numbuf); 5802 else 5803 s = tv2string(&item->li_tv, &tofree, numbuf); 5804 if (s != NULL) 5805 ga_concat(gap, s); 5806 vim_free(tofree); 5807 if (s == NULL) 5808 return FAIL; 5809 } 5810 return OK; 5811 } 5812 5813 /* 5814 * Garbage collection for lists and dictionaries. 5815 * 5816 * We use reference counts to be able to free most items right away when they 5817 * are no longer used. But for composite items it's possible that it becomes 5818 * unused while the reference count is > 0: When there is a recursive 5819 * reference. Example: 5820 * :let l = [1, 2, 3] 5821 * :let d = {9: l} 5822 * :let l[1] = d 5823 * 5824 * Since this is quite unusual we handle this with garbage collection: every 5825 * once in a while find out which lists and dicts are not referenced from any 5826 * variable. 5827 * 5828 * Here is a good reference text about garbage collection (refers to Python 5829 * but it applies to all reference-counting mechanisms): 5830 * http://python.ca/nas/python/gc/ 5831 */ 5832 5833 /* 5834 * Do garbage collection for lists and dicts. 5835 * Return TRUE if some memory was freed. 5836 */ 5837 int 5838 garbage_collect() 5839 { 5840 dict_T *dd; 5841 list_T *ll; 5842 int copyID = ++current_copyID; 5843 buf_T *buf; 5844 win_T *wp; 5845 int i; 5846 funccall_T *fc; 5847 int did_free = FALSE; 5848 5849 /* 5850 * 1. Go through all accessible variables and mark all lists and dicts 5851 * with copyID. 5852 */ 5853 /* script-local variables */ 5854 for (i = 1; i <= ga_scripts.ga_len; ++i) 5855 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5856 5857 /* buffer-local variables */ 5858 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5859 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5860 5861 /* window-local variables */ 5862 FOR_ALL_WINDOWS(wp) 5863 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5864 5865 /* global variables */ 5866 set_ref_in_ht(&globvarht, copyID); 5867 5868 /* function-local variables */ 5869 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5870 { 5871 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5872 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5873 } 5874 5875 /* 5876 * 2. Go through the list of dicts and free items without the copyID. 5877 */ 5878 for (dd = first_dict; dd != NULL; ) 5879 if (dd->dv_copyID != copyID) 5880 { 5881 dict_free(dd); 5882 did_free = TRUE; 5883 5884 /* restart, next dict may also have been freed */ 5885 dd = first_dict; 5886 } 5887 else 5888 dd = dd->dv_used_next; 5889 5890 /* 5891 * 3. Go through the list of lists and free items without the copyID. 5892 * But don't free a list that has a watcher (used in a for loop), these 5893 * are not referenced anywhere. 5894 */ 5895 for (ll = first_list; ll != NULL; ) 5896 if (ll->lv_copyID != copyID && ll->lv_watch == NULL) 5897 { 5898 list_free(ll); 5899 did_free = TRUE; 5900 5901 /* restart, next list may also have been freed */ 5902 ll = first_list; 5903 } 5904 else 5905 ll = ll->lv_used_next; 5906 5907 return did_free; 5908 } 5909 5910 /* 5911 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5912 */ 5913 static void 5914 set_ref_in_ht(ht, copyID) 5915 hashtab_T *ht; 5916 int copyID; 5917 { 5918 int todo; 5919 hashitem_T *hi; 5920 5921 todo = ht->ht_used; 5922 for (hi = ht->ht_array; todo > 0; ++hi) 5923 if (!HASHITEM_EMPTY(hi)) 5924 { 5925 --todo; 5926 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5927 } 5928 } 5929 5930 /* 5931 * Mark all lists and dicts referenced through list "l" with "copyID". 5932 */ 5933 static void 5934 set_ref_in_list(l, copyID) 5935 list_T *l; 5936 int copyID; 5937 { 5938 listitem_T *li; 5939 5940 for (li = l->lv_first; li != NULL; li = li->li_next) 5941 set_ref_in_item(&li->li_tv, copyID); 5942 } 5943 5944 /* 5945 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5946 */ 5947 static void 5948 set_ref_in_item(tv, copyID) 5949 typval_T *tv; 5950 int copyID; 5951 { 5952 dict_T *dd; 5953 list_T *ll; 5954 5955 switch (tv->v_type) 5956 { 5957 case VAR_DICT: 5958 dd = tv->vval.v_dict; 5959 if (dd->dv_copyID != copyID) 5960 { 5961 /* Didn't see this dict yet. */ 5962 dd->dv_copyID = copyID; 5963 set_ref_in_ht(&dd->dv_hashtab, copyID); 5964 } 5965 break; 5966 5967 case VAR_LIST: 5968 ll = tv->vval.v_list; 5969 if (ll->lv_copyID != copyID) 5970 { 5971 /* Didn't see this list yet. */ 5972 ll->lv_copyID = copyID; 5973 set_ref_in_list(ll, copyID); 5974 } 5975 break; 5976 } 5977 return; 5978 } 5979 5980 /* 5981 * Allocate an empty header for a dictionary. 5982 */ 5983 dict_T * 5984 dict_alloc() 5985 { 5986 dict_T *d; 5987 5988 d = (dict_T *)alloc(sizeof(dict_T)); 5989 if (d != NULL) 5990 { 5991 /* Add the list to the hashtable for garbage collection. */ 5992 if (first_dict != NULL) 5993 first_dict->dv_used_prev = d; 5994 d->dv_used_next = first_dict; 5995 d->dv_used_prev = NULL; 5996 5997 hash_init(&d->dv_hashtab); 5998 d->dv_lock = 0; 5999 d->dv_refcount = 0; 6000 d->dv_copyID = 0; 6001 } 6002 return d; 6003 } 6004 6005 /* 6006 * Unreference a Dictionary: decrement the reference count and free it when it 6007 * becomes zero. 6008 */ 6009 static void 6010 dict_unref(d) 6011 dict_T *d; 6012 { 6013 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 6014 dict_free(d); 6015 } 6016 6017 /* 6018 * Free a Dictionary, including all items it contains. 6019 * Ignores the reference count. 6020 */ 6021 static void 6022 dict_free(d) 6023 dict_T *d; 6024 { 6025 int todo; 6026 hashitem_T *hi; 6027 dictitem_T *di; 6028 6029 /* Avoid that recursive reference to the dict frees us again. */ 6030 d->dv_refcount = DEL_REFCOUNT; 6031 6032 /* Remove the dict from the list of dicts for garbage collection. */ 6033 if (d->dv_used_prev == NULL) 6034 first_dict = d->dv_used_next; 6035 else 6036 d->dv_used_prev->dv_used_next = d->dv_used_next; 6037 if (d->dv_used_next != NULL) 6038 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6039 6040 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6041 hash_lock(&d->dv_hashtab); 6042 todo = d->dv_hashtab.ht_used; 6043 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6044 { 6045 if (!HASHITEM_EMPTY(hi)) 6046 { 6047 /* Remove the item before deleting it, just in case there is 6048 * something recursive causing trouble. */ 6049 di = HI2DI(hi); 6050 hash_remove(&d->dv_hashtab, hi); 6051 dictitem_free(di); 6052 --todo; 6053 } 6054 } 6055 hash_clear(&d->dv_hashtab); 6056 vim_free(d); 6057 } 6058 6059 /* 6060 * Allocate a Dictionary item. 6061 * The "key" is copied to the new item. 6062 * Note that the value of the item "di_tv" still needs to be initialized! 6063 * Returns NULL when out of memory. 6064 */ 6065 static dictitem_T * 6066 dictitem_alloc(key) 6067 char_u *key; 6068 { 6069 dictitem_T *di; 6070 6071 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6072 if (di != NULL) 6073 { 6074 STRCPY(di->di_key, key); 6075 di->di_flags = 0; 6076 } 6077 return di; 6078 } 6079 6080 /* 6081 * Make a copy of a Dictionary item. 6082 */ 6083 static dictitem_T * 6084 dictitem_copy(org) 6085 dictitem_T *org; 6086 { 6087 dictitem_T *di; 6088 6089 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6090 if (di != NULL) 6091 { 6092 STRCPY(di->di_key, org->di_key); 6093 di->di_flags = 0; 6094 copy_tv(&org->di_tv, &di->di_tv); 6095 } 6096 return di; 6097 } 6098 6099 /* 6100 * Remove item "item" from Dictionary "dict" and free it. 6101 */ 6102 static void 6103 dictitem_remove(dict, item) 6104 dict_T *dict; 6105 dictitem_T *item; 6106 { 6107 hashitem_T *hi; 6108 6109 hi = hash_find(&dict->dv_hashtab, item->di_key); 6110 if (HASHITEM_EMPTY(hi)) 6111 EMSG2(_(e_intern2), "dictitem_remove()"); 6112 else 6113 hash_remove(&dict->dv_hashtab, hi); 6114 dictitem_free(item); 6115 } 6116 6117 /* 6118 * Free a dict item. Also clears the value. 6119 */ 6120 static void 6121 dictitem_free(item) 6122 dictitem_T *item; 6123 { 6124 clear_tv(&item->di_tv); 6125 vim_free(item); 6126 } 6127 6128 /* 6129 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6130 * The refcount of the new dict is set to 1. 6131 * See item_copy() for "copyID". 6132 * Returns NULL when out of memory. 6133 */ 6134 static dict_T * 6135 dict_copy(orig, deep, copyID) 6136 dict_T *orig; 6137 int deep; 6138 int copyID; 6139 { 6140 dict_T *copy; 6141 dictitem_T *di; 6142 int todo; 6143 hashitem_T *hi; 6144 6145 if (orig == NULL) 6146 return NULL; 6147 6148 copy = dict_alloc(); 6149 if (copy != NULL) 6150 { 6151 if (copyID != 0) 6152 { 6153 orig->dv_copyID = copyID; 6154 orig->dv_copydict = copy; 6155 } 6156 todo = orig->dv_hashtab.ht_used; 6157 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6158 { 6159 if (!HASHITEM_EMPTY(hi)) 6160 { 6161 --todo; 6162 6163 di = dictitem_alloc(hi->hi_key); 6164 if (di == NULL) 6165 break; 6166 if (deep) 6167 { 6168 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6169 copyID) == FAIL) 6170 { 6171 vim_free(di); 6172 break; 6173 } 6174 } 6175 else 6176 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6177 if (dict_add(copy, di) == FAIL) 6178 { 6179 dictitem_free(di); 6180 break; 6181 } 6182 } 6183 } 6184 6185 ++copy->dv_refcount; 6186 if (todo > 0) 6187 { 6188 dict_unref(copy); 6189 copy = NULL; 6190 } 6191 } 6192 6193 return copy; 6194 } 6195 6196 /* 6197 * Add item "item" to Dictionary "d". 6198 * Returns FAIL when out of memory and when key already existed. 6199 */ 6200 static int 6201 dict_add(d, item) 6202 dict_T *d; 6203 dictitem_T *item; 6204 { 6205 return hash_add(&d->dv_hashtab, item->di_key); 6206 } 6207 6208 /* 6209 * Add a number or string entry to dictionary "d". 6210 * When "str" is NULL use number "nr", otherwise use "str". 6211 * Returns FAIL when out of memory and when key already exists. 6212 */ 6213 int 6214 dict_add_nr_str(d, key, nr, str) 6215 dict_T *d; 6216 char *key; 6217 long nr; 6218 char_u *str; 6219 { 6220 dictitem_T *item; 6221 6222 item = dictitem_alloc((char_u *)key); 6223 if (item == NULL) 6224 return FAIL; 6225 item->di_tv.v_lock = 0; 6226 if (str == NULL) 6227 { 6228 item->di_tv.v_type = VAR_NUMBER; 6229 item->di_tv.vval.v_number = nr; 6230 } 6231 else 6232 { 6233 item->di_tv.v_type = VAR_STRING; 6234 item->di_tv.vval.v_string = vim_strsave(str); 6235 } 6236 if (dict_add(d, item) == FAIL) 6237 { 6238 dictitem_free(item); 6239 return FAIL; 6240 } 6241 return OK; 6242 } 6243 6244 /* 6245 * Get the number of items in a Dictionary. 6246 */ 6247 static long 6248 dict_len(d) 6249 dict_T *d; 6250 { 6251 if (d == NULL) 6252 return 0L; 6253 return d->dv_hashtab.ht_used; 6254 } 6255 6256 /* 6257 * Find item "key[len]" in Dictionary "d". 6258 * If "len" is negative use strlen(key). 6259 * Returns NULL when not found. 6260 */ 6261 static dictitem_T * 6262 dict_find(d, key, len) 6263 dict_T *d; 6264 char_u *key; 6265 int len; 6266 { 6267 #define AKEYLEN 200 6268 char_u buf[AKEYLEN]; 6269 char_u *akey; 6270 char_u *tofree = NULL; 6271 hashitem_T *hi; 6272 6273 if (len < 0) 6274 akey = key; 6275 else if (len >= AKEYLEN) 6276 { 6277 tofree = akey = vim_strnsave(key, len); 6278 if (akey == NULL) 6279 return NULL; 6280 } 6281 else 6282 { 6283 /* Avoid a malloc/free by using buf[]. */ 6284 vim_strncpy(buf, key, len); 6285 akey = buf; 6286 } 6287 6288 hi = hash_find(&d->dv_hashtab, akey); 6289 vim_free(tofree); 6290 if (HASHITEM_EMPTY(hi)) 6291 return NULL; 6292 return HI2DI(hi); 6293 } 6294 6295 /* 6296 * Get a string item from a dictionary in allocated memory. 6297 * Returns NULL if the entry doesn't exist or out of memory. 6298 */ 6299 char_u * 6300 get_dict_string(d, key) 6301 dict_T *d; 6302 char_u *key; 6303 { 6304 dictitem_T *di; 6305 6306 di = dict_find(d, key, -1); 6307 if (di == NULL) 6308 return NULL; 6309 return vim_strsave(get_tv_string(&di->di_tv)); 6310 } 6311 6312 /* 6313 * Get a number item from a dictionary. 6314 * Returns 0 if the entry doesn't exist or out of memory. 6315 */ 6316 long 6317 get_dict_number(d, key) 6318 dict_T *d; 6319 char_u *key; 6320 { 6321 dictitem_T *di; 6322 6323 di = dict_find(d, key, -1); 6324 if (di == NULL) 6325 return 0; 6326 return get_tv_number(&di->di_tv); 6327 } 6328 6329 /* 6330 * Return an allocated string with the string representation of a Dictionary. 6331 * May return NULL. 6332 */ 6333 static char_u * 6334 dict2string(tv) 6335 typval_T *tv; 6336 { 6337 garray_T ga; 6338 int first = TRUE; 6339 char_u *tofree; 6340 char_u numbuf[NUMBUFLEN]; 6341 hashitem_T *hi; 6342 char_u *s; 6343 dict_T *d; 6344 int todo; 6345 6346 if ((d = tv->vval.v_dict) == NULL) 6347 return NULL; 6348 ga_init2(&ga, (int)sizeof(char), 80); 6349 ga_append(&ga, '{'); 6350 6351 todo = d->dv_hashtab.ht_used; 6352 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6353 { 6354 if (!HASHITEM_EMPTY(hi)) 6355 { 6356 --todo; 6357 6358 if (first) 6359 first = FALSE; 6360 else 6361 ga_concat(&ga, (char_u *)", "); 6362 6363 tofree = string_quote(hi->hi_key, FALSE); 6364 if (tofree != NULL) 6365 { 6366 ga_concat(&ga, tofree); 6367 vim_free(tofree); 6368 } 6369 ga_concat(&ga, (char_u *)": "); 6370 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6371 if (s != NULL) 6372 ga_concat(&ga, s); 6373 vim_free(tofree); 6374 if (s == NULL) 6375 break; 6376 } 6377 } 6378 if (todo > 0) 6379 { 6380 vim_free(ga.ga_data); 6381 return NULL; 6382 } 6383 6384 ga_append(&ga, '}'); 6385 ga_append(&ga, NUL); 6386 return (char_u *)ga.ga_data; 6387 } 6388 6389 /* 6390 * Allocate a variable for a Dictionary and fill it from "*arg". 6391 * Return OK or FAIL. Returns NOTDONE for {expr}. 6392 */ 6393 static int 6394 get_dict_tv(arg, rettv, evaluate) 6395 char_u **arg; 6396 typval_T *rettv; 6397 int evaluate; 6398 { 6399 dict_T *d = NULL; 6400 typval_T tvkey; 6401 typval_T tv; 6402 char_u *key; 6403 dictitem_T *item; 6404 char_u *start = skipwhite(*arg + 1); 6405 char_u buf[NUMBUFLEN]; 6406 6407 /* 6408 * First check if it's not a curly-braces thing: {expr}. 6409 * Must do this without evaluating, otherwise a function may be called 6410 * twice. Unfortunately this means we need to call eval1() twice for the 6411 * first item. 6412 * But {} is an empty Dictionary. 6413 */ 6414 if (*start != '}') 6415 { 6416 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6417 return FAIL; 6418 if (*start == '}') 6419 return NOTDONE; 6420 } 6421 6422 if (evaluate) 6423 { 6424 d = dict_alloc(); 6425 if (d == NULL) 6426 return FAIL; 6427 } 6428 tvkey.v_type = VAR_UNKNOWN; 6429 tv.v_type = VAR_UNKNOWN; 6430 6431 *arg = skipwhite(*arg + 1); 6432 while (**arg != '}' && **arg != NUL) 6433 { 6434 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6435 goto failret; 6436 if (**arg != ':') 6437 { 6438 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6439 clear_tv(&tvkey); 6440 goto failret; 6441 } 6442 key = get_tv_string_buf_chk(&tvkey, buf); 6443 if (key == NULL || *key == NUL) 6444 { 6445 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6446 if (key != NULL) 6447 EMSG(_(e_emptykey)); 6448 clear_tv(&tvkey); 6449 goto failret; 6450 } 6451 6452 *arg = skipwhite(*arg + 1); 6453 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6454 { 6455 clear_tv(&tvkey); 6456 goto failret; 6457 } 6458 if (evaluate) 6459 { 6460 item = dict_find(d, key, -1); 6461 if (item != NULL) 6462 { 6463 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6464 clear_tv(&tvkey); 6465 clear_tv(&tv); 6466 goto failret; 6467 } 6468 item = dictitem_alloc(key); 6469 clear_tv(&tvkey); 6470 if (item != NULL) 6471 { 6472 item->di_tv = tv; 6473 item->di_tv.v_lock = 0; 6474 if (dict_add(d, item) == FAIL) 6475 dictitem_free(item); 6476 } 6477 } 6478 6479 if (**arg == '}') 6480 break; 6481 if (**arg != ',') 6482 { 6483 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6484 goto failret; 6485 } 6486 *arg = skipwhite(*arg + 1); 6487 } 6488 6489 if (**arg != '}') 6490 { 6491 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6492 failret: 6493 if (evaluate) 6494 dict_free(d); 6495 return FAIL; 6496 } 6497 6498 *arg = skipwhite(*arg + 1); 6499 if (evaluate) 6500 { 6501 rettv->v_type = VAR_DICT; 6502 rettv->vval.v_dict = d; 6503 ++d->dv_refcount; 6504 } 6505 6506 return OK; 6507 } 6508 6509 /* 6510 * Return a string with the string representation of a variable. 6511 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6512 * "numbuf" is used for a number. 6513 * Does not put quotes around strings, as ":echo" displays values. 6514 * May return NULL; 6515 */ 6516 static char_u * 6517 echo_string(tv, tofree, numbuf) 6518 typval_T *tv; 6519 char_u **tofree; 6520 char_u *numbuf; 6521 { 6522 static int recurse = 0; 6523 char_u *r = NULL; 6524 6525 if (recurse >= DICT_MAXNEST) 6526 { 6527 EMSG(_("E724: variable nested too deep for displaying")); 6528 *tofree = NULL; 6529 return NULL; 6530 } 6531 ++recurse; 6532 6533 switch (tv->v_type) 6534 { 6535 case VAR_FUNC: 6536 *tofree = NULL; 6537 r = tv->vval.v_string; 6538 break; 6539 case VAR_LIST: 6540 *tofree = list2string(tv); 6541 r = *tofree; 6542 break; 6543 case VAR_DICT: 6544 *tofree = dict2string(tv); 6545 r = *tofree; 6546 break; 6547 case VAR_STRING: 6548 case VAR_NUMBER: 6549 *tofree = NULL; 6550 r = get_tv_string_buf(tv, numbuf); 6551 break; 6552 default: 6553 EMSG2(_(e_intern2), "echo_string()"); 6554 *tofree = NULL; 6555 } 6556 6557 --recurse; 6558 return r; 6559 } 6560 6561 /* 6562 * Return a string with the string representation of a variable. 6563 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6564 * "numbuf" is used for a number. 6565 * Puts quotes around strings, so that they can be parsed back by eval(). 6566 * May return NULL; 6567 */ 6568 static char_u * 6569 tv2string(tv, tofree, numbuf) 6570 typval_T *tv; 6571 char_u **tofree; 6572 char_u *numbuf; 6573 { 6574 switch (tv->v_type) 6575 { 6576 case VAR_FUNC: 6577 *tofree = string_quote(tv->vval.v_string, TRUE); 6578 return *tofree; 6579 case VAR_STRING: 6580 *tofree = string_quote(tv->vval.v_string, FALSE); 6581 return *tofree; 6582 case VAR_NUMBER: 6583 case VAR_LIST: 6584 case VAR_DICT: 6585 break; 6586 default: 6587 EMSG2(_(e_intern2), "tv2string()"); 6588 } 6589 return echo_string(tv, tofree, numbuf); 6590 } 6591 6592 /* 6593 * Return string "str" in ' quotes, doubling ' characters. 6594 * If "str" is NULL an empty string is assumed. 6595 * If "function" is TRUE make it function('string'). 6596 */ 6597 static char_u * 6598 string_quote(str, function) 6599 char_u *str; 6600 int function; 6601 { 6602 unsigned len; 6603 char_u *p, *r, *s; 6604 6605 len = (function ? 13 : 3); 6606 if (str != NULL) 6607 { 6608 len += STRLEN(str); 6609 for (p = str; *p != NUL; mb_ptr_adv(p)) 6610 if (*p == '\'') 6611 ++len; 6612 } 6613 s = r = alloc(len); 6614 if (r != NULL) 6615 { 6616 if (function) 6617 { 6618 STRCPY(r, "function('"); 6619 r += 10; 6620 } 6621 else 6622 *r++ = '\''; 6623 if (str != NULL) 6624 for (p = str; *p != NUL; ) 6625 { 6626 if (*p == '\'') 6627 *r++ = '\''; 6628 MB_COPY_CHAR(p, r); 6629 } 6630 *r++ = '\''; 6631 if (function) 6632 *r++ = ')'; 6633 *r++ = NUL; 6634 } 6635 return s; 6636 } 6637 6638 /* 6639 * Get the value of an environment variable. 6640 * "arg" is pointing to the '$'. It is advanced to after the name. 6641 * If the environment variable was not set, silently assume it is empty. 6642 * Always return OK. 6643 */ 6644 static int 6645 get_env_tv(arg, rettv, evaluate) 6646 char_u **arg; 6647 typval_T *rettv; 6648 int evaluate; 6649 { 6650 char_u *string = NULL; 6651 int len; 6652 int cc; 6653 char_u *name; 6654 int mustfree = FALSE; 6655 6656 ++*arg; 6657 name = *arg; 6658 len = get_env_len(arg); 6659 if (evaluate) 6660 { 6661 if (len != 0) 6662 { 6663 cc = name[len]; 6664 name[len] = NUL; 6665 /* first try vim_getenv(), fast for normal environment vars */ 6666 string = vim_getenv(name, &mustfree); 6667 if (string != NULL && *string != NUL) 6668 { 6669 if (!mustfree) 6670 string = vim_strsave(string); 6671 } 6672 else 6673 { 6674 if (mustfree) 6675 vim_free(string); 6676 6677 /* next try expanding things like $VIM and ${HOME} */ 6678 string = expand_env_save(name - 1); 6679 if (string != NULL && *string == '$') 6680 { 6681 vim_free(string); 6682 string = NULL; 6683 } 6684 } 6685 name[len] = cc; 6686 } 6687 rettv->v_type = VAR_STRING; 6688 rettv->vval.v_string = string; 6689 } 6690 6691 return OK; 6692 } 6693 6694 /* 6695 * Array with names and number of arguments of all internal functions 6696 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6697 */ 6698 static struct fst 6699 { 6700 char *f_name; /* function name */ 6701 char f_min_argc; /* minimal number of arguments */ 6702 char f_max_argc; /* maximal number of arguments */ 6703 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6704 /* implemenation of function */ 6705 } functions[] = 6706 { 6707 {"add", 2, 2, f_add}, 6708 {"append", 2, 2, f_append}, 6709 {"argc", 0, 0, f_argc}, 6710 {"argidx", 0, 0, f_argidx}, 6711 {"argv", 1, 1, f_argv}, 6712 {"browse", 4, 4, f_browse}, 6713 {"browsedir", 2, 2, f_browsedir}, 6714 {"bufexists", 1, 1, f_bufexists}, 6715 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6716 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6717 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6718 {"buflisted", 1, 1, f_buflisted}, 6719 {"bufloaded", 1, 1, f_bufloaded}, 6720 {"bufname", 1, 1, f_bufname}, 6721 {"bufnr", 1, 1, f_bufnr}, 6722 {"bufwinnr", 1, 1, f_bufwinnr}, 6723 {"byte2line", 1, 1, f_byte2line}, 6724 {"byteidx", 2, 2, f_byteidx}, 6725 {"call", 2, 3, f_call}, 6726 {"char2nr", 1, 1, f_char2nr}, 6727 {"cindent", 1, 1, f_cindent}, 6728 {"col", 1, 1, f_col}, 6729 #if defined(FEAT_INS_EXPAND) 6730 {"complete_add", 1, 1, f_complete_add}, 6731 {"complete_check", 0, 0, f_complete_check}, 6732 #endif 6733 {"confirm", 1, 4, f_confirm}, 6734 {"copy", 1, 1, f_copy}, 6735 {"count", 2, 4, f_count}, 6736 {"cscope_connection",0,3, f_cscope_connection}, 6737 {"cursor", 2, 2, f_cursor}, 6738 {"deepcopy", 1, 2, f_deepcopy}, 6739 {"delete", 1, 1, f_delete}, 6740 {"did_filetype", 0, 0, f_did_filetype}, 6741 {"diff_filler", 1, 1, f_diff_filler}, 6742 {"diff_hlID", 2, 2, f_diff_hlID}, 6743 {"empty", 1, 1, f_empty}, 6744 {"escape", 2, 2, f_escape}, 6745 {"eval", 1, 1, f_eval}, 6746 {"eventhandler", 0, 0, f_eventhandler}, 6747 {"executable", 1, 1, f_executable}, 6748 {"exists", 1, 1, f_exists}, 6749 {"expand", 1, 2, f_expand}, 6750 {"extend", 2, 3, f_extend}, 6751 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6752 {"filereadable", 1, 1, f_filereadable}, 6753 {"filewritable", 1, 1, f_filewritable}, 6754 {"filter", 2, 2, f_filter}, 6755 {"finddir", 1, 3, f_finddir}, 6756 {"findfile", 1, 3, f_findfile}, 6757 {"fnamemodify", 2, 2, f_fnamemodify}, 6758 {"foldclosed", 1, 1, f_foldclosed}, 6759 {"foldclosedend", 1, 1, f_foldclosedend}, 6760 {"foldlevel", 1, 1, f_foldlevel}, 6761 {"foldtext", 0, 0, f_foldtext}, 6762 {"foldtextresult", 1, 1, f_foldtextresult}, 6763 {"foreground", 0, 0, f_foreground}, 6764 {"function", 1, 1, f_function}, 6765 {"garbagecollect", 0, 0, f_garbagecollect}, 6766 {"get", 2, 3, f_get}, 6767 {"getbufline", 2, 3, f_getbufline}, 6768 {"getbufvar", 2, 2, f_getbufvar}, 6769 {"getchar", 0, 1, f_getchar}, 6770 {"getcharmod", 0, 0, f_getcharmod}, 6771 {"getcmdline", 0, 0, f_getcmdline}, 6772 {"getcmdpos", 0, 0, f_getcmdpos}, 6773 {"getcmdtype", 0, 0, f_getcmdtype}, 6774 {"getcwd", 0, 0, f_getcwd}, 6775 {"getfontname", 0, 1, f_getfontname}, 6776 {"getfperm", 1, 1, f_getfperm}, 6777 {"getfsize", 1, 1, f_getfsize}, 6778 {"getftime", 1, 1, f_getftime}, 6779 {"getftype", 1, 1, f_getftype}, 6780 {"getline", 1, 2, f_getline}, 6781 {"getqflist", 0, 0, f_getqflist}, 6782 {"getreg", 0, 2, f_getreg}, 6783 {"getregtype", 0, 1, f_getregtype}, 6784 {"getwinposx", 0, 0, f_getwinposx}, 6785 {"getwinposy", 0, 0, f_getwinposy}, 6786 {"getwinvar", 2, 2, f_getwinvar}, 6787 {"glob", 1, 1, f_glob}, 6788 {"globpath", 2, 2, f_globpath}, 6789 {"has", 1, 1, f_has}, 6790 {"has_key", 2, 2, f_has_key}, 6791 {"hasmapto", 1, 2, f_hasmapto}, 6792 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6793 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6794 {"histadd", 2, 2, f_histadd}, 6795 {"histdel", 1, 2, f_histdel}, 6796 {"histget", 1, 2, f_histget}, 6797 {"histnr", 1, 1, f_histnr}, 6798 {"hlID", 1, 1, f_hlID}, 6799 {"hlexists", 1, 1, f_hlexists}, 6800 {"hostname", 0, 0, f_hostname}, 6801 {"iconv", 3, 3, f_iconv}, 6802 {"indent", 1, 1, f_indent}, 6803 {"index", 2, 4, f_index}, 6804 {"input", 1, 3, f_input}, 6805 {"inputdialog", 1, 3, f_inputdialog}, 6806 {"inputlist", 1, 1, f_inputlist}, 6807 {"inputrestore", 0, 0, f_inputrestore}, 6808 {"inputsave", 0, 0, f_inputsave}, 6809 {"inputsecret", 1, 2, f_inputsecret}, 6810 {"insert", 2, 3, f_insert}, 6811 {"isdirectory", 1, 1, f_isdirectory}, 6812 {"islocked", 1, 1, f_islocked}, 6813 {"items", 1, 1, f_items}, 6814 {"join", 1, 2, f_join}, 6815 {"keys", 1, 1, f_keys}, 6816 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6817 {"len", 1, 1, f_len}, 6818 {"libcall", 3, 3, f_libcall}, 6819 {"libcallnr", 3, 3, f_libcallnr}, 6820 {"line", 1, 1, f_line}, 6821 {"line2byte", 1, 1, f_line2byte}, 6822 {"lispindent", 1, 1, f_lispindent}, 6823 {"localtime", 0, 0, f_localtime}, 6824 {"map", 2, 2, f_map}, 6825 {"maparg", 1, 2, f_maparg}, 6826 {"mapcheck", 1, 2, f_mapcheck}, 6827 {"match", 2, 4, f_match}, 6828 {"matchend", 2, 4, f_matchend}, 6829 {"matchlist", 2, 4, f_matchlist}, 6830 {"matchstr", 2, 4, f_matchstr}, 6831 {"max", 1, 1, f_max}, 6832 {"min", 1, 1, f_min}, 6833 #ifdef vim_mkdir 6834 {"mkdir", 1, 3, f_mkdir}, 6835 #endif 6836 {"mode", 0, 0, f_mode}, 6837 {"nextnonblank", 1, 1, f_nextnonblank}, 6838 {"nr2char", 1, 1, f_nr2char}, 6839 {"prevnonblank", 1, 1, f_prevnonblank}, 6840 {"printf", 2, 19, f_printf}, 6841 {"range", 1, 3, f_range}, 6842 {"readfile", 1, 3, f_readfile}, 6843 {"remote_expr", 2, 3, f_remote_expr}, 6844 {"remote_foreground", 1, 1, f_remote_foreground}, 6845 {"remote_peek", 1, 2, f_remote_peek}, 6846 {"remote_read", 1, 1, f_remote_read}, 6847 {"remote_send", 2, 3, f_remote_send}, 6848 {"remove", 2, 3, f_remove}, 6849 {"rename", 2, 2, f_rename}, 6850 {"repeat", 2, 2, f_repeat}, 6851 {"resolve", 1, 1, f_resolve}, 6852 {"reverse", 1, 1, f_reverse}, 6853 {"search", 1, 2, f_search}, 6854 {"searchdecl", 1, 3, f_searchdecl}, 6855 {"searchpair", 3, 5, f_searchpair}, 6856 {"server2client", 2, 2, f_server2client}, 6857 {"serverlist", 0, 0, f_serverlist}, 6858 {"setbufvar", 3, 3, f_setbufvar}, 6859 {"setcmdpos", 1, 1, f_setcmdpos}, 6860 {"setline", 2, 2, f_setline}, 6861 {"setqflist", 1, 2, f_setqflist}, 6862 {"setreg", 2, 3, f_setreg}, 6863 {"setwinvar", 3, 3, f_setwinvar}, 6864 {"simplify", 1, 1, f_simplify}, 6865 {"sort", 1, 2, f_sort}, 6866 {"soundfold", 1, 1, f_soundfold}, 6867 {"spellbadword", 0, 0, f_spellbadword}, 6868 {"spellsuggest", 1, 2, f_spellsuggest}, 6869 {"split", 1, 3, f_split}, 6870 #ifdef HAVE_STRFTIME 6871 {"strftime", 1, 2, f_strftime}, 6872 #endif 6873 {"stridx", 2, 3, f_stridx}, 6874 {"string", 1, 1, f_string}, 6875 {"strlen", 1, 1, f_strlen}, 6876 {"strpart", 2, 3, f_strpart}, 6877 {"strridx", 2, 3, f_strridx}, 6878 {"strtrans", 1, 1, f_strtrans}, 6879 {"submatch", 1, 1, f_submatch}, 6880 {"substitute", 4, 4, f_substitute}, 6881 {"synID", 3, 3, f_synID}, 6882 {"synIDattr", 2, 3, f_synIDattr}, 6883 {"synIDtrans", 1, 1, f_synIDtrans}, 6884 {"system", 1, 2, f_system}, 6885 {"tagfiles", 0, 0, f_tagfiles}, 6886 {"taglist", 1, 1, f_taglist}, 6887 {"tempname", 0, 0, f_tempname}, 6888 {"test", 1, 1, f_test}, 6889 {"tolower", 1, 1, f_tolower}, 6890 {"toupper", 1, 1, f_toupper}, 6891 {"tr", 3, 3, f_tr}, 6892 {"type", 1, 1, f_type}, 6893 {"values", 1, 1, f_values}, 6894 {"virtcol", 1, 1, f_virtcol}, 6895 {"visualmode", 0, 1, f_visualmode}, 6896 {"winbufnr", 1, 1, f_winbufnr}, 6897 {"wincol", 0, 0, f_wincol}, 6898 {"winheight", 1, 1, f_winheight}, 6899 {"winline", 0, 0, f_winline}, 6900 {"winnr", 0, 1, f_winnr}, 6901 {"winrestcmd", 0, 0, f_winrestcmd}, 6902 {"winwidth", 1, 1, f_winwidth}, 6903 {"writefile", 2, 3, f_writefile}, 6904 }; 6905 6906 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6907 6908 /* 6909 * Function given to ExpandGeneric() to obtain the list of internal 6910 * or user defined function names. 6911 */ 6912 char_u * 6913 get_function_name(xp, idx) 6914 expand_T *xp; 6915 int idx; 6916 { 6917 static int intidx = -1; 6918 char_u *name; 6919 6920 if (idx == 0) 6921 intidx = -1; 6922 if (intidx < 0) 6923 { 6924 name = get_user_func_name(xp, idx); 6925 if (name != NULL) 6926 return name; 6927 } 6928 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6929 { 6930 STRCPY(IObuff, functions[intidx].f_name); 6931 STRCAT(IObuff, "("); 6932 if (functions[intidx].f_max_argc == 0) 6933 STRCAT(IObuff, ")"); 6934 return IObuff; 6935 } 6936 6937 return NULL; 6938 } 6939 6940 /* 6941 * Function given to ExpandGeneric() to obtain the list of internal or 6942 * user defined variable or function names. 6943 */ 6944 /*ARGSUSED*/ 6945 char_u * 6946 get_expr_name(xp, idx) 6947 expand_T *xp; 6948 int idx; 6949 { 6950 static int intidx = -1; 6951 char_u *name; 6952 6953 if (idx == 0) 6954 intidx = -1; 6955 if (intidx < 0) 6956 { 6957 name = get_function_name(xp, idx); 6958 if (name != NULL) 6959 return name; 6960 } 6961 return get_user_var_name(xp, ++intidx); 6962 } 6963 6964 #endif /* FEAT_CMDL_COMPL */ 6965 6966 /* 6967 * Find internal function in table above. 6968 * Return index, or -1 if not found 6969 */ 6970 static int 6971 find_internal_func(name) 6972 char_u *name; /* name of the function */ 6973 { 6974 int first = 0; 6975 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6976 int cmp; 6977 int x; 6978 6979 /* 6980 * Find the function name in the table. Binary search. 6981 */ 6982 while (first <= last) 6983 { 6984 x = first + ((unsigned)(last - first) >> 1); 6985 cmp = STRCMP(name, functions[x].f_name); 6986 if (cmp < 0) 6987 last = x - 1; 6988 else if (cmp > 0) 6989 first = x + 1; 6990 else 6991 return x; 6992 } 6993 return -1; 6994 } 6995 6996 /* 6997 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6998 * name it contains, otherwise return "name". 6999 */ 7000 static char_u * 7001 deref_func_name(name, lenp) 7002 char_u *name; 7003 int *lenp; 7004 { 7005 dictitem_T *v; 7006 int cc; 7007 7008 cc = name[*lenp]; 7009 name[*lenp] = NUL; 7010 v = find_var(name, NULL); 7011 name[*lenp] = cc; 7012 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 7013 { 7014 if (v->di_tv.vval.v_string == NULL) 7015 { 7016 *lenp = 0; 7017 return (char_u *)""; /* just in case */ 7018 } 7019 *lenp = STRLEN(v->di_tv.vval.v_string); 7020 return v->di_tv.vval.v_string; 7021 } 7022 7023 return name; 7024 } 7025 7026 /* 7027 * Allocate a variable for the result of a function. 7028 * Return OK or FAIL. 7029 */ 7030 static int 7031 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 7032 evaluate, selfdict) 7033 char_u *name; /* name of the function */ 7034 int len; /* length of "name" */ 7035 typval_T *rettv; 7036 char_u **arg; /* argument, pointing to the '(' */ 7037 linenr_T firstline; /* first line of range */ 7038 linenr_T lastline; /* last line of range */ 7039 int *doesrange; /* return: function handled range */ 7040 int evaluate; 7041 dict_T *selfdict; /* Dictionary for "self" */ 7042 { 7043 char_u *argp; 7044 int ret = OK; 7045 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7046 int argcount = 0; /* number of arguments found */ 7047 7048 /* 7049 * Get the arguments. 7050 */ 7051 argp = *arg; 7052 while (argcount < MAX_FUNC_ARGS) 7053 { 7054 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7055 if (*argp == ')' || *argp == ',' || *argp == NUL) 7056 break; 7057 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7058 { 7059 ret = FAIL; 7060 break; 7061 } 7062 ++argcount; 7063 if (*argp != ',') 7064 break; 7065 } 7066 if (*argp == ')') 7067 ++argp; 7068 else 7069 ret = FAIL; 7070 7071 if (ret == OK) 7072 ret = call_func(name, len, rettv, argcount, argvars, 7073 firstline, lastline, doesrange, evaluate, selfdict); 7074 else if (!aborting()) 7075 { 7076 if (argcount == MAX_FUNC_ARGS) 7077 emsg_funcname("E740: Too many arguments for function %s", name); 7078 else 7079 emsg_funcname("E116: Invalid arguments for function %s", name); 7080 } 7081 7082 while (--argcount >= 0) 7083 clear_tv(&argvars[argcount]); 7084 7085 *arg = skipwhite(argp); 7086 return ret; 7087 } 7088 7089 7090 /* 7091 * Call a function with its resolved parameters 7092 * Return OK or FAIL. 7093 */ 7094 static int 7095 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7096 doesrange, evaluate, selfdict) 7097 char_u *name; /* name of the function */ 7098 int len; /* length of "name" */ 7099 typval_T *rettv; /* return value goes here */ 7100 int argcount; /* number of "argvars" */ 7101 typval_T *argvars; /* vars for arguments */ 7102 linenr_T firstline; /* first line of range */ 7103 linenr_T lastline; /* last line of range */ 7104 int *doesrange; /* return: function handled range */ 7105 int evaluate; 7106 dict_T *selfdict; /* Dictionary for "self" */ 7107 { 7108 int ret = FAIL; 7109 #define ERROR_UNKNOWN 0 7110 #define ERROR_TOOMANY 1 7111 #define ERROR_TOOFEW 2 7112 #define ERROR_SCRIPT 3 7113 #define ERROR_DICT 4 7114 #define ERROR_NONE 5 7115 #define ERROR_OTHER 6 7116 int error = ERROR_NONE; 7117 int i; 7118 int llen; 7119 ufunc_T *fp; 7120 int cc; 7121 #define FLEN_FIXED 40 7122 char_u fname_buf[FLEN_FIXED + 1]; 7123 char_u *fname; 7124 7125 /* 7126 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7127 * Change <SNR>123_name() to K_SNR 123_name(). 7128 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7129 */ 7130 cc = name[len]; 7131 name[len] = NUL; 7132 llen = eval_fname_script(name); 7133 if (llen > 0) 7134 { 7135 fname_buf[0] = K_SPECIAL; 7136 fname_buf[1] = KS_EXTRA; 7137 fname_buf[2] = (int)KE_SNR; 7138 i = 3; 7139 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7140 { 7141 if (current_SID <= 0) 7142 error = ERROR_SCRIPT; 7143 else 7144 { 7145 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7146 i = (int)STRLEN(fname_buf); 7147 } 7148 } 7149 if (i + STRLEN(name + llen) < FLEN_FIXED) 7150 { 7151 STRCPY(fname_buf + i, name + llen); 7152 fname = fname_buf; 7153 } 7154 else 7155 { 7156 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7157 if (fname == NULL) 7158 error = ERROR_OTHER; 7159 else 7160 { 7161 mch_memmove(fname, fname_buf, (size_t)i); 7162 STRCPY(fname + i, name + llen); 7163 } 7164 } 7165 } 7166 else 7167 fname = name; 7168 7169 *doesrange = FALSE; 7170 7171 7172 /* execute the function if no errors detected and executing */ 7173 if (evaluate && error == ERROR_NONE) 7174 { 7175 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7176 error = ERROR_UNKNOWN; 7177 7178 if (!builtin_function(fname)) 7179 { 7180 /* 7181 * User defined function. 7182 */ 7183 fp = find_func(fname); 7184 7185 #ifdef FEAT_AUTOCMD 7186 /* Trigger FuncUndefined event, may load the function. */ 7187 if (fp == NULL 7188 && apply_autocmds(EVENT_FUNCUNDEFINED, 7189 fname, fname, TRUE, NULL) 7190 && !aborting()) 7191 { 7192 /* executed an autocommand, search for the function again */ 7193 fp = find_func(fname); 7194 } 7195 #endif 7196 /* Try loading a package. */ 7197 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7198 { 7199 /* loaded a package, search for the function again */ 7200 fp = find_func(fname); 7201 } 7202 7203 if (fp != NULL) 7204 { 7205 if (fp->uf_flags & FC_RANGE) 7206 *doesrange = TRUE; 7207 if (argcount < fp->uf_args.ga_len) 7208 error = ERROR_TOOFEW; 7209 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7210 error = ERROR_TOOMANY; 7211 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7212 error = ERROR_DICT; 7213 else 7214 { 7215 /* 7216 * Call the user function. 7217 * Save and restore search patterns, script variables and 7218 * redo buffer. 7219 */ 7220 save_search_patterns(); 7221 saveRedobuff(); 7222 ++fp->uf_calls; 7223 call_user_func(fp, argcount, argvars, rettv, 7224 firstline, lastline, 7225 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7226 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7227 && fp->uf_refcount <= 0) 7228 /* Function was unreferenced while being used, free it 7229 * now. */ 7230 func_free(fp); 7231 restoreRedobuff(); 7232 restore_search_patterns(); 7233 error = ERROR_NONE; 7234 } 7235 } 7236 } 7237 else 7238 { 7239 /* 7240 * Find the function name in the table, call its implementation. 7241 */ 7242 i = find_internal_func(fname); 7243 if (i >= 0) 7244 { 7245 if (argcount < functions[i].f_min_argc) 7246 error = ERROR_TOOFEW; 7247 else if (argcount > functions[i].f_max_argc) 7248 error = ERROR_TOOMANY; 7249 else 7250 { 7251 argvars[argcount].v_type = VAR_UNKNOWN; 7252 functions[i].f_func(argvars, rettv); 7253 error = ERROR_NONE; 7254 } 7255 } 7256 } 7257 /* 7258 * The function call (or "FuncUndefined" autocommand sequence) might 7259 * have been aborted by an error, an interrupt, or an explicitly thrown 7260 * exception that has not been caught so far. This situation can be 7261 * tested for by calling aborting(). For an error in an internal 7262 * function or for the "E132" error in call_user_func(), however, the 7263 * throw point at which the "force_abort" flag (temporarily reset by 7264 * emsg()) is normally updated has not been reached yet. We need to 7265 * update that flag first to make aborting() reliable. 7266 */ 7267 update_force_abort(); 7268 } 7269 if (error == ERROR_NONE) 7270 ret = OK; 7271 7272 /* 7273 * Report an error unless the argument evaluation or function call has been 7274 * cancelled due to an aborting error, an interrupt, or an exception. 7275 */ 7276 if (!aborting()) 7277 { 7278 switch (error) 7279 { 7280 case ERROR_UNKNOWN: 7281 emsg_funcname("E117: Unknown function: %s", name); 7282 break; 7283 case ERROR_TOOMANY: 7284 emsg_funcname(e_toomanyarg, name); 7285 break; 7286 case ERROR_TOOFEW: 7287 emsg_funcname("E119: Not enough arguments for function: %s", 7288 name); 7289 break; 7290 case ERROR_SCRIPT: 7291 emsg_funcname("E120: Using <SID> not in a script context: %s", 7292 name); 7293 break; 7294 case ERROR_DICT: 7295 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7296 name); 7297 break; 7298 } 7299 } 7300 7301 name[len] = cc; 7302 if (fname != name && fname != fname_buf) 7303 vim_free(fname); 7304 7305 return ret; 7306 } 7307 7308 /* 7309 * Give an error message with a function name. Handle <SNR> things. 7310 */ 7311 static void 7312 emsg_funcname(msg, name) 7313 char *msg; 7314 char_u *name; 7315 { 7316 char_u *p; 7317 7318 if (*name == K_SPECIAL) 7319 p = concat_str((char_u *)"<SNR>", name + 3); 7320 else 7321 p = name; 7322 EMSG2(_(msg), p); 7323 if (p != name) 7324 vim_free(p); 7325 } 7326 7327 /********************************************* 7328 * Implementation of the built-in functions 7329 */ 7330 7331 /* 7332 * "add(list, item)" function 7333 */ 7334 static void 7335 f_add(argvars, rettv) 7336 typval_T *argvars; 7337 typval_T *rettv; 7338 { 7339 list_T *l; 7340 7341 rettv->vval.v_number = 1; /* Default: Failed */ 7342 if (argvars[0].v_type == VAR_LIST) 7343 { 7344 if ((l = argvars[0].vval.v_list) != NULL 7345 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7346 && list_append_tv(l, &argvars[1]) == OK) 7347 copy_tv(&argvars[0], rettv); 7348 } 7349 else 7350 EMSG(_(e_listreq)); 7351 } 7352 7353 /* 7354 * "append(lnum, string/list)" function 7355 */ 7356 static void 7357 f_append(argvars, rettv) 7358 typval_T *argvars; 7359 typval_T *rettv; 7360 { 7361 long lnum; 7362 char_u *line; 7363 list_T *l = NULL; 7364 listitem_T *li = NULL; 7365 typval_T *tv; 7366 long added = 0; 7367 7368 lnum = get_tv_lnum(argvars); 7369 if (lnum >= 0 7370 && lnum <= curbuf->b_ml.ml_line_count 7371 && u_save(lnum, lnum + 1) == OK) 7372 { 7373 if (argvars[1].v_type == VAR_LIST) 7374 { 7375 l = argvars[1].vval.v_list; 7376 if (l == NULL) 7377 return; 7378 li = l->lv_first; 7379 } 7380 rettv->vval.v_number = 0; /* Default: Success */ 7381 for (;;) 7382 { 7383 if (l == NULL) 7384 tv = &argvars[1]; /* append a string */ 7385 else if (li == NULL) 7386 break; /* end of list */ 7387 else 7388 tv = &li->li_tv; /* append item from list */ 7389 line = get_tv_string_chk(tv); 7390 if (line == NULL) /* type error */ 7391 { 7392 rettv->vval.v_number = 1; /* Failed */ 7393 break; 7394 } 7395 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7396 ++added; 7397 if (l == NULL) 7398 break; 7399 li = li->li_next; 7400 } 7401 7402 appended_lines_mark(lnum, added); 7403 if (curwin->w_cursor.lnum > lnum) 7404 curwin->w_cursor.lnum += added; 7405 } 7406 else 7407 rettv->vval.v_number = 1; /* Failed */ 7408 } 7409 7410 /* 7411 * "argc()" function 7412 */ 7413 /* ARGSUSED */ 7414 static void 7415 f_argc(argvars, rettv) 7416 typval_T *argvars; 7417 typval_T *rettv; 7418 { 7419 rettv->vval.v_number = ARGCOUNT; 7420 } 7421 7422 /* 7423 * "argidx()" function 7424 */ 7425 /* ARGSUSED */ 7426 static void 7427 f_argidx(argvars, rettv) 7428 typval_T *argvars; 7429 typval_T *rettv; 7430 { 7431 rettv->vval.v_number = curwin->w_arg_idx; 7432 } 7433 7434 /* 7435 * "argv(nr)" function 7436 */ 7437 static void 7438 f_argv(argvars, rettv) 7439 typval_T *argvars; 7440 typval_T *rettv; 7441 { 7442 int idx; 7443 7444 idx = get_tv_number_chk(&argvars[0], NULL); 7445 if (idx >= 0 && idx < ARGCOUNT) 7446 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7447 else 7448 rettv->vval.v_string = NULL; 7449 rettv->v_type = VAR_STRING; 7450 } 7451 7452 /* 7453 * "browse(save, title, initdir, default)" function 7454 */ 7455 /* ARGSUSED */ 7456 static void 7457 f_browse(argvars, rettv) 7458 typval_T *argvars; 7459 typval_T *rettv; 7460 { 7461 #ifdef FEAT_BROWSE 7462 int save; 7463 char_u *title; 7464 char_u *initdir; 7465 char_u *defname; 7466 char_u buf[NUMBUFLEN]; 7467 char_u buf2[NUMBUFLEN]; 7468 int error = FALSE; 7469 7470 save = get_tv_number_chk(&argvars[0], &error); 7471 title = get_tv_string_chk(&argvars[1]); 7472 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7473 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7474 7475 if (error || title == NULL || initdir == NULL || defname == NULL) 7476 rettv->vval.v_string = NULL; 7477 else 7478 rettv->vval.v_string = 7479 do_browse(save ? BROWSE_SAVE : 0, 7480 title, defname, NULL, initdir, NULL, curbuf); 7481 #else 7482 rettv->vval.v_string = NULL; 7483 #endif 7484 rettv->v_type = VAR_STRING; 7485 } 7486 7487 /* 7488 * "browsedir(title, initdir)" function 7489 */ 7490 /* ARGSUSED */ 7491 static void 7492 f_browsedir(argvars, rettv) 7493 typval_T *argvars; 7494 typval_T *rettv; 7495 { 7496 #ifdef FEAT_BROWSE 7497 char_u *title; 7498 char_u *initdir; 7499 char_u buf[NUMBUFLEN]; 7500 7501 title = get_tv_string_chk(&argvars[0]); 7502 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7503 7504 if (title == NULL || initdir == NULL) 7505 rettv->vval.v_string = NULL; 7506 else 7507 rettv->vval.v_string = do_browse(BROWSE_DIR, 7508 title, NULL, NULL, initdir, NULL, curbuf); 7509 #else 7510 rettv->vval.v_string = NULL; 7511 #endif 7512 rettv->v_type = VAR_STRING; 7513 } 7514 7515 static buf_T *find_buffer __ARGS((typval_T *avar)); 7516 7517 /* 7518 * Find a buffer by number or exact name. 7519 */ 7520 static buf_T * 7521 find_buffer(avar) 7522 typval_T *avar; 7523 { 7524 buf_T *buf = NULL; 7525 7526 if (avar->v_type == VAR_NUMBER) 7527 buf = buflist_findnr((int)avar->vval.v_number); 7528 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7529 { 7530 buf = buflist_findname_exp(avar->vval.v_string); 7531 if (buf == NULL) 7532 { 7533 /* No full path name match, try a match with a URL or a "nofile" 7534 * buffer, these don't use the full path. */ 7535 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7536 if (buf->b_fname != NULL 7537 && (path_with_url(buf->b_fname) 7538 #ifdef FEAT_QUICKFIX 7539 || bt_nofile(buf) 7540 #endif 7541 ) 7542 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7543 break; 7544 } 7545 } 7546 return buf; 7547 } 7548 7549 /* 7550 * "bufexists(expr)" function 7551 */ 7552 static void 7553 f_bufexists(argvars, rettv) 7554 typval_T *argvars; 7555 typval_T *rettv; 7556 { 7557 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7558 } 7559 7560 /* 7561 * "buflisted(expr)" function 7562 */ 7563 static void 7564 f_buflisted(argvars, rettv) 7565 typval_T *argvars; 7566 typval_T *rettv; 7567 { 7568 buf_T *buf; 7569 7570 buf = find_buffer(&argvars[0]); 7571 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7572 } 7573 7574 /* 7575 * "bufloaded(expr)" function 7576 */ 7577 static void 7578 f_bufloaded(argvars, rettv) 7579 typval_T *argvars; 7580 typval_T *rettv; 7581 { 7582 buf_T *buf; 7583 7584 buf = find_buffer(&argvars[0]); 7585 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7586 } 7587 7588 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7589 7590 /* 7591 * Get buffer by number or pattern. 7592 */ 7593 static buf_T * 7594 get_buf_tv(tv) 7595 typval_T *tv; 7596 { 7597 char_u *name = tv->vval.v_string; 7598 int save_magic; 7599 char_u *save_cpo; 7600 buf_T *buf; 7601 7602 if (tv->v_type == VAR_NUMBER) 7603 return buflist_findnr((int)tv->vval.v_number); 7604 if (tv->v_type != VAR_STRING) 7605 return NULL; 7606 if (name == NULL || *name == NUL) 7607 return curbuf; 7608 if (name[0] == '$' && name[1] == NUL) 7609 return lastbuf; 7610 7611 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7612 save_magic = p_magic; 7613 p_magic = TRUE; 7614 save_cpo = p_cpo; 7615 p_cpo = (char_u *)""; 7616 7617 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7618 TRUE, FALSE)); 7619 7620 p_magic = save_magic; 7621 p_cpo = save_cpo; 7622 7623 /* If not found, try expanding the name, like done for bufexists(). */ 7624 if (buf == NULL) 7625 buf = find_buffer(tv); 7626 7627 return buf; 7628 } 7629 7630 /* 7631 * "bufname(expr)" function 7632 */ 7633 static void 7634 f_bufname(argvars, rettv) 7635 typval_T *argvars; 7636 typval_T *rettv; 7637 { 7638 buf_T *buf; 7639 7640 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7641 ++emsg_off; 7642 buf = get_buf_tv(&argvars[0]); 7643 rettv->v_type = VAR_STRING; 7644 if (buf != NULL && buf->b_fname != NULL) 7645 rettv->vval.v_string = vim_strsave(buf->b_fname); 7646 else 7647 rettv->vval.v_string = NULL; 7648 --emsg_off; 7649 } 7650 7651 /* 7652 * "bufnr(expr)" function 7653 */ 7654 static void 7655 f_bufnr(argvars, rettv) 7656 typval_T *argvars; 7657 typval_T *rettv; 7658 { 7659 buf_T *buf; 7660 7661 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7662 ++emsg_off; 7663 buf = get_buf_tv(&argvars[0]); 7664 if (buf != NULL) 7665 rettv->vval.v_number = buf->b_fnum; 7666 else 7667 rettv->vval.v_number = -1; 7668 --emsg_off; 7669 } 7670 7671 /* 7672 * "bufwinnr(nr)" function 7673 */ 7674 static void 7675 f_bufwinnr(argvars, rettv) 7676 typval_T *argvars; 7677 typval_T *rettv; 7678 { 7679 #ifdef FEAT_WINDOWS 7680 win_T *wp; 7681 int winnr = 0; 7682 #endif 7683 buf_T *buf; 7684 7685 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7686 ++emsg_off; 7687 buf = get_buf_tv(&argvars[0]); 7688 #ifdef FEAT_WINDOWS 7689 for (wp = firstwin; wp; wp = wp->w_next) 7690 { 7691 ++winnr; 7692 if (wp->w_buffer == buf) 7693 break; 7694 } 7695 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7696 #else 7697 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7698 #endif 7699 --emsg_off; 7700 } 7701 7702 /* 7703 * "byte2line(byte)" function 7704 */ 7705 /*ARGSUSED*/ 7706 static void 7707 f_byte2line(argvars, rettv) 7708 typval_T *argvars; 7709 typval_T *rettv; 7710 { 7711 #ifndef FEAT_BYTEOFF 7712 rettv->vval.v_number = -1; 7713 #else 7714 long boff = 0; 7715 7716 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7717 if (boff < 0) 7718 rettv->vval.v_number = -1; 7719 else 7720 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7721 (linenr_T)0, &boff); 7722 #endif 7723 } 7724 7725 /* 7726 * "byteidx()" function 7727 */ 7728 /*ARGSUSED*/ 7729 static void 7730 f_byteidx(argvars, rettv) 7731 typval_T *argvars; 7732 typval_T *rettv; 7733 { 7734 #ifdef FEAT_MBYTE 7735 char_u *t; 7736 #endif 7737 char_u *str; 7738 long idx; 7739 7740 str = get_tv_string_chk(&argvars[0]); 7741 idx = get_tv_number_chk(&argvars[1], NULL); 7742 rettv->vval.v_number = -1; 7743 if (str == NULL || idx < 0) 7744 return; 7745 7746 #ifdef FEAT_MBYTE 7747 t = str; 7748 for ( ; idx > 0; idx--) 7749 { 7750 if (*t == NUL) /* EOL reached */ 7751 return; 7752 t += (*mb_ptr2len)(t); 7753 } 7754 rettv->vval.v_number = t - str; 7755 #else 7756 if (idx <= STRLEN(str)) 7757 rettv->vval.v_number = idx; 7758 #endif 7759 } 7760 7761 /* 7762 * "call(func, arglist)" function 7763 */ 7764 static void 7765 f_call(argvars, rettv) 7766 typval_T *argvars; 7767 typval_T *rettv; 7768 { 7769 char_u *func; 7770 typval_T argv[MAX_FUNC_ARGS]; 7771 int argc = 0; 7772 listitem_T *item; 7773 int dummy; 7774 dict_T *selfdict = NULL; 7775 7776 rettv->vval.v_number = 0; 7777 if (argvars[1].v_type != VAR_LIST) 7778 { 7779 EMSG(_(e_listreq)); 7780 return; 7781 } 7782 if (argvars[1].vval.v_list == NULL) 7783 return; 7784 7785 if (argvars[0].v_type == VAR_FUNC) 7786 func = argvars[0].vval.v_string; 7787 else 7788 func = get_tv_string(&argvars[0]); 7789 if (*func == NUL) 7790 return; /* type error or empty name */ 7791 7792 if (argvars[2].v_type != VAR_UNKNOWN) 7793 { 7794 if (argvars[2].v_type != VAR_DICT) 7795 { 7796 EMSG(_(e_dictreq)); 7797 return; 7798 } 7799 selfdict = argvars[2].vval.v_dict; 7800 } 7801 7802 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7803 item = item->li_next) 7804 { 7805 if (argc == MAX_FUNC_ARGS) 7806 { 7807 EMSG(_("E699: Too many arguments")); 7808 break; 7809 } 7810 /* Make a copy of each argument. This is needed to be able to set 7811 * v_lock to VAR_FIXED in the copy without changing the original list. 7812 */ 7813 copy_tv(&item->li_tv, &argv[argc++]); 7814 } 7815 7816 if (item == NULL) 7817 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7818 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7819 &dummy, TRUE, selfdict); 7820 7821 /* Free the arguments. */ 7822 while (argc > 0) 7823 clear_tv(&argv[--argc]); 7824 } 7825 7826 /* 7827 * "char2nr(string)" function 7828 */ 7829 static void 7830 f_char2nr(argvars, rettv) 7831 typval_T *argvars; 7832 typval_T *rettv; 7833 { 7834 #ifdef FEAT_MBYTE 7835 if (has_mbyte) 7836 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7837 else 7838 #endif 7839 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7840 } 7841 7842 /* 7843 * "cindent(lnum)" function 7844 */ 7845 static void 7846 f_cindent(argvars, rettv) 7847 typval_T *argvars; 7848 typval_T *rettv; 7849 { 7850 #ifdef FEAT_CINDENT 7851 pos_T pos; 7852 linenr_T lnum; 7853 7854 pos = curwin->w_cursor; 7855 lnum = get_tv_lnum(argvars); 7856 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7857 { 7858 curwin->w_cursor.lnum = lnum; 7859 rettv->vval.v_number = get_c_indent(); 7860 curwin->w_cursor = pos; 7861 } 7862 else 7863 #endif 7864 rettv->vval.v_number = -1; 7865 } 7866 7867 /* 7868 * "col(string)" function 7869 */ 7870 static void 7871 f_col(argvars, rettv) 7872 typval_T *argvars; 7873 typval_T *rettv; 7874 { 7875 colnr_T col = 0; 7876 pos_T *fp; 7877 7878 fp = var2fpos(&argvars[0], FALSE); 7879 if (fp != NULL) 7880 { 7881 if (fp->col == MAXCOL) 7882 { 7883 /* '> can be MAXCOL, get the length of the line then */ 7884 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7885 col = STRLEN(ml_get(fp->lnum)) + 1; 7886 else 7887 col = MAXCOL; 7888 } 7889 else 7890 { 7891 col = fp->col + 1; 7892 #ifdef FEAT_VIRTUALEDIT 7893 /* col(".") when the cursor is on the NUL at the end of the line 7894 * because of "coladd" can be seen as an extra column. */ 7895 if (virtual_active() && fp == &curwin->w_cursor) 7896 { 7897 char_u *p = ml_get_cursor(); 7898 7899 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7900 curwin->w_virtcol - curwin->w_cursor.coladd)) 7901 { 7902 # ifdef FEAT_MBYTE 7903 int l; 7904 7905 if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) 7906 col += l; 7907 # else 7908 if (*p != NUL && p[1] == NUL) 7909 ++col; 7910 # endif 7911 } 7912 } 7913 #endif 7914 } 7915 } 7916 rettv->vval.v_number = col; 7917 } 7918 7919 #if defined(FEAT_INS_EXPAND) 7920 /* 7921 * "complete_add()" function 7922 */ 7923 /*ARGSUSED*/ 7924 static void 7925 f_complete_add(argvars, rettv) 7926 typval_T *argvars; 7927 typval_T *rettv; 7928 { 7929 char_u *s; 7930 7931 s = get_tv_string_chk(&argvars[0]); 7932 if (s != NULL) 7933 rettv->vval.v_number = ins_compl_add(s, -1, NULL, FORWARD, 0); 7934 } 7935 7936 /* 7937 * "complete_check()" function 7938 */ 7939 /*ARGSUSED*/ 7940 static void 7941 f_complete_check(argvars, rettv) 7942 typval_T *argvars; 7943 typval_T *rettv; 7944 { 7945 int saved = RedrawingDisabled; 7946 7947 RedrawingDisabled = 0; 7948 ins_compl_check_keys(0); 7949 rettv->vval.v_number = compl_interrupted; 7950 RedrawingDisabled = saved; 7951 } 7952 #endif 7953 7954 /* 7955 * "confirm(message, buttons[, default [, type]])" function 7956 */ 7957 /*ARGSUSED*/ 7958 static void 7959 f_confirm(argvars, rettv) 7960 typval_T *argvars; 7961 typval_T *rettv; 7962 { 7963 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7964 char_u *message; 7965 char_u *buttons = NULL; 7966 char_u buf[NUMBUFLEN]; 7967 char_u buf2[NUMBUFLEN]; 7968 int def = 1; 7969 int type = VIM_GENERIC; 7970 char_u *typestr; 7971 int error = FALSE; 7972 7973 message = get_tv_string_chk(&argvars[0]); 7974 if (message == NULL) 7975 error = TRUE; 7976 if (argvars[1].v_type != VAR_UNKNOWN) 7977 { 7978 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7979 if (buttons == NULL) 7980 error = TRUE; 7981 if (argvars[2].v_type != VAR_UNKNOWN) 7982 { 7983 def = get_tv_number_chk(&argvars[2], &error); 7984 if (argvars[3].v_type != VAR_UNKNOWN) 7985 { 7986 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7987 if (typestr == NULL) 7988 error = TRUE; 7989 else 7990 { 7991 switch (TOUPPER_ASC(*typestr)) 7992 { 7993 case 'E': type = VIM_ERROR; break; 7994 case 'Q': type = VIM_QUESTION; break; 7995 case 'I': type = VIM_INFO; break; 7996 case 'W': type = VIM_WARNING; break; 7997 case 'G': type = VIM_GENERIC; break; 7998 } 7999 } 8000 } 8001 } 8002 } 8003 8004 if (buttons == NULL || *buttons == NUL) 8005 buttons = (char_u *)_("&Ok"); 8006 8007 if (error) 8008 rettv->vval.v_number = 0; 8009 else 8010 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 8011 def, NULL); 8012 #else 8013 rettv->vval.v_number = 0; 8014 #endif 8015 } 8016 8017 /* 8018 * "copy()" function 8019 */ 8020 static void 8021 f_copy(argvars, rettv) 8022 typval_T *argvars; 8023 typval_T *rettv; 8024 { 8025 item_copy(&argvars[0], rettv, FALSE, 0); 8026 } 8027 8028 /* 8029 * "count()" function 8030 */ 8031 static void 8032 f_count(argvars, rettv) 8033 typval_T *argvars; 8034 typval_T *rettv; 8035 { 8036 long n = 0; 8037 int ic = FALSE; 8038 8039 if (argvars[0].v_type == VAR_LIST) 8040 { 8041 listitem_T *li; 8042 list_T *l; 8043 long idx; 8044 8045 if ((l = argvars[0].vval.v_list) != NULL) 8046 { 8047 li = l->lv_first; 8048 if (argvars[2].v_type != VAR_UNKNOWN) 8049 { 8050 int error = FALSE; 8051 8052 ic = get_tv_number_chk(&argvars[2], &error); 8053 if (argvars[3].v_type != VAR_UNKNOWN) 8054 { 8055 idx = get_tv_number_chk(&argvars[3], &error); 8056 if (!error) 8057 { 8058 li = list_find(l, idx); 8059 if (li == NULL) 8060 EMSGN(_(e_listidx), idx); 8061 } 8062 } 8063 if (error) 8064 li = NULL; 8065 } 8066 8067 for ( ; li != NULL; li = li->li_next) 8068 if (tv_equal(&li->li_tv, &argvars[1], ic)) 8069 ++n; 8070 } 8071 } 8072 else if (argvars[0].v_type == VAR_DICT) 8073 { 8074 int todo; 8075 dict_T *d; 8076 hashitem_T *hi; 8077 8078 if ((d = argvars[0].vval.v_dict) != NULL) 8079 { 8080 int error = FALSE; 8081 8082 if (argvars[2].v_type != VAR_UNKNOWN) 8083 { 8084 ic = get_tv_number_chk(&argvars[2], &error); 8085 if (argvars[3].v_type != VAR_UNKNOWN) 8086 EMSG(_(e_invarg)); 8087 } 8088 8089 todo = error ? 0 : d->dv_hashtab.ht_used; 8090 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8091 { 8092 if (!HASHITEM_EMPTY(hi)) 8093 { 8094 --todo; 8095 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8096 ++n; 8097 } 8098 } 8099 } 8100 } 8101 else 8102 EMSG2(_(e_listdictarg), "count()"); 8103 rettv->vval.v_number = n; 8104 } 8105 8106 /* 8107 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8108 * 8109 * Checks the existence of a cscope connection. 8110 */ 8111 /*ARGSUSED*/ 8112 static void 8113 f_cscope_connection(argvars, rettv) 8114 typval_T *argvars; 8115 typval_T *rettv; 8116 { 8117 #ifdef FEAT_CSCOPE 8118 int num = 0; 8119 char_u *dbpath = NULL; 8120 char_u *prepend = NULL; 8121 char_u buf[NUMBUFLEN]; 8122 8123 if (argvars[0].v_type != VAR_UNKNOWN 8124 && argvars[1].v_type != VAR_UNKNOWN) 8125 { 8126 num = (int)get_tv_number(&argvars[0]); 8127 dbpath = get_tv_string(&argvars[1]); 8128 if (argvars[2].v_type != VAR_UNKNOWN) 8129 prepend = get_tv_string_buf(&argvars[2], buf); 8130 } 8131 8132 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8133 #else 8134 rettv->vval.v_number = 0; 8135 #endif 8136 } 8137 8138 /* 8139 * "cursor(lnum, col)" function 8140 * 8141 * Moves the cursor to the specified line and column 8142 */ 8143 /*ARGSUSED*/ 8144 static void 8145 f_cursor(argvars, rettv) 8146 typval_T *argvars; 8147 typval_T *rettv; 8148 { 8149 long line, col; 8150 8151 line = get_tv_lnum(argvars); 8152 col = get_tv_number_chk(&argvars[1], NULL); 8153 if (line < 0 || col < 0) 8154 return; /* type error; errmsg already given */ 8155 if (line > 0) 8156 curwin->w_cursor.lnum = line; 8157 if (col > 0) 8158 curwin->w_cursor.col = col - 1; 8159 #ifdef FEAT_VIRTUALEDIT 8160 curwin->w_cursor.coladd = 0; 8161 #endif 8162 8163 /* Make sure the cursor is in a valid position. */ 8164 check_cursor(); 8165 #ifdef FEAT_MBYTE 8166 /* Correct cursor for multi-byte character. */ 8167 if (has_mbyte) 8168 mb_adjust_cursor(); 8169 #endif 8170 8171 curwin->w_set_curswant = TRUE; 8172 } 8173 8174 /* 8175 * "deepcopy()" function 8176 */ 8177 static void 8178 f_deepcopy(argvars, rettv) 8179 typval_T *argvars; 8180 typval_T *rettv; 8181 { 8182 int noref = 0; 8183 8184 if (argvars[1].v_type != VAR_UNKNOWN) 8185 noref = get_tv_number_chk(&argvars[1], NULL); 8186 if (noref < 0 || noref > 1) 8187 EMSG(_(e_invarg)); 8188 else 8189 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8190 } 8191 8192 /* 8193 * "delete()" function 8194 */ 8195 static void 8196 f_delete(argvars, rettv) 8197 typval_T *argvars; 8198 typval_T *rettv; 8199 { 8200 if (check_restricted() || check_secure()) 8201 rettv->vval.v_number = -1; 8202 else 8203 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8204 } 8205 8206 /* 8207 * "did_filetype()" function 8208 */ 8209 /*ARGSUSED*/ 8210 static void 8211 f_did_filetype(argvars, rettv) 8212 typval_T *argvars; 8213 typval_T *rettv; 8214 { 8215 #ifdef FEAT_AUTOCMD 8216 rettv->vval.v_number = did_filetype; 8217 #else 8218 rettv->vval.v_number = 0; 8219 #endif 8220 } 8221 8222 /* 8223 * "diff_filler()" function 8224 */ 8225 /*ARGSUSED*/ 8226 static void 8227 f_diff_filler(argvars, rettv) 8228 typval_T *argvars; 8229 typval_T *rettv; 8230 { 8231 #ifdef FEAT_DIFF 8232 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8233 #endif 8234 } 8235 8236 /* 8237 * "diff_hlID()" function 8238 */ 8239 /*ARGSUSED*/ 8240 static void 8241 f_diff_hlID(argvars, rettv) 8242 typval_T *argvars; 8243 typval_T *rettv; 8244 { 8245 #ifdef FEAT_DIFF 8246 linenr_T lnum = get_tv_lnum(argvars); 8247 static linenr_T prev_lnum = 0; 8248 static int changedtick = 0; 8249 static int fnum = 0; 8250 static int change_start = 0; 8251 static int change_end = 0; 8252 static enum hlf_value hlID = 0; 8253 int filler_lines; 8254 int col; 8255 8256 if (lnum < 0) /* ignore type error in {lnum} arg */ 8257 lnum = 0; 8258 if (lnum != prev_lnum 8259 || changedtick != curbuf->b_changedtick 8260 || fnum != curbuf->b_fnum) 8261 { 8262 /* New line, buffer, change: need to get the values. */ 8263 filler_lines = diff_check(curwin, lnum); 8264 if (filler_lines < 0) 8265 { 8266 if (filler_lines == -1) 8267 { 8268 change_start = MAXCOL; 8269 change_end = -1; 8270 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8271 hlID = HLF_ADD; /* added line */ 8272 else 8273 hlID = HLF_CHD; /* changed line */ 8274 } 8275 else 8276 hlID = HLF_ADD; /* added line */ 8277 } 8278 else 8279 hlID = (enum hlf_value)0; 8280 prev_lnum = lnum; 8281 changedtick = curbuf->b_changedtick; 8282 fnum = curbuf->b_fnum; 8283 } 8284 8285 if (hlID == HLF_CHD || hlID == HLF_TXD) 8286 { 8287 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8288 if (col >= change_start && col <= change_end) 8289 hlID = HLF_TXD; /* changed text */ 8290 else 8291 hlID = HLF_CHD; /* changed line */ 8292 } 8293 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8294 #endif 8295 } 8296 8297 /* 8298 * "empty({expr})" function 8299 */ 8300 static void 8301 f_empty(argvars, rettv) 8302 typval_T *argvars; 8303 typval_T *rettv; 8304 { 8305 int n; 8306 8307 switch (argvars[0].v_type) 8308 { 8309 case VAR_STRING: 8310 case VAR_FUNC: 8311 n = argvars[0].vval.v_string == NULL 8312 || *argvars[0].vval.v_string == NUL; 8313 break; 8314 case VAR_NUMBER: 8315 n = argvars[0].vval.v_number == 0; 8316 break; 8317 case VAR_LIST: 8318 n = argvars[0].vval.v_list == NULL 8319 || argvars[0].vval.v_list->lv_first == NULL; 8320 break; 8321 case VAR_DICT: 8322 n = argvars[0].vval.v_dict == NULL 8323 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8324 break; 8325 default: 8326 EMSG2(_(e_intern2), "f_empty()"); 8327 n = 0; 8328 } 8329 8330 rettv->vval.v_number = n; 8331 } 8332 8333 /* 8334 * "escape({string}, {chars})" function 8335 */ 8336 static void 8337 f_escape(argvars, rettv) 8338 typval_T *argvars; 8339 typval_T *rettv; 8340 { 8341 char_u buf[NUMBUFLEN]; 8342 8343 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8344 get_tv_string_buf(&argvars[1], buf)); 8345 rettv->v_type = VAR_STRING; 8346 } 8347 8348 /* 8349 * "eval()" function 8350 */ 8351 /*ARGSUSED*/ 8352 static void 8353 f_eval(argvars, rettv) 8354 typval_T *argvars; 8355 typval_T *rettv; 8356 { 8357 char_u *s; 8358 8359 s = get_tv_string_chk(&argvars[0]); 8360 if (s != NULL) 8361 s = skipwhite(s); 8362 8363 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8364 { 8365 rettv->v_type = VAR_NUMBER; 8366 rettv->vval.v_number = 0; 8367 } 8368 else if (*s != NUL) 8369 EMSG(_(e_trailing)); 8370 } 8371 8372 /* 8373 * "eventhandler()" function 8374 */ 8375 /*ARGSUSED*/ 8376 static void 8377 f_eventhandler(argvars, rettv) 8378 typval_T *argvars; 8379 typval_T *rettv; 8380 { 8381 rettv->vval.v_number = vgetc_busy; 8382 } 8383 8384 /* 8385 * "executable()" function 8386 */ 8387 static void 8388 f_executable(argvars, rettv) 8389 typval_T *argvars; 8390 typval_T *rettv; 8391 { 8392 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8393 } 8394 8395 /* 8396 * "exists()" function 8397 */ 8398 static void 8399 f_exists(argvars, rettv) 8400 typval_T *argvars; 8401 typval_T *rettv; 8402 { 8403 char_u *p; 8404 char_u *name; 8405 int n = FALSE; 8406 int len = 0; 8407 8408 p = get_tv_string(&argvars[0]); 8409 if (*p == '$') /* environment variable */ 8410 { 8411 /* first try "normal" environment variables (fast) */ 8412 if (mch_getenv(p + 1) != NULL) 8413 n = TRUE; 8414 else 8415 { 8416 /* try expanding things like $VIM and ${HOME} */ 8417 p = expand_env_save(p); 8418 if (p != NULL && *p != '$') 8419 n = TRUE; 8420 vim_free(p); 8421 } 8422 } 8423 else if (*p == '&' || *p == '+') /* option */ 8424 n = (get_option_tv(&p, NULL, TRUE) == OK); 8425 else if (*p == '*') /* internal or user defined function */ 8426 { 8427 n = function_exists(p + 1); 8428 } 8429 else if (*p == ':') 8430 { 8431 n = cmd_exists(p + 1); 8432 } 8433 else if (*p == '#') 8434 { 8435 #ifdef FEAT_AUTOCMD 8436 name = p + 1; 8437 p = vim_strchr(name, '#'); 8438 if (p != NULL) 8439 n = au_exists(name, p, p + 1); 8440 else 8441 n = au_exists(name, name + STRLEN(name), NULL); 8442 #endif 8443 } 8444 else /* internal variable */ 8445 { 8446 char_u *tofree; 8447 typval_T tv; 8448 8449 /* get_name_len() takes care of expanding curly braces */ 8450 name = p; 8451 len = get_name_len(&p, &tofree, TRUE, FALSE); 8452 if (len > 0) 8453 { 8454 if (tofree != NULL) 8455 name = tofree; 8456 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8457 if (n) 8458 { 8459 /* handle d.key, l[idx], f(expr) */ 8460 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8461 if (n) 8462 clear_tv(&tv); 8463 } 8464 } 8465 8466 vim_free(tofree); 8467 } 8468 8469 rettv->vval.v_number = n; 8470 } 8471 8472 /* 8473 * "expand()" function 8474 */ 8475 static void 8476 f_expand(argvars, rettv) 8477 typval_T *argvars; 8478 typval_T *rettv; 8479 { 8480 char_u *s; 8481 int len; 8482 char_u *errormsg; 8483 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8484 expand_T xpc; 8485 int error = FALSE; 8486 8487 rettv->v_type = VAR_STRING; 8488 s = get_tv_string(&argvars[0]); 8489 if (*s == '%' || *s == '#' || *s == '<') 8490 { 8491 ++emsg_off; 8492 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8493 --emsg_off; 8494 } 8495 else 8496 { 8497 /* When the optional second argument is non-zero, don't remove matches 8498 * for 'suffixes' and 'wildignore' */ 8499 if (argvars[1].v_type != VAR_UNKNOWN 8500 && get_tv_number_chk(&argvars[1], &error)) 8501 flags |= WILD_KEEP_ALL; 8502 if (!error) 8503 { 8504 ExpandInit(&xpc); 8505 xpc.xp_context = EXPAND_FILES; 8506 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8507 ExpandCleanup(&xpc); 8508 } 8509 else 8510 rettv->vval.v_string = NULL; 8511 } 8512 } 8513 8514 /* 8515 * "extend(list, list [, idx])" function 8516 * "extend(dict, dict [, action])" function 8517 */ 8518 static void 8519 f_extend(argvars, rettv) 8520 typval_T *argvars; 8521 typval_T *rettv; 8522 { 8523 rettv->vval.v_number = 0; 8524 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8525 { 8526 list_T *l1, *l2; 8527 listitem_T *item; 8528 long before; 8529 int error = FALSE; 8530 8531 l1 = argvars[0].vval.v_list; 8532 l2 = argvars[1].vval.v_list; 8533 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8534 && l2 != NULL) 8535 { 8536 if (argvars[2].v_type != VAR_UNKNOWN) 8537 { 8538 before = get_tv_number_chk(&argvars[2], &error); 8539 if (error) 8540 return; /* type error; errmsg already given */ 8541 8542 if (before == l1->lv_len) 8543 item = NULL; 8544 else 8545 { 8546 item = list_find(l1, before); 8547 if (item == NULL) 8548 { 8549 EMSGN(_(e_listidx), before); 8550 return; 8551 } 8552 } 8553 } 8554 else 8555 item = NULL; 8556 list_extend(l1, l2, item); 8557 8558 copy_tv(&argvars[0], rettv); 8559 } 8560 } 8561 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8562 { 8563 dict_T *d1, *d2; 8564 dictitem_T *di1; 8565 char_u *action; 8566 int i; 8567 hashitem_T *hi2; 8568 int todo; 8569 8570 d1 = argvars[0].vval.v_dict; 8571 d2 = argvars[1].vval.v_dict; 8572 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8573 && d2 != NULL) 8574 { 8575 /* Check the third argument. */ 8576 if (argvars[2].v_type != VAR_UNKNOWN) 8577 { 8578 static char *(av[]) = {"keep", "force", "error"}; 8579 8580 action = get_tv_string_chk(&argvars[2]); 8581 if (action == NULL) 8582 return; /* type error; errmsg already given */ 8583 for (i = 0; i < 3; ++i) 8584 if (STRCMP(action, av[i]) == 0) 8585 break; 8586 if (i == 3) 8587 { 8588 EMSGN(_(e_invarg2), action); 8589 return; 8590 } 8591 } 8592 else 8593 action = (char_u *)"force"; 8594 8595 /* Go over all entries in the second dict and add them to the 8596 * first dict. */ 8597 todo = d2->dv_hashtab.ht_used; 8598 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8599 { 8600 if (!HASHITEM_EMPTY(hi2)) 8601 { 8602 --todo; 8603 di1 = dict_find(d1, hi2->hi_key, -1); 8604 if (di1 == NULL) 8605 { 8606 di1 = dictitem_copy(HI2DI(hi2)); 8607 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8608 dictitem_free(di1); 8609 } 8610 else if (*action == 'e') 8611 { 8612 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8613 break; 8614 } 8615 else if (*action == 'f') 8616 { 8617 clear_tv(&di1->di_tv); 8618 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8619 } 8620 } 8621 } 8622 8623 copy_tv(&argvars[0], rettv); 8624 } 8625 } 8626 else 8627 EMSG2(_(e_listdictarg), "extend()"); 8628 } 8629 8630 /* 8631 * "filereadable()" function 8632 */ 8633 static void 8634 f_filereadable(argvars, rettv) 8635 typval_T *argvars; 8636 typval_T *rettv; 8637 { 8638 FILE *fd; 8639 char_u *p; 8640 int n; 8641 8642 p = get_tv_string(&argvars[0]); 8643 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8644 { 8645 n = TRUE; 8646 fclose(fd); 8647 } 8648 else 8649 n = FALSE; 8650 8651 rettv->vval.v_number = n; 8652 } 8653 8654 /* 8655 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8656 * rights to write into. 8657 */ 8658 static void 8659 f_filewritable(argvars, rettv) 8660 typval_T *argvars; 8661 typval_T *rettv; 8662 { 8663 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8664 } 8665 8666 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8667 8668 static void 8669 findfilendir(argvars, rettv, dir) 8670 typval_T *argvars; 8671 typval_T *rettv; 8672 int dir; 8673 { 8674 #ifdef FEAT_SEARCHPATH 8675 char_u *fname; 8676 char_u *fresult = NULL; 8677 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8678 char_u *p; 8679 char_u pathbuf[NUMBUFLEN]; 8680 int count = 1; 8681 int first = TRUE; 8682 8683 fname = get_tv_string(&argvars[0]); 8684 8685 if (argvars[1].v_type != VAR_UNKNOWN) 8686 { 8687 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8688 if (p == NULL) 8689 count = -1; /* error */ 8690 else 8691 { 8692 if (*p != NUL) 8693 path = p; 8694 8695 if (argvars[2].v_type != VAR_UNKNOWN) 8696 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8697 } 8698 } 8699 8700 if (*fname != NUL && count >= 0) 8701 { 8702 do 8703 { 8704 vim_free(fresult); 8705 fresult = find_file_in_path_option(first ? fname : NULL, 8706 first ? (int)STRLEN(fname) : 0, 8707 0, first, path, dir, NULL); 8708 first = FALSE; 8709 } while (--count > 0 && fresult != NULL); 8710 } 8711 8712 rettv->vval.v_string = fresult; 8713 #else 8714 rettv->vval.v_string = NULL; 8715 #endif 8716 rettv->v_type = VAR_STRING; 8717 } 8718 8719 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8720 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8721 8722 /* 8723 * Implementation of map() and filter(). 8724 */ 8725 static void 8726 filter_map(argvars, rettv, map) 8727 typval_T *argvars; 8728 typval_T *rettv; 8729 int map; 8730 { 8731 char_u buf[NUMBUFLEN]; 8732 char_u *expr; 8733 listitem_T *li, *nli; 8734 list_T *l = NULL; 8735 dictitem_T *di; 8736 hashtab_T *ht; 8737 hashitem_T *hi; 8738 dict_T *d = NULL; 8739 typval_T save_val; 8740 typval_T save_key; 8741 int rem; 8742 int todo; 8743 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8744 8745 8746 rettv->vval.v_number = 0; 8747 if (argvars[0].v_type == VAR_LIST) 8748 { 8749 if ((l = argvars[0].vval.v_list) == NULL 8750 || (map && tv_check_lock(l->lv_lock, msg))) 8751 return; 8752 } 8753 else if (argvars[0].v_type == VAR_DICT) 8754 { 8755 if ((d = argvars[0].vval.v_dict) == NULL 8756 || (map && tv_check_lock(d->dv_lock, msg))) 8757 return; 8758 } 8759 else 8760 { 8761 EMSG2(_(e_listdictarg), msg); 8762 return; 8763 } 8764 8765 expr = get_tv_string_buf_chk(&argvars[1], buf); 8766 /* On type errors, the preceding call has already displayed an error 8767 * message. Avoid a misleading error message for an empty string that 8768 * was not passed as argument. */ 8769 if (expr != NULL) 8770 { 8771 prepare_vimvar(VV_VAL, &save_val); 8772 expr = skipwhite(expr); 8773 8774 if (argvars[0].v_type == VAR_DICT) 8775 { 8776 prepare_vimvar(VV_KEY, &save_key); 8777 vimvars[VV_KEY].vv_type = VAR_STRING; 8778 8779 ht = &d->dv_hashtab; 8780 hash_lock(ht); 8781 todo = ht->ht_used; 8782 for (hi = ht->ht_array; todo > 0; ++hi) 8783 { 8784 if (!HASHITEM_EMPTY(hi)) 8785 { 8786 --todo; 8787 di = HI2DI(hi); 8788 if (tv_check_lock(di->di_tv.v_lock, msg)) 8789 break; 8790 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8791 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8792 break; 8793 if (!map && rem) 8794 dictitem_remove(d, di); 8795 clear_tv(&vimvars[VV_KEY].vv_tv); 8796 } 8797 } 8798 hash_unlock(ht); 8799 8800 restore_vimvar(VV_KEY, &save_key); 8801 } 8802 else 8803 { 8804 for (li = l->lv_first; li != NULL; li = nli) 8805 { 8806 if (tv_check_lock(li->li_tv.v_lock, msg)) 8807 break; 8808 nli = li->li_next; 8809 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8810 break; 8811 if (!map && rem) 8812 listitem_remove(l, li); 8813 } 8814 } 8815 8816 restore_vimvar(VV_VAL, &save_val); 8817 } 8818 8819 copy_tv(&argvars[0], rettv); 8820 } 8821 8822 static int 8823 filter_map_one(tv, expr, map, remp) 8824 typval_T *tv; 8825 char_u *expr; 8826 int map; 8827 int *remp; 8828 { 8829 typval_T rettv; 8830 char_u *s; 8831 8832 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8833 s = expr; 8834 if (eval1(&s, &rettv, TRUE) == FAIL) 8835 return FAIL; 8836 if (*s != NUL) /* check for trailing chars after expr */ 8837 { 8838 EMSG2(_(e_invexpr2), s); 8839 return FAIL; 8840 } 8841 if (map) 8842 { 8843 /* map(): replace the list item value */ 8844 clear_tv(tv); 8845 *tv = rettv; 8846 } 8847 else 8848 { 8849 int error = FALSE; 8850 8851 /* filter(): when expr is zero remove the item */ 8852 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8853 clear_tv(&rettv); 8854 /* On type error, nothing has been removed; return FAIL to stop the 8855 * loop. The error message was given by get_tv_number_chk(). */ 8856 if (error) 8857 return FAIL; 8858 } 8859 clear_tv(&vimvars[VV_VAL].vv_tv); 8860 return OK; 8861 } 8862 8863 /* 8864 * "filter()" function 8865 */ 8866 static void 8867 f_filter(argvars, rettv) 8868 typval_T *argvars; 8869 typval_T *rettv; 8870 { 8871 filter_map(argvars, rettv, FALSE); 8872 } 8873 8874 /* 8875 * "finddir({fname}[, {path}[, {count}]])" function 8876 */ 8877 static void 8878 f_finddir(argvars, rettv) 8879 typval_T *argvars; 8880 typval_T *rettv; 8881 { 8882 findfilendir(argvars, rettv, TRUE); 8883 } 8884 8885 /* 8886 * "findfile({fname}[, {path}[, {count}]])" function 8887 */ 8888 static void 8889 f_findfile(argvars, rettv) 8890 typval_T *argvars; 8891 typval_T *rettv; 8892 { 8893 findfilendir(argvars, rettv, FALSE); 8894 } 8895 8896 /* 8897 * "fnamemodify({fname}, {mods})" function 8898 */ 8899 static void 8900 f_fnamemodify(argvars, rettv) 8901 typval_T *argvars; 8902 typval_T *rettv; 8903 { 8904 char_u *fname; 8905 char_u *mods; 8906 int usedlen = 0; 8907 int len; 8908 char_u *fbuf = NULL; 8909 char_u buf[NUMBUFLEN]; 8910 8911 fname = get_tv_string_chk(&argvars[0]); 8912 mods = get_tv_string_buf_chk(&argvars[1], buf); 8913 if (fname == NULL || mods == NULL) 8914 fname = NULL; 8915 else 8916 { 8917 len = (int)STRLEN(fname); 8918 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8919 } 8920 8921 rettv->v_type = VAR_STRING; 8922 if (fname == NULL) 8923 rettv->vval.v_string = NULL; 8924 else 8925 rettv->vval.v_string = vim_strnsave(fname, len); 8926 vim_free(fbuf); 8927 } 8928 8929 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8930 8931 /* 8932 * "foldclosed()" function 8933 */ 8934 static void 8935 foldclosed_both(argvars, rettv, end) 8936 typval_T *argvars; 8937 typval_T *rettv; 8938 int end; 8939 { 8940 #ifdef FEAT_FOLDING 8941 linenr_T lnum; 8942 linenr_T first, last; 8943 8944 lnum = get_tv_lnum(argvars); 8945 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8946 { 8947 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8948 { 8949 if (end) 8950 rettv->vval.v_number = (varnumber_T)last; 8951 else 8952 rettv->vval.v_number = (varnumber_T)first; 8953 return; 8954 } 8955 } 8956 #endif 8957 rettv->vval.v_number = -1; 8958 } 8959 8960 /* 8961 * "foldclosed()" function 8962 */ 8963 static void 8964 f_foldclosed(argvars, rettv) 8965 typval_T *argvars; 8966 typval_T *rettv; 8967 { 8968 foldclosed_both(argvars, rettv, FALSE); 8969 } 8970 8971 /* 8972 * "foldclosedend()" function 8973 */ 8974 static void 8975 f_foldclosedend(argvars, rettv) 8976 typval_T *argvars; 8977 typval_T *rettv; 8978 { 8979 foldclosed_both(argvars, rettv, TRUE); 8980 } 8981 8982 /* 8983 * "foldlevel()" function 8984 */ 8985 static void 8986 f_foldlevel(argvars, rettv) 8987 typval_T *argvars; 8988 typval_T *rettv; 8989 { 8990 #ifdef FEAT_FOLDING 8991 linenr_T lnum; 8992 8993 lnum = get_tv_lnum(argvars); 8994 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8995 rettv->vval.v_number = foldLevel(lnum); 8996 else 8997 #endif 8998 rettv->vval.v_number = 0; 8999 } 9000 9001 /* 9002 * "foldtext()" function 9003 */ 9004 /*ARGSUSED*/ 9005 static void 9006 f_foldtext(argvars, rettv) 9007 typval_T *argvars; 9008 typval_T *rettv; 9009 { 9010 #ifdef FEAT_FOLDING 9011 linenr_T lnum; 9012 char_u *s; 9013 char_u *r; 9014 int len; 9015 char *txt; 9016 #endif 9017 9018 rettv->v_type = VAR_STRING; 9019 rettv->vval.v_string = NULL; 9020 #ifdef FEAT_FOLDING 9021 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 9022 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 9023 <= curbuf->b_ml.ml_line_count 9024 && vimvars[VV_FOLDDASHES].vv_str != NULL) 9025 { 9026 /* Find first non-empty line in the fold. */ 9027 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 9028 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9029 { 9030 if (!linewhite(lnum)) 9031 break; 9032 ++lnum; 9033 } 9034 9035 /* Find interesting text in this line. */ 9036 s = skipwhite(ml_get(lnum)); 9037 /* skip C comment-start */ 9038 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 9039 { 9040 s = skipwhite(s + 2); 9041 if (*skipwhite(s) == NUL 9042 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 9043 { 9044 s = skipwhite(ml_get(lnum + 1)); 9045 if (*s == '*') 9046 s = skipwhite(s + 1); 9047 } 9048 } 9049 txt = _("+-%s%3ld lines: "); 9050 r = alloc((unsigned)(STRLEN(txt) 9051 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 9052 + 20 /* for %3ld */ 9053 + STRLEN(s))); /* concatenated */ 9054 if (r != NULL) 9055 { 9056 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 9057 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 9058 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 9059 len = (int)STRLEN(r); 9060 STRCAT(r, s); 9061 /* remove 'foldmarker' and 'commentstring' */ 9062 foldtext_cleanup(r + len); 9063 rettv->vval.v_string = r; 9064 } 9065 } 9066 #endif 9067 } 9068 9069 /* 9070 * "foldtextresult(lnum)" function 9071 */ 9072 /*ARGSUSED*/ 9073 static void 9074 f_foldtextresult(argvars, rettv) 9075 typval_T *argvars; 9076 typval_T *rettv; 9077 { 9078 #ifdef FEAT_FOLDING 9079 linenr_T lnum; 9080 char_u *text; 9081 char_u buf[51]; 9082 foldinfo_T foldinfo; 9083 int fold_count; 9084 #endif 9085 9086 rettv->v_type = VAR_STRING; 9087 rettv->vval.v_string = NULL; 9088 #ifdef FEAT_FOLDING 9089 lnum = get_tv_lnum(argvars); 9090 /* treat illegal types and illegal string values for {lnum} the same */ 9091 if (lnum < 0) 9092 lnum = 0; 9093 fold_count = foldedCount(curwin, lnum, &foldinfo); 9094 if (fold_count > 0) 9095 { 9096 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9097 &foldinfo, buf); 9098 if (text == buf) 9099 text = vim_strsave(text); 9100 rettv->vval.v_string = text; 9101 } 9102 #endif 9103 } 9104 9105 /* 9106 * "foreground()" function 9107 */ 9108 /*ARGSUSED*/ 9109 static void 9110 f_foreground(argvars, rettv) 9111 typval_T *argvars; 9112 typval_T *rettv; 9113 { 9114 rettv->vval.v_number = 0; 9115 #ifdef FEAT_GUI 9116 if (gui.in_use) 9117 gui_mch_set_foreground(); 9118 #else 9119 # ifdef WIN32 9120 win32_set_foreground(); 9121 # endif 9122 #endif 9123 } 9124 9125 /* 9126 * "function()" function 9127 */ 9128 /*ARGSUSED*/ 9129 static void 9130 f_function(argvars, rettv) 9131 typval_T *argvars; 9132 typval_T *rettv; 9133 { 9134 char_u *s; 9135 9136 rettv->vval.v_number = 0; 9137 s = get_tv_string(&argvars[0]); 9138 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9139 EMSG2(_(e_invarg2), s); 9140 else if (!function_exists(s)) 9141 EMSG2(_("E700: Unknown function: %s"), s); 9142 else 9143 { 9144 rettv->vval.v_string = vim_strsave(s); 9145 rettv->v_type = VAR_FUNC; 9146 } 9147 } 9148 9149 /* 9150 * "garbagecollect()" function 9151 */ 9152 /*ARGSUSED*/ 9153 static void 9154 f_garbagecollect(argvars, rettv) 9155 typval_T *argvars; 9156 typval_T *rettv; 9157 { 9158 garbage_collect(); 9159 } 9160 9161 /* 9162 * "get()" function 9163 */ 9164 static void 9165 f_get(argvars, rettv) 9166 typval_T *argvars; 9167 typval_T *rettv; 9168 { 9169 listitem_T *li; 9170 list_T *l; 9171 dictitem_T *di; 9172 dict_T *d; 9173 typval_T *tv = NULL; 9174 9175 if (argvars[0].v_type == VAR_LIST) 9176 { 9177 if ((l = argvars[0].vval.v_list) != NULL) 9178 { 9179 int error = FALSE; 9180 9181 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9182 if (!error && li != NULL) 9183 tv = &li->li_tv; 9184 } 9185 } 9186 else if (argvars[0].v_type == VAR_DICT) 9187 { 9188 if ((d = argvars[0].vval.v_dict) != NULL) 9189 { 9190 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9191 if (di != NULL) 9192 tv = &di->di_tv; 9193 } 9194 } 9195 else 9196 EMSG2(_(e_listdictarg), "get()"); 9197 9198 if (tv == NULL) 9199 { 9200 if (argvars[2].v_type == VAR_UNKNOWN) 9201 rettv->vval.v_number = 0; 9202 else 9203 copy_tv(&argvars[2], rettv); 9204 } 9205 else 9206 copy_tv(tv, rettv); 9207 } 9208 9209 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9210 9211 /* 9212 * Get line or list of lines from buffer "buf" into "rettv". 9213 * Return a range (from start to end) of lines in rettv from the specified 9214 * buffer. 9215 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9216 */ 9217 static void 9218 get_buffer_lines(buf, start, end, retlist, rettv) 9219 buf_T *buf; 9220 linenr_T start; 9221 linenr_T end; 9222 int retlist; 9223 typval_T *rettv; 9224 { 9225 char_u *p; 9226 list_T *l = NULL; 9227 9228 if (retlist) 9229 { 9230 l = list_alloc(); 9231 if (l == NULL) 9232 return; 9233 9234 rettv->vval.v_list = l; 9235 rettv->v_type = VAR_LIST; 9236 ++l->lv_refcount; 9237 } 9238 else 9239 rettv->vval.v_number = 0; 9240 9241 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9242 return; 9243 9244 if (!retlist) 9245 { 9246 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9247 p = ml_get_buf(buf, start, FALSE); 9248 else 9249 p = (char_u *)""; 9250 9251 rettv->v_type = VAR_STRING; 9252 rettv->vval.v_string = vim_strsave(p); 9253 } 9254 else 9255 { 9256 if (end < start) 9257 return; 9258 9259 if (start < 1) 9260 start = 1; 9261 if (end > buf->b_ml.ml_line_count) 9262 end = buf->b_ml.ml_line_count; 9263 while (start <= end) 9264 if (list_append_string(l, ml_get_buf(buf, start++, FALSE)) == FAIL) 9265 break; 9266 } 9267 } 9268 9269 /* 9270 * "getbufline()" function 9271 */ 9272 static void 9273 f_getbufline(argvars, rettv) 9274 typval_T *argvars; 9275 typval_T *rettv; 9276 { 9277 linenr_T lnum; 9278 linenr_T end; 9279 buf_T *buf; 9280 9281 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9282 ++emsg_off; 9283 buf = get_buf_tv(&argvars[0]); 9284 --emsg_off; 9285 9286 lnum = get_tv_lnum_buf(&argvars[1], buf); 9287 if (argvars[2].v_type == VAR_UNKNOWN) 9288 end = lnum; 9289 else 9290 end = get_tv_lnum_buf(&argvars[2], buf); 9291 9292 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9293 } 9294 9295 /* 9296 * "getbufvar()" function 9297 */ 9298 static void 9299 f_getbufvar(argvars, rettv) 9300 typval_T *argvars; 9301 typval_T *rettv; 9302 { 9303 buf_T *buf; 9304 buf_T *save_curbuf; 9305 char_u *varname; 9306 dictitem_T *v; 9307 9308 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9309 varname = get_tv_string_chk(&argvars[1]); 9310 ++emsg_off; 9311 buf = get_buf_tv(&argvars[0]); 9312 9313 rettv->v_type = VAR_STRING; 9314 rettv->vval.v_string = NULL; 9315 9316 if (buf != NULL && varname != NULL) 9317 { 9318 if (*varname == '&') /* buffer-local-option */ 9319 { 9320 /* set curbuf to be our buf, temporarily */ 9321 save_curbuf = curbuf; 9322 curbuf = buf; 9323 9324 get_option_tv(&varname, rettv, TRUE); 9325 9326 /* restore previous notion of curbuf */ 9327 curbuf = save_curbuf; 9328 } 9329 else 9330 { 9331 if (*varname == NUL) 9332 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9333 * scope prefix before the NUL byte is required by 9334 * find_var_in_ht(). */ 9335 varname = (char_u *)"b:" + 2; 9336 /* look up the variable */ 9337 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9338 if (v != NULL) 9339 copy_tv(&v->di_tv, rettv); 9340 } 9341 } 9342 9343 --emsg_off; 9344 } 9345 9346 /* 9347 * "getchar()" function 9348 */ 9349 static void 9350 f_getchar(argvars, rettv) 9351 typval_T *argvars; 9352 typval_T *rettv; 9353 { 9354 varnumber_T n; 9355 int error = FALSE; 9356 9357 ++no_mapping; 9358 ++allow_keys; 9359 if (argvars[0].v_type == VAR_UNKNOWN) 9360 /* getchar(): blocking wait. */ 9361 n = safe_vgetc(); 9362 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9363 /* getchar(1): only check if char avail */ 9364 n = vpeekc(); 9365 else if (error || vpeekc() == NUL) 9366 /* illegal argument or getchar(0) and no char avail: return zero */ 9367 n = 0; 9368 else 9369 /* getchar(0) and char avail: return char */ 9370 n = safe_vgetc(); 9371 --no_mapping; 9372 --allow_keys; 9373 9374 rettv->vval.v_number = n; 9375 if (IS_SPECIAL(n) || mod_mask != 0) 9376 { 9377 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9378 int i = 0; 9379 9380 /* Turn a special key into three bytes, plus modifier. */ 9381 if (mod_mask != 0) 9382 { 9383 temp[i++] = K_SPECIAL; 9384 temp[i++] = KS_MODIFIER; 9385 temp[i++] = mod_mask; 9386 } 9387 if (IS_SPECIAL(n)) 9388 { 9389 temp[i++] = K_SPECIAL; 9390 temp[i++] = K_SECOND(n); 9391 temp[i++] = K_THIRD(n); 9392 } 9393 #ifdef FEAT_MBYTE 9394 else if (has_mbyte) 9395 i += (*mb_char2bytes)(n, temp + i); 9396 #endif 9397 else 9398 temp[i++] = n; 9399 temp[i++] = NUL; 9400 rettv->v_type = VAR_STRING; 9401 rettv->vval.v_string = vim_strsave(temp); 9402 } 9403 } 9404 9405 /* 9406 * "getcharmod()" function 9407 */ 9408 /*ARGSUSED*/ 9409 static void 9410 f_getcharmod(argvars, rettv) 9411 typval_T *argvars; 9412 typval_T *rettv; 9413 { 9414 rettv->vval.v_number = mod_mask; 9415 } 9416 9417 /* 9418 * "getcmdline()" function 9419 */ 9420 /*ARGSUSED*/ 9421 static void 9422 f_getcmdline(argvars, rettv) 9423 typval_T *argvars; 9424 typval_T *rettv; 9425 { 9426 rettv->v_type = VAR_STRING; 9427 rettv->vval.v_string = get_cmdline_str(); 9428 } 9429 9430 /* 9431 * "getcmdpos()" function 9432 */ 9433 /*ARGSUSED*/ 9434 static void 9435 f_getcmdpos(argvars, rettv) 9436 typval_T *argvars; 9437 typval_T *rettv; 9438 { 9439 rettv->vval.v_number = get_cmdline_pos() + 1; 9440 } 9441 9442 /* 9443 * "getcmdtype()" function 9444 */ 9445 /*ARGSUSED*/ 9446 static void 9447 f_getcmdtype(argvars, rettv) 9448 typval_T *argvars; 9449 typval_T *rettv; 9450 { 9451 rettv->v_type = VAR_STRING; 9452 rettv->vval.v_string = alloc(2); 9453 if (rettv->vval.v_string != NULL) 9454 { 9455 rettv->vval.v_string[0] = get_cmdline_type(); 9456 rettv->vval.v_string[1] = NUL; 9457 } 9458 } 9459 9460 /* 9461 * "getcwd()" function 9462 */ 9463 /*ARGSUSED*/ 9464 static void 9465 f_getcwd(argvars, rettv) 9466 typval_T *argvars; 9467 typval_T *rettv; 9468 { 9469 char_u cwd[MAXPATHL]; 9470 9471 rettv->v_type = VAR_STRING; 9472 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9473 rettv->vval.v_string = NULL; 9474 else 9475 { 9476 rettv->vval.v_string = vim_strsave(cwd); 9477 #ifdef BACKSLASH_IN_FILENAME 9478 if (rettv->vval.v_string != NULL) 9479 slash_adjust(rettv->vval.v_string); 9480 #endif 9481 } 9482 } 9483 9484 /* 9485 * "getfontname()" function 9486 */ 9487 /*ARGSUSED*/ 9488 static void 9489 f_getfontname(argvars, rettv) 9490 typval_T *argvars; 9491 typval_T *rettv; 9492 { 9493 rettv->v_type = VAR_STRING; 9494 rettv->vval.v_string = NULL; 9495 #ifdef FEAT_GUI 9496 if (gui.in_use) 9497 { 9498 GuiFont font; 9499 char_u *name = NULL; 9500 9501 if (argvars[0].v_type == VAR_UNKNOWN) 9502 { 9503 /* Get the "Normal" font. Either the name saved by 9504 * hl_set_font_name() or from the font ID. */ 9505 font = gui.norm_font; 9506 name = hl_get_font_name(); 9507 } 9508 else 9509 { 9510 name = get_tv_string(&argvars[0]); 9511 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9512 return; 9513 font = gui_mch_get_font(name, FALSE); 9514 if (font == NOFONT) 9515 return; /* Invalid font name, return empty string. */ 9516 } 9517 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9518 if (argvars[0].v_type != VAR_UNKNOWN) 9519 gui_mch_free_font(font); 9520 } 9521 #endif 9522 } 9523 9524 /* 9525 * "getfperm({fname})" function 9526 */ 9527 static void 9528 f_getfperm(argvars, rettv) 9529 typval_T *argvars; 9530 typval_T *rettv; 9531 { 9532 char_u *fname; 9533 struct stat st; 9534 char_u *perm = NULL; 9535 char_u flags[] = "rwx"; 9536 int i; 9537 9538 fname = get_tv_string(&argvars[0]); 9539 9540 rettv->v_type = VAR_STRING; 9541 if (mch_stat((char *)fname, &st) >= 0) 9542 { 9543 perm = vim_strsave((char_u *)"---------"); 9544 if (perm != NULL) 9545 { 9546 for (i = 0; i < 9; i++) 9547 { 9548 if (st.st_mode & (1 << (8 - i))) 9549 perm[i] = flags[i % 3]; 9550 } 9551 } 9552 } 9553 rettv->vval.v_string = perm; 9554 } 9555 9556 /* 9557 * "getfsize({fname})" function 9558 */ 9559 static void 9560 f_getfsize(argvars, rettv) 9561 typval_T *argvars; 9562 typval_T *rettv; 9563 { 9564 char_u *fname; 9565 struct stat st; 9566 9567 fname = get_tv_string(&argvars[0]); 9568 9569 rettv->v_type = VAR_NUMBER; 9570 9571 if (mch_stat((char *)fname, &st) >= 0) 9572 { 9573 if (mch_isdir(fname)) 9574 rettv->vval.v_number = 0; 9575 else 9576 rettv->vval.v_number = (varnumber_T)st.st_size; 9577 } 9578 else 9579 rettv->vval.v_number = -1; 9580 } 9581 9582 /* 9583 * "getftime({fname})" function 9584 */ 9585 static void 9586 f_getftime(argvars, rettv) 9587 typval_T *argvars; 9588 typval_T *rettv; 9589 { 9590 char_u *fname; 9591 struct stat st; 9592 9593 fname = get_tv_string(&argvars[0]); 9594 9595 if (mch_stat((char *)fname, &st) >= 0) 9596 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9597 else 9598 rettv->vval.v_number = -1; 9599 } 9600 9601 /* 9602 * "getftype({fname})" function 9603 */ 9604 static void 9605 f_getftype(argvars, rettv) 9606 typval_T *argvars; 9607 typval_T *rettv; 9608 { 9609 char_u *fname; 9610 struct stat st; 9611 char_u *type = NULL; 9612 char *t; 9613 9614 fname = get_tv_string(&argvars[0]); 9615 9616 rettv->v_type = VAR_STRING; 9617 if (mch_lstat((char *)fname, &st) >= 0) 9618 { 9619 #ifdef S_ISREG 9620 if (S_ISREG(st.st_mode)) 9621 t = "file"; 9622 else if (S_ISDIR(st.st_mode)) 9623 t = "dir"; 9624 # ifdef S_ISLNK 9625 else if (S_ISLNK(st.st_mode)) 9626 t = "link"; 9627 # endif 9628 # ifdef S_ISBLK 9629 else if (S_ISBLK(st.st_mode)) 9630 t = "bdev"; 9631 # endif 9632 # ifdef S_ISCHR 9633 else if (S_ISCHR(st.st_mode)) 9634 t = "cdev"; 9635 # endif 9636 # ifdef S_ISFIFO 9637 else if (S_ISFIFO(st.st_mode)) 9638 t = "fifo"; 9639 # endif 9640 # ifdef S_ISSOCK 9641 else if (S_ISSOCK(st.st_mode)) 9642 t = "fifo"; 9643 # endif 9644 else 9645 t = "other"; 9646 #else 9647 # ifdef S_IFMT 9648 switch (st.st_mode & S_IFMT) 9649 { 9650 case S_IFREG: t = "file"; break; 9651 case S_IFDIR: t = "dir"; break; 9652 # ifdef S_IFLNK 9653 case S_IFLNK: t = "link"; break; 9654 # endif 9655 # ifdef S_IFBLK 9656 case S_IFBLK: t = "bdev"; break; 9657 # endif 9658 # ifdef S_IFCHR 9659 case S_IFCHR: t = "cdev"; break; 9660 # endif 9661 # ifdef S_IFIFO 9662 case S_IFIFO: t = "fifo"; break; 9663 # endif 9664 # ifdef S_IFSOCK 9665 case S_IFSOCK: t = "socket"; break; 9666 # endif 9667 default: t = "other"; 9668 } 9669 # else 9670 if (mch_isdir(fname)) 9671 t = "dir"; 9672 else 9673 t = "file"; 9674 # endif 9675 #endif 9676 type = vim_strsave((char_u *)t); 9677 } 9678 rettv->vval.v_string = type; 9679 } 9680 9681 /* 9682 * "getline(lnum, [end])" function 9683 */ 9684 static void 9685 f_getline(argvars, rettv) 9686 typval_T *argvars; 9687 typval_T *rettv; 9688 { 9689 linenr_T lnum; 9690 linenr_T end; 9691 int retlist; 9692 9693 lnum = get_tv_lnum(argvars); 9694 if (argvars[1].v_type == VAR_UNKNOWN) 9695 { 9696 end = 0; 9697 retlist = FALSE; 9698 } 9699 else 9700 { 9701 end = get_tv_lnum(&argvars[1]); 9702 retlist = TRUE; 9703 } 9704 9705 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9706 } 9707 9708 /* 9709 * "getqflist()" function 9710 */ 9711 /*ARGSUSED*/ 9712 static void 9713 f_getqflist(argvars, rettv) 9714 typval_T *argvars; 9715 typval_T *rettv; 9716 { 9717 #ifdef FEAT_QUICKFIX 9718 list_T *l; 9719 #endif 9720 9721 rettv->vval.v_number = FALSE; 9722 #ifdef FEAT_QUICKFIX 9723 l = list_alloc(); 9724 if (l != NULL) 9725 { 9726 rettv->vval.v_list = l; 9727 rettv->v_type = VAR_LIST; 9728 ++l->lv_refcount; 9729 (void)get_errorlist(l); 9730 } 9731 #endif 9732 } 9733 9734 /* 9735 * "getreg()" function 9736 */ 9737 static void 9738 f_getreg(argvars, rettv) 9739 typval_T *argvars; 9740 typval_T *rettv; 9741 { 9742 char_u *strregname; 9743 int regname; 9744 int arg2 = FALSE; 9745 int error = FALSE; 9746 9747 if (argvars[0].v_type != VAR_UNKNOWN) 9748 { 9749 strregname = get_tv_string_chk(&argvars[0]); 9750 error = strregname == NULL; 9751 if (argvars[1].v_type != VAR_UNKNOWN) 9752 arg2 = get_tv_number_chk(&argvars[1], &error); 9753 } 9754 else 9755 strregname = vimvars[VV_REG].vv_str; 9756 regname = (strregname == NULL ? '"' : *strregname); 9757 if (regname == 0) 9758 regname = '"'; 9759 9760 rettv->v_type = VAR_STRING; 9761 rettv->vval.v_string = error ? NULL : 9762 get_reg_contents(regname, TRUE, arg2); 9763 } 9764 9765 /* 9766 * "getregtype()" function 9767 */ 9768 static void 9769 f_getregtype(argvars, rettv) 9770 typval_T *argvars; 9771 typval_T *rettv; 9772 { 9773 char_u *strregname; 9774 int regname; 9775 char_u buf[NUMBUFLEN + 2]; 9776 long reglen = 0; 9777 9778 if (argvars[0].v_type != VAR_UNKNOWN) 9779 { 9780 strregname = get_tv_string_chk(&argvars[0]); 9781 if (strregname == NULL) /* type error; errmsg already given */ 9782 { 9783 rettv->v_type = VAR_STRING; 9784 rettv->vval.v_string = NULL; 9785 return; 9786 } 9787 } 9788 else 9789 /* Default to v:register */ 9790 strregname = vimvars[VV_REG].vv_str; 9791 9792 regname = (strregname == NULL ? '"' : *strregname); 9793 if (regname == 0) 9794 regname = '"'; 9795 9796 buf[0] = NUL; 9797 buf[1] = NUL; 9798 switch (get_reg_type(regname, ®len)) 9799 { 9800 case MLINE: buf[0] = 'V'; break; 9801 case MCHAR: buf[0] = 'v'; break; 9802 #ifdef FEAT_VISUAL 9803 case MBLOCK: 9804 buf[0] = Ctrl_V; 9805 sprintf((char *)buf + 1, "%ld", reglen + 1); 9806 break; 9807 #endif 9808 } 9809 rettv->v_type = VAR_STRING; 9810 rettv->vval.v_string = vim_strsave(buf); 9811 } 9812 9813 /* 9814 * "getwinposx()" function 9815 */ 9816 /*ARGSUSED*/ 9817 static void 9818 f_getwinposx(argvars, rettv) 9819 typval_T *argvars; 9820 typval_T *rettv; 9821 { 9822 rettv->vval.v_number = -1; 9823 #ifdef FEAT_GUI 9824 if (gui.in_use) 9825 { 9826 int x, y; 9827 9828 if (gui_mch_get_winpos(&x, &y) == OK) 9829 rettv->vval.v_number = x; 9830 } 9831 #endif 9832 } 9833 9834 /* 9835 * "getwinposy()" function 9836 */ 9837 /*ARGSUSED*/ 9838 static void 9839 f_getwinposy(argvars, rettv) 9840 typval_T *argvars; 9841 typval_T *rettv; 9842 { 9843 rettv->vval.v_number = -1; 9844 #ifdef FEAT_GUI 9845 if (gui.in_use) 9846 { 9847 int x, y; 9848 9849 if (gui_mch_get_winpos(&x, &y) == OK) 9850 rettv->vval.v_number = y; 9851 } 9852 #endif 9853 } 9854 9855 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9856 9857 static win_T * 9858 find_win_by_nr(vp) 9859 typval_T *vp; 9860 { 9861 #ifdef FEAT_WINDOWS 9862 win_T *wp; 9863 #endif 9864 int nr; 9865 9866 nr = get_tv_number_chk(vp, NULL); 9867 9868 #ifdef FEAT_WINDOWS 9869 if (nr < 0) 9870 return NULL; 9871 if (nr == 0) 9872 return curwin; 9873 9874 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9875 if (--nr <= 0) 9876 break; 9877 return wp; 9878 #else 9879 if (nr == 0 || nr == 1) 9880 return curwin; 9881 return NULL; 9882 #endif 9883 } 9884 9885 /* 9886 * "getwinvar()" function 9887 */ 9888 static void 9889 f_getwinvar(argvars, rettv) 9890 typval_T *argvars; 9891 typval_T *rettv; 9892 { 9893 win_T *win, *oldcurwin; 9894 char_u *varname; 9895 dictitem_T *v; 9896 9897 win = find_win_by_nr(&argvars[0]); 9898 varname = get_tv_string_chk(&argvars[1]); 9899 ++emsg_off; 9900 9901 rettv->v_type = VAR_STRING; 9902 rettv->vval.v_string = NULL; 9903 9904 if (win != NULL && varname != NULL) 9905 { 9906 if (*varname == '&') /* window-local-option */ 9907 { 9908 /* Set curwin to be our win, temporarily. Also set curbuf, so 9909 * that we can get buffer-local options. */ 9910 oldcurwin = curwin; 9911 curwin = win; 9912 curbuf = win->w_buffer; 9913 9914 get_option_tv(&varname, rettv, 1); 9915 9916 /* restore previous notion of curwin */ 9917 curwin = oldcurwin; 9918 curbuf = curwin->w_buffer; 9919 } 9920 else 9921 { 9922 if (*varname == NUL) 9923 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9924 * scope prefix before the NUL byte is required by 9925 * find_var_in_ht(). */ 9926 varname = (char_u *)"w:" + 2; 9927 /* look up the variable */ 9928 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9929 if (v != NULL) 9930 copy_tv(&v->di_tv, rettv); 9931 } 9932 } 9933 9934 --emsg_off; 9935 } 9936 9937 /* 9938 * "glob()" function 9939 */ 9940 static void 9941 f_glob(argvars, rettv) 9942 typval_T *argvars; 9943 typval_T *rettv; 9944 { 9945 expand_T xpc; 9946 9947 ExpandInit(&xpc); 9948 xpc.xp_context = EXPAND_FILES; 9949 rettv->v_type = VAR_STRING; 9950 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9951 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9952 ExpandCleanup(&xpc); 9953 } 9954 9955 /* 9956 * "globpath()" function 9957 */ 9958 static void 9959 f_globpath(argvars, rettv) 9960 typval_T *argvars; 9961 typval_T *rettv; 9962 { 9963 char_u buf1[NUMBUFLEN]; 9964 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9965 9966 rettv->v_type = VAR_STRING; 9967 if (file == NULL) 9968 rettv->vval.v_string = NULL; 9969 else 9970 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9971 } 9972 9973 /* 9974 * "has()" function 9975 */ 9976 static void 9977 f_has(argvars, rettv) 9978 typval_T *argvars; 9979 typval_T *rettv; 9980 { 9981 int i; 9982 char_u *name; 9983 int n = FALSE; 9984 static char *(has_list[]) = 9985 { 9986 #ifdef AMIGA 9987 "amiga", 9988 # ifdef FEAT_ARP 9989 "arp", 9990 # endif 9991 #endif 9992 #ifdef __BEOS__ 9993 "beos", 9994 #endif 9995 #ifdef MSDOS 9996 # ifdef DJGPP 9997 "dos32", 9998 # else 9999 "dos16", 10000 # endif 10001 #endif 10002 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 10003 "mac", 10004 #endif 10005 #if defined(MACOS_X_UNIX) 10006 "macunix", 10007 #endif 10008 #ifdef OS2 10009 "os2", 10010 #endif 10011 #ifdef __QNX__ 10012 "qnx", 10013 #endif 10014 #ifdef RISCOS 10015 "riscos", 10016 #endif 10017 #ifdef UNIX 10018 "unix", 10019 #endif 10020 #ifdef VMS 10021 "vms", 10022 #endif 10023 #ifdef WIN16 10024 "win16", 10025 #endif 10026 #ifdef WIN32 10027 "win32", 10028 #endif 10029 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 10030 "win32unix", 10031 #endif 10032 #ifdef WIN64 10033 "win64", 10034 #endif 10035 #ifdef EBCDIC 10036 "ebcdic", 10037 #endif 10038 #ifndef CASE_INSENSITIVE_FILENAME 10039 "fname_case", 10040 #endif 10041 #ifdef FEAT_ARABIC 10042 "arabic", 10043 #endif 10044 #ifdef FEAT_AUTOCMD 10045 "autocmd", 10046 #endif 10047 #ifdef FEAT_BEVAL 10048 "balloon_eval", 10049 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 10050 "balloon_multiline", 10051 # endif 10052 #endif 10053 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 10054 "builtin_terms", 10055 # ifdef ALL_BUILTIN_TCAPS 10056 "all_builtin_terms", 10057 # endif 10058 #endif 10059 #ifdef FEAT_BYTEOFF 10060 "byte_offset", 10061 #endif 10062 #ifdef FEAT_CINDENT 10063 "cindent", 10064 #endif 10065 #ifdef FEAT_CLIENTSERVER 10066 "clientserver", 10067 #endif 10068 #ifdef FEAT_CLIPBOARD 10069 "clipboard", 10070 #endif 10071 #ifdef FEAT_CMDL_COMPL 10072 "cmdline_compl", 10073 #endif 10074 #ifdef FEAT_CMDHIST 10075 "cmdline_hist", 10076 #endif 10077 #ifdef FEAT_COMMENTS 10078 "comments", 10079 #endif 10080 #ifdef FEAT_CRYPT 10081 "cryptv", 10082 #endif 10083 #ifdef FEAT_CSCOPE 10084 "cscope", 10085 #endif 10086 #ifdef CURSOR_SHAPE 10087 "cursorshape", 10088 #endif 10089 #ifdef DEBUG 10090 "debug", 10091 #endif 10092 #ifdef FEAT_CON_DIALOG 10093 "dialog_con", 10094 #endif 10095 #ifdef FEAT_GUI_DIALOG 10096 "dialog_gui", 10097 #endif 10098 #ifdef FEAT_DIFF 10099 "diff", 10100 #endif 10101 #ifdef FEAT_DIGRAPHS 10102 "digraphs", 10103 #endif 10104 #ifdef FEAT_DND 10105 "dnd", 10106 #endif 10107 #ifdef FEAT_EMACS_TAGS 10108 "emacs_tags", 10109 #endif 10110 "eval", /* always present, of course! */ 10111 #ifdef FEAT_EX_EXTRA 10112 "ex_extra", 10113 #endif 10114 #ifdef FEAT_SEARCH_EXTRA 10115 "extra_search", 10116 #endif 10117 #ifdef FEAT_FKMAP 10118 "farsi", 10119 #endif 10120 #ifdef FEAT_SEARCHPATH 10121 "file_in_path", 10122 #endif 10123 #if defined(UNIX) && !defined(USE_SYSTEM) 10124 "filterpipe", 10125 #endif 10126 #ifdef FEAT_FIND_ID 10127 "find_in_path", 10128 #endif 10129 #ifdef FEAT_FOLDING 10130 "folding", 10131 #endif 10132 #ifdef FEAT_FOOTER 10133 "footer", 10134 #endif 10135 #if !defined(USE_SYSTEM) && defined(UNIX) 10136 "fork", 10137 #endif 10138 #ifdef FEAT_GETTEXT 10139 "gettext", 10140 #endif 10141 #ifdef FEAT_GUI 10142 "gui", 10143 #endif 10144 #ifdef FEAT_GUI_ATHENA 10145 # ifdef FEAT_GUI_NEXTAW 10146 "gui_neXtaw", 10147 # else 10148 "gui_athena", 10149 # endif 10150 #endif 10151 #ifdef FEAT_GUI_KDE 10152 "gui_kde", 10153 #endif 10154 #ifdef FEAT_GUI_GTK 10155 "gui_gtk", 10156 # ifdef HAVE_GTK2 10157 "gui_gtk2", 10158 # endif 10159 #endif 10160 #ifdef FEAT_GUI_MAC 10161 "gui_mac", 10162 #endif 10163 #ifdef FEAT_GUI_MOTIF 10164 "gui_motif", 10165 #endif 10166 #ifdef FEAT_GUI_PHOTON 10167 "gui_photon", 10168 #endif 10169 #ifdef FEAT_GUI_W16 10170 "gui_win16", 10171 #endif 10172 #ifdef FEAT_GUI_W32 10173 "gui_win32", 10174 #endif 10175 #ifdef FEAT_HANGULIN 10176 "hangul_input", 10177 #endif 10178 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10179 "iconv", 10180 #endif 10181 #ifdef FEAT_INS_EXPAND 10182 "insert_expand", 10183 #endif 10184 #ifdef FEAT_JUMPLIST 10185 "jumplist", 10186 #endif 10187 #ifdef FEAT_KEYMAP 10188 "keymap", 10189 #endif 10190 #ifdef FEAT_LANGMAP 10191 "langmap", 10192 #endif 10193 #ifdef FEAT_LIBCALL 10194 "libcall", 10195 #endif 10196 #ifdef FEAT_LINEBREAK 10197 "linebreak", 10198 #endif 10199 #ifdef FEAT_LISP 10200 "lispindent", 10201 #endif 10202 #ifdef FEAT_LISTCMDS 10203 "listcmds", 10204 #endif 10205 #ifdef FEAT_LOCALMAP 10206 "localmap", 10207 #endif 10208 #ifdef FEAT_MENU 10209 "menu", 10210 #endif 10211 #ifdef FEAT_SESSION 10212 "mksession", 10213 #endif 10214 #ifdef FEAT_MODIFY_FNAME 10215 "modify_fname", 10216 #endif 10217 #ifdef FEAT_MOUSE 10218 "mouse", 10219 #endif 10220 #ifdef FEAT_MOUSESHAPE 10221 "mouseshape", 10222 #endif 10223 #if defined(UNIX) || defined(VMS) 10224 # ifdef FEAT_MOUSE_DEC 10225 "mouse_dec", 10226 # endif 10227 # ifdef FEAT_MOUSE_GPM 10228 "mouse_gpm", 10229 # endif 10230 # ifdef FEAT_MOUSE_JSB 10231 "mouse_jsbterm", 10232 # endif 10233 # ifdef FEAT_MOUSE_NET 10234 "mouse_netterm", 10235 # endif 10236 # ifdef FEAT_MOUSE_PTERM 10237 "mouse_pterm", 10238 # endif 10239 # ifdef FEAT_MOUSE_XTERM 10240 "mouse_xterm", 10241 # endif 10242 #endif 10243 #ifdef FEAT_MBYTE 10244 "multi_byte", 10245 #endif 10246 #ifdef FEAT_MBYTE_IME 10247 "multi_byte_ime", 10248 #endif 10249 #ifdef FEAT_MULTI_LANG 10250 "multi_lang", 10251 #endif 10252 #ifdef FEAT_MZSCHEME 10253 #ifndef DYNAMIC_MZSCHEME 10254 "mzscheme", 10255 #endif 10256 #endif 10257 #ifdef FEAT_OLE 10258 "ole", 10259 #endif 10260 #ifdef FEAT_OSFILETYPE 10261 "osfiletype", 10262 #endif 10263 #ifdef FEAT_PATH_EXTRA 10264 "path_extra", 10265 #endif 10266 #ifdef FEAT_PERL 10267 #ifndef DYNAMIC_PERL 10268 "perl", 10269 #endif 10270 #endif 10271 #ifdef FEAT_PYTHON 10272 #ifndef DYNAMIC_PYTHON 10273 "python", 10274 #endif 10275 #endif 10276 #ifdef FEAT_POSTSCRIPT 10277 "postscript", 10278 #endif 10279 #ifdef FEAT_PRINTER 10280 "printer", 10281 #endif 10282 #ifdef FEAT_PROFILE 10283 "profile", 10284 #endif 10285 #ifdef FEAT_QUICKFIX 10286 "quickfix", 10287 #endif 10288 #ifdef FEAT_RIGHTLEFT 10289 "rightleft", 10290 #endif 10291 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10292 "ruby", 10293 #endif 10294 #ifdef FEAT_SCROLLBIND 10295 "scrollbind", 10296 #endif 10297 #ifdef FEAT_CMDL_INFO 10298 "showcmd", 10299 "cmdline_info", 10300 #endif 10301 #ifdef FEAT_SIGNS 10302 "signs", 10303 #endif 10304 #ifdef FEAT_SMARTINDENT 10305 "smartindent", 10306 #endif 10307 #ifdef FEAT_SNIFF 10308 "sniff", 10309 #endif 10310 #ifdef FEAT_STL_OPT 10311 "statusline", 10312 #endif 10313 #ifdef FEAT_SUN_WORKSHOP 10314 "sun_workshop", 10315 #endif 10316 #ifdef FEAT_NETBEANS_INTG 10317 "netbeans_intg", 10318 #endif 10319 #ifdef FEAT_SYN_HL 10320 "spell", 10321 #endif 10322 #ifdef FEAT_SYN_HL 10323 "syntax", 10324 #endif 10325 #if defined(USE_SYSTEM) || !defined(UNIX) 10326 "system", 10327 #endif 10328 #ifdef FEAT_TAG_BINS 10329 "tag_binary", 10330 #endif 10331 #ifdef FEAT_TAG_OLDSTATIC 10332 "tag_old_static", 10333 #endif 10334 #ifdef FEAT_TAG_ANYWHITE 10335 "tag_any_white", 10336 #endif 10337 #ifdef FEAT_TCL 10338 # ifndef DYNAMIC_TCL 10339 "tcl", 10340 # endif 10341 #endif 10342 #ifdef TERMINFO 10343 "terminfo", 10344 #endif 10345 #ifdef FEAT_TERMRESPONSE 10346 "termresponse", 10347 #endif 10348 #ifdef FEAT_TEXTOBJ 10349 "textobjects", 10350 #endif 10351 #ifdef HAVE_TGETENT 10352 "tgetent", 10353 #endif 10354 #ifdef FEAT_TITLE 10355 "title", 10356 #endif 10357 #ifdef FEAT_TOOLBAR 10358 "toolbar", 10359 #endif 10360 #ifdef FEAT_USR_CMDS 10361 "user-commands", /* was accidentally included in 5.4 */ 10362 "user_commands", 10363 #endif 10364 #ifdef FEAT_VIMINFO 10365 "viminfo", 10366 #endif 10367 #ifdef FEAT_VERTSPLIT 10368 "vertsplit", 10369 #endif 10370 #ifdef FEAT_VIRTUALEDIT 10371 "virtualedit", 10372 #endif 10373 #ifdef FEAT_VISUAL 10374 "visual", 10375 #endif 10376 #ifdef FEAT_VISUALEXTRA 10377 "visualextra", 10378 #endif 10379 #ifdef FEAT_VREPLACE 10380 "vreplace", 10381 #endif 10382 #ifdef FEAT_WILDIGN 10383 "wildignore", 10384 #endif 10385 #ifdef FEAT_WILDMENU 10386 "wildmenu", 10387 #endif 10388 #ifdef FEAT_WINDOWS 10389 "windows", 10390 #endif 10391 #ifdef FEAT_WAK 10392 "winaltkeys", 10393 #endif 10394 #ifdef FEAT_WRITEBACKUP 10395 "writebackup", 10396 #endif 10397 #ifdef FEAT_XIM 10398 "xim", 10399 #endif 10400 #ifdef FEAT_XFONTSET 10401 "xfontset", 10402 #endif 10403 #ifdef USE_XSMP 10404 "xsmp", 10405 #endif 10406 #ifdef USE_XSMP_INTERACT 10407 "xsmp_interact", 10408 #endif 10409 #ifdef FEAT_XCLIPBOARD 10410 "xterm_clipboard", 10411 #endif 10412 #ifdef FEAT_XTERM_SAVE 10413 "xterm_save", 10414 #endif 10415 #if defined(UNIX) && defined(FEAT_X11) 10416 "X11", 10417 #endif 10418 NULL 10419 }; 10420 10421 name = get_tv_string(&argvars[0]); 10422 for (i = 0; has_list[i] != NULL; ++i) 10423 if (STRICMP(name, has_list[i]) == 0) 10424 { 10425 n = TRUE; 10426 break; 10427 } 10428 10429 if (n == FALSE) 10430 { 10431 if (STRNICMP(name, "patch", 5) == 0) 10432 n = has_patch(atoi((char *)name + 5)); 10433 else if (STRICMP(name, "vim_starting") == 0) 10434 n = (starting != 0); 10435 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10436 else if (STRICMP(name, "balloon_multiline") == 0) 10437 n = multiline_balloon_available(); 10438 #endif 10439 #ifdef DYNAMIC_TCL 10440 else if (STRICMP(name, "tcl") == 0) 10441 n = tcl_enabled(FALSE); 10442 #endif 10443 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10444 else if (STRICMP(name, "iconv") == 0) 10445 n = iconv_enabled(FALSE); 10446 #endif 10447 #ifdef DYNAMIC_MZSCHEME 10448 else if (STRICMP(name, "mzscheme") == 0) 10449 n = mzscheme_enabled(FALSE); 10450 #endif 10451 #ifdef DYNAMIC_RUBY 10452 else if (STRICMP(name, "ruby") == 0) 10453 n = ruby_enabled(FALSE); 10454 #endif 10455 #ifdef DYNAMIC_PYTHON 10456 else if (STRICMP(name, "python") == 0) 10457 n = python_enabled(FALSE); 10458 #endif 10459 #ifdef DYNAMIC_PERL 10460 else if (STRICMP(name, "perl") == 0) 10461 n = perl_enabled(FALSE); 10462 #endif 10463 #ifdef FEAT_GUI 10464 else if (STRICMP(name, "gui_running") == 0) 10465 n = (gui.in_use || gui.starting); 10466 # ifdef FEAT_GUI_W32 10467 else if (STRICMP(name, "gui_win32s") == 0) 10468 n = gui_is_win32s(); 10469 # endif 10470 # ifdef FEAT_BROWSE 10471 else if (STRICMP(name, "browse") == 0) 10472 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10473 # endif 10474 #endif 10475 #ifdef FEAT_SYN_HL 10476 else if (STRICMP(name, "syntax_items") == 0) 10477 n = syntax_present(curbuf); 10478 #endif 10479 #if defined(WIN3264) 10480 else if (STRICMP(name, "win95") == 0) 10481 n = mch_windows95(); 10482 #endif 10483 #ifdef FEAT_NETBEANS_INTG 10484 else if (STRICMP(name, "netbeans_enabled") == 0) 10485 n = usingNetbeans; 10486 #endif 10487 } 10488 10489 rettv->vval.v_number = n; 10490 } 10491 10492 /* 10493 * "has_key()" function 10494 */ 10495 static void 10496 f_has_key(argvars, rettv) 10497 typval_T *argvars; 10498 typval_T *rettv; 10499 { 10500 rettv->vval.v_number = 0; 10501 if (argvars[0].v_type != VAR_DICT) 10502 { 10503 EMSG(_(e_dictreq)); 10504 return; 10505 } 10506 if (argvars[0].vval.v_dict == NULL) 10507 return; 10508 10509 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10510 get_tv_string(&argvars[1]), -1) != NULL; 10511 } 10512 10513 /* 10514 * "hasmapto()" function 10515 */ 10516 static void 10517 f_hasmapto(argvars, rettv) 10518 typval_T *argvars; 10519 typval_T *rettv; 10520 { 10521 char_u *name; 10522 char_u *mode; 10523 char_u buf[NUMBUFLEN]; 10524 10525 name = get_tv_string(&argvars[0]); 10526 if (argvars[1].v_type == VAR_UNKNOWN) 10527 mode = (char_u *)"nvo"; 10528 else 10529 mode = get_tv_string_buf(&argvars[1], buf); 10530 10531 if (map_to_exists(name, mode)) 10532 rettv->vval.v_number = TRUE; 10533 else 10534 rettv->vval.v_number = FALSE; 10535 } 10536 10537 /* 10538 * "histadd()" function 10539 */ 10540 /*ARGSUSED*/ 10541 static void 10542 f_histadd(argvars, rettv) 10543 typval_T *argvars; 10544 typval_T *rettv; 10545 { 10546 #ifdef FEAT_CMDHIST 10547 int histype; 10548 char_u *str; 10549 char_u buf[NUMBUFLEN]; 10550 #endif 10551 10552 rettv->vval.v_number = FALSE; 10553 if (check_restricted() || check_secure()) 10554 return; 10555 #ifdef FEAT_CMDHIST 10556 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10557 histype = str != NULL ? get_histtype(str) : -1; 10558 if (histype >= 0) 10559 { 10560 str = get_tv_string_buf(&argvars[1], buf); 10561 if (*str != NUL) 10562 { 10563 add_to_history(histype, str, FALSE, NUL); 10564 rettv->vval.v_number = TRUE; 10565 return; 10566 } 10567 } 10568 #endif 10569 } 10570 10571 /* 10572 * "histdel()" function 10573 */ 10574 /*ARGSUSED*/ 10575 static void 10576 f_histdel(argvars, rettv) 10577 typval_T *argvars; 10578 typval_T *rettv; 10579 { 10580 #ifdef FEAT_CMDHIST 10581 int n; 10582 char_u buf[NUMBUFLEN]; 10583 char_u *str; 10584 10585 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10586 if (str == NULL) 10587 n = 0; 10588 else if (argvars[1].v_type == VAR_UNKNOWN) 10589 /* only one argument: clear entire history */ 10590 n = clr_history(get_histtype(str)); 10591 else if (argvars[1].v_type == VAR_NUMBER) 10592 /* index given: remove that entry */ 10593 n = del_history_idx(get_histtype(str), 10594 (int)get_tv_number(&argvars[1])); 10595 else 10596 /* string given: remove all matching entries */ 10597 n = del_history_entry(get_histtype(str), 10598 get_tv_string_buf(&argvars[1], buf)); 10599 rettv->vval.v_number = n; 10600 #else 10601 rettv->vval.v_number = 0; 10602 #endif 10603 } 10604 10605 /* 10606 * "histget()" function 10607 */ 10608 /*ARGSUSED*/ 10609 static void 10610 f_histget(argvars, rettv) 10611 typval_T *argvars; 10612 typval_T *rettv; 10613 { 10614 #ifdef FEAT_CMDHIST 10615 int type; 10616 int idx; 10617 char_u *str; 10618 10619 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10620 if (str == NULL) 10621 rettv->vval.v_string = NULL; 10622 else 10623 { 10624 type = get_histtype(str); 10625 if (argvars[1].v_type == VAR_UNKNOWN) 10626 idx = get_history_idx(type); 10627 else 10628 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10629 /* -1 on type error */ 10630 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10631 } 10632 #else 10633 rettv->vval.v_string = NULL; 10634 #endif 10635 rettv->v_type = VAR_STRING; 10636 } 10637 10638 /* 10639 * "histnr()" function 10640 */ 10641 /*ARGSUSED*/ 10642 static void 10643 f_histnr(argvars, rettv) 10644 typval_T *argvars; 10645 typval_T *rettv; 10646 { 10647 int i; 10648 10649 #ifdef FEAT_CMDHIST 10650 char_u *history = get_tv_string_chk(&argvars[0]); 10651 10652 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10653 if (i >= HIST_CMD && i < HIST_COUNT) 10654 i = get_history_idx(i); 10655 else 10656 #endif 10657 i = -1; 10658 rettv->vval.v_number = i; 10659 } 10660 10661 /* 10662 * "highlightID(name)" function 10663 */ 10664 static void 10665 f_hlID(argvars, rettv) 10666 typval_T *argvars; 10667 typval_T *rettv; 10668 { 10669 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10670 } 10671 10672 /* 10673 * "highlight_exists()" function 10674 */ 10675 static void 10676 f_hlexists(argvars, rettv) 10677 typval_T *argvars; 10678 typval_T *rettv; 10679 { 10680 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10681 } 10682 10683 /* 10684 * "hostname()" function 10685 */ 10686 /*ARGSUSED*/ 10687 static void 10688 f_hostname(argvars, rettv) 10689 typval_T *argvars; 10690 typval_T *rettv; 10691 { 10692 char_u hostname[256]; 10693 10694 mch_get_host_name(hostname, 256); 10695 rettv->v_type = VAR_STRING; 10696 rettv->vval.v_string = vim_strsave(hostname); 10697 } 10698 10699 /* 10700 * iconv() function 10701 */ 10702 /*ARGSUSED*/ 10703 static void 10704 f_iconv(argvars, rettv) 10705 typval_T *argvars; 10706 typval_T *rettv; 10707 { 10708 #ifdef FEAT_MBYTE 10709 char_u buf1[NUMBUFLEN]; 10710 char_u buf2[NUMBUFLEN]; 10711 char_u *from, *to, *str; 10712 vimconv_T vimconv; 10713 #endif 10714 10715 rettv->v_type = VAR_STRING; 10716 rettv->vval.v_string = NULL; 10717 10718 #ifdef FEAT_MBYTE 10719 str = get_tv_string(&argvars[0]); 10720 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10721 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10722 vimconv.vc_type = CONV_NONE; 10723 convert_setup(&vimconv, from, to); 10724 10725 /* If the encodings are equal, no conversion needed. */ 10726 if (vimconv.vc_type == CONV_NONE) 10727 rettv->vval.v_string = vim_strsave(str); 10728 else 10729 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10730 10731 convert_setup(&vimconv, NULL, NULL); 10732 vim_free(from); 10733 vim_free(to); 10734 #endif 10735 } 10736 10737 /* 10738 * "indent()" function 10739 */ 10740 static void 10741 f_indent(argvars, rettv) 10742 typval_T *argvars; 10743 typval_T *rettv; 10744 { 10745 linenr_T lnum; 10746 10747 lnum = get_tv_lnum(argvars); 10748 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10749 rettv->vval.v_number = get_indent_lnum(lnum); 10750 else 10751 rettv->vval.v_number = -1; 10752 } 10753 10754 /* 10755 * "index()" function 10756 */ 10757 static void 10758 f_index(argvars, rettv) 10759 typval_T *argvars; 10760 typval_T *rettv; 10761 { 10762 list_T *l; 10763 listitem_T *item; 10764 long idx = 0; 10765 int ic = FALSE; 10766 10767 rettv->vval.v_number = -1; 10768 if (argvars[0].v_type != VAR_LIST) 10769 { 10770 EMSG(_(e_listreq)); 10771 return; 10772 } 10773 l = argvars[0].vval.v_list; 10774 if (l != NULL) 10775 { 10776 item = l->lv_first; 10777 if (argvars[2].v_type != VAR_UNKNOWN) 10778 { 10779 int error = FALSE; 10780 10781 /* Start at specified item. Use the cached index that list_find() 10782 * sets, so that a negative number also works. */ 10783 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10784 idx = l->lv_idx; 10785 if (argvars[3].v_type != VAR_UNKNOWN) 10786 ic = get_tv_number_chk(&argvars[3], &error); 10787 if (error) 10788 item = NULL; 10789 } 10790 10791 for ( ; item != NULL; item = item->li_next, ++idx) 10792 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10793 { 10794 rettv->vval.v_number = idx; 10795 break; 10796 } 10797 } 10798 } 10799 10800 static int inputsecret_flag = 0; 10801 10802 /* 10803 * "input()" function 10804 * Also handles inputsecret() when inputsecret is set. 10805 */ 10806 static void 10807 f_input(argvars, rettv) 10808 typval_T *argvars; 10809 typval_T *rettv; 10810 { 10811 char_u *prompt = get_tv_string_chk(&argvars[0]); 10812 char_u *p = NULL; 10813 int c; 10814 char_u buf[NUMBUFLEN]; 10815 int cmd_silent_save = cmd_silent; 10816 char_u *defstr = (char_u *)""; 10817 int xp_type = EXPAND_NOTHING; 10818 char_u *xp_arg = NULL; 10819 10820 rettv->v_type = VAR_STRING; 10821 10822 #ifdef NO_CONSOLE_INPUT 10823 /* While starting up, there is no place to enter text. */ 10824 if (no_console_input()) 10825 { 10826 rettv->vval.v_string = NULL; 10827 return; 10828 } 10829 #endif 10830 10831 cmd_silent = FALSE; /* Want to see the prompt. */ 10832 if (prompt != NULL) 10833 { 10834 /* Only the part of the message after the last NL is considered as 10835 * prompt for the command line */ 10836 p = vim_strrchr(prompt, '\n'); 10837 if (p == NULL) 10838 p = prompt; 10839 else 10840 { 10841 ++p; 10842 c = *p; 10843 *p = NUL; 10844 msg_start(); 10845 msg_clr_eos(); 10846 msg_puts_attr(prompt, echo_attr); 10847 msg_didout = FALSE; 10848 msg_starthere(); 10849 *p = c; 10850 } 10851 cmdline_row = msg_row; 10852 10853 if (argvars[1].v_type != VAR_UNKNOWN) 10854 { 10855 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10856 if (defstr != NULL) 10857 stuffReadbuffSpec(defstr); 10858 } 10859 10860 if (argvars[2].v_type != VAR_UNKNOWN) 10861 { 10862 char_u *xp_name; 10863 int xp_namelen; 10864 long argt; 10865 10866 rettv->vval.v_string = NULL; 10867 10868 xp_name = get_tv_string_buf_chk(&argvars[2], buf); 10869 if (xp_name == NULL) 10870 return; 10871 10872 xp_namelen = STRLEN(xp_name); 10873 10874 if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt, &xp_arg) 10875 == FAIL) 10876 return; 10877 } 10878 10879 if (defstr != NULL) 10880 rettv->vval.v_string = 10881 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, 10882 xp_type, xp_arg); 10883 10884 vim_free(xp_arg); 10885 10886 /* since the user typed this, no need to wait for return */ 10887 need_wait_return = FALSE; 10888 msg_didout = FALSE; 10889 } 10890 cmd_silent = cmd_silent_save; 10891 } 10892 10893 /* 10894 * "inputdialog()" function 10895 */ 10896 static void 10897 f_inputdialog(argvars, rettv) 10898 typval_T *argvars; 10899 typval_T *rettv; 10900 { 10901 #if defined(FEAT_GUI_TEXTDIALOG) 10902 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10903 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10904 { 10905 char_u *message; 10906 char_u buf[NUMBUFLEN]; 10907 char_u *defstr = (char_u *)""; 10908 10909 message = get_tv_string_chk(&argvars[0]); 10910 if (argvars[1].v_type != VAR_UNKNOWN 10911 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10912 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10913 else 10914 IObuff[0] = NUL; 10915 if (message != NULL && defstr != NULL 10916 && do_dialog(VIM_QUESTION, NULL, message, 10917 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10918 rettv->vval.v_string = vim_strsave(IObuff); 10919 else 10920 { 10921 if (message != NULL && defstr != NULL 10922 && argvars[1].v_type != VAR_UNKNOWN 10923 && argvars[2].v_type != VAR_UNKNOWN) 10924 rettv->vval.v_string = vim_strsave( 10925 get_tv_string_buf(&argvars[2], buf)); 10926 else 10927 rettv->vval.v_string = NULL; 10928 } 10929 rettv->v_type = VAR_STRING; 10930 } 10931 else 10932 #endif 10933 f_input(argvars, rettv); 10934 } 10935 10936 /* 10937 * "inputlist()" function 10938 */ 10939 static void 10940 f_inputlist(argvars, rettv) 10941 typval_T *argvars; 10942 typval_T *rettv; 10943 { 10944 listitem_T *li; 10945 int selected; 10946 int mouse_used; 10947 10948 rettv->vval.v_number = 0; 10949 #ifdef NO_CONSOLE_INPUT 10950 /* While starting up, there is no place to enter text. */ 10951 if (no_console_input()) 10952 return; 10953 #endif 10954 if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) 10955 { 10956 EMSG2(_(e_listarg), "inputlist()"); 10957 return; 10958 } 10959 10960 msg_start(); 10961 lines_left = Rows; /* avoid more prompt */ 10962 msg_scroll = TRUE; 10963 msg_clr_eos(); 10964 10965 for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) 10966 { 10967 msg_puts(get_tv_string(&li->li_tv)); 10968 msg_putchar('\n'); 10969 } 10970 10971 /* Ask for choice. */ 10972 selected = prompt_for_number(&mouse_used); 10973 if (mouse_used) 10974 selected -= lines_left; 10975 10976 rettv->vval.v_number = selected; 10977 } 10978 10979 10980 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10981 10982 /* 10983 * "inputrestore()" function 10984 */ 10985 /*ARGSUSED*/ 10986 static void 10987 f_inputrestore(argvars, rettv) 10988 typval_T *argvars; 10989 typval_T *rettv; 10990 { 10991 if (ga_userinput.ga_len > 0) 10992 { 10993 --ga_userinput.ga_len; 10994 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10995 + ga_userinput.ga_len); 10996 rettv->vval.v_number = 0; /* OK */ 10997 } 10998 else if (p_verbose > 1) 10999 { 11000 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 11001 rettv->vval.v_number = 1; /* Failed */ 11002 } 11003 } 11004 11005 /* 11006 * "inputsave()" function 11007 */ 11008 /*ARGSUSED*/ 11009 static void 11010 f_inputsave(argvars, rettv) 11011 typval_T *argvars; 11012 typval_T *rettv; 11013 { 11014 /* Add an entry to the stack of typehead storage. */ 11015 if (ga_grow(&ga_userinput, 1) == OK) 11016 { 11017 save_typeahead((tasave_T *)(ga_userinput.ga_data) 11018 + ga_userinput.ga_len); 11019 ++ga_userinput.ga_len; 11020 rettv->vval.v_number = 0; /* OK */ 11021 } 11022 else 11023 rettv->vval.v_number = 1; /* Failed */ 11024 } 11025 11026 /* 11027 * "inputsecret()" function 11028 */ 11029 static void 11030 f_inputsecret(argvars, rettv) 11031 typval_T *argvars; 11032 typval_T *rettv; 11033 { 11034 ++cmdline_star; 11035 ++inputsecret_flag; 11036 f_input(argvars, rettv); 11037 --cmdline_star; 11038 --inputsecret_flag; 11039 } 11040 11041 /* 11042 * "insert()" function 11043 */ 11044 static void 11045 f_insert(argvars, rettv) 11046 typval_T *argvars; 11047 typval_T *rettv; 11048 { 11049 long before = 0; 11050 listitem_T *item; 11051 list_T *l; 11052 int error = FALSE; 11053 11054 rettv->vval.v_number = 0; 11055 if (argvars[0].v_type != VAR_LIST) 11056 EMSG2(_(e_listarg), "insert()"); 11057 else if ((l = argvars[0].vval.v_list) != NULL 11058 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 11059 { 11060 if (argvars[2].v_type != VAR_UNKNOWN) 11061 before = get_tv_number_chk(&argvars[2], &error); 11062 if (error) 11063 return; /* type error; errmsg already given */ 11064 11065 if (before == l->lv_len) 11066 item = NULL; 11067 else 11068 { 11069 item = list_find(l, before); 11070 if (item == NULL) 11071 { 11072 EMSGN(_(e_listidx), before); 11073 l = NULL; 11074 } 11075 } 11076 if (l != NULL) 11077 { 11078 list_insert_tv(l, &argvars[1], item); 11079 copy_tv(&argvars[0], rettv); 11080 } 11081 } 11082 } 11083 11084 /* 11085 * "isdirectory()" function 11086 */ 11087 static void 11088 f_isdirectory(argvars, rettv) 11089 typval_T *argvars; 11090 typval_T *rettv; 11091 { 11092 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 11093 } 11094 11095 /* 11096 * "islocked()" function 11097 */ 11098 static void 11099 f_islocked(argvars, rettv) 11100 typval_T *argvars; 11101 typval_T *rettv; 11102 { 11103 lval_T lv; 11104 char_u *end; 11105 dictitem_T *di; 11106 11107 rettv->vval.v_number = -1; 11108 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 11109 FNE_CHECK_START); 11110 if (end != NULL && lv.ll_name != NULL) 11111 { 11112 if (*end != NUL) 11113 EMSG(_(e_trailing)); 11114 else 11115 { 11116 if (lv.ll_tv == NULL) 11117 { 11118 if (check_changedtick(lv.ll_name)) 11119 rettv->vval.v_number = 1; /* always locked */ 11120 else 11121 { 11122 di = find_var(lv.ll_name, NULL); 11123 if (di != NULL) 11124 { 11125 /* Consider a variable locked when: 11126 * 1. the variable itself is locked 11127 * 2. the value of the variable is locked. 11128 * 3. the List or Dict value is locked. 11129 */ 11130 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 11131 || tv_islocked(&di->di_tv)); 11132 } 11133 } 11134 } 11135 else if (lv.ll_range) 11136 EMSG(_("E745: Range not allowed")); 11137 else if (lv.ll_newkey != NULL) 11138 EMSG2(_(e_dictkey), lv.ll_newkey); 11139 else if (lv.ll_list != NULL) 11140 /* List item. */ 11141 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 11142 else 11143 /* Dictionary item. */ 11144 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 11145 } 11146 } 11147 11148 clear_lval(&lv); 11149 } 11150 11151 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 11152 11153 /* 11154 * Turn a dict into a list: 11155 * "what" == 0: list of keys 11156 * "what" == 1: list of values 11157 * "what" == 2: list of items 11158 */ 11159 static void 11160 dict_list(argvars, rettv, what) 11161 typval_T *argvars; 11162 typval_T *rettv; 11163 int what; 11164 { 11165 list_T *l; 11166 list_T *l2; 11167 dictitem_T *di; 11168 hashitem_T *hi; 11169 listitem_T *li; 11170 listitem_T *li2; 11171 dict_T *d; 11172 int todo; 11173 11174 rettv->vval.v_number = 0; 11175 if (argvars[0].v_type != VAR_DICT) 11176 { 11177 EMSG(_(e_dictreq)); 11178 return; 11179 } 11180 if ((d = argvars[0].vval.v_dict) == NULL) 11181 return; 11182 11183 l = list_alloc(); 11184 if (l == NULL) 11185 return; 11186 rettv->v_type = VAR_LIST; 11187 rettv->vval.v_list = l; 11188 ++l->lv_refcount; 11189 11190 todo = d->dv_hashtab.ht_used; 11191 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11192 { 11193 if (!HASHITEM_EMPTY(hi)) 11194 { 11195 --todo; 11196 di = HI2DI(hi); 11197 11198 li = listitem_alloc(); 11199 if (li == NULL) 11200 break; 11201 list_append(l, li); 11202 11203 if (what == 0) 11204 { 11205 /* keys() */ 11206 li->li_tv.v_type = VAR_STRING; 11207 li->li_tv.v_lock = 0; 11208 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11209 } 11210 else if (what == 1) 11211 { 11212 /* values() */ 11213 copy_tv(&di->di_tv, &li->li_tv); 11214 } 11215 else 11216 { 11217 /* items() */ 11218 l2 = list_alloc(); 11219 li->li_tv.v_type = VAR_LIST; 11220 li->li_tv.v_lock = 0; 11221 li->li_tv.vval.v_list = l2; 11222 if (l2 == NULL) 11223 break; 11224 ++l2->lv_refcount; 11225 11226 li2 = listitem_alloc(); 11227 if (li2 == NULL) 11228 break; 11229 list_append(l2, li2); 11230 li2->li_tv.v_type = VAR_STRING; 11231 li2->li_tv.v_lock = 0; 11232 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11233 11234 li2 = listitem_alloc(); 11235 if (li2 == NULL) 11236 break; 11237 list_append(l2, li2); 11238 copy_tv(&di->di_tv, &li2->li_tv); 11239 } 11240 } 11241 } 11242 } 11243 11244 /* 11245 * "items(dict)" function 11246 */ 11247 static void 11248 f_items(argvars, rettv) 11249 typval_T *argvars; 11250 typval_T *rettv; 11251 { 11252 dict_list(argvars, rettv, 2); 11253 } 11254 11255 /* 11256 * "join()" function 11257 */ 11258 static void 11259 f_join(argvars, rettv) 11260 typval_T *argvars; 11261 typval_T *rettv; 11262 { 11263 garray_T ga; 11264 char_u *sep; 11265 11266 rettv->vval.v_number = 0; 11267 if (argvars[0].v_type != VAR_LIST) 11268 { 11269 EMSG(_(e_listreq)); 11270 return; 11271 } 11272 if (argvars[0].vval.v_list == NULL) 11273 return; 11274 if (argvars[1].v_type == VAR_UNKNOWN) 11275 sep = (char_u *)" "; 11276 else 11277 sep = get_tv_string_chk(&argvars[1]); 11278 11279 rettv->v_type = VAR_STRING; 11280 11281 if (sep != NULL) 11282 { 11283 ga_init2(&ga, (int)sizeof(char), 80); 11284 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11285 ga_append(&ga, NUL); 11286 rettv->vval.v_string = (char_u *)ga.ga_data; 11287 } 11288 else 11289 rettv->vval.v_string = NULL; 11290 } 11291 11292 /* 11293 * "keys()" function 11294 */ 11295 static void 11296 f_keys(argvars, rettv) 11297 typval_T *argvars; 11298 typval_T *rettv; 11299 { 11300 dict_list(argvars, rettv, 0); 11301 } 11302 11303 /* 11304 * "last_buffer_nr()" function. 11305 */ 11306 /*ARGSUSED*/ 11307 static void 11308 f_last_buffer_nr(argvars, rettv) 11309 typval_T *argvars; 11310 typval_T *rettv; 11311 { 11312 int n = 0; 11313 buf_T *buf; 11314 11315 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11316 if (n < buf->b_fnum) 11317 n = buf->b_fnum; 11318 11319 rettv->vval.v_number = n; 11320 } 11321 11322 /* 11323 * "len()" function 11324 */ 11325 static void 11326 f_len(argvars, rettv) 11327 typval_T *argvars; 11328 typval_T *rettv; 11329 { 11330 switch (argvars[0].v_type) 11331 { 11332 case VAR_STRING: 11333 case VAR_NUMBER: 11334 rettv->vval.v_number = (varnumber_T)STRLEN( 11335 get_tv_string(&argvars[0])); 11336 break; 11337 case VAR_LIST: 11338 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11339 break; 11340 case VAR_DICT: 11341 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11342 break; 11343 default: 11344 EMSG(_("E701: Invalid type for len()")); 11345 break; 11346 } 11347 } 11348 11349 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11350 11351 static void 11352 libcall_common(argvars, rettv, type) 11353 typval_T *argvars; 11354 typval_T *rettv; 11355 int type; 11356 { 11357 #ifdef FEAT_LIBCALL 11358 char_u *string_in; 11359 char_u **string_result; 11360 int nr_result; 11361 #endif 11362 11363 rettv->v_type = type; 11364 if (type == VAR_NUMBER) 11365 rettv->vval.v_number = 0; 11366 else 11367 rettv->vval.v_string = NULL; 11368 11369 if (check_restricted() || check_secure()) 11370 return; 11371 11372 #ifdef FEAT_LIBCALL 11373 /* The first two args must be strings, otherwise its meaningless */ 11374 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11375 { 11376 string_in = NULL; 11377 if (argvars[2].v_type == VAR_STRING) 11378 string_in = argvars[2].vval.v_string; 11379 if (type == VAR_NUMBER) 11380 string_result = NULL; 11381 else 11382 string_result = &rettv->vval.v_string; 11383 if (mch_libcall(argvars[0].vval.v_string, 11384 argvars[1].vval.v_string, 11385 string_in, 11386 argvars[2].vval.v_number, 11387 string_result, 11388 &nr_result) == OK 11389 && type == VAR_NUMBER) 11390 rettv->vval.v_number = nr_result; 11391 } 11392 #endif 11393 } 11394 11395 /* 11396 * "libcall()" function 11397 */ 11398 static void 11399 f_libcall(argvars, rettv) 11400 typval_T *argvars; 11401 typval_T *rettv; 11402 { 11403 libcall_common(argvars, rettv, VAR_STRING); 11404 } 11405 11406 /* 11407 * "libcallnr()" function 11408 */ 11409 static void 11410 f_libcallnr(argvars, rettv) 11411 typval_T *argvars; 11412 typval_T *rettv; 11413 { 11414 libcall_common(argvars, rettv, VAR_NUMBER); 11415 } 11416 11417 /* 11418 * "line(string)" function 11419 */ 11420 static void 11421 f_line(argvars, rettv) 11422 typval_T *argvars; 11423 typval_T *rettv; 11424 { 11425 linenr_T lnum = 0; 11426 pos_T *fp; 11427 11428 fp = var2fpos(&argvars[0], TRUE); 11429 if (fp != NULL) 11430 lnum = fp->lnum; 11431 rettv->vval.v_number = lnum; 11432 } 11433 11434 /* 11435 * "line2byte(lnum)" function 11436 */ 11437 /*ARGSUSED*/ 11438 static void 11439 f_line2byte(argvars, rettv) 11440 typval_T *argvars; 11441 typval_T *rettv; 11442 { 11443 #ifndef FEAT_BYTEOFF 11444 rettv->vval.v_number = -1; 11445 #else 11446 linenr_T lnum; 11447 11448 lnum = get_tv_lnum(argvars); 11449 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11450 rettv->vval.v_number = -1; 11451 else 11452 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11453 if (rettv->vval.v_number >= 0) 11454 ++rettv->vval.v_number; 11455 #endif 11456 } 11457 11458 /* 11459 * "lispindent(lnum)" function 11460 */ 11461 static void 11462 f_lispindent(argvars, rettv) 11463 typval_T *argvars; 11464 typval_T *rettv; 11465 { 11466 #ifdef FEAT_LISP 11467 pos_T pos; 11468 linenr_T lnum; 11469 11470 pos = curwin->w_cursor; 11471 lnum = get_tv_lnum(argvars); 11472 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11473 { 11474 curwin->w_cursor.lnum = lnum; 11475 rettv->vval.v_number = get_lisp_indent(); 11476 curwin->w_cursor = pos; 11477 } 11478 else 11479 #endif 11480 rettv->vval.v_number = -1; 11481 } 11482 11483 /* 11484 * "localtime()" function 11485 */ 11486 /*ARGSUSED*/ 11487 static void 11488 f_localtime(argvars, rettv) 11489 typval_T *argvars; 11490 typval_T *rettv; 11491 { 11492 rettv->vval.v_number = (varnumber_T)time(NULL); 11493 } 11494 11495 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11496 11497 static void 11498 get_maparg(argvars, rettv, exact) 11499 typval_T *argvars; 11500 typval_T *rettv; 11501 int exact; 11502 { 11503 char_u *keys; 11504 char_u *which; 11505 char_u buf[NUMBUFLEN]; 11506 char_u *keys_buf = NULL; 11507 char_u *rhs; 11508 int mode; 11509 garray_T ga; 11510 11511 /* return empty string for failure */ 11512 rettv->v_type = VAR_STRING; 11513 rettv->vval.v_string = NULL; 11514 11515 keys = get_tv_string(&argvars[0]); 11516 if (*keys == NUL) 11517 return; 11518 11519 if (argvars[1].v_type != VAR_UNKNOWN) 11520 which = get_tv_string_buf_chk(&argvars[1], buf); 11521 else 11522 which = (char_u *)""; 11523 if (which == NULL) 11524 return; 11525 11526 mode = get_map_mode(&which, 0); 11527 11528 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11529 rhs = check_map(keys, mode, exact, FALSE); 11530 vim_free(keys_buf); 11531 if (rhs != NULL) 11532 { 11533 ga_init(&ga); 11534 ga.ga_itemsize = 1; 11535 ga.ga_growsize = 40; 11536 11537 while (*rhs != NUL) 11538 ga_concat(&ga, str2special(&rhs, FALSE)); 11539 11540 ga_append(&ga, NUL); 11541 rettv->vval.v_string = (char_u *)ga.ga_data; 11542 } 11543 } 11544 11545 /* 11546 * "map()" function 11547 */ 11548 static void 11549 f_map(argvars, rettv) 11550 typval_T *argvars; 11551 typval_T *rettv; 11552 { 11553 filter_map(argvars, rettv, TRUE); 11554 } 11555 11556 /* 11557 * "maparg()" function 11558 */ 11559 static void 11560 f_maparg(argvars, rettv) 11561 typval_T *argvars; 11562 typval_T *rettv; 11563 { 11564 get_maparg(argvars, rettv, TRUE); 11565 } 11566 11567 /* 11568 * "mapcheck()" function 11569 */ 11570 static void 11571 f_mapcheck(argvars, rettv) 11572 typval_T *argvars; 11573 typval_T *rettv; 11574 { 11575 get_maparg(argvars, rettv, FALSE); 11576 } 11577 11578 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11579 11580 static void 11581 find_some_match(argvars, rettv, type) 11582 typval_T *argvars; 11583 typval_T *rettv; 11584 int type; 11585 { 11586 char_u *str = NULL; 11587 char_u *expr = NULL; 11588 char_u *pat; 11589 regmatch_T regmatch; 11590 char_u patbuf[NUMBUFLEN]; 11591 char_u strbuf[NUMBUFLEN]; 11592 char_u *save_cpo; 11593 long start = 0; 11594 long nth = 1; 11595 int match = 0; 11596 list_T *l = NULL; 11597 listitem_T *li = NULL; 11598 long idx = 0; 11599 char_u *tofree = NULL; 11600 11601 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11602 save_cpo = p_cpo; 11603 p_cpo = (char_u *)""; 11604 11605 rettv->vval.v_number = -1; 11606 if (type == 3) 11607 { 11608 /* return empty list when there are no matches */ 11609 if ((rettv->vval.v_list = list_alloc()) == NULL) 11610 goto theend; 11611 rettv->v_type = VAR_LIST; 11612 ++rettv->vval.v_list->lv_refcount; 11613 } 11614 else if (type == 2) 11615 { 11616 rettv->v_type = VAR_STRING; 11617 rettv->vval.v_string = NULL; 11618 } 11619 11620 if (argvars[0].v_type == VAR_LIST) 11621 { 11622 if ((l = argvars[0].vval.v_list) == NULL) 11623 goto theend; 11624 li = l->lv_first; 11625 } 11626 else 11627 expr = str = get_tv_string(&argvars[0]); 11628 11629 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11630 if (pat == NULL) 11631 goto theend; 11632 11633 if (argvars[2].v_type != VAR_UNKNOWN) 11634 { 11635 int error = FALSE; 11636 11637 start = get_tv_number_chk(&argvars[2], &error); 11638 if (error) 11639 goto theend; 11640 if (l != NULL) 11641 { 11642 li = list_find(l, start); 11643 if (li == NULL) 11644 goto theend; 11645 idx = l->lv_idx; /* use the cached index */ 11646 } 11647 else 11648 { 11649 if (start < 0) 11650 start = 0; 11651 if (start > (long)STRLEN(str)) 11652 goto theend; 11653 str += start; 11654 } 11655 11656 if (argvars[3].v_type != VAR_UNKNOWN) 11657 nth = get_tv_number_chk(&argvars[3], &error); 11658 if (error) 11659 goto theend; 11660 } 11661 11662 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11663 if (regmatch.regprog != NULL) 11664 { 11665 regmatch.rm_ic = p_ic; 11666 11667 for (;;) 11668 { 11669 if (l != NULL) 11670 { 11671 if (li == NULL) 11672 { 11673 match = FALSE; 11674 break; 11675 } 11676 vim_free(tofree); 11677 str = echo_string(&li->li_tv, &tofree, strbuf); 11678 if (str == NULL) 11679 break; 11680 } 11681 11682 match = vim_regexec_nl(®match, str, (colnr_T)0); 11683 11684 if (match && --nth <= 0) 11685 break; 11686 if (l == NULL && !match) 11687 break; 11688 11689 /* Advance to just after the match. */ 11690 if (l != NULL) 11691 { 11692 li = li->li_next; 11693 ++idx; 11694 } 11695 else 11696 { 11697 #ifdef FEAT_MBYTE 11698 str = regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]); 11699 #else 11700 str = regmatch.startp[0] + 1; 11701 #endif 11702 } 11703 } 11704 11705 if (match) 11706 { 11707 if (type == 3) 11708 { 11709 int i; 11710 11711 /* return list with matched string and submatches */ 11712 for (i = 0; i < NSUBEXP; ++i) 11713 { 11714 if (regmatch.endp[i] == NULL) 11715 break; 11716 li = listitem_alloc(); 11717 if (li == NULL) 11718 break; 11719 li->li_tv.v_type = VAR_STRING; 11720 li->li_tv.v_lock = 0; 11721 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11722 (int)(regmatch.endp[i] - regmatch.startp[i])); 11723 list_append(rettv->vval.v_list, li); 11724 } 11725 } 11726 else if (type == 2) 11727 { 11728 /* return matched string */ 11729 if (l != NULL) 11730 copy_tv(&li->li_tv, rettv); 11731 else 11732 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11733 (int)(regmatch.endp[0] - regmatch.startp[0])); 11734 } 11735 else if (l != NULL) 11736 rettv->vval.v_number = idx; 11737 else 11738 { 11739 if (type != 0) 11740 rettv->vval.v_number = 11741 (varnumber_T)(regmatch.startp[0] - str); 11742 else 11743 rettv->vval.v_number = 11744 (varnumber_T)(regmatch.endp[0] - str); 11745 rettv->vval.v_number += str - expr; 11746 } 11747 } 11748 vim_free(regmatch.regprog); 11749 } 11750 11751 theend: 11752 vim_free(tofree); 11753 p_cpo = save_cpo; 11754 } 11755 11756 /* 11757 * "match()" function 11758 */ 11759 static void 11760 f_match(argvars, rettv) 11761 typval_T *argvars; 11762 typval_T *rettv; 11763 { 11764 find_some_match(argvars, rettv, 1); 11765 } 11766 11767 /* 11768 * "matchend()" function 11769 */ 11770 static void 11771 f_matchend(argvars, rettv) 11772 typval_T *argvars; 11773 typval_T *rettv; 11774 { 11775 find_some_match(argvars, rettv, 0); 11776 } 11777 11778 /* 11779 * "matchlist()" function 11780 */ 11781 static void 11782 f_matchlist(argvars, rettv) 11783 typval_T *argvars; 11784 typval_T *rettv; 11785 { 11786 find_some_match(argvars, rettv, 3); 11787 } 11788 11789 /* 11790 * "matchstr()" function 11791 */ 11792 static void 11793 f_matchstr(argvars, rettv) 11794 typval_T *argvars; 11795 typval_T *rettv; 11796 { 11797 find_some_match(argvars, rettv, 2); 11798 } 11799 11800 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11801 11802 static void 11803 max_min(argvars, rettv, domax) 11804 typval_T *argvars; 11805 typval_T *rettv; 11806 int domax; 11807 { 11808 long n = 0; 11809 long i; 11810 int error = FALSE; 11811 11812 if (argvars[0].v_type == VAR_LIST) 11813 { 11814 list_T *l; 11815 listitem_T *li; 11816 11817 l = argvars[0].vval.v_list; 11818 if (l != NULL) 11819 { 11820 li = l->lv_first; 11821 if (li != NULL) 11822 { 11823 n = get_tv_number_chk(&li->li_tv, &error); 11824 for (;;) 11825 { 11826 li = li->li_next; 11827 if (li == NULL) 11828 break; 11829 i = get_tv_number_chk(&li->li_tv, &error); 11830 if (domax ? i > n : i < n) 11831 n = i; 11832 } 11833 } 11834 } 11835 } 11836 else if (argvars[0].v_type == VAR_DICT) 11837 { 11838 dict_T *d; 11839 int first = TRUE; 11840 hashitem_T *hi; 11841 int todo; 11842 11843 d = argvars[0].vval.v_dict; 11844 if (d != NULL) 11845 { 11846 todo = d->dv_hashtab.ht_used; 11847 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11848 { 11849 if (!HASHITEM_EMPTY(hi)) 11850 { 11851 --todo; 11852 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11853 if (first) 11854 { 11855 n = i; 11856 first = FALSE; 11857 } 11858 else if (domax ? i > n : i < n) 11859 n = i; 11860 } 11861 } 11862 } 11863 } 11864 else 11865 EMSG(_(e_listdictarg)); 11866 rettv->vval.v_number = error ? 0 : n; 11867 } 11868 11869 /* 11870 * "max()" function 11871 */ 11872 static void 11873 f_max(argvars, rettv) 11874 typval_T *argvars; 11875 typval_T *rettv; 11876 { 11877 max_min(argvars, rettv, TRUE); 11878 } 11879 11880 /* 11881 * "min()" function 11882 */ 11883 static void 11884 f_min(argvars, rettv) 11885 typval_T *argvars; 11886 typval_T *rettv; 11887 { 11888 max_min(argvars, rettv, FALSE); 11889 } 11890 11891 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11892 11893 /* 11894 * Create the directory in which "dir" is located, and higher levels when 11895 * needed. 11896 */ 11897 static int 11898 mkdir_recurse(dir, prot) 11899 char_u *dir; 11900 int prot; 11901 { 11902 char_u *p; 11903 char_u *updir; 11904 int r = FAIL; 11905 11906 /* Get end of directory name in "dir". 11907 * We're done when it's "/" or "c:/". */ 11908 p = gettail_sep(dir); 11909 if (p <= get_past_head(dir)) 11910 return OK; 11911 11912 /* If the directory exists we're done. Otherwise: create it.*/ 11913 updir = vim_strnsave(dir, (int)(p - dir)); 11914 if (updir == NULL) 11915 return FAIL; 11916 if (mch_isdir(updir)) 11917 r = OK; 11918 else if (mkdir_recurse(updir, prot) == OK) 11919 r = vim_mkdir_emsg(updir, prot); 11920 vim_free(updir); 11921 return r; 11922 } 11923 11924 #ifdef vim_mkdir 11925 /* 11926 * "mkdir()" function 11927 */ 11928 static void 11929 f_mkdir(argvars, rettv) 11930 typval_T *argvars; 11931 typval_T *rettv; 11932 { 11933 char_u *dir; 11934 char_u buf[NUMBUFLEN]; 11935 int prot = 0755; 11936 11937 rettv->vval.v_number = FAIL; 11938 if (check_restricted() || check_secure()) 11939 return; 11940 11941 dir = get_tv_string_buf(&argvars[0], buf); 11942 if (argvars[1].v_type != VAR_UNKNOWN) 11943 { 11944 if (argvars[2].v_type != VAR_UNKNOWN) 11945 prot = get_tv_number_chk(&argvars[2], NULL); 11946 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11947 mkdir_recurse(dir, prot); 11948 } 11949 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11950 } 11951 #endif 11952 11953 /* 11954 * "mode()" function 11955 */ 11956 /*ARGSUSED*/ 11957 static void 11958 f_mode(argvars, rettv) 11959 typval_T *argvars; 11960 typval_T *rettv; 11961 { 11962 char_u buf[2]; 11963 11964 #ifdef FEAT_VISUAL 11965 if (VIsual_active) 11966 { 11967 if (VIsual_select) 11968 buf[0] = VIsual_mode + 's' - 'v'; 11969 else 11970 buf[0] = VIsual_mode; 11971 } 11972 else 11973 #endif 11974 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11975 buf[0] = 'r'; 11976 else if (State & INSERT) 11977 { 11978 if (State & REPLACE_FLAG) 11979 buf[0] = 'R'; 11980 else 11981 buf[0] = 'i'; 11982 } 11983 else if (State & CMDLINE) 11984 buf[0] = 'c'; 11985 else 11986 buf[0] = 'n'; 11987 11988 buf[1] = NUL; 11989 rettv->vval.v_string = vim_strsave(buf); 11990 rettv->v_type = VAR_STRING; 11991 } 11992 11993 /* 11994 * "nextnonblank()" function 11995 */ 11996 static void 11997 f_nextnonblank(argvars, rettv) 11998 typval_T *argvars; 11999 typval_T *rettv; 12000 { 12001 linenr_T lnum; 12002 12003 for (lnum = get_tv_lnum(argvars); ; ++lnum) 12004 { 12005 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 12006 { 12007 lnum = 0; 12008 break; 12009 } 12010 if (*skipwhite(ml_get(lnum)) != NUL) 12011 break; 12012 } 12013 rettv->vval.v_number = lnum; 12014 } 12015 12016 /* 12017 * "nr2char()" function 12018 */ 12019 static void 12020 f_nr2char(argvars, rettv) 12021 typval_T *argvars; 12022 typval_T *rettv; 12023 { 12024 char_u buf[NUMBUFLEN]; 12025 12026 #ifdef FEAT_MBYTE 12027 if (has_mbyte) 12028 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 12029 else 12030 #endif 12031 { 12032 buf[0] = (char_u)get_tv_number(&argvars[0]); 12033 buf[1] = NUL; 12034 } 12035 rettv->v_type = VAR_STRING; 12036 rettv->vval.v_string = vim_strsave(buf); 12037 } 12038 12039 /* 12040 * "prevnonblank()" function 12041 */ 12042 static void 12043 f_prevnonblank(argvars, rettv) 12044 typval_T *argvars; 12045 typval_T *rettv; 12046 { 12047 linenr_T lnum; 12048 12049 lnum = get_tv_lnum(argvars); 12050 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 12051 lnum = 0; 12052 else 12053 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 12054 --lnum; 12055 rettv->vval.v_number = lnum; 12056 } 12057 12058 #ifdef HAVE_STDARG_H 12059 /* This dummy va_list is here because: 12060 * - passing a NULL pointer doesn't work when va_list isn't a pointer 12061 * - locally in the function results in a "used before set" warning 12062 * - using va_start() to initialize it gives "function with fixed args" error */ 12063 static va_list ap; 12064 #endif 12065 12066 /* 12067 * "printf()" function 12068 */ 12069 static void 12070 f_printf(argvars, rettv) 12071 typval_T *argvars; 12072 typval_T *rettv; 12073 { 12074 rettv->v_type = VAR_STRING; 12075 rettv->vval.v_string = NULL; 12076 #ifdef HAVE_STDARG_H /* only very old compilers can't do this */ 12077 { 12078 char_u buf[NUMBUFLEN]; 12079 int len; 12080 char_u *s; 12081 int saved_did_emsg = did_emsg; 12082 char *fmt; 12083 12084 /* Get the required length, allocate the buffer and do it for real. */ 12085 did_emsg = FALSE; 12086 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 12087 len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1); 12088 if (!did_emsg) 12089 { 12090 s = alloc(len + 1); 12091 if (s != NULL) 12092 { 12093 rettv->vval.v_string = s; 12094 (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1); 12095 } 12096 } 12097 did_emsg |= saved_did_emsg; 12098 } 12099 #endif 12100 } 12101 12102 /* 12103 * "range()" function 12104 */ 12105 static void 12106 f_range(argvars, rettv) 12107 typval_T *argvars; 12108 typval_T *rettv; 12109 { 12110 long start; 12111 long end; 12112 long stride = 1; 12113 long i; 12114 list_T *l; 12115 listitem_T *li; 12116 int error = FALSE; 12117 12118 start = get_tv_number_chk(&argvars[0], &error); 12119 if (argvars[1].v_type == VAR_UNKNOWN) 12120 { 12121 end = start - 1; 12122 start = 0; 12123 } 12124 else 12125 { 12126 end = get_tv_number_chk(&argvars[1], &error); 12127 if (argvars[2].v_type != VAR_UNKNOWN) 12128 stride = get_tv_number_chk(&argvars[2], &error); 12129 } 12130 12131 rettv->vval.v_number = 0; 12132 if (error) 12133 return; /* type error; errmsg already given */ 12134 if (stride == 0) 12135 EMSG(_("E726: Stride is zero")); 12136 else if (stride > 0 ? end + 1 < start : end - 1 > start) 12137 EMSG(_("E727: Start past end")); 12138 else 12139 { 12140 l = list_alloc(); 12141 if (l != NULL) 12142 { 12143 rettv->v_type = VAR_LIST; 12144 rettv->vval.v_list = l; 12145 ++l->lv_refcount; 12146 12147 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 12148 { 12149 li = listitem_alloc(); 12150 if (li == NULL) 12151 break; 12152 li->li_tv.v_type = VAR_NUMBER; 12153 li->li_tv.v_lock = 0; 12154 li->li_tv.vval.v_number = i; 12155 list_append(l, li); 12156 } 12157 } 12158 } 12159 } 12160 12161 /* 12162 * "readfile()" function 12163 */ 12164 static void 12165 f_readfile(argvars, rettv) 12166 typval_T *argvars; 12167 typval_T *rettv; 12168 { 12169 int binary = FALSE; 12170 char_u *fname; 12171 FILE *fd; 12172 list_T *l; 12173 listitem_T *li; 12174 #define FREAD_SIZE 200 /* optimized for text lines */ 12175 char_u buf[FREAD_SIZE]; 12176 int readlen; /* size of last fread() */ 12177 int buflen; /* nr of valid chars in buf[] */ 12178 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12179 int tolist; /* first byte in buf[] still to be put in list */ 12180 int chop; /* how many CR to chop off */ 12181 char_u *prev = NULL; /* previously read bytes, if any */ 12182 int prevlen = 0; /* length of "prev" if not NULL */ 12183 char_u *s; 12184 int len; 12185 long maxline = MAXLNUM; 12186 long cnt = 0; 12187 12188 if (argvars[1].v_type != VAR_UNKNOWN) 12189 { 12190 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12191 binary = TRUE; 12192 if (argvars[2].v_type != VAR_UNKNOWN) 12193 maxline = get_tv_number(&argvars[2]); 12194 } 12195 12196 l = list_alloc(); 12197 if (l == NULL) 12198 return; 12199 rettv->v_type = VAR_LIST; 12200 rettv->vval.v_list = l; 12201 l->lv_refcount = 1; 12202 12203 /* Always open the file in binary mode, library functions have a mind of 12204 * their own about CR-LF conversion. */ 12205 fname = get_tv_string(&argvars[0]); 12206 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12207 { 12208 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12209 return; 12210 } 12211 12212 filtd = 0; 12213 while (cnt < maxline || maxline < 0) 12214 { 12215 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12216 buflen = filtd + readlen; 12217 tolist = 0; 12218 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12219 { 12220 if (buf[filtd] == '\n' || readlen <= 0) 12221 { 12222 /* Only when in binary mode add an empty list item when the 12223 * last line ends in a '\n'. */ 12224 if (!binary && readlen == 0 && filtd == 0) 12225 break; 12226 12227 /* Found end-of-line or end-of-file: add a text line to the 12228 * list. */ 12229 chop = 0; 12230 if (!binary) 12231 while (filtd - chop - 1 >= tolist 12232 && buf[filtd - chop - 1] == '\r') 12233 ++chop; 12234 len = filtd - tolist - chop; 12235 if (prev == NULL) 12236 s = vim_strnsave(buf + tolist, len); 12237 else 12238 { 12239 s = alloc((unsigned)(prevlen + len + 1)); 12240 if (s != NULL) 12241 { 12242 mch_memmove(s, prev, prevlen); 12243 vim_free(prev); 12244 prev = NULL; 12245 mch_memmove(s + prevlen, buf + tolist, len); 12246 s[prevlen + len] = NUL; 12247 } 12248 } 12249 tolist = filtd + 1; 12250 12251 li = listitem_alloc(); 12252 if (li == NULL) 12253 { 12254 vim_free(s); 12255 break; 12256 } 12257 li->li_tv.v_type = VAR_STRING; 12258 li->li_tv.v_lock = 0; 12259 li->li_tv.vval.v_string = s; 12260 list_append(l, li); 12261 12262 if (++cnt >= maxline && maxline >= 0) 12263 break; 12264 if (readlen <= 0) 12265 break; 12266 } 12267 else if (buf[filtd] == NUL) 12268 buf[filtd] = '\n'; 12269 } 12270 if (readlen <= 0) 12271 break; 12272 12273 if (tolist == 0) 12274 { 12275 /* "buf" is full, need to move text to an allocated buffer */ 12276 if (prev == NULL) 12277 { 12278 prev = vim_strnsave(buf, buflen); 12279 prevlen = buflen; 12280 } 12281 else 12282 { 12283 s = alloc((unsigned)(prevlen + buflen)); 12284 if (s != NULL) 12285 { 12286 mch_memmove(s, prev, prevlen); 12287 mch_memmove(s + prevlen, buf, buflen); 12288 vim_free(prev); 12289 prev = s; 12290 prevlen += buflen; 12291 } 12292 } 12293 filtd = 0; 12294 } 12295 else 12296 { 12297 mch_memmove(buf, buf + tolist, buflen - tolist); 12298 filtd -= tolist; 12299 } 12300 } 12301 12302 /* 12303 * For a negative line count use only the lines at the end of the file, 12304 * free the rest. 12305 */ 12306 if (maxline < 0) 12307 while (cnt > -maxline) 12308 { 12309 listitem_remove(l, l->lv_first); 12310 --cnt; 12311 } 12312 12313 vim_free(prev); 12314 fclose(fd); 12315 } 12316 12317 12318 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12319 static void make_connection __ARGS((void)); 12320 static int check_connection __ARGS((void)); 12321 12322 static void 12323 make_connection() 12324 { 12325 if (X_DISPLAY == NULL 12326 # ifdef FEAT_GUI 12327 && !gui.in_use 12328 # endif 12329 ) 12330 { 12331 x_force_connect = TRUE; 12332 setup_term_clip(); 12333 x_force_connect = FALSE; 12334 } 12335 } 12336 12337 static int 12338 check_connection() 12339 { 12340 make_connection(); 12341 if (X_DISPLAY == NULL) 12342 { 12343 EMSG(_("E240: No connection to Vim server")); 12344 return FAIL; 12345 } 12346 return OK; 12347 } 12348 #endif 12349 12350 #ifdef FEAT_CLIENTSERVER 12351 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12352 12353 static void 12354 remote_common(argvars, rettv, expr) 12355 typval_T *argvars; 12356 typval_T *rettv; 12357 int expr; 12358 { 12359 char_u *server_name; 12360 char_u *keys; 12361 char_u *r = NULL; 12362 char_u buf[NUMBUFLEN]; 12363 # ifdef WIN32 12364 HWND w; 12365 # else 12366 Window w; 12367 # endif 12368 12369 if (check_restricted() || check_secure()) 12370 return; 12371 12372 # ifdef FEAT_X11 12373 if (check_connection() == FAIL) 12374 return; 12375 # endif 12376 12377 server_name = get_tv_string_chk(&argvars[0]); 12378 if (server_name == NULL) 12379 return; /* type error; errmsg already given */ 12380 keys = get_tv_string_buf(&argvars[1], buf); 12381 # ifdef WIN32 12382 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12383 # else 12384 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12385 < 0) 12386 # endif 12387 { 12388 if (r != NULL) 12389 EMSG(r); /* sending worked but evaluation failed */ 12390 else 12391 EMSG2(_("E241: Unable to send to %s"), server_name); 12392 return; 12393 } 12394 12395 rettv->vval.v_string = r; 12396 12397 if (argvars[2].v_type != VAR_UNKNOWN) 12398 { 12399 dictitem_T v; 12400 char_u str[30]; 12401 char_u *idvar; 12402 12403 sprintf((char *)str, "0x%x", (unsigned int)w); 12404 v.di_tv.v_type = VAR_STRING; 12405 v.di_tv.vval.v_string = vim_strsave(str); 12406 idvar = get_tv_string_chk(&argvars[2]); 12407 if (idvar != NULL) 12408 set_var(idvar, &v.di_tv, FALSE); 12409 vim_free(v.di_tv.vval.v_string); 12410 } 12411 } 12412 #endif 12413 12414 /* 12415 * "remote_expr()" function 12416 */ 12417 /*ARGSUSED*/ 12418 static void 12419 f_remote_expr(argvars, rettv) 12420 typval_T *argvars; 12421 typval_T *rettv; 12422 { 12423 rettv->v_type = VAR_STRING; 12424 rettv->vval.v_string = NULL; 12425 #ifdef FEAT_CLIENTSERVER 12426 remote_common(argvars, rettv, TRUE); 12427 #endif 12428 } 12429 12430 /* 12431 * "remote_foreground()" function 12432 */ 12433 /*ARGSUSED*/ 12434 static void 12435 f_remote_foreground(argvars, rettv) 12436 typval_T *argvars; 12437 typval_T *rettv; 12438 { 12439 rettv->vval.v_number = 0; 12440 #ifdef FEAT_CLIENTSERVER 12441 # ifdef WIN32 12442 /* On Win32 it's done in this application. */ 12443 { 12444 char_u *server_name = get_tv_string_chk(&argvars[0]); 12445 12446 if (server_name != NULL) 12447 serverForeground(server_name); 12448 } 12449 # else 12450 /* Send a foreground() expression to the server. */ 12451 argvars[1].v_type = VAR_STRING; 12452 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12453 argvars[2].v_type = VAR_UNKNOWN; 12454 remote_common(argvars, rettv, TRUE); 12455 vim_free(argvars[1].vval.v_string); 12456 # endif 12457 #endif 12458 } 12459 12460 /*ARGSUSED*/ 12461 static void 12462 f_remote_peek(argvars, rettv) 12463 typval_T *argvars; 12464 typval_T *rettv; 12465 { 12466 #ifdef FEAT_CLIENTSERVER 12467 dictitem_T v; 12468 char_u *s = NULL; 12469 # ifdef WIN32 12470 int n = 0; 12471 # endif 12472 char_u *serverid; 12473 12474 if (check_restricted() || check_secure()) 12475 { 12476 rettv->vval.v_number = -1; 12477 return; 12478 } 12479 serverid = get_tv_string_chk(&argvars[0]); 12480 if (serverid == NULL) 12481 { 12482 rettv->vval.v_number = -1; 12483 return; /* type error; errmsg already given */ 12484 } 12485 # ifdef WIN32 12486 sscanf(serverid, "%x", &n); 12487 if (n == 0) 12488 rettv->vval.v_number = -1; 12489 else 12490 { 12491 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12492 rettv->vval.v_number = (s != NULL); 12493 } 12494 # else 12495 rettv->vval.v_number = 0; 12496 if (check_connection() == FAIL) 12497 return; 12498 12499 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12500 serverStrToWin(serverid), &s); 12501 # endif 12502 12503 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12504 { 12505 char_u *retvar; 12506 12507 v.di_tv.v_type = VAR_STRING; 12508 v.di_tv.vval.v_string = vim_strsave(s); 12509 retvar = get_tv_string_chk(&argvars[1]); 12510 if (retvar != NULL) 12511 set_var(retvar, &v.di_tv, FALSE); 12512 vim_free(v.di_tv.vval.v_string); 12513 } 12514 #else 12515 rettv->vval.v_number = -1; 12516 #endif 12517 } 12518 12519 /*ARGSUSED*/ 12520 static void 12521 f_remote_read(argvars, rettv) 12522 typval_T *argvars; 12523 typval_T *rettv; 12524 { 12525 char_u *r = NULL; 12526 12527 #ifdef FEAT_CLIENTSERVER 12528 char_u *serverid = get_tv_string_chk(&argvars[0]); 12529 12530 if (serverid != NULL && !check_restricted() && !check_secure()) 12531 { 12532 # ifdef WIN32 12533 /* The server's HWND is encoded in the 'id' parameter */ 12534 int n = 0; 12535 12536 sscanf(serverid, "%x", &n); 12537 if (n != 0) 12538 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12539 if (r == NULL) 12540 # else 12541 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12542 serverStrToWin(serverid), &r, FALSE) < 0) 12543 # endif 12544 EMSG(_("E277: Unable to read a server reply")); 12545 } 12546 #endif 12547 rettv->v_type = VAR_STRING; 12548 rettv->vval.v_string = r; 12549 } 12550 12551 /* 12552 * "remote_send()" function 12553 */ 12554 /*ARGSUSED*/ 12555 static void 12556 f_remote_send(argvars, rettv) 12557 typval_T *argvars; 12558 typval_T *rettv; 12559 { 12560 rettv->v_type = VAR_STRING; 12561 rettv->vval.v_string = NULL; 12562 #ifdef FEAT_CLIENTSERVER 12563 remote_common(argvars, rettv, FALSE); 12564 #endif 12565 } 12566 12567 /* 12568 * "remove()" function 12569 */ 12570 static void 12571 f_remove(argvars, rettv) 12572 typval_T *argvars; 12573 typval_T *rettv; 12574 { 12575 list_T *l; 12576 listitem_T *item, *item2; 12577 listitem_T *li; 12578 long idx; 12579 long end; 12580 char_u *key; 12581 dict_T *d; 12582 dictitem_T *di; 12583 12584 rettv->vval.v_number = 0; 12585 if (argvars[0].v_type == VAR_DICT) 12586 { 12587 if (argvars[2].v_type != VAR_UNKNOWN) 12588 EMSG2(_(e_toomanyarg), "remove()"); 12589 else if ((d = argvars[0].vval.v_dict) != NULL 12590 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12591 { 12592 key = get_tv_string_chk(&argvars[1]); 12593 if (key != NULL) 12594 { 12595 di = dict_find(d, key, -1); 12596 if (di == NULL) 12597 EMSG2(_(e_dictkey), key); 12598 else 12599 { 12600 *rettv = di->di_tv; 12601 init_tv(&di->di_tv); 12602 dictitem_remove(d, di); 12603 } 12604 } 12605 } 12606 } 12607 else if (argvars[0].v_type != VAR_LIST) 12608 EMSG2(_(e_listdictarg), "remove()"); 12609 else if ((l = argvars[0].vval.v_list) != NULL 12610 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12611 { 12612 int error = FALSE; 12613 12614 idx = get_tv_number_chk(&argvars[1], &error); 12615 if (error) 12616 ; /* type error: do nothing, errmsg already given */ 12617 else if ((item = list_find(l, idx)) == NULL) 12618 EMSGN(_(e_listidx), idx); 12619 else 12620 { 12621 if (argvars[2].v_type == VAR_UNKNOWN) 12622 { 12623 /* Remove one item, return its value. */ 12624 list_remove(l, item, item); 12625 *rettv = item->li_tv; 12626 vim_free(item); 12627 } 12628 else 12629 { 12630 /* Remove range of items, return list with values. */ 12631 end = get_tv_number_chk(&argvars[2], &error); 12632 if (error) 12633 ; /* type error: do nothing */ 12634 else if ((item2 = list_find(l, end)) == NULL) 12635 EMSGN(_(e_listidx), end); 12636 else 12637 { 12638 int cnt = 0; 12639 12640 for (li = item; li != NULL; li = li->li_next) 12641 { 12642 ++cnt; 12643 if (li == item2) 12644 break; 12645 } 12646 if (li == NULL) /* didn't find "item2" after "item" */ 12647 EMSG(_(e_invrange)); 12648 else 12649 { 12650 list_remove(l, item, item2); 12651 l = list_alloc(); 12652 if (l != NULL) 12653 { 12654 rettv->v_type = VAR_LIST; 12655 rettv->vval.v_list = l; 12656 l->lv_first = item; 12657 l->lv_last = item2; 12658 l->lv_refcount = 1; 12659 item->li_prev = NULL; 12660 item2->li_next = NULL; 12661 l->lv_len = cnt; 12662 } 12663 } 12664 } 12665 } 12666 } 12667 } 12668 } 12669 12670 /* 12671 * "rename({from}, {to})" function 12672 */ 12673 static void 12674 f_rename(argvars, rettv) 12675 typval_T *argvars; 12676 typval_T *rettv; 12677 { 12678 char_u buf[NUMBUFLEN]; 12679 12680 if (check_restricted() || check_secure()) 12681 rettv->vval.v_number = -1; 12682 else 12683 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12684 get_tv_string_buf(&argvars[1], buf)); 12685 } 12686 12687 /* 12688 * "repeat()" function 12689 */ 12690 /*ARGSUSED*/ 12691 static void 12692 f_repeat(argvars, rettv) 12693 typval_T *argvars; 12694 typval_T *rettv; 12695 { 12696 char_u *p; 12697 int n; 12698 int slen; 12699 int len; 12700 char_u *r; 12701 int i; 12702 list_T *l; 12703 12704 n = get_tv_number(&argvars[1]); 12705 if (argvars[0].v_type == VAR_LIST) 12706 { 12707 l = list_alloc(); 12708 if (l != NULL && argvars[0].vval.v_list != NULL) 12709 { 12710 l->lv_refcount = 1; 12711 while (n-- > 0) 12712 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12713 break; 12714 } 12715 rettv->v_type = VAR_LIST; 12716 rettv->vval.v_list = l; 12717 } 12718 else 12719 { 12720 p = get_tv_string(&argvars[0]); 12721 rettv->v_type = VAR_STRING; 12722 rettv->vval.v_string = NULL; 12723 12724 slen = (int)STRLEN(p); 12725 len = slen * n; 12726 if (len <= 0) 12727 return; 12728 12729 r = alloc(len + 1); 12730 if (r != NULL) 12731 { 12732 for (i = 0; i < n; i++) 12733 mch_memmove(r + i * slen, p, (size_t)slen); 12734 r[len] = NUL; 12735 } 12736 12737 rettv->vval.v_string = r; 12738 } 12739 } 12740 12741 /* 12742 * "resolve()" function 12743 */ 12744 static void 12745 f_resolve(argvars, rettv) 12746 typval_T *argvars; 12747 typval_T *rettv; 12748 { 12749 char_u *p; 12750 12751 p = get_tv_string(&argvars[0]); 12752 #ifdef FEAT_SHORTCUT 12753 { 12754 char_u *v = NULL; 12755 12756 v = mch_resolve_shortcut(p); 12757 if (v != NULL) 12758 rettv->vval.v_string = v; 12759 else 12760 rettv->vval.v_string = vim_strsave(p); 12761 } 12762 #else 12763 # ifdef HAVE_READLINK 12764 { 12765 char_u buf[MAXPATHL + 1]; 12766 char_u *cpy; 12767 int len; 12768 char_u *remain = NULL; 12769 char_u *q; 12770 int is_relative_to_current = FALSE; 12771 int has_trailing_pathsep = FALSE; 12772 int limit = 100; 12773 12774 p = vim_strsave(p); 12775 12776 if (p[0] == '.' && (vim_ispathsep(p[1]) 12777 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12778 is_relative_to_current = TRUE; 12779 12780 len = STRLEN(p); 12781 if (len > 0 && after_pathsep(p, p + len)) 12782 has_trailing_pathsep = TRUE; 12783 12784 q = getnextcomp(p); 12785 if (*q != NUL) 12786 { 12787 /* Separate the first path component in "p", and keep the 12788 * remainder (beginning with the path separator). */ 12789 remain = vim_strsave(q - 1); 12790 q[-1] = NUL; 12791 } 12792 12793 for (;;) 12794 { 12795 for (;;) 12796 { 12797 len = readlink((char *)p, (char *)buf, MAXPATHL); 12798 if (len <= 0) 12799 break; 12800 buf[len] = NUL; 12801 12802 if (limit-- == 0) 12803 { 12804 vim_free(p); 12805 vim_free(remain); 12806 EMSG(_("E655: Too many symbolic links (cycle?)")); 12807 rettv->vval.v_string = NULL; 12808 goto fail; 12809 } 12810 12811 /* Ensure that the result will have a trailing path separator 12812 * if the argument has one. */ 12813 if (remain == NULL && has_trailing_pathsep) 12814 add_pathsep(buf); 12815 12816 /* Separate the first path component in the link value and 12817 * concatenate the remainders. */ 12818 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12819 if (*q != NUL) 12820 { 12821 if (remain == NULL) 12822 remain = vim_strsave(q - 1); 12823 else 12824 { 12825 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12826 if (cpy != NULL) 12827 { 12828 STRCAT(cpy, remain); 12829 vim_free(remain); 12830 remain = cpy; 12831 } 12832 } 12833 q[-1] = NUL; 12834 } 12835 12836 q = gettail(p); 12837 if (q > p && *q == NUL) 12838 { 12839 /* Ignore trailing path separator. */ 12840 q[-1] = NUL; 12841 q = gettail(p); 12842 } 12843 if (q > p && !mch_isFullName(buf)) 12844 { 12845 /* symlink is relative to directory of argument */ 12846 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12847 if (cpy != NULL) 12848 { 12849 STRCPY(cpy, p); 12850 STRCPY(gettail(cpy), buf); 12851 vim_free(p); 12852 p = cpy; 12853 } 12854 } 12855 else 12856 { 12857 vim_free(p); 12858 p = vim_strsave(buf); 12859 } 12860 } 12861 12862 if (remain == NULL) 12863 break; 12864 12865 /* Append the first path component of "remain" to "p". */ 12866 q = getnextcomp(remain + 1); 12867 len = q - remain - (*q != NUL); 12868 cpy = vim_strnsave(p, STRLEN(p) + len); 12869 if (cpy != NULL) 12870 { 12871 STRNCAT(cpy, remain, len); 12872 vim_free(p); 12873 p = cpy; 12874 } 12875 /* Shorten "remain". */ 12876 if (*q != NUL) 12877 STRCPY(remain, q - 1); 12878 else 12879 { 12880 vim_free(remain); 12881 remain = NULL; 12882 } 12883 } 12884 12885 /* If the result is a relative path name, make it explicitly relative to 12886 * the current directory if and only if the argument had this form. */ 12887 if (!vim_ispathsep(*p)) 12888 { 12889 if (is_relative_to_current 12890 && *p != NUL 12891 && !(p[0] == '.' 12892 && (p[1] == NUL 12893 || vim_ispathsep(p[1]) 12894 || (p[1] == '.' 12895 && (p[2] == NUL 12896 || vim_ispathsep(p[2])))))) 12897 { 12898 /* Prepend "./". */ 12899 cpy = concat_str((char_u *)"./", p); 12900 if (cpy != NULL) 12901 { 12902 vim_free(p); 12903 p = cpy; 12904 } 12905 } 12906 else if (!is_relative_to_current) 12907 { 12908 /* Strip leading "./". */ 12909 q = p; 12910 while (q[0] == '.' && vim_ispathsep(q[1])) 12911 q += 2; 12912 if (q > p) 12913 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12914 } 12915 } 12916 12917 /* Ensure that the result will have no trailing path separator 12918 * if the argument had none. But keep "/" or "//". */ 12919 if (!has_trailing_pathsep) 12920 { 12921 q = p + STRLEN(p); 12922 if (after_pathsep(p, q)) 12923 *gettail_sep(p) = NUL; 12924 } 12925 12926 rettv->vval.v_string = p; 12927 } 12928 # else 12929 rettv->vval.v_string = vim_strsave(p); 12930 # endif 12931 #endif 12932 12933 simplify_filename(rettv->vval.v_string); 12934 12935 #ifdef HAVE_READLINK 12936 fail: 12937 #endif 12938 rettv->v_type = VAR_STRING; 12939 } 12940 12941 /* 12942 * "reverse({list})" function 12943 */ 12944 static void 12945 f_reverse(argvars, rettv) 12946 typval_T *argvars; 12947 typval_T *rettv; 12948 { 12949 list_T *l; 12950 listitem_T *li, *ni; 12951 12952 rettv->vval.v_number = 0; 12953 if (argvars[0].v_type != VAR_LIST) 12954 EMSG2(_(e_listarg), "reverse()"); 12955 else if ((l = argvars[0].vval.v_list) != NULL 12956 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12957 { 12958 li = l->lv_last; 12959 l->lv_first = l->lv_last = NULL; 12960 l->lv_len = 0; 12961 while (li != NULL) 12962 { 12963 ni = li->li_prev; 12964 list_append(l, li); 12965 li = ni; 12966 } 12967 rettv->vval.v_list = l; 12968 rettv->v_type = VAR_LIST; 12969 ++l->lv_refcount; 12970 } 12971 } 12972 12973 #define SP_NOMOVE 1 /* don't move cursor */ 12974 #define SP_REPEAT 2 /* repeat to find outer pair */ 12975 #define SP_RETCOUNT 4 /* return matchcount */ 12976 #define SP_SETPCMARK 8 /* set previous context mark */ 12977 12978 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12979 12980 /* 12981 * Get flags for a search function. 12982 * Possibly sets "p_ws". 12983 * Returns BACKWARD, FORWARD or zero (for an error). 12984 */ 12985 static int 12986 get_search_arg(varp, flagsp) 12987 typval_T *varp; 12988 int *flagsp; 12989 { 12990 int dir = FORWARD; 12991 char_u *flags; 12992 char_u nbuf[NUMBUFLEN]; 12993 int mask; 12994 12995 if (varp->v_type != VAR_UNKNOWN) 12996 { 12997 flags = get_tv_string_buf_chk(varp, nbuf); 12998 if (flags == NULL) 12999 return 0; /* type error; errmsg already given */ 13000 while (*flags != NUL) 13001 { 13002 switch (*flags) 13003 { 13004 case 'b': dir = BACKWARD; break; 13005 case 'w': p_ws = TRUE; break; 13006 case 'W': p_ws = FALSE; break; 13007 default: mask = 0; 13008 if (flagsp != NULL) 13009 switch (*flags) 13010 { 13011 case 'n': mask = SP_NOMOVE; break; 13012 case 'r': mask = SP_REPEAT; break; 13013 case 'm': mask = SP_RETCOUNT; break; 13014 case 's': mask = SP_SETPCMARK; break; 13015 } 13016 if (mask == 0) 13017 { 13018 EMSG2(_(e_invarg2), flags); 13019 dir = 0; 13020 } 13021 else 13022 *flagsp |= mask; 13023 } 13024 if (dir == 0) 13025 break; 13026 ++flags; 13027 } 13028 } 13029 return dir; 13030 } 13031 13032 /* 13033 * "search()" function 13034 */ 13035 static void 13036 f_search(argvars, rettv) 13037 typval_T *argvars; 13038 typval_T *rettv; 13039 { 13040 char_u *pat; 13041 pos_T pos; 13042 pos_T save_cursor; 13043 int save_p_ws = p_ws; 13044 int dir; 13045 int flags = 0; 13046 13047 rettv->vval.v_number = 0; /* default: FAIL */ 13048 13049 pat = get_tv_string(&argvars[0]); 13050 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 13051 if (dir == 0) 13052 goto theend; 13053 /* 13054 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 13055 * Check to make sure only those flags are set. 13056 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 13057 * flags cannot be set. Check for that condition also. 13058 */ 13059 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 13060 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 13061 { 13062 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13063 goto theend; 13064 } 13065 13066 pos = save_cursor = curwin->w_cursor; 13067 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 13068 SEARCH_KEEP, RE_SEARCH) != FAIL) 13069 { 13070 rettv->vval.v_number = pos.lnum; 13071 if (flags & SP_SETPCMARK) 13072 setpcmark(); 13073 curwin->w_cursor = pos; 13074 /* "/$" will put the cursor after the end of the line, may need to 13075 * correct that here */ 13076 check_cursor(); 13077 } 13078 13079 /* If 'n' flag is used: restore cursor position. */ 13080 if (flags & SP_NOMOVE) 13081 curwin->w_cursor = save_cursor; 13082 theend: 13083 p_ws = save_p_ws; 13084 } 13085 13086 /* 13087 * "searchdecl()" function 13088 */ 13089 static void 13090 f_searchdecl(argvars, rettv) 13091 typval_T *argvars; 13092 typval_T *rettv; 13093 { 13094 int locally = 1; 13095 int thisblock = 0; 13096 int error = FALSE; 13097 char_u *name; 13098 13099 rettv->vval.v_number = 1; /* default: FAIL */ 13100 13101 name = get_tv_string_chk(&argvars[0]); 13102 if (argvars[1].v_type != VAR_UNKNOWN) 13103 { 13104 locally = get_tv_number_chk(&argvars[1], &error) == 0; 13105 if (!error && argvars[2].v_type != VAR_UNKNOWN) 13106 thisblock = get_tv_number_chk(&argvars[2], &error) != 0; 13107 } 13108 if (!error && name != NULL) 13109 rettv->vval.v_number = find_decl(name, (int)STRLEN(name), 13110 locally, thisblock, SEARCH_KEEP) == FAIL; 13111 } 13112 13113 /* 13114 * "searchpair()" function 13115 */ 13116 static void 13117 f_searchpair(argvars, rettv) 13118 typval_T *argvars; 13119 typval_T *rettv; 13120 { 13121 char_u *spat, *mpat, *epat; 13122 char_u *skip; 13123 int save_p_ws = p_ws; 13124 int dir; 13125 int flags = 0; 13126 char_u nbuf1[NUMBUFLEN]; 13127 char_u nbuf2[NUMBUFLEN]; 13128 char_u nbuf3[NUMBUFLEN]; 13129 13130 rettv->vval.v_number = 0; /* default: FAIL */ 13131 13132 /* Get the three pattern arguments: start, middle, end. */ 13133 spat = get_tv_string_chk(&argvars[0]); 13134 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 13135 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 13136 if (spat == NULL || mpat == NULL || epat == NULL) 13137 goto theend; /* type error */ 13138 13139 /* Handle the optional fourth argument: flags */ 13140 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 13141 if (dir == 0) 13142 goto theend; 13143 /* 13144 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 13145 */ 13146 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 13147 { 13148 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 13149 goto theend; 13150 } 13151 13152 /* Optional fifth argument: skip expresion */ 13153 if (argvars[3].v_type == VAR_UNKNOWN 13154 || argvars[4].v_type == VAR_UNKNOWN) 13155 skip = (char_u *)""; 13156 else 13157 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 13158 if (skip == NULL) 13159 goto theend; /* type error */ 13160 13161 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 13162 13163 theend: 13164 p_ws = save_p_ws; 13165 } 13166 13167 /* 13168 * Search for a start/middle/end thing. 13169 * Used by searchpair(), see its documentation for the details. 13170 * Returns 0 or -1 for no match, 13171 */ 13172 long 13173 do_searchpair(spat, mpat, epat, dir, skip, flags) 13174 char_u *spat; /* start pattern */ 13175 char_u *mpat; /* middle pattern */ 13176 char_u *epat; /* end pattern */ 13177 int dir; /* BACKWARD or FORWARD */ 13178 char_u *skip; /* skip expression */ 13179 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 13180 { 13181 char_u *save_cpo; 13182 char_u *pat, *pat2 = NULL, *pat3 = NULL; 13183 long retval = 0; 13184 pos_T pos; 13185 pos_T firstpos; 13186 pos_T foundpos; 13187 pos_T save_cursor; 13188 pos_T save_pos; 13189 int n; 13190 int r; 13191 int nest = 1; 13192 int err; 13193 13194 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13195 save_cpo = p_cpo; 13196 p_cpo = (char_u *)""; 13197 13198 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13199 * start/middle/end (pat3, for the top pair). */ 13200 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13201 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13202 if (pat2 == NULL || pat3 == NULL) 13203 goto theend; 13204 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13205 if (*mpat == NUL) 13206 STRCPY(pat3, pat2); 13207 else 13208 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13209 spat, epat, mpat); 13210 13211 save_cursor = curwin->w_cursor; 13212 pos = curwin->w_cursor; 13213 firstpos.lnum = 0; 13214 foundpos.lnum = 0; 13215 pat = pat3; 13216 for (;;) 13217 { 13218 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13219 SEARCH_KEEP, RE_SEARCH); 13220 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13221 /* didn't find it or found the first match again: FAIL */ 13222 break; 13223 13224 if (firstpos.lnum == 0) 13225 firstpos = pos; 13226 if (equalpos(pos, foundpos)) 13227 { 13228 /* Found the same position again. Can happen with a pattern that 13229 * has "\zs" at the end and searching backwards. Advance one 13230 * character and try again. */ 13231 if (dir == BACKWARD) 13232 decl(&pos); 13233 else 13234 incl(&pos); 13235 } 13236 foundpos = pos; 13237 13238 /* If the skip pattern matches, ignore this match. */ 13239 if (*skip != NUL) 13240 { 13241 save_pos = curwin->w_cursor; 13242 curwin->w_cursor = pos; 13243 r = eval_to_bool(skip, &err, NULL, FALSE); 13244 curwin->w_cursor = save_pos; 13245 if (err) 13246 { 13247 /* Evaluating {skip} caused an error, break here. */ 13248 curwin->w_cursor = save_cursor; 13249 retval = -1; 13250 break; 13251 } 13252 if (r) 13253 continue; 13254 } 13255 13256 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13257 { 13258 /* Found end when searching backwards or start when searching 13259 * forward: nested pair. */ 13260 ++nest; 13261 pat = pat2; /* nested, don't search for middle */ 13262 } 13263 else 13264 { 13265 /* Found end when searching forward or start when searching 13266 * backward: end of (nested) pair; or found middle in outer pair. */ 13267 if (--nest == 1) 13268 pat = pat3; /* outer level, search for middle */ 13269 } 13270 13271 if (nest == 0) 13272 { 13273 /* Found the match: return matchcount or line number. */ 13274 if (flags & SP_RETCOUNT) 13275 ++retval; 13276 else 13277 retval = pos.lnum; 13278 if (flags & SP_SETPCMARK) 13279 setpcmark(); 13280 curwin->w_cursor = pos; 13281 if (!(flags & SP_REPEAT)) 13282 break; 13283 nest = 1; /* search for next unmatched */ 13284 } 13285 } 13286 13287 /* If 'n' flag is used or search failed: restore cursor position. */ 13288 if ((flags & SP_NOMOVE) || retval == 0) 13289 curwin->w_cursor = save_cursor; 13290 13291 theend: 13292 vim_free(pat2); 13293 vim_free(pat3); 13294 p_cpo = save_cpo; 13295 13296 return retval; 13297 } 13298 13299 /*ARGSUSED*/ 13300 static void 13301 f_server2client(argvars, rettv) 13302 typval_T *argvars; 13303 typval_T *rettv; 13304 { 13305 #ifdef FEAT_CLIENTSERVER 13306 char_u buf[NUMBUFLEN]; 13307 char_u *server = get_tv_string_chk(&argvars[0]); 13308 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13309 13310 rettv->vval.v_number = -1; 13311 if (server == NULL || reply == NULL) 13312 return; 13313 if (check_restricted() || check_secure()) 13314 return; 13315 # ifdef FEAT_X11 13316 if (check_connection() == FAIL) 13317 return; 13318 # endif 13319 13320 if (serverSendReply(server, reply) < 0) 13321 { 13322 EMSG(_("E258: Unable to send to client")); 13323 return; 13324 } 13325 rettv->vval.v_number = 0; 13326 #else 13327 rettv->vval.v_number = -1; 13328 #endif 13329 } 13330 13331 /*ARGSUSED*/ 13332 static void 13333 f_serverlist(argvars, rettv) 13334 typval_T *argvars; 13335 typval_T *rettv; 13336 { 13337 char_u *r = NULL; 13338 13339 #ifdef FEAT_CLIENTSERVER 13340 # ifdef WIN32 13341 r = serverGetVimNames(); 13342 # else 13343 make_connection(); 13344 if (X_DISPLAY != NULL) 13345 r = serverGetVimNames(X_DISPLAY); 13346 # endif 13347 #endif 13348 rettv->v_type = VAR_STRING; 13349 rettv->vval.v_string = r; 13350 } 13351 13352 /* 13353 * "setbufvar()" function 13354 */ 13355 /*ARGSUSED*/ 13356 static void 13357 f_setbufvar(argvars, rettv) 13358 typval_T *argvars; 13359 typval_T *rettv; 13360 { 13361 buf_T *buf; 13362 #ifdef FEAT_AUTOCMD 13363 aco_save_T aco; 13364 #else 13365 buf_T *save_curbuf; 13366 #endif 13367 char_u *varname, *bufvarname; 13368 typval_T *varp; 13369 char_u nbuf[NUMBUFLEN]; 13370 13371 rettv->vval.v_number = 0; 13372 13373 if (check_restricted() || check_secure()) 13374 return; 13375 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13376 varname = get_tv_string_chk(&argvars[1]); 13377 buf = get_buf_tv(&argvars[0]); 13378 varp = &argvars[2]; 13379 13380 if (buf != NULL && varname != NULL && varp != NULL) 13381 { 13382 /* set curbuf to be our buf, temporarily */ 13383 #ifdef FEAT_AUTOCMD 13384 aucmd_prepbuf(&aco, buf); 13385 #else 13386 save_curbuf = curbuf; 13387 curbuf = buf; 13388 #endif 13389 13390 if (*varname == '&') 13391 { 13392 long numval; 13393 char_u *strval; 13394 int error = FALSE; 13395 13396 ++varname; 13397 numval = get_tv_number_chk(varp, &error); 13398 strval = get_tv_string_buf_chk(varp, nbuf); 13399 if (!error && strval != NULL) 13400 set_option_value(varname, numval, strval, OPT_LOCAL); 13401 } 13402 else 13403 { 13404 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13405 if (bufvarname != NULL) 13406 { 13407 STRCPY(bufvarname, "b:"); 13408 STRCPY(bufvarname + 2, varname); 13409 set_var(bufvarname, varp, TRUE); 13410 vim_free(bufvarname); 13411 } 13412 } 13413 13414 /* reset notion of buffer */ 13415 #ifdef FEAT_AUTOCMD 13416 aucmd_restbuf(&aco); 13417 #else 13418 curbuf = save_curbuf; 13419 #endif 13420 } 13421 } 13422 13423 /* 13424 * "setcmdpos()" function 13425 */ 13426 static void 13427 f_setcmdpos(argvars, rettv) 13428 typval_T *argvars; 13429 typval_T *rettv; 13430 { 13431 int pos = (int)get_tv_number(&argvars[0]) - 1; 13432 13433 if (pos >= 0) 13434 rettv->vval.v_number = set_cmdline_pos(pos); 13435 } 13436 13437 /* 13438 * "setline()" function 13439 */ 13440 static void 13441 f_setline(argvars, rettv) 13442 typval_T *argvars; 13443 typval_T *rettv; 13444 { 13445 linenr_T lnum; 13446 char_u *line = NULL; 13447 list_T *l = NULL; 13448 listitem_T *li = NULL; 13449 long added = 0; 13450 linenr_T lcount = curbuf->b_ml.ml_line_count; 13451 13452 lnum = get_tv_lnum(&argvars[0]); 13453 if (argvars[1].v_type == VAR_LIST) 13454 { 13455 l = argvars[1].vval.v_list; 13456 li = l->lv_first; 13457 } 13458 else 13459 line = get_tv_string_chk(&argvars[1]); 13460 13461 rettv->vval.v_number = 0; /* OK */ 13462 for (;;) 13463 { 13464 if (l != NULL) 13465 { 13466 /* list argument, get next string */ 13467 if (li == NULL) 13468 break; 13469 line = get_tv_string_chk(&li->li_tv); 13470 li = li->li_next; 13471 } 13472 13473 rettv->vval.v_number = 1; /* FAIL */ 13474 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13475 break; 13476 if (lnum <= curbuf->b_ml.ml_line_count) 13477 { 13478 /* existing line, replace it */ 13479 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13480 { 13481 changed_bytes(lnum, 0); 13482 check_cursor_col(); 13483 rettv->vval.v_number = 0; /* OK */ 13484 } 13485 } 13486 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13487 { 13488 /* lnum is one past the last line, append the line */ 13489 ++added; 13490 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13491 rettv->vval.v_number = 0; /* OK */ 13492 } 13493 13494 if (l == NULL) /* only one string argument */ 13495 break; 13496 ++lnum; 13497 } 13498 13499 if (added > 0) 13500 appended_lines_mark(lcount, added); 13501 } 13502 13503 /* 13504 * "setqflist()" function 13505 */ 13506 /*ARGSUSED*/ 13507 static void 13508 f_setqflist(argvars, rettv) 13509 typval_T *argvars; 13510 typval_T *rettv; 13511 { 13512 char_u *act; 13513 int action = ' '; 13514 13515 rettv->vval.v_number = -1; 13516 13517 #ifdef FEAT_QUICKFIX 13518 if (argvars[0].v_type != VAR_LIST) 13519 EMSG(_(e_listreq)); 13520 else 13521 { 13522 list_T *l = argvars[0].vval.v_list; 13523 13524 if (argvars[1].v_type == VAR_STRING) 13525 { 13526 act = get_tv_string_chk(&argvars[1]); 13527 if (act == NULL) 13528 return; /* type error; errmsg already given */ 13529 if (*act == 'a' || *act == 'r') 13530 action = *act; 13531 } 13532 13533 if (l != NULL && set_errorlist(l, action) == OK) 13534 rettv->vval.v_number = 0; 13535 } 13536 #endif 13537 } 13538 13539 /* 13540 * "setreg()" function 13541 */ 13542 static void 13543 f_setreg(argvars, rettv) 13544 typval_T *argvars; 13545 typval_T *rettv; 13546 { 13547 int regname; 13548 char_u *strregname; 13549 char_u *stropt; 13550 char_u *strval; 13551 int append; 13552 char_u yank_type; 13553 long block_len; 13554 13555 block_len = -1; 13556 yank_type = MAUTO; 13557 append = FALSE; 13558 13559 strregname = get_tv_string_chk(argvars); 13560 rettv->vval.v_number = 1; /* FAIL is default */ 13561 13562 if (strregname == NULL) 13563 return; /* type error; errmsg already given */ 13564 regname = *strregname; 13565 if (regname == 0 || regname == '@') 13566 regname = '"'; 13567 else if (regname == '=') 13568 return; 13569 13570 if (argvars[2].v_type != VAR_UNKNOWN) 13571 { 13572 stropt = get_tv_string_chk(&argvars[2]); 13573 if (stropt == NULL) 13574 return; /* type error */ 13575 for (; *stropt != NUL; ++stropt) 13576 switch (*stropt) 13577 { 13578 case 'a': case 'A': /* append */ 13579 append = TRUE; 13580 break; 13581 case 'v': case 'c': /* character-wise selection */ 13582 yank_type = MCHAR; 13583 break; 13584 case 'V': case 'l': /* line-wise selection */ 13585 yank_type = MLINE; 13586 break; 13587 #ifdef FEAT_VISUAL 13588 case 'b': case Ctrl_V: /* block-wise selection */ 13589 yank_type = MBLOCK; 13590 if (VIM_ISDIGIT(stropt[1])) 13591 { 13592 ++stropt; 13593 block_len = getdigits(&stropt) - 1; 13594 --stropt; 13595 } 13596 break; 13597 #endif 13598 } 13599 } 13600 13601 strval = get_tv_string_chk(&argvars[1]); 13602 if (strval != NULL) 13603 write_reg_contents_ex(regname, strval, -1, 13604 append, yank_type, block_len); 13605 rettv->vval.v_number = 0; 13606 } 13607 13608 13609 /* 13610 * "setwinvar(expr)" function 13611 */ 13612 /*ARGSUSED*/ 13613 static void 13614 f_setwinvar(argvars, rettv) 13615 typval_T *argvars; 13616 typval_T *rettv; 13617 { 13618 win_T *win; 13619 #ifdef FEAT_WINDOWS 13620 win_T *save_curwin; 13621 #endif 13622 char_u *varname, *winvarname; 13623 typval_T *varp; 13624 char_u nbuf[NUMBUFLEN]; 13625 13626 rettv->vval.v_number = 0; 13627 13628 if (check_restricted() || check_secure()) 13629 return; 13630 win = find_win_by_nr(&argvars[0]); 13631 varname = get_tv_string_chk(&argvars[1]); 13632 varp = &argvars[2]; 13633 13634 if (win != NULL && varname != NULL && varp != NULL) 13635 { 13636 #ifdef FEAT_WINDOWS 13637 /* set curwin to be our win, temporarily */ 13638 save_curwin = curwin; 13639 curwin = win; 13640 curbuf = curwin->w_buffer; 13641 #endif 13642 13643 if (*varname == '&') 13644 { 13645 long numval; 13646 char_u *strval; 13647 int error = FALSE; 13648 13649 ++varname; 13650 numval = get_tv_number_chk(varp, &error); 13651 strval = get_tv_string_buf_chk(varp, nbuf); 13652 if (!error && strval != NULL) 13653 set_option_value(varname, numval, strval, OPT_LOCAL); 13654 } 13655 else 13656 { 13657 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13658 if (winvarname != NULL) 13659 { 13660 STRCPY(winvarname, "w:"); 13661 STRCPY(winvarname + 2, varname); 13662 set_var(winvarname, varp, TRUE); 13663 vim_free(winvarname); 13664 } 13665 } 13666 13667 #ifdef FEAT_WINDOWS 13668 /* Restore current window, if it's still valid (autocomands can make 13669 * it invalid). */ 13670 if (win_valid(save_curwin)) 13671 { 13672 curwin = save_curwin; 13673 curbuf = curwin->w_buffer; 13674 } 13675 #endif 13676 } 13677 } 13678 13679 /* 13680 * "simplify()" function 13681 */ 13682 static void 13683 f_simplify(argvars, rettv) 13684 typval_T *argvars; 13685 typval_T *rettv; 13686 { 13687 char_u *p; 13688 13689 p = get_tv_string(&argvars[0]); 13690 rettv->vval.v_string = vim_strsave(p); 13691 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13692 rettv->v_type = VAR_STRING; 13693 } 13694 13695 static int 13696 #ifdef __BORLANDC__ 13697 _RTLENTRYF 13698 #endif 13699 item_compare __ARGS((const void *s1, const void *s2)); 13700 static int 13701 #ifdef __BORLANDC__ 13702 _RTLENTRYF 13703 #endif 13704 item_compare2 __ARGS((const void *s1, const void *s2)); 13705 13706 static int item_compare_ic; 13707 static char_u *item_compare_func; 13708 static int item_compare_func_err; 13709 #define ITEM_COMPARE_FAIL 999 13710 13711 /* 13712 * Compare functions for f_sort() below. 13713 */ 13714 static int 13715 #ifdef __BORLANDC__ 13716 _RTLENTRYF 13717 #endif 13718 item_compare(s1, s2) 13719 const void *s1; 13720 const void *s2; 13721 { 13722 char_u *p1, *p2; 13723 char_u *tofree1, *tofree2; 13724 int res; 13725 char_u numbuf1[NUMBUFLEN]; 13726 char_u numbuf2[NUMBUFLEN]; 13727 13728 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13729 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13730 if (item_compare_ic) 13731 res = STRICMP(p1, p2); 13732 else 13733 res = STRCMP(p1, p2); 13734 vim_free(tofree1); 13735 vim_free(tofree2); 13736 return res; 13737 } 13738 13739 static int 13740 #ifdef __BORLANDC__ 13741 _RTLENTRYF 13742 #endif 13743 item_compare2(s1, s2) 13744 const void *s1; 13745 const void *s2; 13746 { 13747 int res; 13748 typval_T rettv; 13749 typval_T argv[2]; 13750 int dummy; 13751 13752 /* shortcut after failure in previous call; compare all items equal */ 13753 if (item_compare_func_err) 13754 return 0; 13755 13756 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13757 * in the copy without changing the original list items. */ 13758 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13759 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13760 13761 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13762 res = call_func(item_compare_func, STRLEN(item_compare_func), 13763 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13764 clear_tv(&argv[0]); 13765 clear_tv(&argv[1]); 13766 13767 if (res == FAIL) 13768 res = ITEM_COMPARE_FAIL; 13769 else 13770 /* return value has wrong type */ 13771 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13772 if (item_compare_func_err) 13773 res = ITEM_COMPARE_FAIL; 13774 clear_tv(&rettv); 13775 return res; 13776 } 13777 13778 /* 13779 * "sort({list})" function 13780 */ 13781 static void 13782 f_sort(argvars, rettv) 13783 typval_T *argvars; 13784 typval_T *rettv; 13785 { 13786 list_T *l; 13787 listitem_T *li; 13788 listitem_T **ptrs; 13789 long len; 13790 long i; 13791 13792 rettv->vval.v_number = 0; 13793 if (argvars[0].v_type != VAR_LIST) 13794 EMSG2(_(e_listarg), "sort()"); 13795 else 13796 { 13797 l = argvars[0].vval.v_list; 13798 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13799 return; 13800 rettv->vval.v_list = l; 13801 rettv->v_type = VAR_LIST; 13802 ++l->lv_refcount; 13803 13804 len = list_len(l); 13805 if (len <= 1) 13806 return; /* short list sorts pretty quickly */ 13807 13808 item_compare_ic = FALSE; 13809 item_compare_func = NULL; 13810 if (argvars[1].v_type != VAR_UNKNOWN) 13811 { 13812 if (argvars[1].v_type == VAR_FUNC) 13813 item_compare_func = argvars[1].vval.v_string; 13814 else 13815 { 13816 int error = FALSE; 13817 13818 i = get_tv_number_chk(&argvars[1], &error); 13819 if (error) 13820 return; /* type error; errmsg already given */ 13821 if (i == 1) 13822 item_compare_ic = TRUE; 13823 else 13824 item_compare_func = get_tv_string(&argvars[1]); 13825 } 13826 } 13827 13828 /* Make an array with each entry pointing to an item in the List. */ 13829 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13830 if (ptrs == NULL) 13831 return; 13832 i = 0; 13833 for (li = l->lv_first; li != NULL; li = li->li_next) 13834 ptrs[i++] = li; 13835 13836 item_compare_func_err = FALSE; 13837 /* test the compare function */ 13838 if (item_compare_func != NULL 13839 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13840 == ITEM_COMPARE_FAIL) 13841 EMSG(_("E702: Sort compare function failed")); 13842 else 13843 { 13844 /* Sort the array with item pointers. */ 13845 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13846 item_compare_func == NULL ? item_compare : item_compare2); 13847 13848 if (!item_compare_func_err) 13849 { 13850 /* Clear the List and append the items in the sorted order. */ 13851 l->lv_first = l->lv_last = NULL; 13852 l->lv_len = 0; 13853 for (i = 0; i < len; ++i) 13854 list_append(l, ptrs[i]); 13855 } 13856 } 13857 13858 vim_free(ptrs); 13859 } 13860 } 13861 13862 /* 13863 * "soundfold({word})" function 13864 */ 13865 static void 13866 f_soundfold(argvars, rettv) 13867 typval_T *argvars; 13868 typval_T *rettv; 13869 { 13870 char_u *s; 13871 13872 rettv->v_type = VAR_STRING; 13873 s = get_tv_string(&argvars[0]); 13874 #ifdef FEAT_SYN_HL 13875 rettv->vval.v_string = eval_soundfold(s); 13876 #else 13877 rettv->vval.v_string = vim_strsave(s); 13878 #endif 13879 } 13880 13881 /* 13882 * "spellbadword()" function 13883 */ 13884 /* ARGSUSED */ 13885 static void 13886 f_spellbadword(argvars, rettv) 13887 typval_T *argvars; 13888 typval_T *rettv; 13889 { 13890 int len; 13891 13892 rettv->vval.v_string = NULL; 13893 rettv->v_type = VAR_STRING; 13894 13895 #ifdef FEAT_SYN_HL 13896 /* Find the start and length of the badly spelled word. */ 13897 len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); 13898 if (len != 0) 13899 rettv->vval.v_string = vim_strnsave(ml_get_cursor(), len); 13900 #endif 13901 } 13902 13903 /* 13904 * "spellsuggest()" function 13905 */ 13906 static void 13907 f_spellsuggest(argvars, rettv) 13908 typval_T *argvars; 13909 typval_T *rettv; 13910 { 13911 char_u *str; 13912 int maxcount; 13913 garray_T ga; 13914 list_T *l; 13915 listitem_T *li; 13916 int i; 13917 13918 l = list_alloc(); 13919 if (l == NULL) 13920 return; 13921 rettv->v_type = VAR_LIST; 13922 rettv->vval.v_list = l; 13923 ++l->lv_refcount; 13924 13925 #ifdef FEAT_SYN_HL 13926 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13927 { 13928 str = get_tv_string(&argvars[0]); 13929 if (argvars[1].v_type != VAR_UNKNOWN) 13930 { 13931 maxcount = get_tv_number(&argvars[1]); 13932 if (maxcount <= 0) 13933 return; 13934 } 13935 else 13936 maxcount = 25; 13937 13938 spell_suggest_list(&ga, str, maxcount, FALSE); 13939 13940 for (i = 0; i < ga.ga_len; ++i) 13941 { 13942 str = ((char_u **)ga.ga_data)[i]; 13943 13944 li = listitem_alloc(); 13945 if (li == NULL) 13946 vim_free(str); 13947 else 13948 { 13949 li->li_tv.v_type = VAR_STRING; 13950 li->li_tv.v_lock = 0; 13951 li->li_tv.vval.v_string = str; 13952 list_append(l, li); 13953 } 13954 } 13955 ga_clear(&ga); 13956 } 13957 #endif 13958 } 13959 13960 static void 13961 f_split(argvars, rettv) 13962 typval_T *argvars; 13963 typval_T *rettv; 13964 { 13965 char_u *str; 13966 char_u *end; 13967 char_u *pat = NULL; 13968 regmatch_T regmatch; 13969 char_u patbuf[NUMBUFLEN]; 13970 char_u *save_cpo; 13971 int match; 13972 listitem_T *ni; 13973 list_T *l; 13974 colnr_T col = 0; 13975 int keepempty = FALSE; 13976 int typeerr = FALSE; 13977 13978 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13979 save_cpo = p_cpo; 13980 p_cpo = (char_u *)""; 13981 13982 str = get_tv_string(&argvars[0]); 13983 if (argvars[1].v_type != VAR_UNKNOWN) 13984 { 13985 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13986 if (pat == NULL) 13987 typeerr = TRUE; 13988 if (argvars[2].v_type != VAR_UNKNOWN) 13989 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13990 } 13991 if (pat == NULL || *pat == NUL) 13992 pat = (char_u *)"[\\x01- ]\\+"; 13993 13994 l = list_alloc(); 13995 if (l == NULL) 13996 return; 13997 rettv->v_type = VAR_LIST; 13998 rettv->vval.v_list = l; 13999 ++l->lv_refcount; 14000 if (typeerr) 14001 return; 14002 14003 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 14004 if (regmatch.regprog != NULL) 14005 { 14006 regmatch.rm_ic = FALSE; 14007 while (*str != NUL || keepempty) 14008 { 14009 if (*str == NUL) 14010 match = FALSE; /* empty item at the end */ 14011 else 14012 match = vim_regexec_nl(®match, str, col); 14013 if (match) 14014 end = regmatch.startp[0]; 14015 else 14016 end = str + STRLEN(str); 14017 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 14018 && match && end < regmatch.endp[0])) 14019 { 14020 ni = listitem_alloc(); 14021 if (ni == NULL) 14022 break; 14023 ni->li_tv.v_type = VAR_STRING; 14024 ni->li_tv.v_lock = 0; 14025 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 14026 list_append(l, ni); 14027 } 14028 if (!match) 14029 break; 14030 /* Advance to just after the match. */ 14031 if (regmatch.endp[0] > str) 14032 col = 0; 14033 else 14034 { 14035 /* Don't get stuck at the same match. */ 14036 #ifdef FEAT_MBYTE 14037 col = (*mb_ptr2len)(regmatch.endp[0]); 14038 #else 14039 col = 1; 14040 #endif 14041 } 14042 str = regmatch.endp[0]; 14043 } 14044 14045 vim_free(regmatch.regprog); 14046 } 14047 14048 p_cpo = save_cpo; 14049 } 14050 14051 #ifdef HAVE_STRFTIME 14052 /* 14053 * "strftime({format}[, {time}])" function 14054 */ 14055 static void 14056 f_strftime(argvars, rettv) 14057 typval_T *argvars; 14058 typval_T *rettv; 14059 { 14060 char_u result_buf[256]; 14061 struct tm *curtime; 14062 time_t seconds; 14063 char_u *p; 14064 14065 rettv->v_type = VAR_STRING; 14066 14067 p = get_tv_string(&argvars[0]); 14068 if (argvars[1].v_type == VAR_UNKNOWN) 14069 seconds = time(NULL); 14070 else 14071 seconds = (time_t)get_tv_number(&argvars[1]); 14072 curtime = localtime(&seconds); 14073 /* MSVC returns NULL for an invalid value of seconds. */ 14074 if (curtime == NULL) 14075 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 14076 else 14077 { 14078 # ifdef FEAT_MBYTE 14079 vimconv_T conv; 14080 char_u *enc; 14081 14082 conv.vc_type = CONV_NONE; 14083 enc = enc_locale(); 14084 convert_setup(&conv, p_enc, enc); 14085 if (conv.vc_type != CONV_NONE) 14086 p = string_convert(&conv, p, NULL); 14087 # endif 14088 if (p != NULL) 14089 (void)strftime((char *)result_buf, sizeof(result_buf), 14090 (char *)p, curtime); 14091 else 14092 result_buf[0] = NUL; 14093 14094 # ifdef FEAT_MBYTE 14095 if (conv.vc_type != CONV_NONE) 14096 vim_free(p); 14097 convert_setup(&conv, enc, p_enc); 14098 if (conv.vc_type != CONV_NONE) 14099 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 14100 else 14101 # endif 14102 rettv->vval.v_string = vim_strsave(result_buf); 14103 14104 # ifdef FEAT_MBYTE 14105 /* Release conversion descriptors */ 14106 convert_setup(&conv, NULL, NULL); 14107 vim_free(enc); 14108 # endif 14109 } 14110 } 14111 #endif 14112 14113 /* 14114 * "stridx()" function 14115 */ 14116 static void 14117 f_stridx(argvars, rettv) 14118 typval_T *argvars; 14119 typval_T *rettv; 14120 { 14121 char_u buf[NUMBUFLEN]; 14122 char_u *needle; 14123 char_u *haystack; 14124 char_u *save_haystack; 14125 char_u *pos; 14126 int start_idx; 14127 14128 needle = get_tv_string_chk(&argvars[1]); 14129 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 14130 rettv->vval.v_number = -1; 14131 if (needle == NULL || haystack == NULL) 14132 return; /* type error; errmsg already given */ 14133 14134 if (argvars[2].v_type != VAR_UNKNOWN) 14135 { 14136 int error = FALSE; 14137 14138 start_idx = get_tv_number_chk(&argvars[2], &error); 14139 if (error || start_idx >= (int)STRLEN(haystack)) 14140 return; 14141 if (start_idx >= 0) 14142 haystack += start_idx; 14143 } 14144 14145 pos = (char_u *)strstr((char *)haystack, (char *)needle); 14146 if (pos != NULL) 14147 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 14148 } 14149 14150 /* 14151 * "string()" function 14152 */ 14153 static void 14154 f_string(argvars, rettv) 14155 typval_T *argvars; 14156 typval_T *rettv; 14157 { 14158 char_u *tofree; 14159 char_u numbuf[NUMBUFLEN]; 14160 14161 rettv->v_type = VAR_STRING; 14162 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 14163 if (tofree == NULL) 14164 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 14165 } 14166 14167 /* 14168 * "strlen()" function 14169 */ 14170 static void 14171 f_strlen(argvars, rettv) 14172 typval_T *argvars; 14173 typval_T *rettv; 14174 { 14175 rettv->vval.v_number = (varnumber_T)(STRLEN( 14176 get_tv_string(&argvars[0]))); 14177 } 14178 14179 /* 14180 * "strpart()" function 14181 */ 14182 static void 14183 f_strpart(argvars, rettv) 14184 typval_T *argvars; 14185 typval_T *rettv; 14186 { 14187 char_u *p; 14188 int n; 14189 int len; 14190 int slen; 14191 int error = FALSE; 14192 14193 p = get_tv_string(&argvars[0]); 14194 slen = (int)STRLEN(p); 14195 14196 n = get_tv_number_chk(&argvars[1], &error); 14197 if (error) 14198 len = 0; 14199 else if (argvars[2].v_type != VAR_UNKNOWN) 14200 len = get_tv_number(&argvars[2]); 14201 else 14202 len = slen - n; /* default len: all bytes that are available. */ 14203 14204 /* 14205 * Only return the overlap between the specified part and the actual 14206 * string. 14207 */ 14208 if (n < 0) 14209 { 14210 len += n; 14211 n = 0; 14212 } 14213 else if (n > slen) 14214 n = slen; 14215 if (len < 0) 14216 len = 0; 14217 else if (n + len > slen) 14218 len = slen - n; 14219 14220 rettv->v_type = VAR_STRING; 14221 rettv->vval.v_string = vim_strnsave(p + n, len); 14222 } 14223 14224 /* 14225 * "strridx()" function 14226 */ 14227 static void 14228 f_strridx(argvars, rettv) 14229 typval_T *argvars; 14230 typval_T *rettv; 14231 { 14232 char_u buf[NUMBUFLEN]; 14233 char_u *needle; 14234 char_u *haystack; 14235 char_u *rest; 14236 char_u *lastmatch = NULL; 14237 int haystack_len, end_idx; 14238 14239 needle = get_tv_string_chk(&argvars[1]); 14240 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14241 haystack_len = STRLEN(haystack); 14242 14243 rettv->vval.v_number = -1; 14244 if (needle == NULL || haystack == NULL) 14245 return; /* type error; errmsg already given */ 14246 if (argvars[2].v_type != VAR_UNKNOWN) 14247 { 14248 /* Third argument: upper limit for index */ 14249 end_idx = get_tv_number_chk(&argvars[2], NULL); 14250 if (end_idx < 0) 14251 return; /* can never find a match */ 14252 } 14253 else 14254 end_idx = haystack_len; 14255 14256 if (*needle == NUL) 14257 { 14258 /* Empty string matches past the end. */ 14259 lastmatch = haystack + end_idx; 14260 } 14261 else 14262 { 14263 for (rest = haystack; *rest != '\0'; ++rest) 14264 { 14265 rest = (char_u *)strstr((char *)rest, (char *)needle); 14266 if (rest == NULL || rest > haystack + end_idx) 14267 break; 14268 lastmatch = rest; 14269 } 14270 } 14271 14272 if (lastmatch == NULL) 14273 rettv->vval.v_number = -1; 14274 else 14275 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14276 } 14277 14278 /* 14279 * "strtrans()" function 14280 */ 14281 static void 14282 f_strtrans(argvars, rettv) 14283 typval_T *argvars; 14284 typval_T *rettv; 14285 { 14286 rettv->v_type = VAR_STRING; 14287 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14288 } 14289 14290 /* 14291 * "submatch()" function 14292 */ 14293 static void 14294 f_submatch(argvars, rettv) 14295 typval_T *argvars; 14296 typval_T *rettv; 14297 { 14298 rettv->v_type = VAR_STRING; 14299 rettv->vval.v_string = 14300 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14301 } 14302 14303 /* 14304 * "substitute()" function 14305 */ 14306 static void 14307 f_substitute(argvars, rettv) 14308 typval_T *argvars; 14309 typval_T *rettv; 14310 { 14311 char_u patbuf[NUMBUFLEN]; 14312 char_u subbuf[NUMBUFLEN]; 14313 char_u flagsbuf[NUMBUFLEN]; 14314 14315 char_u *str = get_tv_string_chk(&argvars[0]); 14316 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14317 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14318 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14319 14320 rettv->v_type = VAR_STRING; 14321 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14322 rettv->vval.v_string = NULL; 14323 else 14324 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14325 } 14326 14327 /* 14328 * "synID(lnum, col, trans)" function 14329 */ 14330 /*ARGSUSED*/ 14331 static void 14332 f_synID(argvars, rettv) 14333 typval_T *argvars; 14334 typval_T *rettv; 14335 { 14336 int id = 0; 14337 #ifdef FEAT_SYN_HL 14338 long lnum; 14339 long col; 14340 int trans; 14341 int transerr = FALSE; 14342 14343 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14344 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14345 trans = get_tv_number_chk(&argvars[2], &transerr); 14346 14347 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14348 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14349 id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL); 14350 #endif 14351 14352 rettv->vval.v_number = id; 14353 } 14354 14355 /* 14356 * "synIDattr(id, what [, mode])" function 14357 */ 14358 /*ARGSUSED*/ 14359 static void 14360 f_synIDattr(argvars, rettv) 14361 typval_T *argvars; 14362 typval_T *rettv; 14363 { 14364 char_u *p = NULL; 14365 #ifdef FEAT_SYN_HL 14366 int id; 14367 char_u *what; 14368 char_u *mode; 14369 char_u modebuf[NUMBUFLEN]; 14370 int modec; 14371 14372 id = get_tv_number(&argvars[0]); 14373 what = get_tv_string(&argvars[1]); 14374 if (argvars[2].v_type != VAR_UNKNOWN) 14375 { 14376 mode = get_tv_string_buf(&argvars[2], modebuf); 14377 modec = TOLOWER_ASC(mode[0]); 14378 if (modec != 't' && modec != 'c' 14379 #ifdef FEAT_GUI 14380 && modec != 'g' 14381 #endif 14382 ) 14383 modec = 0; /* replace invalid with current */ 14384 } 14385 else 14386 { 14387 #ifdef FEAT_GUI 14388 if (gui.in_use) 14389 modec = 'g'; 14390 else 14391 #endif 14392 if (t_colors > 1) 14393 modec = 'c'; 14394 else 14395 modec = 't'; 14396 } 14397 14398 14399 switch (TOLOWER_ASC(what[0])) 14400 { 14401 case 'b': 14402 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14403 p = highlight_color(id, what, modec); 14404 else /* bold */ 14405 p = highlight_has_attr(id, HL_BOLD, modec); 14406 break; 14407 14408 case 'f': /* fg[#] */ 14409 p = highlight_color(id, what, modec); 14410 break; 14411 14412 case 'i': 14413 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14414 p = highlight_has_attr(id, HL_INVERSE, modec); 14415 else /* italic */ 14416 p = highlight_has_attr(id, HL_ITALIC, modec); 14417 break; 14418 14419 case 'n': /* name */ 14420 p = get_highlight_name(NULL, id - 1); 14421 break; 14422 14423 case 'r': /* reverse */ 14424 p = highlight_has_attr(id, HL_INVERSE, modec); 14425 break; 14426 14427 case 's': /* standout */ 14428 p = highlight_has_attr(id, HL_STANDOUT, modec); 14429 break; 14430 14431 case 'u': 14432 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14433 /* underline */ 14434 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14435 else 14436 /* undercurl */ 14437 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14438 break; 14439 } 14440 14441 if (p != NULL) 14442 p = vim_strsave(p); 14443 #endif 14444 rettv->v_type = VAR_STRING; 14445 rettv->vval.v_string = p; 14446 } 14447 14448 /* 14449 * "synIDtrans(id)" function 14450 */ 14451 /*ARGSUSED*/ 14452 static void 14453 f_synIDtrans(argvars, rettv) 14454 typval_T *argvars; 14455 typval_T *rettv; 14456 { 14457 int id; 14458 14459 #ifdef FEAT_SYN_HL 14460 id = get_tv_number(&argvars[0]); 14461 14462 if (id > 0) 14463 id = syn_get_final_id(id); 14464 else 14465 #endif 14466 id = 0; 14467 14468 rettv->vval.v_number = id; 14469 } 14470 14471 /* 14472 * "system()" function 14473 */ 14474 static void 14475 f_system(argvars, rettv) 14476 typval_T *argvars; 14477 typval_T *rettv; 14478 { 14479 char_u *res = NULL; 14480 char_u *p; 14481 char_u *infile = NULL; 14482 char_u buf[NUMBUFLEN]; 14483 int err = FALSE; 14484 FILE *fd; 14485 14486 if (argvars[1].v_type != VAR_UNKNOWN) 14487 { 14488 /* 14489 * Write the string to a temp file, to be used for input of the shell 14490 * command. 14491 */ 14492 if ((infile = vim_tempname('i')) == NULL) 14493 { 14494 EMSG(_(e_notmp)); 14495 return; 14496 } 14497 14498 fd = mch_fopen((char *)infile, WRITEBIN); 14499 if (fd == NULL) 14500 { 14501 EMSG2(_(e_notopen), infile); 14502 goto done; 14503 } 14504 p = get_tv_string_buf_chk(&argvars[1], buf); 14505 if (p == NULL) 14506 goto done; /* type error; errmsg already given */ 14507 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14508 err = TRUE; 14509 if (fclose(fd) != 0) 14510 err = TRUE; 14511 if (err) 14512 { 14513 EMSG(_("E677: Error writing temp file")); 14514 goto done; 14515 } 14516 } 14517 14518 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14519 14520 #ifdef USE_CR 14521 /* translate <CR> into <NL> */ 14522 if (res != NULL) 14523 { 14524 char_u *s; 14525 14526 for (s = res; *s; ++s) 14527 { 14528 if (*s == CAR) 14529 *s = NL; 14530 } 14531 } 14532 #else 14533 # ifdef USE_CRNL 14534 /* translate <CR><NL> into <NL> */ 14535 if (res != NULL) 14536 { 14537 char_u *s, *d; 14538 14539 d = res; 14540 for (s = res; *s; ++s) 14541 { 14542 if (s[0] == CAR && s[1] == NL) 14543 ++s; 14544 *d++ = *s; 14545 } 14546 *d = NUL; 14547 } 14548 # endif 14549 #endif 14550 14551 done: 14552 if (infile != NULL) 14553 { 14554 mch_remove(infile); 14555 vim_free(infile); 14556 } 14557 rettv->v_type = VAR_STRING; 14558 rettv->vval.v_string = res; 14559 } 14560 14561 /* 14562 * "tagfiles()" function 14563 */ 14564 /*ARGSUSED*/ 14565 static void 14566 f_tagfiles(argvars, rettv) 14567 typval_T *argvars; 14568 typval_T *rettv; 14569 { 14570 char_u fname[MAXPATHL + 1]; 14571 list_T *l; 14572 14573 l = list_alloc(); 14574 if (l == NULL) 14575 { 14576 rettv->vval.v_number = 0; 14577 return; 14578 } 14579 rettv->vval.v_list = l; 14580 rettv->v_type = VAR_LIST; 14581 ++l->lv_refcount; 14582 14583 get_tagfname(TRUE, NULL); 14584 for (;;) 14585 if (get_tagfname(FALSE, fname) == FAIL 14586 || list_append_string(l, fname) == FAIL) 14587 break; 14588 } 14589 14590 /* 14591 * "taglist()" function 14592 */ 14593 static void 14594 f_taglist(argvars, rettv) 14595 typval_T *argvars; 14596 typval_T *rettv; 14597 { 14598 char_u *tag_pattern; 14599 list_T *l; 14600 14601 tag_pattern = get_tv_string(&argvars[0]); 14602 14603 rettv->vval.v_number = FALSE; 14604 if (*tag_pattern == NUL) 14605 return; 14606 14607 l = list_alloc(); 14608 if (l != NULL) 14609 { 14610 if (get_tags(l, tag_pattern) != FAIL) 14611 { 14612 rettv->vval.v_list = l; 14613 rettv->v_type = VAR_LIST; 14614 ++l->lv_refcount; 14615 } 14616 else 14617 list_free(l); 14618 } 14619 } 14620 14621 /* 14622 * "tempname()" function 14623 */ 14624 /*ARGSUSED*/ 14625 static void 14626 f_tempname(argvars, rettv) 14627 typval_T *argvars; 14628 typval_T *rettv; 14629 { 14630 static int x = 'A'; 14631 14632 rettv->v_type = VAR_STRING; 14633 rettv->vval.v_string = vim_tempname(x); 14634 14635 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14636 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14637 do 14638 { 14639 if (x == 'Z') 14640 x = '0'; 14641 else if (x == '9') 14642 x = 'A'; 14643 else 14644 { 14645 #ifdef EBCDIC 14646 if (x == 'I') 14647 x = 'J'; 14648 else if (x == 'R') 14649 x = 'S'; 14650 else 14651 #endif 14652 ++x; 14653 } 14654 } while (x == 'I' || x == 'O'); 14655 } 14656 14657 /* 14658 * "test(list)" function: Just checking the walls... 14659 */ 14660 /*ARGSUSED*/ 14661 static void 14662 f_test(argvars, rettv) 14663 typval_T *argvars; 14664 typval_T *rettv; 14665 { 14666 /* Used for unit testing. Change the code below to your liking. */ 14667 #if 0 14668 listitem_T *li; 14669 list_T *l; 14670 char_u *bad, *good; 14671 14672 if (argvars[0].v_type != VAR_LIST) 14673 return; 14674 l = argvars[0].vval.v_list; 14675 if (l == NULL) 14676 return; 14677 li = l->lv_first; 14678 if (li == NULL) 14679 return; 14680 bad = get_tv_string(&li->li_tv); 14681 li = li->li_next; 14682 if (li == NULL) 14683 return; 14684 good = get_tv_string(&li->li_tv); 14685 rettv->vval.v_number = test_edit_score(bad, good); 14686 #endif 14687 } 14688 14689 /* 14690 * "tolower(string)" function 14691 */ 14692 static void 14693 f_tolower(argvars, rettv) 14694 typval_T *argvars; 14695 typval_T *rettv; 14696 { 14697 char_u *p; 14698 14699 p = vim_strsave(get_tv_string(&argvars[0])); 14700 rettv->v_type = VAR_STRING; 14701 rettv->vval.v_string = p; 14702 14703 if (p != NULL) 14704 while (*p != NUL) 14705 { 14706 #ifdef FEAT_MBYTE 14707 int l; 14708 14709 if (enc_utf8) 14710 { 14711 int c, lc; 14712 14713 c = utf_ptr2char(p); 14714 lc = utf_tolower(c); 14715 l = utf_ptr2len(p); 14716 /* TODO: reallocate string when byte count changes. */ 14717 if (utf_char2len(lc) == l) 14718 utf_char2bytes(lc, p); 14719 p += l; 14720 } 14721 else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) 14722 p += l; /* skip multi-byte character */ 14723 else 14724 #endif 14725 { 14726 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14727 ++p; 14728 } 14729 } 14730 } 14731 14732 /* 14733 * "toupper(string)" function 14734 */ 14735 static void 14736 f_toupper(argvars, rettv) 14737 typval_T *argvars; 14738 typval_T *rettv; 14739 { 14740 rettv->v_type = VAR_STRING; 14741 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14742 } 14743 14744 /* 14745 * "tr(string, fromstr, tostr)" function 14746 */ 14747 static void 14748 f_tr(argvars, rettv) 14749 typval_T *argvars; 14750 typval_T *rettv; 14751 { 14752 char_u *instr; 14753 char_u *fromstr; 14754 char_u *tostr; 14755 char_u *p; 14756 #ifdef FEAT_MBYTE 14757 int inlen; 14758 int fromlen; 14759 int tolen; 14760 int idx; 14761 char_u *cpstr; 14762 int cplen; 14763 int first = TRUE; 14764 #endif 14765 char_u buf[NUMBUFLEN]; 14766 char_u buf2[NUMBUFLEN]; 14767 garray_T ga; 14768 14769 instr = get_tv_string(&argvars[0]); 14770 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14771 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14772 14773 /* Default return value: empty string. */ 14774 rettv->v_type = VAR_STRING; 14775 rettv->vval.v_string = NULL; 14776 if (fromstr == NULL || tostr == NULL) 14777 return; /* type error; errmsg already given */ 14778 ga_init2(&ga, (int)sizeof(char), 80); 14779 14780 #ifdef FEAT_MBYTE 14781 if (!has_mbyte) 14782 #endif 14783 /* not multi-byte: fromstr and tostr must be the same length */ 14784 if (STRLEN(fromstr) != STRLEN(tostr)) 14785 { 14786 #ifdef FEAT_MBYTE 14787 error: 14788 #endif 14789 EMSG2(_(e_invarg2), fromstr); 14790 ga_clear(&ga); 14791 return; 14792 } 14793 14794 /* fromstr and tostr have to contain the same number of chars */ 14795 while (*instr != NUL) 14796 { 14797 #ifdef FEAT_MBYTE 14798 if (has_mbyte) 14799 { 14800 inlen = (*mb_ptr2len)(instr); 14801 cpstr = instr; 14802 cplen = inlen; 14803 idx = 0; 14804 for (p = fromstr; *p != NUL; p += fromlen) 14805 { 14806 fromlen = (*mb_ptr2len)(p); 14807 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14808 { 14809 for (p = tostr; *p != NUL; p += tolen) 14810 { 14811 tolen = (*mb_ptr2len)(p); 14812 if (idx-- == 0) 14813 { 14814 cplen = tolen; 14815 cpstr = p; 14816 break; 14817 } 14818 } 14819 if (*p == NUL) /* tostr is shorter than fromstr */ 14820 goto error; 14821 break; 14822 } 14823 ++idx; 14824 } 14825 14826 if (first && cpstr == instr) 14827 { 14828 /* Check that fromstr and tostr have the same number of 14829 * (multi-byte) characters. Done only once when a character 14830 * of instr doesn't appear in fromstr. */ 14831 first = FALSE; 14832 for (p = tostr; *p != NUL; p += tolen) 14833 { 14834 tolen = (*mb_ptr2len)(p); 14835 --idx; 14836 } 14837 if (idx != 0) 14838 goto error; 14839 } 14840 14841 ga_grow(&ga, cplen); 14842 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14843 ga.ga_len += cplen; 14844 14845 instr += inlen; 14846 } 14847 else 14848 #endif 14849 { 14850 /* When not using multi-byte chars we can do it faster. */ 14851 p = vim_strchr(fromstr, *instr); 14852 if (p != NULL) 14853 ga_append(&ga, tostr[p - fromstr]); 14854 else 14855 ga_append(&ga, *instr); 14856 ++instr; 14857 } 14858 } 14859 14860 rettv->vval.v_string = ga.ga_data; 14861 } 14862 14863 /* 14864 * "type(expr)" function 14865 */ 14866 static void 14867 f_type(argvars, rettv) 14868 typval_T *argvars; 14869 typval_T *rettv; 14870 { 14871 int n; 14872 14873 switch (argvars[0].v_type) 14874 { 14875 case VAR_NUMBER: n = 0; break; 14876 case VAR_STRING: n = 1; break; 14877 case VAR_FUNC: n = 2; break; 14878 case VAR_LIST: n = 3; break; 14879 case VAR_DICT: n = 4; break; 14880 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14881 } 14882 rettv->vval.v_number = n; 14883 } 14884 14885 /* 14886 * "values(dict)" function 14887 */ 14888 static void 14889 f_values(argvars, rettv) 14890 typval_T *argvars; 14891 typval_T *rettv; 14892 { 14893 dict_list(argvars, rettv, 1); 14894 } 14895 14896 /* 14897 * "virtcol(string)" function 14898 */ 14899 static void 14900 f_virtcol(argvars, rettv) 14901 typval_T *argvars; 14902 typval_T *rettv; 14903 { 14904 colnr_T vcol = 0; 14905 pos_T *fp; 14906 14907 fp = var2fpos(&argvars[0], FALSE); 14908 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14909 { 14910 getvvcol(curwin, fp, NULL, NULL, &vcol); 14911 ++vcol; 14912 } 14913 14914 rettv->vval.v_number = vcol; 14915 } 14916 14917 /* 14918 * "visualmode()" function 14919 */ 14920 /*ARGSUSED*/ 14921 static void 14922 f_visualmode(argvars, rettv) 14923 typval_T *argvars; 14924 typval_T *rettv; 14925 { 14926 #ifdef FEAT_VISUAL 14927 char_u str[2]; 14928 14929 rettv->v_type = VAR_STRING; 14930 str[0] = curbuf->b_visual_mode_eval; 14931 str[1] = NUL; 14932 rettv->vval.v_string = vim_strsave(str); 14933 14934 /* A non-zero number or non-empty string argument: reset mode. */ 14935 if ((argvars[0].v_type == VAR_NUMBER 14936 && argvars[0].vval.v_number != 0) 14937 || (argvars[0].v_type == VAR_STRING 14938 && *get_tv_string(&argvars[0]) != NUL)) 14939 curbuf->b_visual_mode_eval = NUL; 14940 #else 14941 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14942 #endif 14943 } 14944 14945 /* 14946 * "winbufnr(nr)" function 14947 */ 14948 static void 14949 f_winbufnr(argvars, rettv) 14950 typval_T *argvars; 14951 typval_T *rettv; 14952 { 14953 win_T *wp; 14954 14955 wp = find_win_by_nr(&argvars[0]); 14956 if (wp == NULL) 14957 rettv->vval.v_number = -1; 14958 else 14959 rettv->vval.v_number = wp->w_buffer->b_fnum; 14960 } 14961 14962 /* 14963 * "wincol()" function 14964 */ 14965 /*ARGSUSED*/ 14966 static void 14967 f_wincol(argvars, rettv) 14968 typval_T *argvars; 14969 typval_T *rettv; 14970 { 14971 validate_cursor(); 14972 rettv->vval.v_number = curwin->w_wcol + 1; 14973 } 14974 14975 /* 14976 * "winheight(nr)" function 14977 */ 14978 static void 14979 f_winheight(argvars, rettv) 14980 typval_T *argvars; 14981 typval_T *rettv; 14982 { 14983 win_T *wp; 14984 14985 wp = find_win_by_nr(&argvars[0]); 14986 if (wp == NULL) 14987 rettv->vval.v_number = -1; 14988 else 14989 rettv->vval.v_number = wp->w_height; 14990 } 14991 14992 /* 14993 * "winline()" function 14994 */ 14995 /*ARGSUSED*/ 14996 static void 14997 f_winline(argvars, rettv) 14998 typval_T *argvars; 14999 typval_T *rettv; 15000 { 15001 validate_cursor(); 15002 rettv->vval.v_number = curwin->w_wrow + 1; 15003 } 15004 15005 /* 15006 * "winnr()" function 15007 */ 15008 /* ARGSUSED */ 15009 static void 15010 f_winnr(argvars, rettv) 15011 typval_T *argvars; 15012 typval_T *rettv; 15013 { 15014 int nr = 1; 15015 #ifdef FEAT_WINDOWS 15016 win_T *wp; 15017 win_T *twin = curwin; 15018 char_u *arg; 15019 15020 if (argvars[0].v_type != VAR_UNKNOWN) 15021 { 15022 arg = get_tv_string_chk(&argvars[0]); 15023 if (arg == NULL) 15024 nr = 0; /* type error; errmsg already given */ 15025 else if (STRCMP(arg, "$") == 0) 15026 twin = lastwin; 15027 else if (STRCMP(arg, "#") == 0) 15028 { 15029 twin = prevwin; 15030 if (prevwin == NULL) 15031 nr = 0; 15032 } 15033 else 15034 { 15035 EMSG2(_(e_invexpr2), arg); 15036 nr = 0; 15037 } 15038 } 15039 15040 if (nr > 0) 15041 for (wp = firstwin; wp != twin; wp = wp->w_next) 15042 ++nr; 15043 #endif 15044 rettv->vval.v_number = nr; 15045 } 15046 15047 /* 15048 * "winrestcmd()" function 15049 */ 15050 /* ARGSUSED */ 15051 static void 15052 f_winrestcmd(argvars, rettv) 15053 typval_T *argvars; 15054 typval_T *rettv; 15055 { 15056 #ifdef FEAT_WINDOWS 15057 win_T *wp; 15058 int winnr = 1; 15059 garray_T ga; 15060 char_u buf[50]; 15061 15062 ga_init2(&ga, (int)sizeof(char), 70); 15063 for (wp = firstwin; wp != NULL; wp = wp->w_next) 15064 { 15065 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 15066 ga_concat(&ga, buf); 15067 # ifdef FEAT_VERTSPLIT 15068 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 15069 ga_concat(&ga, buf); 15070 # endif 15071 ++winnr; 15072 } 15073 ga_append(&ga, NUL); 15074 15075 rettv->vval.v_string = ga.ga_data; 15076 #else 15077 rettv->vval.v_string = NULL; 15078 #endif 15079 rettv->v_type = VAR_STRING; 15080 } 15081 15082 /* 15083 * "winwidth(nr)" function 15084 */ 15085 static void 15086 f_winwidth(argvars, rettv) 15087 typval_T *argvars; 15088 typval_T *rettv; 15089 { 15090 win_T *wp; 15091 15092 wp = find_win_by_nr(&argvars[0]); 15093 if (wp == NULL) 15094 rettv->vval.v_number = -1; 15095 else 15096 #ifdef FEAT_VERTSPLIT 15097 rettv->vval.v_number = wp->w_width; 15098 #else 15099 rettv->vval.v_number = Columns; 15100 #endif 15101 } 15102 15103 /* 15104 * "writefile()" function 15105 */ 15106 static void 15107 f_writefile(argvars, rettv) 15108 typval_T *argvars; 15109 typval_T *rettv; 15110 { 15111 int binary = FALSE; 15112 char_u *fname; 15113 FILE *fd; 15114 listitem_T *li; 15115 char_u *s; 15116 int ret = 0; 15117 int c; 15118 15119 if (argvars[0].v_type != VAR_LIST) 15120 { 15121 EMSG2(_(e_listarg), "writefile()"); 15122 return; 15123 } 15124 if (argvars[0].vval.v_list == NULL) 15125 return; 15126 15127 if (argvars[2].v_type != VAR_UNKNOWN 15128 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 15129 binary = TRUE; 15130 15131 /* Always open the file in binary mode, library functions have a mind of 15132 * their own about CR-LF conversion. */ 15133 fname = get_tv_string(&argvars[1]); 15134 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 15135 { 15136 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 15137 ret = -1; 15138 } 15139 else 15140 { 15141 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 15142 li = li->li_next) 15143 { 15144 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 15145 { 15146 if (*s == '\n') 15147 c = putc(NUL, fd); 15148 else 15149 c = putc(*s, fd); 15150 if (c == EOF) 15151 { 15152 ret = -1; 15153 break; 15154 } 15155 } 15156 if (!binary || li->li_next != NULL) 15157 if (putc('\n', fd) == EOF) 15158 { 15159 ret = -1; 15160 break; 15161 } 15162 if (ret < 0) 15163 { 15164 EMSG(_(e_write)); 15165 break; 15166 } 15167 } 15168 fclose(fd); 15169 } 15170 15171 rettv->vval.v_number = ret; 15172 } 15173 15174 /* 15175 * Translate a String variable into a position. 15176 */ 15177 static pos_T * 15178 var2fpos(varp, lnum) 15179 typval_T *varp; 15180 int lnum; /* TRUE when $ is last line */ 15181 { 15182 char_u *name; 15183 static pos_T pos; 15184 pos_T *pp; 15185 15186 name = get_tv_string_chk(varp); 15187 if (name == NULL) 15188 return NULL; 15189 if (name[0] == '.') /* cursor */ 15190 return &curwin->w_cursor; 15191 if (name[0] == '\'') /* mark */ 15192 { 15193 pp = getmark(name[1], FALSE); 15194 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 15195 return NULL; 15196 return pp; 15197 } 15198 if (name[0] == '$') /* last column or line */ 15199 { 15200 if (lnum) 15201 { 15202 pos.lnum = curbuf->b_ml.ml_line_count; 15203 pos.col = 0; 15204 } 15205 else 15206 { 15207 pos.lnum = curwin->w_cursor.lnum; 15208 pos.col = (colnr_T)STRLEN(ml_get_curline()); 15209 } 15210 return &pos; 15211 } 15212 return NULL; 15213 } 15214 15215 /* 15216 * Get the length of an environment variable name. 15217 * Advance "arg" to the first character after the name. 15218 * Return 0 for error. 15219 */ 15220 static int 15221 get_env_len(arg) 15222 char_u **arg; 15223 { 15224 char_u *p; 15225 int len; 15226 15227 for (p = *arg; vim_isIDc(*p); ++p) 15228 ; 15229 if (p == *arg) /* no name found */ 15230 return 0; 15231 15232 len = (int)(p - *arg); 15233 *arg = p; 15234 return len; 15235 } 15236 15237 /* 15238 * Get the length of the name of a function or internal variable. 15239 * "arg" is advanced to the first non-white character after the name. 15240 * Return 0 if something is wrong. 15241 */ 15242 static int 15243 get_id_len(arg) 15244 char_u **arg; 15245 { 15246 char_u *p; 15247 int len; 15248 15249 /* Find the end of the name. */ 15250 for (p = *arg; eval_isnamec(*p); ++p) 15251 ; 15252 if (p == *arg) /* no name found */ 15253 return 0; 15254 15255 len = (int)(p - *arg); 15256 *arg = skipwhite(p); 15257 15258 return len; 15259 } 15260 15261 /* 15262 * Get the length of the name of a variable or function. 15263 * Only the name is recognized, does not handle ".key" or "[idx]". 15264 * "arg" is advanced to the first non-white character after the name. 15265 * Return -1 if curly braces expansion failed. 15266 * Return 0 if something else is wrong. 15267 * If the name contains 'magic' {}'s, expand them and return the 15268 * expanded name in an allocated string via 'alias' - caller must free. 15269 */ 15270 static int 15271 get_name_len(arg, alias, evaluate, verbose) 15272 char_u **arg; 15273 char_u **alias; 15274 int evaluate; 15275 int verbose; 15276 { 15277 int len; 15278 char_u *p; 15279 char_u *expr_start; 15280 char_u *expr_end; 15281 15282 *alias = NULL; /* default to no alias */ 15283 15284 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15285 && (*arg)[2] == (int)KE_SNR) 15286 { 15287 /* hard coded <SNR>, already translated */ 15288 *arg += 3; 15289 return get_id_len(arg) + 3; 15290 } 15291 len = eval_fname_script(*arg); 15292 if (len > 0) 15293 { 15294 /* literal "<SID>", "s:" or "<SNR>" */ 15295 *arg += len; 15296 } 15297 15298 /* 15299 * Find the end of the name; check for {} construction. 15300 */ 15301 p = find_name_end(*arg, &expr_start, &expr_end, 15302 len > 0 ? 0 : FNE_CHECK_START); 15303 if (expr_start != NULL) 15304 { 15305 char_u *temp_string; 15306 15307 if (!evaluate) 15308 { 15309 len += (int)(p - *arg); 15310 *arg = skipwhite(p); 15311 return len; 15312 } 15313 15314 /* 15315 * Include any <SID> etc in the expanded string: 15316 * Thus the -len here. 15317 */ 15318 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15319 if (temp_string == NULL) 15320 return -1; 15321 *alias = temp_string; 15322 *arg = skipwhite(p); 15323 return (int)STRLEN(temp_string); 15324 } 15325 15326 len += get_id_len(arg); 15327 if (len == 0 && verbose) 15328 EMSG2(_(e_invexpr2), *arg); 15329 15330 return len; 15331 } 15332 15333 /* 15334 * Find the end of a variable or function name, taking care of magic braces. 15335 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15336 * start and end of the first magic braces item. 15337 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15338 * Return a pointer to just after the name. Equal to "arg" if there is no 15339 * valid name. 15340 */ 15341 static char_u * 15342 find_name_end(arg, expr_start, expr_end, flags) 15343 char_u *arg; 15344 char_u **expr_start; 15345 char_u **expr_end; 15346 int flags; 15347 { 15348 int mb_nest = 0; 15349 int br_nest = 0; 15350 char_u *p; 15351 15352 if (expr_start != NULL) 15353 { 15354 *expr_start = NULL; 15355 *expr_end = NULL; 15356 } 15357 15358 /* Quick check for valid starting character. */ 15359 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15360 return arg; 15361 15362 for (p = arg; *p != NUL 15363 && (eval_isnamec(*p) 15364 || *p == '{' 15365 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15366 || mb_nest != 0 15367 || br_nest != 0); mb_ptr_adv(p)) 15368 { 15369 if (*p == '\'') 15370 { 15371 /* skip over 'string' to avoid counting [ and ] inside it. */ 15372 for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p)) 15373 ; 15374 if (*p == NUL) 15375 break; 15376 } 15377 else if (*p == '"') 15378 { 15379 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ 15380 for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 15381 if (*p == '\\' && p[1] != NUL) 15382 ++p; 15383 if (*p == NUL) 15384 break; 15385 } 15386 15387 if (mb_nest == 0) 15388 { 15389 if (*p == '[') 15390 ++br_nest; 15391 else if (*p == ']') 15392 --br_nest; 15393 } 15394 15395 if (br_nest == 0) 15396 { 15397 if (*p == '{') 15398 { 15399 mb_nest++; 15400 if (expr_start != NULL && *expr_start == NULL) 15401 *expr_start = p; 15402 } 15403 else if (*p == '}') 15404 { 15405 mb_nest--; 15406 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15407 *expr_end = p; 15408 } 15409 } 15410 } 15411 15412 return p; 15413 } 15414 15415 /* 15416 * Expands out the 'magic' {}'s in a variable/function name. 15417 * Note that this can call itself recursively, to deal with 15418 * constructs like foo{bar}{baz}{bam} 15419 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15420 * "in_start" ^ 15421 * "expr_start" ^ 15422 * "expr_end" ^ 15423 * "in_end" ^ 15424 * 15425 * Returns a new allocated string, which the caller must free. 15426 * Returns NULL for failure. 15427 */ 15428 static char_u * 15429 make_expanded_name(in_start, expr_start, expr_end, in_end) 15430 char_u *in_start; 15431 char_u *expr_start; 15432 char_u *expr_end; 15433 char_u *in_end; 15434 { 15435 char_u c1; 15436 char_u *retval = NULL; 15437 char_u *temp_result; 15438 char_u *nextcmd = NULL; 15439 15440 if (expr_end == NULL || in_end == NULL) 15441 return NULL; 15442 *expr_start = NUL; 15443 *expr_end = NUL; 15444 c1 = *in_end; 15445 *in_end = NUL; 15446 15447 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15448 if (temp_result != NULL && nextcmd == NULL) 15449 { 15450 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15451 + (in_end - expr_end) + 1)); 15452 if (retval != NULL) 15453 { 15454 STRCPY(retval, in_start); 15455 STRCAT(retval, temp_result); 15456 STRCAT(retval, expr_end + 1); 15457 } 15458 } 15459 vim_free(temp_result); 15460 15461 *in_end = c1; /* put char back for error messages */ 15462 *expr_start = '{'; 15463 *expr_end = '}'; 15464 15465 if (retval != NULL) 15466 { 15467 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15468 if (expr_start != NULL) 15469 { 15470 /* Further expansion! */ 15471 temp_result = make_expanded_name(retval, expr_start, 15472 expr_end, temp_result); 15473 vim_free(retval); 15474 retval = temp_result; 15475 } 15476 } 15477 15478 return retval; 15479 } 15480 15481 /* 15482 * Return TRUE if character "c" can be used in a variable or function name. 15483 * Does not include '{' or '}' for magic braces. 15484 */ 15485 static int 15486 eval_isnamec(c) 15487 int c; 15488 { 15489 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15490 } 15491 15492 /* 15493 * Return TRUE if character "c" can be used as the first character in a 15494 * variable or function name (excluding '{' and '}'). 15495 */ 15496 static int 15497 eval_isnamec1(c) 15498 int c; 15499 { 15500 return (ASCII_ISALPHA(c) || c == '_'); 15501 } 15502 15503 /* 15504 * Set number v: variable to "val". 15505 */ 15506 void 15507 set_vim_var_nr(idx, val) 15508 int idx; 15509 long val; 15510 { 15511 vimvars[idx].vv_nr = val; 15512 } 15513 15514 /* 15515 * Get number v: variable value. 15516 */ 15517 long 15518 get_vim_var_nr(idx) 15519 int idx; 15520 { 15521 return vimvars[idx].vv_nr; 15522 } 15523 15524 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15525 /* 15526 * Get string v: variable value. Uses a static buffer, can only be used once. 15527 */ 15528 char_u * 15529 get_vim_var_str(idx) 15530 int idx; 15531 { 15532 return get_tv_string(&vimvars[idx].vv_tv); 15533 } 15534 #endif 15535 15536 /* 15537 * Set v:count, v:count1 and v:prevcount. 15538 */ 15539 void 15540 set_vcount(count, count1) 15541 long count; 15542 long count1; 15543 { 15544 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15545 vimvars[VV_COUNT].vv_nr = count; 15546 vimvars[VV_COUNT1].vv_nr = count1; 15547 } 15548 15549 /* 15550 * Set string v: variable to a copy of "val". 15551 */ 15552 void 15553 set_vim_var_string(idx, val, len) 15554 int idx; 15555 char_u *val; 15556 int len; /* length of "val" to use or -1 (whole string) */ 15557 { 15558 /* Need to do this (at least) once, since we can't initialize a union. 15559 * Will always be invoked when "v:progname" is set. */ 15560 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15561 15562 vim_free(vimvars[idx].vv_str); 15563 if (val == NULL) 15564 vimvars[idx].vv_str = NULL; 15565 else if (len == -1) 15566 vimvars[idx].vv_str = vim_strsave(val); 15567 else 15568 vimvars[idx].vv_str = vim_strnsave(val, len); 15569 } 15570 15571 /* 15572 * Set v:register if needed. 15573 */ 15574 void 15575 set_reg_var(c) 15576 int c; 15577 { 15578 char_u regname; 15579 15580 if (c == 0 || c == ' ') 15581 regname = '"'; 15582 else 15583 regname = c; 15584 /* Avoid free/alloc when the value is already right. */ 15585 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15586 set_vim_var_string(VV_REG, ®name, 1); 15587 } 15588 15589 /* 15590 * Get or set v:exception. If "oldval" == NULL, return the current value. 15591 * Otherwise, restore the value to "oldval" and return NULL. 15592 * Must always be called in pairs to save and restore v:exception! Does not 15593 * take care of memory allocations. 15594 */ 15595 char_u * 15596 v_exception(oldval) 15597 char_u *oldval; 15598 { 15599 if (oldval == NULL) 15600 return vimvars[VV_EXCEPTION].vv_str; 15601 15602 vimvars[VV_EXCEPTION].vv_str = oldval; 15603 return NULL; 15604 } 15605 15606 /* 15607 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15608 * Otherwise, restore the value to "oldval" and return NULL. 15609 * Must always be called in pairs to save and restore v:throwpoint! Does not 15610 * take care of memory allocations. 15611 */ 15612 char_u * 15613 v_throwpoint(oldval) 15614 char_u *oldval; 15615 { 15616 if (oldval == NULL) 15617 return vimvars[VV_THROWPOINT].vv_str; 15618 15619 vimvars[VV_THROWPOINT].vv_str = oldval; 15620 return NULL; 15621 } 15622 15623 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15624 /* 15625 * Set v:cmdarg. 15626 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15627 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15628 * Must always be called in pairs! 15629 */ 15630 char_u * 15631 set_cmdarg(eap, oldarg) 15632 exarg_T *eap; 15633 char_u *oldarg; 15634 { 15635 char_u *oldval; 15636 char_u *newval; 15637 unsigned len; 15638 15639 oldval = vimvars[VV_CMDARG].vv_str; 15640 if (eap == NULL) 15641 { 15642 vim_free(oldval); 15643 vimvars[VV_CMDARG].vv_str = oldarg; 15644 return NULL; 15645 } 15646 15647 if (eap->force_bin == FORCE_BIN) 15648 len = 6; 15649 else if (eap->force_bin == FORCE_NOBIN) 15650 len = 8; 15651 else 15652 len = 0; 15653 if (eap->force_ff != 0) 15654 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15655 # ifdef FEAT_MBYTE 15656 if (eap->force_enc != 0) 15657 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15658 # endif 15659 15660 newval = alloc(len + 1); 15661 if (newval == NULL) 15662 return NULL; 15663 15664 if (eap->force_bin == FORCE_BIN) 15665 sprintf((char *)newval, " ++bin"); 15666 else if (eap->force_bin == FORCE_NOBIN) 15667 sprintf((char *)newval, " ++nobin"); 15668 else 15669 *newval = NUL; 15670 if (eap->force_ff != 0) 15671 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15672 eap->cmd + eap->force_ff); 15673 # ifdef FEAT_MBYTE 15674 if (eap->force_enc != 0) 15675 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15676 eap->cmd + eap->force_enc); 15677 # endif 15678 vimvars[VV_CMDARG].vv_str = newval; 15679 return oldval; 15680 } 15681 #endif 15682 15683 /* 15684 * Get the value of internal variable "name". 15685 * Return OK or FAIL. 15686 */ 15687 static int 15688 get_var_tv(name, len, rettv, verbose) 15689 char_u *name; 15690 int len; /* length of "name" */ 15691 typval_T *rettv; /* NULL when only checking existence */ 15692 int verbose; /* may give error message */ 15693 { 15694 int ret = OK; 15695 typval_T *tv = NULL; 15696 typval_T atv; 15697 dictitem_T *v; 15698 int cc; 15699 15700 /* truncate the name, so that we can use strcmp() */ 15701 cc = name[len]; 15702 name[len] = NUL; 15703 15704 /* 15705 * Check for "b:changedtick". 15706 */ 15707 if (STRCMP(name, "b:changedtick") == 0) 15708 { 15709 atv.v_type = VAR_NUMBER; 15710 atv.vval.v_number = curbuf->b_changedtick; 15711 tv = &atv; 15712 } 15713 15714 /* 15715 * Check for user-defined variables. 15716 */ 15717 else 15718 { 15719 v = find_var(name, NULL); 15720 if (v != NULL) 15721 tv = &v->di_tv; 15722 } 15723 15724 if (tv == NULL) 15725 { 15726 if (rettv != NULL && verbose) 15727 EMSG2(_(e_undefvar), name); 15728 ret = FAIL; 15729 } 15730 else if (rettv != NULL) 15731 copy_tv(tv, rettv); 15732 15733 name[len] = cc; 15734 15735 return ret; 15736 } 15737 15738 /* 15739 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15740 * Also handle function call with Funcref variable: func(expr) 15741 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15742 */ 15743 static int 15744 handle_subscript(arg, rettv, evaluate, verbose) 15745 char_u **arg; 15746 typval_T *rettv; 15747 int evaluate; /* do more than finding the end */ 15748 int verbose; /* give error messages */ 15749 { 15750 int ret = OK; 15751 dict_T *selfdict = NULL; 15752 char_u *s; 15753 int len; 15754 typval_T functv; 15755 15756 while (ret == OK 15757 && (**arg == '[' 15758 || (**arg == '.' && rettv->v_type == VAR_DICT) 15759 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15760 && !vim_iswhite(*(*arg - 1))) 15761 { 15762 if (**arg == '(') 15763 { 15764 /* need to copy the funcref so that we can clear rettv */ 15765 functv = *rettv; 15766 rettv->v_type = VAR_UNKNOWN; 15767 15768 /* Invoke the function. Recursive! */ 15769 s = functv.vval.v_string; 15770 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15771 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15772 &len, evaluate, selfdict); 15773 15774 /* Clear the funcref afterwards, so that deleting it while 15775 * evaluating the arguments is possible (see test55). */ 15776 clear_tv(&functv); 15777 15778 /* Stop the expression evaluation when immediately aborting on 15779 * error, or when an interrupt occurred or an exception was thrown 15780 * but not caught. */ 15781 if (aborting()) 15782 { 15783 if (ret == OK) 15784 clear_tv(rettv); 15785 ret = FAIL; 15786 } 15787 dict_unref(selfdict); 15788 selfdict = NULL; 15789 } 15790 else /* **arg == '[' || **arg == '.' */ 15791 { 15792 dict_unref(selfdict); 15793 if (rettv->v_type == VAR_DICT) 15794 { 15795 selfdict = rettv->vval.v_dict; 15796 if (selfdict != NULL) 15797 ++selfdict->dv_refcount; 15798 } 15799 else 15800 selfdict = NULL; 15801 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15802 { 15803 clear_tv(rettv); 15804 ret = FAIL; 15805 } 15806 } 15807 } 15808 dict_unref(selfdict); 15809 return ret; 15810 } 15811 15812 /* 15813 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15814 * value). 15815 */ 15816 static typval_T * 15817 alloc_tv() 15818 { 15819 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15820 } 15821 15822 /* 15823 * Allocate memory for a variable type-value, and assign a string to it. 15824 * The string "s" must have been allocated, it is consumed. 15825 * Return NULL for out of memory, the variable otherwise. 15826 */ 15827 static typval_T * 15828 alloc_string_tv(s) 15829 char_u *s; 15830 { 15831 typval_T *rettv; 15832 15833 rettv = alloc_tv(); 15834 if (rettv != NULL) 15835 { 15836 rettv->v_type = VAR_STRING; 15837 rettv->vval.v_string = s; 15838 } 15839 else 15840 vim_free(s); 15841 return rettv; 15842 } 15843 15844 /* 15845 * Free the memory for a variable type-value. 15846 */ 15847 static void 15848 free_tv(varp) 15849 typval_T *varp; 15850 { 15851 if (varp != NULL) 15852 { 15853 switch (varp->v_type) 15854 { 15855 case VAR_FUNC: 15856 func_unref(varp->vval.v_string); 15857 /*FALLTHROUGH*/ 15858 case VAR_STRING: 15859 vim_free(varp->vval.v_string); 15860 break; 15861 case VAR_LIST: 15862 list_unref(varp->vval.v_list); 15863 break; 15864 case VAR_DICT: 15865 dict_unref(varp->vval.v_dict); 15866 break; 15867 case VAR_NUMBER: 15868 case VAR_UNKNOWN: 15869 break; 15870 default: 15871 EMSG2(_(e_intern2), "free_tv()"); 15872 break; 15873 } 15874 vim_free(varp); 15875 } 15876 } 15877 15878 /* 15879 * Free the memory for a variable value and set the value to NULL or 0. 15880 */ 15881 void 15882 clear_tv(varp) 15883 typval_T *varp; 15884 { 15885 if (varp != NULL) 15886 { 15887 switch (varp->v_type) 15888 { 15889 case VAR_FUNC: 15890 func_unref(varp->vval.v_string); 15891 /*FALLTHROUGH*/ 15892 case VAR_STRING: 15893 vim_free(varp->vval.v_string); 15894 varp->vval.v_string = NULL; 15895 break; 15896 case VAR_LIST: 15897 list_unref(varp->vval.v_list); 15898 varp->vval.v_list = NULL; 15899 break; 15900 case VAR_DICT: 15901 dict_unref(varp->vval.v_dict); 15902 varp->vval.v_dict = NULL; 15903 break; 15904 case VAR_NUMBER: 15905 varp->vval.v_number = 0; 15906 break; 15907 case VAR_UNKNOWN: 15908 break; 15909 default: 15910 EMSG2(_(e_intern2), "clear_tv()"); 15911 } 15912 varp->v_lock = 0; 15913 } 15914 } 15915 15916 /* 15917 * Set the value of a variable to NULL without freeing items. 15918 */ 15919 static void 15920 init_tv(varp) 15921 typval_T *varp; 15922 { 15923 if (varp != NULL) 15924 vim_memset(varp, 0, sizeof(typval_T)); 15925 } 15926 15927 /* 15928 * Get the number value of a variable. 15929 * If it is a String variable, uses vim_str2nr(). 15930 * For incompatible types, return 0. 15931 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15932 * caller of incompatible types: it sets *denote to TRUE if "denote" 15933 * is not NULL or returns -1 otherwise. 15934 */ 15935 static long 15936 get_tv_number(varp) 15937 typval_T *varp; 15938 { 15939 int error = FALSE; 15940 15941 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15942 } 15943 15944 long 15945 get_tv_number_chk(varp, denote) 15946 typval_T *varp; 15947 int *denote; 15948 { 15949 long n = 0L; 15950 15951 switch (varp->v_type) 15952 { 15953 case VAR_NUMBER: 15954 return (long)(varp->vval.v_number); 15955 case VAR_FUNC: 15956 EMSG(_("E703: Using a Funcref as a number")); 15957 break; 15958 case VAR_STRING: 15959 if (varp->vval.v_string != NULL) 15960 vim_str2nr(varp->vval.v_string, NULL, NULL, 15961 TRUE, TRUE, &n, NULL); 15962 return n; 15963 case VAR_LIST: 15964 EMSG(_("E745: Using a List as a number")); 15965 break; 15966 case VAR_DICT: 15967 EMSG(_("E728: Using a Dictionary as a number")); 15968 break; 15969 default: 15970 EMSG2(_(e_intern2), "get_tv_number()"); 15971 break; 15972 } 15973 if (denote == NULL) /* useful for values that must be unsigned */ 15974 n = -1; 15975 else 15976 *denote = TRUE; 15977 return n; 15978 } 15979 15980 /* 15981 * Get the lnum from the first argument. 15982 * Also accepts ".", "$", etc., but that only works for the current buffer. 15983 * Returns -1 on error. 15984 */ 15985 static linenr_T 15986 get_tv_lnum(argvars) 15987 typval_T *argvars; 15988 { 15989 typval_T rettv; 15990 linenr_T lnum; 15991 15992 lnum = get_tv_number_chk(&argvars[0], NULL); 15993 if (lnum == 0) /* no valid number, try using line() */ 15994 { 15995 rettv.v_type = VAR_NUMBER; 15996 f_line(argvars, &rettv); 15997 lnum = rettv.vval.v_number; 15998 clear_tv(&rettv); 15999 } 16000 return lnum; 16001 } 16002 16003 /* 16004 * Get the lnum from the first argument. 16005 * Also accepts "$", then "buf" is used. 16006 * Returns 0 on error. 16007 */ 16008 static linenr_T 16009 get_tv_lnum_buf(argvars, buf) 16010 typval_T *argvars; 16011 buf_T *buf; 16012 { 16013 if (argvars[0].v_type == VAR_STRING 16014 && argvars[0].vval.v_string != NULL 16015 && argvars[0].vval.v_string[0] == '$' 16016 && buf != NULL) 16017 return buf->b_ml.ml_line_count; 16018 return get_tv_number_chk(&argvars[0], NULL); 16019 } 16020 16021 /* 16022 * Get the string value of a variable. 16023 * If it is a Number variable, the number is converted into a string. 16024 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 16025 * get_tv_string_buf() uses a given buffer. 16026 * If the String variable has never been set, return an empty string. 16027 * Never returns NULL; 16028 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 16029 * NULL on error. 16030 */ 16031 static char_u * 16032 get_tv_string(varp) 16033 typval_T *varp; 16034 { 16035 static char_u mybuf[NUMBUFLEN]; 16036 16037 return get_tv_string_buf(varp, mybuf); 16038 } 16039 16040 static char_u * 16041 get_tv_string_buf(varp, buf) 16042 typval_T *varp; 16043 char_u *buf; 16044 { 16045 char_u *res = get_tv_string_buf_chk(varp, buf); 16046 16047 return res != NULL ? res : (char_u *)""; 16048 } 16049 16050 char_u * 16051 get_tv_string_chk(varp) 16052 typval_T *varp; 16053 { 16054 static char_u mybuf[NUMBUFLEN]; 16055 16056 return get_tv_string_buf_chk(varp, mybuf); 16057 } 16058 16059 static char_u * 16060 get_tv_string_buf_chk(varp, buf) 16061 typval_T *varp; 16062 char_u *buf; 16063 { 16064 switch (varp->v_type) 16065 { 16066 case VAR_NUMBER: 16067 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 16068 return buf; 16069 case VAR_FUNC: 16070 EMSG(_("E729: using Funcref as a String")); 16071 break; 16072 case VAR_LIST: 16073 EMSG(_("E730: using List as a String")); 16074 break; 16075 case VAR_DICT: 16076 EMSG(_("E731: using Dictionary as a String")); 16077 break; 16078 case VAR_STRING: 16079 if (varp->vval.v_string != NULL) 16080 return varp->vval.v_string; 16081 return (char_u *)""; 16082 default: 16083 EMSG2(_(e_intern2), "get_tv_string_buf()"); 16084 break; 16085 } 16086 return NULL; 16087 } 16088 16089 /* 16090 * Find variable "name" in the list of variables. 16091 * Return a pointer to it if found, NULL if not found. 16092 * Careful: "a:0" variables don't have a name. 16093 * When "htp" is not NULL we are writing to the variable, set "htp" to the 16094 * hashtab_T used. 16095 */ 16096 static dictitem_T * 16097 find_var(name, htp) 16098 char_u *name; 16099 hashtab_T **htp; 16100 { 16101 char_u *varname; 16102 hashtab_T *ht; 16103 16104 ht = find_var_ht(name, &varname); 16105 if (htp != NULL) 16106 *htp = ht; 16107 if (ht == NULL) 16108 return NULL; 16109 return find_var_in_ht(ht, varname, htp != NULL); 16110 } 16111 16112 /* 16113 * Find variable "varname" in hashtab "ht". 16114 * Returns NULL if not found. 16115 */ 16116 static dictitem_T * 16117 find_var_in_ht(ht, varname, writing) 16118 hashtab_T *ht; 16119 char_u *varname; 16120 int writing; 16121 { 16122 hashitem_T *hi; 16123 16124 if (*varname == NUL) 16125 { 16126 /* Must be something like "s:", otherwise "ht" would be NULL. */ 16127 switch (varname[-2]) 16128 { 16129 case 's': return &SCRIPT_SV(current_SID).sv_var; 16130 case 'g': return &globvars_var; 16131 case 'v': return &vimvars_var; 16132 case 'b': return &curbuf->b_bufvar; 16133 case 'w': return &curwin->w_winvar; 16134 case 'l': return current_funccal == NULL 16135 ? NULL : ¤t_funccal->l_vars_var; 16136 case 'a': return current_funccal == NULL 16137 ? NULL : ¤t_funccal->l_avars_var; 16138 } 16139 return NULL; 16140 } 16141 16142 hi = hash_find(ht, varname); 16143 if (HASHITEM_EMPTY(hi)) 16144 { 16145 /* For global variables we may try auto-loading the script. If it 16146 * worked find the variable again. Don't auto-load a script if it was 16147 * loaded already, otherwise it would be loaded every time when 16148 * checking if a function name is a Funcref variable. */ 16149 if (ht == &globvarht && !writing 16150 && script_autoload(varname, FALSE) && !aborting()) 16151 hi = hash_find(ht, varname); 16152 if (HASHITEM_EMPTY(hi)) 16153 return NULL; 16154 } 16155 return HI2DI(hi); 16156 } 16157 16158 /* 16159 * Find the hashtab used for a variable name. 16160 * Set "varname" to the start of name without ':'. 16161 */ 16162 static hashtab_T * 16163 find_var_ht(name, varname) 16164 char_u *name; 16165 char_u **varname; 16166 { 16167 hashitem_T *hi; 16168 16169 if (name[1] != ':') 16170 { 16171 /* The name must not start with a colon or #. */ 16172 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 16173 return NULL; 16174 *varname = name; 16175 16176 /* "version" is "v:version" in all scopes */ 16177 hi = hash_find(&compat_hashtab, name); 16178 if (!HASHITEM_EMPTY(hi)) 16179 return &compat_hashtab; 16180 16181 if (current_funccal == NULL) 16182 return &globvarht; /* global variable */ 16183 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 16184 } 16185 *varname = name + 2; 16186 if (*name == 'g') /* global variable */ 16187 return &globvarht; 16188 /* There must be no ':' or '#' in the rest of the name, unless g: is used 16189 */ 16190 if (vim_strchr(name + 2, ':') != NULL 16191 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 16192 return NULL; 16193 if (*name == 'b') /* buffer variable */ 16194 return &curbuf->b_vars.dv_hashtab; 16195 if (*name == 'w') /* window variable */ 16196 return &curwin->w_vars.dv_hashtab; 16197 if (*name == 'v') /* v: variable */ 16198 return &vimvarht; 16199 if (*name == 'a' && current_funccal != NULL) /* function argument */ 16200 return ¤t_funccal->l_avars.dv_hashtab; 16201 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 16202 return ¤t_funccal->l_vars.dv_hashtab; 16203 if (*name == 's' /* script variable */ 16204 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 16205 return &SCRIPT_VARS(current_SID); 16206 return NULL; 16207 } 16208 16209 /* 16210 * Get the string value of a (global/local) variable. 16211 * Returns NULL when it doesn't exist. 16212 */ 16213 char_u * 16214 get_var_value(name) 16215 char_u *name; 16216 { 16217 dictitem_T *v; 16218 16219 v = find_var(name, NULL); 16220 if (v == NULL) 16221 return NULL; 16222 return get_tv_string(&v->di_tv); 16223 } 16224 16225 /* 16226 * Allocate a new hashtab for a sourced script. It will be used while 16227 * sourcing this script and when executing functions defined in the script. 16228 */ 16229 void 16230 new_script_vars(id) 16231 scid_T id; 16232 { 16233 int i; 16234 hashtab_T *ht; 16235 scriptvar_T *sv; 16236 16237 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 16238 { 16239 /* Re-allocating ga_data means that an ht_array pointing to 16240 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 16241 * at its init value. Also reset "v_dict", it's always the same. */ 16242 for (i = 1; i <= ga_scripts.ga_len; ++i) 16243 { 16244 ht = &SCRIPT_VARS(i); 16245 if (ht->ht_mask == HT_INIT_SIZE - 1) 16246 ht->ht_array = ht->ht_smallarray; 16247 sv = &SCRIPT_SV(i); 16248 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 16249 } 16250 16251 while (ga_scripts.ga_len < id) 16252 { 16253 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 16254 init_var_dict(&sv->sv_dict, &sv->sv_var); 16255 ++ga_scripts.ga_len; 16256 } 16257 } 16258 } 16259 16260 /* 16261 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 16262 * point to it. 16263 */ 16264 void 16265 init_var_dict(dict, dict_var) 16266 dict_T *dict; 16267 dictitem_T *dict_var; 16268 { 16269 hash_init(&dict->dv_hashtab); 16270 dict->dv_refcount = 99999; 16271 dict_var->di_tv.vval.v_dict = dict; 16272 dict_var->di_tv.v_type = VAR_DICT; 16273 dict_var->di_tv.v_lock = VAR_FIXED; 16274 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16275 dict_var->di_key[0] = NUL; 16276 } 16277 16278 /* 16279 * Clean up a list of internal variables. 16280 * Frees all allocated variables and the value they contain. 16281 * Clears hashtab "ht", does not free it. 16282 */ 16283 void 16284 vars_clear(ht) 16285 hashtab_T *ht; 16286 { 16287 vars_clear_ext(ht, TRUE); 16288 } 16289 16290 /* 16291 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16292 */ 16293 static void 16294 vars_clear_ext(ht, free_val) 16295 hashtab_T *ht; 16296 int free_val; 16297 { 16298 int todo; 16299 hashitem_T *hi; 16300 dictitem_T *v; 16301 16302 hash_lock(ht); 16303 todo = ht->ht_used; 16304 for (hi = ht->ht_array; todo > 0; ++hi) 16305 { 16306 if (!HASHITEM_EMPTY(hi)) 16307 { 16308 --todo; 16309 16310 /* Free the variable. Don't remove it from the hashtab, 16311 * ht_array might change then. hash_clear() takes care of it 16312 * later. */ 16313 v = HI2DI(hi); 16314 if (free_val) 16315 clear_tv(&v->di_tv); 16316 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16317 vim_free(v); 16318 } 16319 } 16320 hash_clear(ht); 16321 ht->ht_used = 0; 16322 } 16323 16324 /* 16325 * Delete a variable from hashtab "ht" at item "hi". 16326 * Clear the variable value and free the dictitem. 16327 */ 16328 static void 16329 delete_var(ht, hi) 16330 hashtab_T *ht; 16331 hashitem_T *hi; 16332 { 16333 dictitem_T *di = HI2DI(hi); 16334 16335 hash_remove(ht, hi); 16336 clear_tv(&di->di_tv); 16337 vim_free(di); 16338 } 16339 16340 /* 16341 * List the value of one internal variable. 16342 */ 16343 static void 16344 list_one_var(v, prefix) 16345 dictitem_T *v; 16346 char_u *prefix; 16347 { 16348 char_u *tofree; 16349 char_u *s; 16350 char_u numbuf[NUMBUFLEN]; 16351 16352 s = echo_string(&v->di_tv, &tofree, numbuf); 16353 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16354 s == NULL ? (char_u *)"" : s); 16355 vim_free(tofree); 16356 } 16357 16358 static void 16359 list_one_var_a(prefix, name, type, string) 16360 char_u *prefix; 16361 char_u *name; 16362 int type; 16363 char_u *string; 16364 { 16365 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16366 if (name != NULL) /* "a:" vars don't have a name stored */ 16367 msg_puts(name); 16368 msg_putchar(' '); 16369 msg_advance(22); 16370 if (type == VAR_NUMBER) 16371 msg_putchar('#'); 16372 else if (type == VAR_FUNC) 16373 msg_putchar('*'); 16374 else if (type == VAR_LIST) 16375 { 16376 msg_putchar('['); 16377 if (*string == '[') 16378 ++string; 16379 } 16380 else if (type == VAR_DICT) 16381 { 16382 msg_putchar('{'); 16383 if (*string == '{') 16384 ++string; 16385 } 16386 else 16387 msg_putchar(' '); 16388 16389 msg_outtrans(string); 16390 16391 if (type == VAR_FUNC) 16392 msg_puts((char_u *)"()"); 16393 } 16394 16395 /* 16396 * Set variable "name" to value in "tv". 16397 * If the variable already exists, the value is updated. 16398 * Otherwise the variable is created. 16399 */ 16400 static void 16401 set_var(name, tv, copy) 16402 char_u *name; 16403 typval_T *tv; 16404 int copy; /* make copy of value in "tv" */ 16405 { 16406 dictitem_T *v; 16407 char_u *varname; 16408 hashtab_T *ht; 16409 char_u *p; 16410 16411 if (tv->v_type == VAR_FUNC) 16412 { 16413 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16414 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16415 ? name[2] : name[0])) 16416 { 16417 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16418 return; 16419 } 16420 if (function_exists(name)) 16421 { 16422 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16423 name); 16424 return; 16425 } 16426 } 16427 16428 ht = find_var_ht(name, &varname); 16429 if (ht == NULL || *varname == NUL) 16430 { 16431 EMSG2(_(e_illvar), name); 16432 return; 16433 } 16434 16435 v = find_var_in_ht(ht, varname, TRUE); 16436 if (v != NULL) 16437 { 16438 /* existing variable, need to clear the value */ 16439 if (var_check_ro(v->di_flags, name) 16440 || tv_check_lock(v->di_tv.v_lock, name)) 16441 return; 16442 if (v->di_tv.v_type != tv->v_type 16443 && !((v->di_tv.v_type == VAR_STRING 16444 || v->di_tv.v_type == VAR_NUMBER) 16445 && (tv->v_type == VAR_STRING 16446 || tv->v_type == VAR_NUMBER))) 16447 { 16448 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16449 return; 16450 } 16451 16452 /* 16453 * Handle setting internal v: variables separately: we don't change 16454 * the type. 16455 */ 16456 if (ht == &vimvarht) 16457 { 16458 if (v->di_tv.v_type == VAR_STRING) 16459 { 16460 vim_free(v->di_tv.vval.v_string); 16461 if (copy || tv->v_type != VAR_STRING) 16462 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16463 else 16464 { 16465 /* Take over the string to avoid an extra alloc/free. */ 16466 v->di_tv.vval.v_string = tv->vval.v_string; 16467 tv->vval.v_string = NULL; 16468 } 16469 } 16470 else if (v->di_tv.v_type != VAR_NUMBER) 16471 EMSG2(_(e_intern2), "set_var()"); 16472 else 16473 v->di_tv.vval.v_number = get_tv_number(tv); 16474 return; 16475 } 16476 16477 clear_tv(&v->di_tv); 16478 } 16479 else /* add a new variable */ 16480 { 16481 /* Make sure the variable name is valid. */ 16482 for (p = varname; *p != NUL; ++p) 16483 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16484 { 16485 EMSG2(_(e_illvar), varname); 16486 return; 16487 } 16488 16489 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16490 + STRLEN(varname))); 16491 if (v == NULL) 16492 return; 16493 STRCPY(v->di_key, varname); 16494 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16495 { 16496 vim_free(v); 16497 return; 16498 } 16499 v->di_flags = 0; 16500 } 16501 16502 if (copy || tv->v_type == VAR_NUMBER) 16503 copy_tv(tv, &v->di_tv); 16504 else 16505 { 16506 v->di_tv = *tv; 16507 v->di_tv.v_lock = 0; 16508 init_tv(tv); 16509 } 16510 } 16511 16512 /* 16513 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16514 * Also give an error message. 16515 */ 16516 static int 16517 var_check_ro(flags, name) 16518 int flags; 16519 char_u *name; 16520 { 16521 if (flags & DI_FLAGS_RO) 16522 { 16523 EMSG2(_(e_readonlyvar), name); 16524 return TRUE; 16525 } 16526 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16527 { 16528 EMSG2(_(e_readonlysbx), name); 16529 return TRUE; 16530 } 16531 return FALSE; 16532 } 16533 16534 /* 16535 * Return TRUE if typeval "tv" is set to be locked (immutable). 16536 * Also give an error message, using "name". 16537 */ 16538 static int 16539 tv_check_lock(lock, name) 16540 int lock; 16541 char_u *name; 16542 { 16543 if (lock & VAR_LOCKED) 16544 { 16545 EMSG2(_("E741: Value is locked: %s"), 16546 name == NULL ? (char_u *)_("Unknown") : name); 16547 return TRUE; 16548 } 16549 if (lock & VAR_FIXED) 16550 { 16551 EMSG2(_("E742: Cannot change value of %s"), 16552 name == NULL ? (char_u *)_("Unknown") : name); 16553 return TRUE; 16554 } 16555 return FALSE; 16556 } 16557 16558 /* 16559 * Copy the values from typval_T "from" to typval_T "to". 16560 * When needed allocates string or increases reference count. 16561 * Does not make a copy of a list or dict but copies the reference! 16562 */ 16563 static void 16564 copy_tv(from, to) 16565 typval_T *from; 16566 typval_T *to; 16567 { 16568 to->v_type = from->v_type; 16569 to->v_lock = 0; 16570 switch (from->v_type) 16571 { 16572 case VAR_NUMBER: 16573 to->vval.v_number = from->vval.v_number; 16574 break; 16575 case VAR_STRING: 16576 case VAR_FUNC: 16577 if (from->vval.v_string == NULL) 16578 to->vval.v_string = NULL; 16579 else 16580 { 16581 to->vval.v_string = vim_strsave(from->vval.v_string); 16582 if (from->v_type == VAR_FUNC) 16583 func_ref(to->vval.v_string); 16584 } 16585 break; 16586 case VAR_LIST: 16587 if (from->vval.v_list == NULL) 16588 to->vval.v_list = NULL; 16589 else 16590 { 16591 to->vval.v_list = from->vval.v_list; 16592 ++to->vval.v_list->lv_refcount; 16593 } 16594 break; 16595 case VAR_DICT: 16596 if (from->vval.v_dict == NULL) 16597 to->vval.v_dict = NULL; 16598 else 16599 { 16600 to->vval.v_dict = from->vval.v_dict; 16601 ++to->vval.v_dict->dv_refcount; 16602 } 16603 break; 16604 default: 16605 EMSG2(_(e_intern2), "copy_tv()"); 16606 break; 16607 } 16608 } 16609 16610 /* 16611 * Make a copy of an item. 16612 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16613 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16614 * reference to an already copied list/dict can be used. 16615 * Returns FAIL or OK. 16616 */ 16617 static int 16618 item_copy(from, to, deep, copyID) 16619 typval_T *from; 16620 typval_T *to; 16621 int deep; 16622 int copyID; 16623 { 16624 static int recurse = 0; 16625 int ret = OK; 16626 16627 if (recurse >= DICT_MAXNEST) 16628 { 16629 EMSG(_("E698: variable nested too deep for making a copy")); 16630 return FAIL; 16631 } 16632 ++recurse; 16633 16634 switch (from->v_type) 16635 { 16636 case VAR_NUMBER: 16637 case VAR_STRING: 16638 case VAR_FUNC: 16639 copy_tv(from, to); 16640 break; 16641 case VAR_LIST: 16642 to->v_type = VAR_LIST; 16643 to->v_lock = 0; 16644 if (from->vval.v_list == NULL) 16645 to->vval.v_list = NULL; 16646 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16647 { 16648 /* use the copy made earlier */ 16649 to->vval.v_list = from->vval.v_list->lv_copylist; 16650 ++to->vval.v_list->lv_refcount; 16651 } 16652 else 16653 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16654 if (to->vval.v_list == NULL) 16655 ret = FAIL; 16656 break; 16657 case VAR_DICT: 16658 to->v_type = VAR_DICT; 16659 to->v_lock = 0; 16660 if (from->vval.v_dict == NULL) 16661 to->vval.v_dict = NULL; 16662 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16663 { 16664 /* use the copy made earlier */ 16665 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16666 ++to->vval.v_dict->dv_refcount; 16667 } 16668 else 16669 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16670 if (to->vval.v_dict == NULL) 16671 ret = FAIL; 16672 break; 16673 default: 16674 EMSG2(_(e_intern2), "item_copy()"); 16675 ret = FAIL; 16676 } 16677 --recurse; 16678 return ret; 16679 } 16680 16681 /* 16682 * ":echo expr1 ..." print each argument separated with a space, add a 16683 * newline at the end. 16684 * ":echon expr1 ..." print each argument plain. 16685 */ 16686 void 16687 ex_echo(eap) 16688 exarg_T *eap; 16689 { 16690 char_u *arg = eap->arg; 16691 typval_T rettv; 16692 char_u *tofree; 16693 char_u *p; 16694 int needclr = TRUE; 16695 int atstart = TRUE; 16696 char_u numbuf[NUMBUFLEN]; 16697 16698 if (eap->skip) 16699 ++emsg_skip; 16700 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16701 { 16702 p = arg; 16703 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16704 { 16705 /* 16706 * Report the invalid expression unless the expression evaluation 16707 * has been cancelled due to an aborting error, an interrupt, or an 16708 * exception. 16709 */ 16710 if (!aborting()) 16711 EMSG2(_(e_invexpr2), p); 16712 break; 16713 } 16714 if (!eap->skip) 16715 { 16716 if (atstart) 16717 { 16718 atstart = FALSE; 16719 /* Call msg_start() after eval1(), evaluating the expression 16720 * may cause a message to appear. */ 16721 if (eap->cmdidx == CMD_echo) 16722 msg_start(); 16723 } 16724 else if (eap->cmdidx == CMD_echo) 16725 msg_puts_attr((char_u *)" ", echo_attr); 16726 p = echo_string(&rettv, &tofree, numbuf); 16727 if (p != NULL) 16728 for ( ; *p != NUL && !got_int; ++p) 16729 { 16730 if (*p == '\n' || *p == '\r' || *p == TAB) 16731 { 16732 if (*p != TAB && needclr) 16733 { 16734 /* remove any text still there from the command */ 16735 msg_clr_eos(); 16736 needclr = FALSE; 16737 } 16738 msg_putchar_attr(*p, echo_attr); 16739 } 16740 else 16741 { 16742 #ifdef FEAT_MBYTE 16743 if (has_mbyte) 16744 { 16745 int i = (*mb_ptr2len)(p); 16746 16747 (void)msg_outtrans_len_attr(p, i, echo_attr); 16748 p += i - 1; 16749 } 16750 else 16751 #endif 16752 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16753 } 16754 } 16755 vim_free(tofree); 16756 } 16757 clear_tv(&rettv); 16758 arg = skipwhite(arg); 16759 } 16760 eap->nextcmd = check_nextcmd(arg); 16761 16762 if (eap->skip) 16763 --emsg_skip; 16764 else 16765 { 16766 /* remove text that may still be there from the command */ 16767 if (needclr) 16768 msg_clr_eos(); 16769 if (eap->cmdidx == CMD_echo) 16770 msg_end(); 16771 } 16772 } 16773 16774 /* 16775 * ":echohl {name}". 16776 */ 16777 void 16778 ex_echohl(eap) 16779 exarg_T *eap; 16780 { 16781 int id; 16782 16783 id = syn_name2id(eap->arg); 16784 if (id == 0) 16785 echo_attr = 0; 16786 else 16787 echo_attr = syn_id2attr(id); 16788 } 16789 16790 /* 16791 * ":execute expr1 ..." execute the result of an expression. 16792 * ":echomsg expr1 ..." Print a message 16793 * ":echoerr expr1 ..." Print an error 16794 * Each gets spaces around each argument and a newline at the end for 16795 * echo commands 16796 */ 16797 void 16798 ex_execute(eap) 16799 exarg_T *eap; 16800 { 16801 char_u *arg = eap->arg; 16802 typval_T rettv; 16803 int ret = OK; 16804 char_u *p; 16805 garray_T ga; 16806 int len; 16807 int save_did_emsg; 16808 16809 ga_init2(&ga, 1, 80); 16810 16811 if (eap->skip) 16812 ++emsg_skip; 16813 while (*arg != NUL && *arg != '|' && *arg != '\n') 16814 { 16815 p = arg; 16816 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16817 { 16818 /* 16819 * Report the invalid expression unless the expression evaluation 16820 * has been cancelled due to an aborting error, an interrupt, or an 16821 * exception. 16822 */ 16823 if (!aborting()) 16824 EMSG2(_(e_invexpr2), p); 16825 ret = FAIL; 16826 break; 16827 } 16828 16829 if (!eap->skip) 16830 { 16831 p = get_tv_string(&rettv); 16832 len = (int)STRLEN(p); 16833 if (ga_grow(&ga, len + 2) == FAIL) 16834 { 16835 clear_tv(&rettv); 16836 ret = FAIL; 16837 break; 16838 } 16839 if (ga.ga_len) 16840 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16841 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16842 ga.ga_len += len; 16843 } 16844 16845 clear_tv(&rettv); 16846 arg = skipwhite(arg); 16847 } 16848 16849 if (ret != FAIL && ga.ga_data != NULL) 16850 { 16851 if (eap->cmdidx == CMD_echomsg) 16852 MSG_ATTR(ga.ga_data, echo_attr); 16853 else if (eap->cmdidx == CMD_echoerr) 16854 { 16855 /* We don't want to abort following commands, restore did_emsg. */ 16856 save_did_emsg = did_emsg; 16857 EMSG((char_u *)ga.ga_data); 16858 if (!force_abort) 16859 did_emsg = save_did_emsg; 16860 } 16861 else if (eap->cmdidx == CMD_execute) 16862 do_cmdline((char_u *)ga.ga_data, 16863 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16864 } 16865 16866 ga_clear(&ga); 16867 16868 if (eap->skip) 16869 --emsg_skip; 16870 16871 eap->nextcmd = check_nextcmd(arg); 16872 } 16873 16874 /* 16875 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16876 * "arg" points to the "&" or '+' when called, to "option" when returning. 16877 * Returns NULL when no option name found. Otherwise pointer to the char 16878 * after the option name. 16879 */ 16880 static char_u * 16881 find_option_end(arg, opt_flags) 16882 char_u **arg; 16883 int *opt_flags; 16884 { 16885 char_u *p = *arg; 16886 16887 ++p; 16888 if (*p == 'g' && p[1] == ':') 16889 { 16890 *opt_flags = OPT_GLOBAL; 16891 p += 2; 16892 } 16893 else if (*p == 'l' && p[1] == ':') 16894 { 16895 *opt_flags = OPT_LOCAL; 16896 p += 2; 16897 } 16898 else 16899 *opt_flags = 0; 16900 16901 if (!ASCII_ISALPHA(*p)) 16902 return NULL; 16903 *arg = p; 16904 16905 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16906 p += 4; /* termcap option */ 16907 else 16908 while (ASCII_ISALPHA(*p)) 16909 ++p; 16910 return p; 16911 } 16912 16913 /* 16914 * ":function" 16915 */ 16916 void 16917 ex_function(eap) 16918 exarg_T *eap; 16919 { 16920 char_u *theline; 16921 int j; 16922 int c; 16923 int saved_did_emsg; 16924 char_u *name = NULL; 16925 char_u *p; 16926 char_u *arg; 16927 garray_T newargs; 16928 garray_T newlines; 16929 int varargs = FALSE; 16930 int mustend = FALSE; 16931 int flags = 0; 16932 ufunc_T *fp; 16933 int indent; 16934 int nesting; 16935 char_u *skip_until = NULL; 16936 dictitem_T *v; 16937 funcdict_T fudi; 16938 static int func_nr = 0; /* number for nameless function */ 16939 int paren; 16940 hashtab_T *ht; 16941 int todo; 16942 hashitem_T *hi; 16943 16944 /* 16945 * ":function" without argument: list functions. 16946 */ 16947 if (ends_excmd(*eap->arg)) 16948 { 16949 if (!eap->skip) 16950 { 16951 todo = func_hashtab.ht_used; 16952 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16953 { 16954 if (!HASHITEM_EMPTY(hi)) 16955 { 16956 --todo; 16957 fp = HI2UF(hi); 16958 if (!isdigit(*fp->uf_name)) 16959 list_func_head(fp, FALSE); 16960 } 16961 } 16962 } 16963 eap->nextcmd = check_nextcmd(eap->arg); 16964 return; 16965 } 16966 16967 /* 16968 * ":function /pat": list functions matching pattern. 16969 */ 16970 if (*eap->arg == '/') 16971 { 16972 p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); 16973 if (!eap->skip) 16974 { 16975 regmatch_T regmatch; 16976 16977 c = *p; 16978 *p = NUL; 16979 regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); 16980 *p = c; 16981 if (regmatch.regprog != NULL) 16982 { 16983 regmatch.rm_ic = p_ic; 16984 16985 todo = func_hashtab.ht_used; 16986 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16987 { 16988 if (!HASHITEM_EMPTY(hi)) 16989 { 16990 --todo; 16991 fp = HI2UF(hi); 16992 if (!isdigit(*fp->uf_name) 16993 && vim_regexec(®match, fp->uf_name, 0)) 16994 list_func_head(fp, FALSE); 16995 } 16996 } 16997 } 16998 } 16999 if (*p == '/') 17000 ++p; 17001 eap->nextcmd = check_nextcmd(p); 17002 return; 17003 } 17004 17005 /* 17006 * Get the function name. There are these situations: 17007 * func normal function name 17008 * "name" == func, "fudi.fd_dict" == NULL 17009 * dict.func new dictionary entry 17010 * "name" == NULL, "fudi.fd_dict" set, 17011 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 17012 * dict.func existing dict entry with a Funcref 17013 * "name" == func, "fudi.fd_dict" set, 17014 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17015 * dict.func existing dict entry that's not a Funcref 17016 * "name" == NULL, "fudi.fd_dict" set, 17017 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 17018 */ 17019 p = eap->arg; 17020 name = trans_function_name(&p, eap->skip, 0, &fudi); 17021 paren = (vim_strchr(p, '(') != NULL); 17022 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 17023 { 17024 /* 17025 * Return on an invalid expression in braces, unless the expression 17026 * evaluation has been cancelled due to an aborting error, an 17027 * interrupt, or an exception. 17028 */ 17029 if (!aborting()) 17030 { 17031 if (!eap->skip && fudi.fd_newkey != NULL) 17032 EMSG2(_(e_dictkey), fudi.fd_newkey); 17033 vim_free(fudi.fd_newkey); 17034 return; 17035 } 17036 else 17037 eap->skip = TRUE; 17038 } 17039 /* An error in a function call during evaluation of an expression in magic 17040 * braces should not cause the function not to be defined. */ 17041 saved_did_emsg = did_emsg; 17042 did_emsg = FALSE; 17043 17044 /* 17045 * ":function func" with only function name: list function. 17046 */ 17047 if (!paren) 17048 { 17049 if (!ends_excmd(*skipwhite(p))) 17050 { 17051 EMSG(_(e_trailing)); 17052 goto ret_free; 17053 } 17054 eap->nextcmd = check_nextcmd(p); 17055 if (eap->nextcmd != NULL) 17056 *p = NUL; 17057 if (!eap->skip && !got_int) 17058 { 17059 fp = find_func(name); 17060 if (fp != NULL) 17061 { 17062 list_func_head(fp, TRUE); 17063 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 17064 { 17065 msg_putchar('\n'); 17066 msg_outnum((long)(j + 1)); 17067 if (j < 9) 17068 msg_putchar(' '); 17069 if (j < 99) 17070 msg_putchar(' '); 17071 msg_prt_line(FUNCLINE(fp, j), FALSE); 17072 out_flush(); /* show a line at a time */ 17073 ui_breakcheck(); 17074 } 17075 if (!got_int) 17076 { 17077 msg_putchar('\n'); 17078 msg_puts((char_u *)" endfunction"); 17079 } 17080 } 17081 else 17082 emsg_funcname("E123: Undefined function: %s", name); 17083 } 17084 goto ret_free; 17085 } 17086 17087 /* 17088 * ":function name(arg1, arg2)" Define function. 17089 */ 17090 p = skipwhite(p); 17091 if (*p != '(') 17092 { 17093 if (!eap->skip) 17094 { 17095 EMSG2(_("E124: Missing '(': %s"), eap->arg); 17096 goto ret_free; 17097 } 17098 /* attempt to continue by skipping some text */ 17099 if (vim_strchr(p, '(') != NULL) 17100 p = vim_strchr(p, '('); 17101 } 17102 p = skipwhite(p + 1); 17103 17104 ga_init2(&newargs, (int)sizeof(char_u *), 3); 17105 ga_init2(&newlines, (int)sizeof(char_u *), 3); 17106 17107 if (!eap->skip) 17108 { 17109 /* Check the name of the function. */ 17110 if (name != NULL) 17111 arg = name; 17112 else 17113 arg = fudi.fd_newkey; 17114 if (arg != NULL) 17115 { 17116 if (*arg == K_SPECIAL) 17117 j = 3; 17118 else 17119 j = 0; 17120 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 17121 : eval_isnamec(arg[j]))) 17122 ++j; 17123 if (arg[j] != NUL) 17124 emsg_funcname(_(e_invarg2), arg); 17125 } 17126 } 17127 17128 /* 17129 * Isolate the arguments: "arg1, arg2, ...)" 17130 */ 17131 while (*p != ')') 17132 { 17133 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 17134 { 17135 varargs = TRUE; 17136 p += 3; 17137 mustend = TRUE; 17138 } 17139 else 17140 { 17141 arg = p; 17142 while (ASCII_ISALNUM(*p) || *p == '_') 17143 ++p; 17144 if (arg == p || isdigit(*arg) 17145 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 17146 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 17147 { 17148 if (!eap->skip) 17149 EMSG2(_("E125: Illegal argument: %s"), arg); 17150 break; 17151 } 17152 if (ga_grow(&newargs, 1) == FAIL) 17153 goto erret; 17154 c = *p; 17155 *p = NUL; 17156 arg = vim_strsave(arg); 17157 if (arg == NULL) 17158 goto erret; 17159 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 17160 *p = c; 17161 newargs.ga_len++; 17162 if (*p == ',') 17163 ++p; 17164 else 17165 mustend = TRUE; 17166 } 17167 p = skipwhite(p); 17168 if (mustend && *p != ')') 17169 { 17170 if (!eap->skip) 17171 EMSG2(_(e_invarg2), eap->arg); 17172 break; 17173 } 17174 } 17175 ++p; /* skip the ')' */ 17176 17177 /* find extra arguments "range", "dict" and "abort" */ 17178 for (;;) 17179 { 17180 p = skipwhite(p); 17181 if (STRNCMP(p, "range", 5) == 0) 17182 { 17183 flags |= FC_RANGE; 17184 p += 5; 17185 } 17186 else if (STRNCMP(p, "dict", 4) == 0) 17187 { 17188 flags |= FC_DICT; 17189 p += 4; 17190 } 17191 else if (STRNCMP(p, "abort", 5) == 0) 17192 { 17193 flags |= FC_ABORT; 17194 p += 5; 17195 } 17196 else 17197 break; 17198 } 17199 17200 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 17201 EMSG(_(e_trailing)); 17202 17203 /* 17204 * Read the body of the function, until ":endfunction" is found. 17205 */ 17206 if (KeyTyped) 17207 { 17208 /* Check if the function already exists, don't let the user type the 17209 * whole function before telling him it doesn't work! For a script we 17210 * need to skip the body to be able to find what follows. */ 17211 if (!eap->skip && !eap->forceit) 17212 { 17213 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 17214 EMSG(_(e_funcdict)); 17215 else if (name != NULL && find_func(name) != NULL) 17216 emsg_funcname(e_funcexts, name); 17217 } 17218 17219 if (!eap->skip && did_emsg) 17220 goto erret; 17221 17222 msg_putchar('\n'); /* don't overwrite the function name */ 17223 cmdline_row = msg_row; 17224 } 17225 17226 indent = 2; 17227 nesting = 0; 17228 for (;;) 17229 { 17230 msg_scroll = TRUE; 17231 need_wait_return = FALSE; 17232 if (eap->getline == NULL) 17233 theline = getcmdline(':', 0L, indent); 17234 else 17235 theline = eap->getline(':', eap->cookie, indent); 17236 if (KeyTyped) 17237 lines_left = Rows - 1; 17238 if (theline == NULL) 17239 { 17240 EMSG(_("E126: Missing :endfunction")); 17241 goto erret; 17242 } 17243 17244 if (skip_until != NULL) 17245 { 17246 /* between ":append" and "." and between ":python <<EOF" and "EOF" 17247 * don't check for ":endfunc". */ 17248 if (STRCMP(theline, skip_until) == 0) 17249 { 17250 vim_free(skip_until); 17251 skip_until = NULL; 17252 } 17253 } 17254 else 17255 { 17256 /* skip ':' and blanks*/ 17257 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 17258 ; 17259 17260 /* Check for "endfunction". */ 17261 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 17262 { 17263 vim_free(theline); 17264 break; 17265 } 17266 17267 /* Increase indent inside "if", "while", "for" and "try", decrease 17268 * at "end". */ 17269 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 17270 indent -= 2; 17271 else if (STRNCMP(p, "if", 2) == 0 17272 || STRNCMP(p, "wh", 2) == 0 17273 || STRNCMP(p, "for", 3) == 0 17274 || STRNCMP(p, "try", 3) == 0) 17275 indent += 2; 17276 17277 /* Check for defining a function inside this function. */ 17278 if (checkforcmd(&p, "function", 2)) 17279 { 17280 if (*p == '!') 17281 p = skipwhite(p + 1); 17282 p += eval_fname_script(p); 17283 if (ASCII_ISALPHA(*p)) 17284 { 17285 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 17286 if (*skipwhite(p) == '(') 17287 { 17288 ++nesting; 17289 indent += 2; 17290 } 17291 } 17292 } 17293 17294 /* Check for ":append" or ":insert". */ 17295 p = skip_range(p, NULL); 17296 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 17297 || (p[0] == 'i' 17298 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 17299 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 17300 skip_until = vim_strsave((char_u *)"."); 17301 17302 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17303 arg = skipwhite(skiptowhite(p)); 17304 if (arg[0] == '<' && arg[1] =='<' 17305 && ((p[0] == 'p' && p[1] == 'y' 17306 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17307 || (p[0] == 'p' && p[1] == 'e' 17308 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17309 || (p[0] == 't' && p[1] == 'c' 17310 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17311 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17312 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17313 || (p[0] == 'm' && p[1] == 'z' 17314 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17315 )) 17316 { 17317 /* ":python <<" continues until a dot, like ":append" */ 17318 p = skipwhite(arg + 2); 17319 if (*p == NUL) 17320 skip_until = vim_strsave((char_u *)"."); 17321 else 17322 skip_until = vim_strsave(p); 17323 } 17324 } 17325 17326 /* Add the line to the function. */ 17327 if (ga_grow(&newlines, 1) == FAIL) 17328 { 17329 vim_free(theline); 17330 goto erret; 17331 } 17332 17333 /* Copy the line to newly allocated memory. get_one_sourceline() 17334 * allocates 250 bytes per line, this saves 80% on average. The cost 17335 * is an extra alloc/free. */ 17336 p = vim_strsave(theline); 17337 if (p != NULL) 17338 { 17339 vim_free(theline); 17340 theline = p; 17341 } 17342 17343 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17344 newlines.ga_len++; 17345 } 17346 17347 /* Don't define the function when skipping commands or when an error was 17348 * detected. */ 17349 if (eap->skip || did_emsg) 17350 goto erret; 17351 17352 /* 17353 * If there are no errors, add the function 17354 */ 17355 if (fudi.fd_dict == NULL) 17356 { 17357 v = find_var(name, &ht); 17358 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17359 { 17360 emsg_funcname("E707: Function name conflicts with variable: %s", 17361 name); 17362 goto erret; 17363 } 17364 17365 fp = find_func(name); 17366 if (fp != NULL) 17367 { 17368 if (!eap->forceit) 17369 { 17370 emsg_funcname(e_funcexts, name); 17371 goto erret; 17372 } 17373 if (fp->uf_calls > 0) 17374 { 17375 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17376 name); 17377 goto erret; 17378 } 17379 /* redefine existing function */ 17380 ga_clear_strings(&(fp->uf_args)); 17381 ga_clear_strings(&(fp->uf_lines)); 17382 vim_free(name); 17383 name = NULL; 17384 } 17385 } 17386 else 17387 { 17388 char numbuf[20]; 17389 17390 fp = NULL; 17391 if (fudi.fd_newkey == NULL && !eap->forceit) 17392 { 17393 EMSG(_(e_funcdict)); 17394 goto erret; 17395 } 17396 if (fudi.fd_di == NULL) 17397 { 17398 /* Can't add a function to a locked dictionary */ 17399 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17400 goto erret; 17401 } 17402 /* Can't change an existing function if it is locked */ 17403 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17404 goto erret; 17405 17406 /* Give the function a sequential number. Can only be used with a 17407 * Funcref! */ 17408 vim_free(name); 17409 sprintf(numbuf, "%d", ++func_nr); 17410 name = vim_strsave((char_u *)numbuf); 17411 if (name == NULL) 17412 goto erret; 17413 } 17414 17415 if (fp == NULL) 17416 { 17417 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17418 { 17419 int slen, plen; 17420 char_u *scriptname; 17421 17422 /* Check that the autoload name matches the script name. */ 17423 j = FAIL; 17424 if (sourcing_name != NULL) 17425 { 17426 scriptname = autoload_name(name); 17427 if (scriptname != NULL) 17428 { 17429 p = vim_strchr(scriptname, '/'); 17430 plen = STRLEN(p); 17431 slen = STRLEN(sourcing_name); 17432 if (slen > plen && fnamecmp(p, 17433 sourcing_name + slen - plen) == 0) 17434 j = OK; 17435 vim_free(scriptname); 17436 } 17437 } 17438 if (j == FAIL) 17439 { 17440 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17441 goto erret; 17442 } 17443 } 17444 17445 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17446 if (fp == NULL) 17447 goto erret; 17448 17449 if (fudi.fd_dict != NULL) 17450 { 17451 if (fudi.fd_di == NULL) 17452 { 17453 /* add new dict entry */ 17454 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17455 if (fudi.fd_di == NULL) 17456 { 17457 vim_free(fp); 17458 goto erret; 17459 } 17460 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17461 { 17462 vim_free(fudi.fd_di); 17463 goto erret; 17464 } 17465 } 17466 else 17467 /* overwrite existing dict entry */ 17468 clear_tv(&fudi.fd_di->di_tv); 17469 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17470 fudi.fd_di->di_tv.v_lock = 0; 17471 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17472 fp->uf_refcount = 1; 17473 } 17474 17475 /* insert the new function in the function list */ 17476 STRCPY(fp->uf_name, name); 17477 hash_add(&func_hashtab, UF2HIKEY(fp)); 17478 } 17479 fp->uf_args = newargs; 17480 fp->uf_lines = newlines; 17481 #ifdef FEAT_PROFILE 17482 fp->uf_tml_count = NULL; 17483 fp->uf_tml_total = NULL; 17484 fp->uf_tml_self = NULL; 17485 fp->uf_profiling = FALSE; 17486 if (prof_def_func()) 17487 func_do_profile(fp); 17488 #endif 17489 fp->uf_varargs = varargs; 17490 fp->uf_flags = flags; 17491 fp->uf_calls = 0; 17492 fp->uf_script_ID = current_SID; 17493 goto ret_free; 17494 17495 erret: 17496 ga_clear_strings(&newargs); 17497 ga_clear_strings(&newlines); 17498 ret_free: 17499 vim_free(skip_until); 17500 vim_free(fudi.fd_newkey); 17501 vim_free(name); 17502 did_emsg |= saved_did_emsg; 17503 } 17504 17505 /* 17506 * Get a function name, translating "<SID>" and "<SNR>". 17507 * Also handles a Funcref in a List or Dictionary. 17508 * Returns the function name in allocated memory, or NULL for failure. 17509 * flags: 17510 * TFN_INT: internal function name OK 17511 * TFN_QUIET: be quiet 17512 * Advances "pp" to just after the function name (if no error). 17513 */ 17514 static char_u * 17515 trans_function_name(pp, skip, flags, fdp) 17516 char_u **pp; 17517 int skip; /* only find the end, don't evaluate */ 17518 int flags; 17519 funcdict_T *fdp; /* return: info about dictionary used */ 17520 { 17521 char_u *name = NULL; 17522 char_u *start; 17523 char_u *end; 17524 int lead; 17525 char_u sid_buf[20]; 17526 int len; 17527 lval_T lv; 17528 17529 if (fdp != NULL) 17530 vim_memset(fdp, 0, sizeof(funcdict_T)); 17531 start = *pp; 17532 17533 /* Check for hard coded <SNR>: already translated function ID (from a user 17534 * command). */ 17535 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17536 && (*pp)[2] == (int)KE_SNR) 17537 { 17538 *pp += 3; 17539 len = get_id_len(pp) + 3; 17540 return vim_strnsave(start, len); 17541 } 17542 17543 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17544 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17545 lead = eval_fname_script(start); 17546 if (lead > 2) 17547 start += lead; 17548 17549 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17550 lead > 2 ? 0 : FNE_CHECK_START); 17551 if (end == start) 17552 { 17553 if (!skip) 17554 EMSG(_("E129: Function name required")); 17555 goto theend; 17556 } 17557 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17558 { 17559 /* 17560 * Report an invalid expression in braces, unless the expression 17561 * evaluation has been cancelled due to an aborting error, an 17562 * interrupt, or an exception. 17563 */ 17564 if (!aborting()) 17565 { 17566 if (end != NULL) 17567 EMSG2(_(e_invarg2), start); 17568 } 17569 else 17570 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17571 goto theend; 17572 } 17573 17574 if (lv.ll_tv != NULL) 17575 { 17576 if (fdp != NULL) 17577 { 17578 fdp->fd_dict = lv.ll_dict; 17579 fdp->fd_newkey = lv.ll_newkey; 17580 lv.ll_newkey = NULL; 17581 fdp->fd_di = lv.ll_di; 17582 } 17583 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17584 { 17585 name = vim_strsave(lv.ll_tv->vval.v_string); 17586 *pp = end; 17587 } 17588 else 17589 { 17590 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17591 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17592 EMSG(_(e_funcref)); 17593 else 17594 *pp = end; 17595 name = NULL; 17596 } 17597 goto theend; 17598 } 17599 17600 if (lv.ll_name == NULL) 17601 { 17602 /* Error found, but continue after the function name. */ 17603 *pp = end; 17604 goto theend; 17605 } 17606 17607 if (lv.ll_exp_name != NULL) 17608 len = STRLEN(lv.ll_exp_name); 17609 else 17610 { 17611 if (lead == 2) /* skip over "s:" */ 17612 lv.ll_name += 2; 17613 len = (int)(end - lv.ll_name); 17614 } 17615 17616 /* 17617 * Copy the function name to allocated memory. 17618 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17619 * Accept <SNR>123_name() outside a script. 17620 */ 17621 if (skip) 17622 lead = 0; /* do nothing */ 17623 else if (lead > 0) 17624 { 17625 lead = 3; 17626 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17627 { 17628 if (current_SID <= 0) 17629 { 17630 EMSG(_(e_usingsid)); 17631 goto theend; 17632 } 17633 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17634 lead += (int)STRLEN(sid_buf); 17635 } 17636 } 17637 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17638 { 17639 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17640 goto theend; 17641 } 17642 name = alloc((unsigned)(len + lead + 1)); 17643 if (name != NULL) 17644 { 17645 if (lead > 0) 17646 { 17647 name[0] = K_SPECIAL; 17648 name[1] = KS_EXTRA; 17649 name[2] = (int)KE_SNR; 17650 if (lead > 3) /* If it's "<SID>" */ 17651 STRCPY(name + 3, sid_buf); 17652 } 17653 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17654 name[len + lead] = NUL; 17655 } 17656 *pp = end; 17657 17658 theend: 17659 clear_lval(&lv); 17660 return name; 17661 } 17662 17663 /* 17664 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17665 * Return 2 if "p" starts with "s:". 17666 * Return 0 otherwise. 17667 */ 17668 static int 17669 eval_fname_script(p) 17670 char_u *p; 17671 { 17672 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17673 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17674 return 5; 17675 if (p[0] == 's' && p[1] == ':') 17676 return 2; 17677 return 0; 17678 } 17679 17680 /* 17681 * Return TRUE if "p" starts with "<SID>" or "s:". 17682 * Only works if eval_fname_script() returned non-zero for "p"! 17683 */ 17684 static int 17685 eval_fname_sid(p) 17686 char_u *p; 17687 { 17688 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17689 } 17690 17691 /* 17692 * List the head of the function: "name(arg1, arg2)". 17693 */ 17694 static void 17695 list_func_head(fp, indent) 17696 ufunc_T *fp; 17697 int indent; 17698 { 17699 int j; 17700 17701 msg_start(); 17702 if (indent) 17703 MSG_PUTS(" "); 17704 MSG_PUTS("function "); 17705 if (fp->uf_name[0] == K_SPECIAL) 17706 { 17707 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17708 msg_puts(fp->uf_name + 3); 17709 } 17710 else 17711 msg_puts(fp->uf_name); 17712 msg_putchar('('); 17713 for (j = 0; j < fp->uf_args.ga_len; ++j) 17714 { 17715 if (j) 17716 MSG_PUTS(", "); 17717 msg_puts(FUNCARG(fp, j)); 17718 } 17719 if (fp->uf_varargs) 17720 { 17721 if (j) 17722 MSG_PUTS(", "); 17723 MSG_PUTS("..."); 17724 } 17725 msg_putchar(')'); 17726 msg_clr_eos(); 17727 if (p_verbose > 0) 17728 last_set_msg(fp->uf_script_ID); 17729 } 17730 17731 /* 17732 * Find a function by name, return pointer to it in ufuncs. 17733 * Return NULL for unknown function. 17734 */ 17735 static ufunc_T * 17736 find_func(name) 17737 char_u *name; 17738 { 17739 hashitem_T *hi; 17740 17741 hi = hash_find(&func_hashtab, name); 17742 if (!HASHITEM_EMPTY(hi)) 17743 return HI2UF(hi); 17744 return NULL; 17745 } 17746 17747 #if defined(EXITFREE) || defined(PROTO) 17748 void 17749 free_all_functions() 17750 { 17751 hashitem_T *hi; 17752 17753 /* Need to start all over every time, because func_free() may change the 17754 * hash table. */ 17755 while (func_hashtab.ht_used > 0) 17756 for (hi = func_hashtab.ht_array; ; ++hi) 17757 if (!HASHITEM_EMPTY(hi)) 17758 { 17759 func_free(HI2UF(hi)); 17760 break; 17761 } 17762 } 17763 #endif 17764 17765 /* 17766 * Return TRUE if a function "name" exists. 17767 */ 17768 static int 17769 function_exists(name) 17770 char_u *name; 17771 { 17772 char_u *p = name; 17773 int n = FALSE; 17774 17775 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17776 if (p != NULL) 17777 { 17778 if (builtin_function(p)) 17779 n = (find_internal_func(p) >= 0); 17780 else 17781 n = (find_func(p) != NULL); 17782 vim_free(p); 17783 } 17784 return n; 17785 } 17786 17787 /* 17788 * Return TRUE if "name" looks like a builtin function name: starts with a 17789 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17790 */ 17791 static int 17792 builtin_function(name) 17793 char_u *name; 17794 { 17795 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17796 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17797 } 17798 17799 #if defined(FEAT_PROFILE) || defined(PROTO) 17800 /* 17801 * Start profiling function "fp". 17802 */ 17803 static void 17804 func_do_profile(fp) 17805 ufunc_T *fp; 17806 { 17807 fp->uf_tm_count = 0; 17808 profile_zero(&fp->uf_tm_self); 17809 profile_zero(&fp->uf_tm_total); 17810 if (fp->uf_tml_count == NULL) 17811 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17812 (sizeof(int) * fp->uf_lines.ga_len)); 17813 if (fp->uf_tml_total == NULL) 17814 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17815 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17816 if (fp->uf_tml_self == NULL) 17817 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17818 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17819 fp->uf_tml_idx = -1; 17820 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17821 || fp->uf_tml_self == NULL) 17822 return; /* out of memory */ 17823 17824 fp->uf_profiling = TRUE; 17825 } 17826 17827 /* 17828 * Dump the profiling results for all functions in file "fd". 17829 */ 17830 void 17831 func_dump_profile(fd) 17832 FILE *fd; 17833 { 17834 hashitem_T *hi; 17835 int todo; 17836 ufunc_T *fp; 17837 int i; 17838 ufunc_T **sorttab; 17839 int st_len = 0; 17840 17841 todo = func_hashtab.ht_used; 17842 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17843 17844 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17845 { 17846 if (!HASHITEM_EMPTY(hi)) 17847 { 17848 --todo; 17849 fp = HI2UF(hi); 17850 if (fp->uf_profiling) 17851 { 17852 if (sorttab != NULL) 17853 sorttab[st_len++] = fp; 17854 17855 if (fp->uf_name[0] == K_SPECIAL) 17856 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17857 else 17858 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17859 if (fp->uf_tm_count == 1) 17860 fprintf(fd, "Called 1 time\n"); 17861 else 17862 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17863 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17864 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17865 fprintf(fd, "\n"); 17866 fprintf(fd, "count total (s) self (s)\n"); 17867 17868 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17869 { 17870 prof_func_line(fd, fp->uf_tml_count[i], 17871 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17872 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17873 } 17874 fprintf(fd, "\n"); 17875 } 17876 } 17877 } 17878 17879 if (sorttab != NULL && st_len > 0) 17880 { 17881 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17882 prof_total_cmp); 17883 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17884 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17885 prof_self_cmp); 17886 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17887 } 17888 } 17889 17890 static void 17891 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17892 FILE *fd; 17893 ufunc_T **sorttab; 17894 int st_len; 17895 char *title; 17896 int prefer_self; /* when equal print only self time */ 17897 { 17898 int i; 17899 ufunc_T *fp; 17900 17901 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17902 fprintf(fd, "count total (s) self (s) function\n"); 17903 for (i = 0; i < 20 && i < st_len; ++i) 17904 { 17905 fp = sorttab[i]; 17906 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17907 prefer_self); 17908 if (fp->uf_name[0] == K_SPECIAL) 17909 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17910 else 17911 fprintf(fd, " %s()\n", fp->uf_name); 17912 } 17913 fprintf(fd, "\n"); 17914 } 17915 17916 /* 17917 * Print the count and times for one function or function line. 17918 */ 17919 static void 17920 prof_func_line(fd, count, total, self, prefer_self) 17921 FILE *fd; 17922 int count; 17923 proftime_T *total; 17924 proftime_T *self; 17925 int prefer_self; /* when equal print only self time */ 17926 { 17927 if (count > 0) 17928 { 17929 fprintf(fd, "%5d ", count); 17930 if (prefer_self && profile_equal(total, self)) 17931 fprintf(fd, " "); 17932 else 17933 fprintf(fd, "%s ", profile_msg(total)); 17934 if (!prefer_self && profile_equal(total, self)) 17935 fprintf(fd, " "); 17936 else 17937 fprintf(fd, "%s ", profile_msg(self)); 17938 } 17939 else 17940 fprintf(fd, " "); 17941 } 17942 17943 /* 17944 * Compare function for total time sorting. 17945 */ 17946 static int 17947 #ifdef __BORLANDC__ 17948 _RTLENTRYF 17949 #endif 17950 prof_total_cmp(s1, s2) 17951 const void *s1; 17952 const void *s2; 17953 { 17954 ufunc_T *p1, *p2; 17955 17956 p1 = *(ufunc_T **)s1; 17957 p2 = *(ufunc_T **)s2; 17958 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17959 } 17960 17961 /* 17962 * Compare function for self time sorting. 17963 */ 17964 static int 17965 #ifdef __BORLANDC__ 17966 _RTLENTRYF 17967 #endif 17968 prof_self_cmp(s1, s2) 17969 const void *s1; 17970 const void *s2; 17971 { 17972 ufunc_T *p1, *p2; 17973 17974 p1 = *(ufunc_T **)s1; 17975 p2 = *(ufunc_T **)s2; 17976 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17977 } 17978 17979 #endif 17980 17981 /* The names of packages that once were loaded is remembered. */ 17982 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17983 17984 /* 17985 * If "name" has a package name try autoloading the script for it. 17986 * Return TRUE if a package was loaded. 17987 */ 17988 static int 17989 script_autoload(name, reload) 17990 char_u *name; 17991 int reload; /* load script again when already loaded */ 17992 { 17993 char_u *p; 17994 char_u *scriptname, *tofree; 17995 int ret = FALSE; 17996 int i; 17997 17998 /* If there is no '#' after name[0] there is no package name. */ 17999 p = vim_strchr(name, AUTOLOAD_CHAR); 18000 if (p == NULL || p == name) 18001 return FALSE; 18002 18003 tofree = scriptname = autoload_name(name); 18004 18005 /* Find the name in the list of previously loaded package names. Skip 18006 * "autoload/", it's always the same. */ 18007 for (i = 0; i < ga_loaded.ga_len; ++i) 18008 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 18009 break; 18010 if (!reload && i < ga_loaded.ga_len) 18011 ret = FALSE; /* was loaded already */ 18012 else 18013 { 18014 /* Remember the name if it wasn't loaded already. */ 18015 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 18016 { 18017 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 18018 tofree = NULL; 18019 } 18020 18021 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 18022 if (source_runtime(scriptname, FALSE) == OK) 18023 ret = TRUE; 18024 } 18025 18026 vim_free(tofree); 18027 return ret; 18028 } 18029 18030 /* 18031 * Return the autoload script name for a function or variable name. 18032 * Returns NULL when out of memory. 18033 */ 18034 static char_u * 18035 autoload_name(name) 18036 char_u *name; 18037 { 18038 char_u *p; 18039 char_u *scriptname; 18040 18041 /* Get the script file name: replace '#' with '/', append ".vim". */ 18042 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 18043 if (scriptname == NULL) 18044 return FALSE; 18045 STRCPY(scriptname, "autoload/"); 18046 STRCAT(scriptname, name); 18047 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 18048 STRCAT(scriptname, ".vim"); 18049 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 18050 *p = '/'; 18051 return scriptname; 18052 } 18053 18054 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 18055 18056 /* 18057 * Function given to ExpandGeneric() to obtain the list of user defined 18058 * function names. 18059 */ 18060 char_u * 18061 get_user_func_name(xp, idx) 18062 expand_T *xp; 18063 int idx; 18064 { 18065 static long_u done; 18066 static hashitem_T *hi; 18067 ufunc_T *fp; 18068 18069 if (idx == 0) 18070 { 18071 done = 0; 18072 hi = func_hashtab.ht_array; 18073 } 18074 if (done < func_hashtab.ht_used) 18075 { 18076 if (done++ > 0) 18077 ++hi; 18078 while (HASHITEM_EMPTY(hi)) 18079 ++hi; 18080 fp = HI2UF(hi); 18081 18082 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 18083 return fp->uf_name; /* prevents overflow */ 18084 18085 cat_func_name(IObuff, fp); 18086 if (xp->xp_context != EXPAND_USER_FUNC) 18087 { 18088 STRCAT(IObuff, "("); 18089 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 18090 STRCAT(IObuff, ")"); 18091 } 18092 return IObuff; 18093 } 18094 return NULL; 18095 } 18096 18097 #endif /* FEAT_CMDL_COMPL */ 18098 18099 /* 18100 * Copy the function name of "fp" to buffer "buf". 18101 * "buf" must be able to hold the function name plus three bytes. 18102 * Takes care of script-local function names. 18103 */ 18104 static void 18105 cat_func_name(buf, fp) 18106 char_u *buf; 18107 ufunc_T *fp; 18108 { 18109 if (fp->uf_name[0] == K_SPECIAL) 18110 { 18111 STRCPY(buf, "<SNR>"); 18112 STRCAT(buf, fp->uf_name + 3); 18113 } 18114 else 18115 STRCPY(buf, fp->uf_name); 18116 } 18117 18118 /* 18119 * ":delfunction {name}" 18120 */ 18121 void 18122 ex_delfunction(eap) 18123 exarg_T *eap; 18124 { 18125 ufunc_T *fp = NULL; 18126 char_u *p; 18127 char_u *name; 18128 funcdict_T fudi; 18129 18130 p = eap->arg; 18131 name = trans_function_name(&p, eap->skip, 0, &fudi); 18132 vim_free(fudi.fd_newkey); 18133 if (name == NULL) 18134 { 18135 if (fudi.fd_dict != NULL && !eap->skip) 18136 EMSG(_(e_funcref)); 18137 return; 18138 } 18139 if (!ends_excmd(*skipwhite(p))) 18140 { 18141 vim_free(name); 18142 EMSG(_(e_trailing)); 18143 return; 18144 } 18145 eap->nextcmd = check_nextcmd(p); 18146 if (eap->nextcmd != NULL) 18147 *p = NUL; 18148 18149 if (!eap->skip) 18150 fp = find_func(name); 18151 vim_free(name); 18152 18153 if (!eap->skip) 18154 { 18155 if (fp == NULL) 18156 { 18157 EMSG2(_(e_nofunc), eap->arg); 18158 return; 18159 } 18160 if (fp->uf_calls > 0) 18161 { 18162 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 18163 return; 18164 } 18165 18166 if (fudi.fd_dict != NULL) 18167 { 18168 /* Delete the dict item that refers to the function, it will 18169 * invoke func_unref() and possibly delete the function. */ 18170 dictitem_remove(fudi.fd_dict, fudi.fd_di); 18171 } 18172 else 18173 func_free(fp); 18174 } 18175 } 18176 18177 /* 18178 * Free a function and remove it from the list of functions. 18179 */ 18180 static void 18181 func_free(fp) 18182 ufunc_T *fp; 18183 { 18184 hashitem_T *hi; 18185 18186 /* clear this function */ 18187 ga_clear_strings(&(fp->uf_args)); 18188 ga_clear_strings(&(fp->uf_lines)); 18189 #ifdef FEAT_PROFILE 18190 vim_free(fp->uf_tml_count); 18191 vim_free(fp->uf_tml_total); 18192 vim_free(fp->uf_tml_self); 18193 #endif 18194 18195 /* remove the function from the function hashtable */ 18196 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 18197 if (HASHITEM_EMPTY(hi)) 18198 EMSG2(_(e_intern2), "func_free()"); 18199 else 18200 hash_remove(&func_hashtab, hi); 18201 18202 vim_free(fp); 18203 } 18204 18205 /* 18206 * Unreference a Function: decrement the reference count and free it when it 18207 * becomes zero. Only for numbered functions. 18208 */ 18209 static void 18210 func_unref(name) 18211 char_u *name; 18212 { 18213 ufunc_T *fp; 18214 18215 if (name != NULL && isdigit(*name)) 18216 { 18217 fp = find_func(name); 18218 if (fp == NULL) 18219 EMSG2(_(e_intern2), "func_unref()"); 18220 else if (--fp->uf_refcount <= 0) 18221 { 18222 /* Only delete it when it's not being used. Otherwise it's done 18223 * when "uf_calls" becomes zero. */ 18224 if (fp->uf_calls == 0) 18225 func_free(fp); 18226 } 18227 } 18228 } 18229 18230 /* 18231 * Count a reference to a Function. 18232 */ 18233 static void 18234 func_ref(name) 18235 char_u *name; 18236 { 18237 ufunc_T *fp; 18238 18239 if (name != NULL && isdigit(*name)) 18240 { 18241 fp = find_func(name); 18242 if (fp == NULL) 18243 EMSG2(_(e_intern2), "func_ref()"); 18244 else 18245 ++fp->uf_refcount; 18246 } 18247 } 18248 18249 /* 18250 * Call a user function. 18251 */ 18252 static void 18253 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 18254 ufunc_T *fp; /* pointer to function */ 18255 int argcount; /* nr of args */ 18256 typval_T *argvars; /* arguments */ 18257 typval_T *rettv; /* return value */ 18258 linenr_T firstline; /* first line of range */ 18259 linenr_T lastline; /* last line of range */ 18260 dict_T *selfdict; /* Dictionary for "self" */ 18261 { 18262 char_u *save_sourcing_name; 18263 linenr_T save_sourcing_lnum; 18264 scid_T save_current_SID; 18265 funccall_T fc; 18266 int save_did_emsg; 18267 static int depth = 0; 18268 dictitem_T *v; 18269 int fixvar_idx = 0; /* index in fixvar[] */ 18270 int i; 18271 int ai; 18272 char_u numbuf[NUMBUFLEN]; 18273 char_u *name; 18274 #ifdef FEAT_PROFILE 18275 proftime_T wait_start; 18276 #endif 18277 18278 /* If depth of calling is getting too high, don't execute the function */ 18279 if (depth >= p_mfd) 18280 { 18281 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 18282 rettv->v_type = VAR_NUMBER; 18283 rettv->vval.v_number = -1; 18284 return; 18285 } 18286 ++depth; 18287 18288 line_breakcheck(); /* check for CTRL-C hit */ 18289 18290 fc.caller = current_funccal; 18291 current_funccal = &fc; 18292 fc.func = fp; 18293 fc.rettv = rettv; 18294 rettv->vval.v_number = 0; 18295 fc.linenr = 0; 18296 fc.returned = FALSE; 18297 fc.level = ex_nesting_level; 18298 /* Check if this function has a breakpoint. */ 18299 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 18300 fc.dbg_tick = debug_tick; 18301 18302 /* 18303 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 18304 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 18305 * each argument variable and saves a lot of time. 18306 */ 18307 /* 18308 * Init l: variables. 18309 */ 18310 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18311 if (selfdict != NULL) 18312 { 18313 /* Set l:self to "selfdict". */ 18314 v = &fc.fixvar[fixvar_idx++].var; 18315 STRCPY(v->di_key, "self"); 18316 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18317 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18318 v->di_tv.v_type = VAR_DICT; 18319 v->di_tv.v_lock = 0; 18320 v->di_tv.vval.v_dict = selfdict; 18321 ++selfdict->dv_refcount; 18322 } 18323 18324 /* 18325 * Init a: variables. 18326 * Set a:0 to "argcount". 18327 * Set a:000 to a list with room for the "..." arguments. 18328 */ 18329 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18330 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18331 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18332 v = &fc.fixvar[fixvar_idx++].var; 18333 STRCPY(v->di_key, "000"); 18334 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18335 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18336 v->di_tv.v_type = VAR_LIST; 18337 v->di_tv.v_lock = VAR_FIXED; 18338 v->di_tv.vval.v_list = &fc.l_varlist; 18339 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18340 fc.l_varlist.lv_refcount = 99999; 18341 18342 /* 18343 * Set a:firstline to "firstline" and a:lastline to "lastline". 18344 * Set a:name to named arguments. 18345 * Set a:N to the "..." arguments. 18346 */ 18347 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18348 (varnumber_T)firstline); 18349 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18350 (varnumber_T)lastline); 18351 for (i = 0; i < argcount; ++i) 18352 { 18353 ai = i - fp->uf_args.ga_len; 18354 if (ai < 0) 18355 /* named argument a:name */ 18356 name = FUNCARG(fp, i); 18357 else 18358 { 18359 /* "..." argument a:1, a:2, etc. */ 18360 sprintf((char *)numbuf, "%d", ai + 1); 18361 name = numbuf; 18362 } 18363 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18364 { 18365 v = &fc.fixvar[fixvar_idx++].var; 18366 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18367 } 18368 else 18369 { 18370 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18371 + STRLEN(name))); 18372 if (v == NULL) 18373 break; 18374 v->di_flags = DI_FLAGS_RO; 18375 } 18376 STRCPY(v->di_key, name); 18377 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18378 18379 /* Note: the values are copied directly to avoid alloc/free. 18380 * "argvars" must have VAR_FIXED for v_lock. */ 18381 v->di_tv = argvars[i]; 18382 v->di_tv.v_lock = VAR_FIXED; 18383 18384 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18385 { 18386 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18387 fc.l_listitems[ai].li_tv = argvars[i]; 18388 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18389 } 18390 } 18391 18392 /* Don't redraw while executing the function. */ 18393 ++RedrawingDisabled; 18394 save_sourcing_name = sourcing_name; 18395 save_sourcing_lnum = sourcing_lnum; 18396 sourcing_lnum = 1; 18397 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18398 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18399 if (sourcing_name != NULL) 18400 { 18401 if (save_sourcing_name != NULL 18402 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18403 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18404 else 18405 STRCPY(sourcing_name, "function "); 18406 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18407 18408 if (p_verbose >= 12) 18409 { 18410 ++no_wait_return; 18411 verbose_enter_scroll(); 18412 18413 smsg((char_u *)_("calling %s"), sourcing_name); 18414 if (p_verbose >= 14) 18415 { 18416 char_u buf[MSG_BUF_LEN]; 18417 char_u numbuf[NUMBUFLEN]; 18418 char_u *tofree; 18419 18420 msg_puts((char_u *)"("); 18421 for (i = 0; i < argcount; ++i) 18422 { 18423 if (i > 0) 18424 msg_puts((char_u *)", "); 18425 if (argvars[i].v_type == VAR_NUMBER) 18426 msg_outnum((long)argvars[i].vval.v_number); 18427 else 18428 { 18429 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18430 buf, MSG_BUF_CLEN); 18431 msg_puts(buf); 18432 vim_free(tofree); 18433 } 18434 } 18435 msg_puts((char_u *)")"); 18436 } 18437 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18438 18439 verbose_leave_scroll(); 18440 --no_wait_return; 18441 } 18442 } 18443 #ifdef FEAT_PROFILE 18444 if (do_profiling) 18445 { 18446 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18447 func_do_profile(fp); 18448 if (fp->uf_profiling 18449 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18450 { 18451 ++fp->uf_tm_count; 18452 profile_start(&fp->uf_tm_start); 18453 profile_zero(&fp->uf_tm_children); 18454 } 18455 script_prof_save(&wait_start); 18456 } 18457 #endif 18458 18459 save_current_SID = current_SID; 18460 current_SID = fp->uf_script_ID; 18461 save_did_emsg = did_emsg; 18462 did_emsg = FALSE; 18463 18464 /* call do_cmdline() to execute the lines */ 18465 do_cmdline(NULL, get_func_line, (void *)&fc, 18466 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18467 18468 --RedrawingDisabled; 18469 18470 /* when the function was aborted because of an error, return -1 */ 18471 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18472 { 18473 clear_tv(rettv); 18474 rettv->v_type = VAR_NUMBER; 18475 rettv->vval.v_number = -1; 18476 } 18477 18478 #ifdef FEAT_PROFILE 18479 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18480 { 18481 profile_end(&fp->uf_tm_start); 18482 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18483 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18484 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18485 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18486 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18487 { 18488 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18489 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18490 } 18491 } 18492 #endif 18493 18494 /* when being verbose, mention the return value */ 18495 if (p_verbose >= 12) 18496 { 18497 ++no_wait_return; 18498 verbose_enter_scroll(); 18499 18500 if (aborting()) 18501 smsg((char_u *)_("%s aborted"), sourcing_name); 18502 else if (fc.rettv->v_type == VAR_NUMBER) 18503 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18504 (long)fc.rettv->vval.v_number); 18505 else 18506 { 18507 char_u buf[MSG_BUF_LEN]; 18508 char_u numbuf[NUMBUFLEN]; 18509 char_u *tofree; 18510 18511 /* The value may be very long. Skip the middle part, so that we 18512 * have some idea how it starts and ends. smsg() would always 18513 * truncate it at the end. */ 18514 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18515 buf, MSG_BUF_CLEN); 18516 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18517 vim_free(tofree); 18518 } 18519 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18520 18521 verbose_leave_scroll(); 18522 --no_wait_return; 18523 } 18524 18525 vim_free(sourcing_name); 18526 sourcing_name = save_sourcing_name; 18527 sourcing_lnum = save_sourcing_lnum; 18528 current_SID = save_current_SID; 18529 #ifdef FEAT_PROFILE 18530 if (do_profiling) 18531 script_prof_restore(&wait_start); 18532 #endif 18533 18534 if (p_verbose >= 12 && sourcing_name != NULL) 18535 { 18536 ++no_wait_return; 18537 verbose_enter_scroll(); 18538 18539 smsg((char_u *)_("continuing in %s"), sourcing_name); 18540 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18541 18542 verbose_leave_scroll(); 18543 --no_wait_return; 18544 } 18545 18546 did_emsg |= save_did_emsg; 18547 current_funccal = fc.caller; 18548 18549 /* The a: variables typevals were not alloced, only free the allocated 18550 * variables. */ 18551 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18552 18553 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18554 --depth; 18555 } 18556 18557 /* 18558 * Add a number variable "name" to dict "dp" with value "nr". 18559 */ 18560 static void 18561 add_nr_var(dp, v, name, nr) 18562 dict_T *dp; 18563 dictitem_T *v; 18564 char *name; 18565 varnumber_T nr; 18566 { 18567 STRCPY(v->di_key, name); 18568 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18569 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18570 v->di_tv.v_type = VAR_NUMBER; 18571 v->di_tv.v_lock = VAR_FIXED; 18572 v->di_tv.vval.v_number = nr; 18573 } 18574 18575 /* 18576 * ":return [expr]" 18577 */ 18578 void 18579 ex_return(eap) 18580 exarg_T *eap; 18581 { 18582 char_u *arg = eap->arg; 18583 typval_T rettv; 18584 int returning = FALSE; 18585 18586 if (current_funccal == NULL) 18587 { 18588 EMSG(_("E133: :return not inside a function")); 18589 return; 18590 } 18591 18592 if (eap->skip) 18593 ++emsg_skip; 18594 18595 eap->nextcmd = NULL; 18596 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18597 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18598 { 18599 if (!eap->skip) 18600 returning = do_return(eap, FALSE, TRUE, &rettv); 18601 else 18602 clear_tv(&rettv); 18603 } 18604 /* It's safer to return also on error. */ 18605 else if (!eap->skip) 18606 { 18607 /* 18608 * Return unless the expression evaluation has been cancelled due to an 18609 * aborting error, an interrupt, or an exception. 18610 */ 18611 if (!aborting()) 18612 returning = do_return(eap, FALSE, TRUE, NULL); 18613 } 18614 18615 /* When skipping or the return gets pending, advance to the next command 18616 * in this line (!returning). Otherwise, ignore the rest of the line. 18617 * Following lines will be ignored by get_func_line(). */ 18618 if (returning) 18619 eap->nextcmd = NULL; 18620 else if (eap->nextcmd == NULL) /* no argument */ 18621 eap->nextcmd = check_nextcmd(arg); 18622 18623 if (eap->skip) 18624 --emsg_skip; 18625 } 18626 18627 /* 18628 * Return from a function. Possibly makes the return pending. Also called 18629 * for a pending return at the ":endtry" or after returning from an extra 18630 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18631 * when called due to a ":return" command. "rettv" may point to a typval_T 18632 * with the return rettv. Returns TRUE when the return can be carried out, 18633 * FALSE when the return gets pending. 18634 */ 18635 int 18636 do_return(eap, reanimate, is_cmd, rettv) 18637 exarg_T *eap; 18638 int reanimate; 18639 int is_cmd; 18640 void *rettv; 18641 { 18642 int idx; 18643 struct condstack *cstack = eap->cstack; 18644 18645 if (reanimate) 18646 /* Undo the return. */ 18647 current_funccal->returned = FALSE; 18648 18649 /* 18650 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18651 * not in its finally clause (which then is to be executed next) is found. 18652 * In this case, make the ":return" pending for execution at the ":endtry". 18653 * Otherwise, return normally. 18654 */ 18655 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18656 if (idx >= 0) 18657 { 18658 cstack->cs_pending[idx] = CSTP_RETURN; 18659 18660 if (!is_cmd && !reanimate) 18661 /* A pending return again gets pending. "rettv" points to an 18662 * allocated variable with the rettv of the original ":return"'s 18663 * argument if present or is NULL else. */ 18664 cstack->cs_rettv[idx] = rettv; 18665 else 18666 { 18667 /* When undoing a return in order to make it pending, get the stored 18668 * return rettv. */ 18669 if (reanimate) 18670 rettv = current_funccal->rettv; 18671 18672 if (rettv != NULL) 18673 { 18674 /* Store the value of the pending return. */ 18675 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18676 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18677 else 18678 EMSG(_(e_outofmem)); 18679 } 18680 else 18681 cstack->cs_rettv[idx] = NULL; 18682 18683 if (reanimate) 18684 { 18685 /* The pending return value could be overwritten by a ":return" 18686 * without argument in a finally clause; reset the default 18687 * return value. */ 18688 current_funccal->rettv->v_type = VAR_NUMBER; 18689 current_funccal->rettv->vval.v_number = 0; 18690 } 18691 } 18692 report_make_pending(CSTP_RETURN, rettv); 18693 } 18694 else 18695 { 18696 current_funccal->returned = TRUE; 18697 18698 /* If the return is carried out now, store the return value. For 18699 * a return immediately after reanimation, the value is already 18700 * there. */ 18701 if (!reanimate && rettv != NULL) 18702 { 18703 clear_tv(current_funccal->rettv); 18704 *current_funccal->rettv = *(typval_T *)rettv; 18705 if (!is_cmd) 18706 vim_free(rettv); 18707 } 18708 } 18709 18710 return idx < 0; 18711 } 18712 18713 /* 18714 * Free the variable with a pending return value. 18715 */ 18716 void 18717 discard_pending_return(rettv) 18718 void *rettv; 18719 { 18720 free_tv((typval_T *)rettv); 18721 } 18722 18723 /* 18724 * Generate a return command for producing the value of "rettv". The result 18725 * is an allocated string. Used by report_pending() for verbose messages. 18726 */ 18727 char_u * 18728 get_return_cmd(rettv) 18729 void *rettv; 18730 { 18731 char_u *s = NULL; 18732 char_u *tofree = NULL; 18733 char_u numbuf[NUMBUFLEN]; 18734 18735 if (rettv != NULL) 18736 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18737 if (s == NULL) 18738 s = (char_u *)""; 18739 18740 STRCPY(IObuff, ":return "); 18741 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18742 if (STRLEN(s) + 8 >= IOSIZE) 18743 STRCPY(IObuff + IOSIZE - 4, "..."); 18744 vim_free(tofree); 18745 return vim_strsave(IObuff); 18746 } 18747 18748 /* 18749 * Get next function line. 18750 * Called by do_cmdline() to get the next line. 18751 * Returns allocated string, or NULL for end of function. 18752 */ 18753 /* ARGSUSED */ 18754 char_u * 18755 get_func_line(c, cookie, indent) 18756 int c; /* not used */ 18757 void *cookie; 18758 int indent; /* not used */ 18759 { 18760 funccall_T *fcp = (funccall_T *)cookie; 18761 ufunc_T *fp = fcp->func; 18762 char_u *retval; 18763 garray_T *gap; /* growarray with function lines */ 18764 18765 /* If breakpoints have been added/deleted need to check for it. */ 18766 if (fcp->dbg_tick != debug_tick) 18767 { 18768 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18769 sourcing_lnum); 18770 fcp->dbg_tick = debug_tick; 18771 } 18772 #ifdef FEAT_PROFILE 18773 if (do_profiling) 18774 func_line_end(cookie); 18775 #endif 18776 18777 gap = &fp->uf_lines; 18778 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18779 retval = NULL; 18780 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18781 retval = NULL; 18782 else 18783 { 18784 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18785 sourcing_lnum = fcp->linenr; 18786 #ifdef FEAT_PROFILE 18787 if (do_profiling) 18788 func_line_start(cookie); 18789 #endif 18790 } 18791 18792 /* Did we encounter a breakpoint? */ 18793 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18794 { 18795 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18796 /* Find next breakpoint. */ 18797 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18798 sourcing_lnum); 18799 fcp->dbg_tick = debug_tick; 18800 } 18801 18802 return retval; 18803 } 18804 18805 #if defined(FEAT_PROFILE) || defined(PROTO) 18806 /* 18807 * Called when starting to read a function line. 18808 * "sourcing_lnum" must be correct! 18809 * When skipping lines it may not actually be executed, but we won't find out 18810 * until later and we need to store the time now. 18811 */ 18812 void 18813 func_line_start(cookie) 18814 void *cookie; 18815 { 18816 funccall_T *fcp = (funccall_T *)cookie; 18817 ufunc_T *fp = fcp->func; 18818 18819 if (fp->uf_profiling && sourcing_lnum >= 1 18820 && sourcing_lnum <= fp->uf_lines.ga_len) 18821 { 18822 fp->uf_tml_idx = sourcing_lnum - 1; 18823 fp->uf_tml_execed = FALSE; 18824 profile_start(&fp->uf_tml_start); 18825 profile_zero(&fp->uf_tml_children); 18826 profile_get_wait(&fp->uf_tml_wait); 18827 } 18828 } 18829 18830 /* 18831 * Called when actually executing a function line. 18832 */ 18833 void 18834 func_line_exec(cookie) 18835 void *cookie; 18836 { 18837 funccall_T *fcp = (funccall_T *)cookie; 18838 ufunc_T *fp = fcp->func; 18839 18840 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18841 fp->uf_tml_execed = TRUE; 18842 } 18843 18844 /* 18845 * Called when done with a function line. 18846 */ 18847 void 18848 func_line_end(cookie) 18849 void *cookie; 18850 { 18851 funccall_T *fcp = (funccall_T *)cookie; 18852 ufunc_T *fp = fcp->func; 18853 18854 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18855 { 18856 if (fp->uf_tml_execed) 18857 { 18858 ++fp->uf_tml_count[fp->uf_tml_idx]; 18859 profile_end(&fp->uf_tml_start); 18860 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18861 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18862 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18863 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18864 } 18865 fp->uf_tml_idx = -1; 18866 } 18867 } 18868 #endif 18869 18870 /* 18871 * Return TRUE if the currently active function should be ended, because a 18872 * return was encountered or an error occured. Used inside a ":while". 18873 */ 18874 int 18875 func_has_ended(cookie) 18876 void *cookie; 18877 { 18878 funccall_T *fcp = (funccall_T *)cookie; 18879 18880 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18881 * an error inside a try conditional. */ 18882 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18883 || fcp->returned); 18884 } 18885 18886 /* 18887 * return TRUE if cookie indicates a function which "abort"s on errors. 18888 */ 18889 int 18890 func_has_abort(cookie) 18891 void *cookie; 18892 { 18893 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18894 } 18895 18896 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18897 typedef enum 18898 { 18899 VAR_FLAVOUR_DEFAULT, 18900 VAR_FLAVOUR_SESSION, 18901 VAR_FLAVOUR_VIMINFO 18902 } var_flavour_T; 18903 18904 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18905 18906 static var_flavour_T 18907 var_flavour(varname) 18908 char_u *varname; 18909 { 18910 char_u *p = varname; 18911 18912 if (ASCII_ISUPPER(*p)) 18913 { 18914 while (*(++p)) 18915 if (ASCII_ISLOWER(*p)) 18916 return VAR_FLAVOUR_SESSION; 18917 return VAR_FLAVOUR_VIMINFO; 18918 } 18919 else 18920 return VAR_FLAVOUR_DEFAULT; 18921 } 18922 #endif 18923 18924 #if defined(FEAT_VIMINFO) || defined(PROTO) 18925 /* 18926 * Restore global vars that start with a capital from the viminfo file 18927 */ 18928 int 18929 read_viminfo_varlist(virp, writing) 18930 vir_T *virp; 18931 int writing; 18932 { 18933 char_u *tab; 18934 int is_string = FALSE; 18935 typval_T tv; 18936 18937 if (!writing && (find_viminfo_parameter('!') != NULL)) 18938 { 18939 tab = vim_strchr(virp->vir_line + 1, '\t'); 18940 if (tab != NULL) 18941 { 18942 *tab++ = '\0'; /* isolate the variable name */ 18943 if (*tab == 'S') /* string var */ 18944 is_string = TRUE; 18945 18946 tab = vim_strchr(tab, '\t'); 18947 if (tab != NULL) 18948 { 18949 if (is_string) 18950 { 18951 tv.v_type = VAR_STRING; 18952 tv.vval.v_string = viminfo_readstring(virp, 18953 (int)(tab - virp->vir_line + 1), TRUE); 18954 } 18955 else 18956 { 18957 tv.v_type = VAR_NUMBER; 18958 tv.vval.v_number = atol((char *)tab + 1); 18959 } 18960 set_var(virp->vir_line + 1, &tv, FALSE); 18961 if (is_string) 18962 vim_free(tv.vval.v_string); 18963 } 18964 } 18965 } 18966 18967 return viminfo_readline(virp); 18968 } 18969 18970 /* 18971 * Write global vars that start with a capital to the viminfo file 18972 */ 18973 void 18974 write_viminfo_varlist(fp) 18975 FILE *fp; 18976 { 18977 hashitem_T *hi; 18978 dictitem_T *this_var; 18979 int todo; 18980 char *s; 18981 char_u *p; 18982 char_u *tofree; 18983 char_u numbuf[NUMBUFLEN]; 18984 18985 if (find_viminfo_parameter('!') == NULL) 18986 return; 18987 18988 fprintf(fp, _("\n# global variables:\n")); 18989 18990 todo = globvarht.ht_used; 18991 for (hi = globvarht.ht_array; todo > 0; ++hi) 18992 { 18993 if (!HASHITEM_EMPTY(hi)) 18994 { 18995 --todo; 18996 this_var = HI2DI(hi); 18997 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18998 { 18999 switch (this_var->di_tv.v_type) 19000 { 19001 case VAR_STRING: s = "STR"; break; 19002 case VAR_NUMBER: s = "NUM"; break; 19003 default: continue; 19004 } 19005 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 19006 p = echo_string(&this_var->di_tv, &tofree, numbuf); 19007 if (p != NULL) 19008 viminfo_writestring(fp, p); 19009 vim_free(tofree); 19010 } 19011 } 19012 } 19013 } 19014 #endif 19015 19016 #if defined(FEAT_SESSION) || defined(PROTO) 19017 int 19018 store_session_globals(fd) 19019 FILE *fd; 19020 { 19021 hashitem_T *hi; 19022 dictitem_T *this_var; 19023 int todo; 19024 char_u *p, *t; 19025 19026 todo = globvarht.ht_used; 19027 for (hi = globvarht.ht_array; todo > 0; ++hi) 19028 { 19029 if (!HASHITEM_EMPTY(hi)) 19030 { 19031 --todo; 19032 this_var = HI2DI(hi); 19033 if ((this_var->di_tv.v_type == VAR_NUMBER 19034 || this_var->di_tv.v_type == VAR_STRING) 19035 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 19036 { 19037 /* Escape special characters with a backslash. Turn a LF and 19038 * CR into \n and \r. */ 19039 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 19040 (char_u *)"\\\"\n\r"); 19041 if (p == NULL) /* out of memory */ 19042 break; 19043 for (t = p; *t != NUL; ++t) 19044 if (*t == '\n') 19045 *t = 'n'; 19046 else if (*t == '\r') 19047 *t = 'r'; 19048 if ((fprintf(fd, "let %s = %c%s%c", 19049 this_var->di_key, 19050 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19051 : ' ', 19052 p, 19053 (this_var->di_tv.v_type == VAR_STRING) ? '"' 19054 : ' ') < 0) 19055 || put_eol(fd) == FAIL) 19056 { 19057 vim_free(p); 19058 return FAIL; 19059 } 19060 vim_free(p); 19061 } 19062 } 19063 } 19064 return OK; 19065 } 19066 #endif 19067 19068 /* 19069 * Display script name where an item was last set. 19070 * Should only be invoked when 'verbose' is non-zero. 19071 */ 19072 void 19073 last_set_msg(scriptID) 19074 scid_T scriptID; 19075 { 19076 char_u *p; 19077 19078 if (scriptID != 0) 19079 { 19080 p = home_replace_save(NULL, get_scriptname(scriptID)); 19081 if (p != NULL) 19082 { 19083 verbose_enter(); 19084 MSG_PUTS(_("\n\tLast set from ")); 19085 MSG_PUTS(p); 19086 vim_free(p); 19087 verbose_leave(); 19088 } 19089 } 19090 } 19091 19092 #endif /* FEAT_EVAL */ 19093 19094 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 19095 19096 19097 #ifdef WIN3264 19098 /* 19099 * Functions for ":8" filename modifier: get 8.3 version of a filename. 19100 */ 19101 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19102 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 19103 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 19104 19105 /* 19106 * Get the short pathname of a file. 19107 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 19108 */ 19109 static int 19110 get_short_pathname(fnamep, bufp, fnamelen) 19111 char_u **fnamep; 19112 char_u **bufp; 19113 int *fnamelen; 19114 { 19115 int l,len; 19116 char_u *newbuf; 19117 19118 len = *fnamelen; 19119 19120 l = GetShortPathName(*fnamep, *fnamep, len); 19121 if (l > len - 1) 19122 { 19123 /* If that doesn't work (not enough space), then save the string 19124 * and try again with a new buffer big enough 19125 */ 19126 newbuf = vim_strnsave(*fnamep, l); 19127 if (newbuf == NULL) 19128 return 0; 19129 19130 vim_free(*bufp); 19131 *fnamep = *bufp = newbuf; 19132 19133 l = GetShortPathName(*fnamep,*fnamep,l+1); 19134 19135 /* Really should always succeed, as the buffer is big enough */ 19136 } 19137 19138 *fnamelen = l; 19139 return 1; 19140 } 19141 19142 /* 19143 * Create a short path name. Returns the length of the buffer it needs. 19144 * Doesn't copy over the end of the buffer passed in. 19145 */ 19146 static int 19147 shortpath_for_invalid_fname(fname, bufp, fnamelen) 19148 char_u **fname; 19149 char_u **bufp; 19150 int *fnamelen; 19151 { 19152 char_u *s, *p, *pbuf2, *pbuf3; 19153 char_u ch; 19154 int len, len2, plen, slen; 19155 19156 /* Make a copy */ 19157 len2 = *fnamelen; 19158 pbuf2 = vim_strnsave(*fname, len2); 19159 pbuf3 = NULL; 19160 19161 s = pbuf2 + len2 - 1; /* Find the end */ 19162 slen = 1; 19163 plen = len2; 19164 19165 if (after_pathsep(pbuf2, s + 1)) 19166 { 19167 --s; 19168 ++slen; 19169 --plen; 19170 } 19171 19172 do 19173 { 19174 /* Go back one path-seperator */ 19175 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 19176 { 19177 --s; 19178 ++slen; 19179 --plen; 19180 } 19181 if (s <= pbuf2) 19182 break; 19183 19184 /* Remeber the character that is about to be blatted */ 19185 ch = *s; 19186 *s = 0; /* get_short_pathname requires a null-terminated string */ 19187 19188 /* Try it in situ */ 19189 p = pbuf2; 19190 if (!get_short_pathname(&p, &pbuf3, &plen)) 19191 { 19192 vim_free(pbuf2); 19193 return -1; 19194 } 19195 *s = ch; /* Preserve the string */ 19196 } while (plen == 0); 19197 19198 if (plen > 0) 19199 { 19200 /* Remeber the length of the new string. */ 19201 *fnamelen = len = plen + slen; 19202 vim_free(*bufp); 19203 if (len > len2) 19204 { 19205 /* If there's not enough space in the currently allocated string, 19206 * then copy it to a buffer big enough. 19207 */ 19208 *fname= *bufp = vim_strnsave(p, len); 19209 if (*fname == NULL) 19210 return -1; 19211 } 19212 else 19213 { 19214 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 19215 *fname = *bufp = pbuf2; 19216 if (p != pbuf2) 19217 strncpy(*fname, p, plen); 19218 pbuf2 = NULL; 19219 } 19220 /* Concat the next bit */ 19221 strncpy(*fname + plen, s, slen); 19222 (*fname)[len] = '\0'; 19223 } 19224 vim_free(pbuf3); 19225 vim_free(pbuf2); 19226 return 0; 19227 } 19228 19229 /* 19230 * Get a pathname for a partial path. 19231 */ 19232 static int 19233 shortpath_for_partial(fnamep, bufp, fnamelen) 19234 char_u **fnamep; 19235 char_u **bufp; 19236 int *fnamelen; 19237 { 19238 int sepcount, len, tflen; 19239 char_u *p; 19240 char_u *pbuf, *tfname; 19241 int hasTilde; 19242 19243 /* Count up the path seperators from the RHS.. so we know which part 19244 * of the path to return. 19245 */ 19246 sepcount = 0; 19247 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 19248 if (vim_ispathsep(*p)) 19249 ++sepcount; 19250 19251 /* Need full path first (use expand_env() to remove a "~/") */ 19252 hasTilde = (**fnamep == '~'); 19253 if (hasTilde) 19254 pbuf = tfname = expand_env_save(*fnamep); 19255 else 19256 pbuf = tfname = FullName_save(*fnamep, FALSE); 19257 19258 len = tflen = STRLEN(tfname); 19259 19260 if (!get_short_pathname(&tfname, &pbuf, &len)) 19261 return -1; 19262 19263 if (len == 0) 19264 { 19265 /* Don't have a valid filename, so shorten the rest of the 19266 * path if we can. This CAN give us invalid 8.3 filenames, but 19267 * there's not a lot of point in guessing what it might be. 19268 */ 19269 len = tflen; 19270 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 19271 return -1; 19272 } 19273 19274 /* Count the paths backward to find the beginning of the desired string. */ 19275 for (p = tfname + len - 1; p >= tfname; --p) 19276 { 19277 #ifdef FEAT_MBYTE 19278 if (has_mbyte) 19279 p -= mb_head_off(tfname, p); 19280 #endif 19281 if (vim_ispathsep(*p)) 19282 { 19283 if (sepcount == 0 || (hasTilde && sepcount == 1)) 19284 break; 19285 else 19286 sepcount --; 19287 } 19288 } 19289 if (hasTilde) 19290 { 19291 --p; 19292 if (p >= tfname) 19293 *p = '~'; 19294 else 19295 return -1; 19296 } 19297 else 19298 ++p; 19299 19300 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 19301 vim_free(*bufp); 19302 *fnamelen = (int)STRLEN(p); 19303 *bufp = pbuf; 19304 *fnamep = p; 19305 19306 return 0; 19307 } 19308 #endif /* WIN3264 */ 19309 19310 /* 19311 * Adjust a filename, according to a string of modifiers. 19312 * *fnamep must be NUL terminated when called. When returning, the length is 19313 * determined by *fnamelen. 19314 * Returns valid flags. 19315 * When there is an error, *fnamep is set to NULL. 19316 */ 19317 int 19318 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19319 char_u *src; /* string with modifiers */ 19320 int *usedlen; /* characters after src that are used */ 19321 char_u **fnamep; /* file name so far */ 19322 char_u **bufp; /* buffer for allocated file name or NULL */ 19323 int *fnamelen; /* length of fnamep */ 19324 { 19325 int valid = 0; 19326 char_u *tail; 19327 char_u *s, *p, *pbuf; 19328 char_u dirname[MAXPATHL]; 19329 int c; 19330 int has_fullname = 0; 19331 #ifdef WIN3264 19332 int has_shortname = 0; 19333 #endif 19334 19335 repeat: 19336 /* ":p" - full path/file_name */ 19337 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19338 { 19339 has_fullname = 1; 19340 19341 valid |= VALID_PATH; 19342 *usedlen += 2; 19343 19344 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19345 if ((*fnamep)[0] == '~' 19346 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19347 && ((*fnamep)[1] == '/' 19348 # ifdef BACKSLASH_IN_FILENAME 19349 || (*fnamep)[1] == '\\' 19350 # endif 19351 || (*fnamep)[1] == NUL) 19352 19353 #endif 19354 ) 19355 { 19356 *fnamep = expand_env_save(*fnamep); 19357 vim_free(*bufp); /* free any allocated file name */ 19358 *bufp = *fnamep; 19359 if (*fnamep == NULL) 19360 return -1; 19361 } 19362 19363 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19364 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19365 { 19366 if (vim_ispathsep(*p) 19367 && p[1] == '.' 19368 && (p[2] == NUL 19369 || vim_ispathsep(p[2]) 19370 || (p[2] == '.' 19371 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19372 break; 19373 } 19374 19375 /* FullName_save() is slow, don't use it when not needed. */ 19376 if (*p != NUL || !vim_isAbsName(*fnamep)) 19377 { 19378 *fnamep = FullName_save(*fnamep, *p != NUL); 19379 vim_free(*bufp); /* free any allocated file name */ 19380 *bufp = *fnamep; 19381 if (*fnamep == NULL) 19382 return -1; 19383 } 19384 19385 /* Append a path separator to a directory. */ 19386 if (mch_isdir(*fnamep)) 19387 { 19388 /* Make room for one or two extra characters. */ 19389 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19390 vim_free(*bufp); /* free any allocated file name */ 19391 *bufp = *fnamep; 19392 if (*fnamep == NULL) 19393 return -1; 19394 add_pathsep(*fnamep); 19395 } 19396 } 19397 19398 /* ":." - path relative to the current directory */ 19399 /* ":~" - path relative to the home directory */ 19400 /* ":8" - shortname path - postponed till after */ 19401 while (src[*usedlen] == ':' 19402 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19403 { 19404 *usedlen += 2; 19405 if (c == '8') 19406 { 19407 #ifdef WIN3264 19408 has_shortname = 1; /* Postpone this. */ 19409 #endif 19410 continue; 19411 } 19412 pbuf = NULL; 19413 /* Need full path first (use expand_env() to remove a "~/") */ 19414 if (!has_fullname) 19415 { 19416 if (c == '.' && **fnamep == '~') 19417 p = pbuf = expand_env_save(*fnamep); 19418 else 19419 p = pbuf = FullName_save(*fnamep, FALSE); 19420 } 19421 else 19422 p = *fnamep; 19423 19424 has_fullname = 0; 19425 19426 if (p != NULL) 19427 { 19428 if (c == '.') 19429 { 19430 mch_dirname(dirname, MAXPATHL); 19431 s = shorten_fname(p, dirname); 19432 if (s != NULL) 19433 { 19434 *fnamep = s; 19435 if (pbuf != NULL) 19436 { 19437 vim_free(*bufp); /* free any allocated file name */ 19438 *bufp = pbuf; 19439 pbuf = NULL; 19440 } 19441 } 19442 } 19443 else 19444 { 19445 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19446 /* Only replace it when it starts with '~' */ 19447 if (*dirname == '~') 19448 { 19449 s = vim_strsave(dirname); 19450 if (s != NULL) 19451 { 19452 *fnamep = s; 19453 vim_free(*bufp); 19454 *bufp = s; 19455 } 19456 } 19457 } 19458 vim_free(pbuf); 19459 } 19460 } 19461 19462 tail = gettail(*fnamep); 19463 *fnamelen = (int)STRLEN(*fnamep); 19464 19465 /* ":h" - head, remove "/file_name", can be repeated */ 19466 /* Don't remove the first "/" or "c:\" */ 19467 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19468 { 19469 valid |= VALID_HEAD; 19470 *usedlen += 2; 19471 s = get_past_head(*fnamep); 19472 while (tail > s && after_pathsep(s, tail)) 19473 --tail; 19474 *fnamelen = (int)(tail - *fnamep); 19475 #ifdef VMS 19476 if (*fnamelen > 0) 19477 *fnamelen += 1; /* the path separator is part of the path */ 19478 #endif 19479 while (tail > s && !after_pathsep(s, tail)) 19480 mb_ptr_back(*fnamep, tail); 19481 } 19482 19483 /* ":8" - shortname */ 19484 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19485 { 19486 *usedlen += 2; 19487 #ifdef WIN3264 19488 has_shortname = 1; 19489 #endif 19490 } 19491 19492 #ifdef WIN3264 19493 /* Check shortname after we have done 'heads' and before we do 'tails' 19494 */ 19495 if (has_shortname) 19496 { 19497 pbuf = NULL; 19498 /* Copy the string if it is shortened by :h */ 19499 if (*fnamelen < (int)STRLEN(*fnamep)) 19500 { 19501 p = vim_strnsave(*fnamep, *fnamelen); 19502 if (p == 0) 19503 return -1; 19504 vim_free(*bufp); 19505 *bufp = *fnamep = p; 19506 } 19507 19508 /* Split into two implementations - makes it easier. First is where 19509 * there isn't a full name already, second is where there is. 19510 */ 19511 if (!has_fullname && !vim_isAbsName(*fnamep)) 19512 { 19513 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19514 return -1; 19515 } 19516 else 19517 { 19518 int l; 19519 19520 /* Simple case, already have the full-name 19521 * Nearly always shorter, so try first time. */ 19522 l = *fnamelen; 19523 if (!get_short_pathname(fnamep, bufp, &l)) 19524 return -1; 19525 19526 if (l == 0) 19527 { 19528 /* Couldn't find the filename.. search the paths. 19529 */ 19530 l = *fnamelen; 19531 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19532 return -1; 19533 } 19534 *fnamelen = l; 19535 } 19536 } 19537 #endif /* WIN3264 */ 19538 19539 /* ":t" - tail, just the basename */ 19540 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19541 { 19542 *usedlen += 2; 19543 *fnamelen -= (int)(tail - *fnamep); 19544 *fnamep = tail; 19545 } 19546 19547 /* ":e" - extension, can be repeated */ 19548 /* ":r" - root, without extension, can be repeated */ 19549 while (src[*usedlen] == ':' 19550 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19551 { 19552 /* find a '.' in the tail: 19553 * - for second :e: before the current fname 19554 * - otherwise: The last '.' 19555 */ 19556 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19557 s = *fnamep - 2; 19558 else 19559 s = *fnamep + *fnamelen - 1; 19560 for ( ; s > tail; --s) 19561 if (s[0] == '.') 19562 break; 19563 if (src[*usedlen + 1] == 'e') /* :e */ 19564 { 19565 if (s > tail) 19566 { 19567 *fnamelen += (int)(*fnamep - (s + 1)); 19568 *fnamep = s + 1; 19569 #ifdef VMS 19570 /* cut version from the extension */ 19571 s = *fnamep + *fnamelen - 1; 19572 for ( ; s > *fnamep; --s) 19573 if (s[0] == ';') 19574 break; 19575 if (s > *fnamep) 19576 *fnamelen = s - *fnamep; 19577 #endif 19578 } 19579 else if (*fnamep <= tail) 19580 *fnamelen = 0; 19581 } 19582 else /* :r */ 19583 { 19584 if (s > tail) /* remove one extension */ 19585 *fnamelen = (int)(s - *fnamep); 19586 } 19587 *usedlen += 2; 19588 } 19589 19590 /* ":s?pat?foo?" - substitute */ 19591 /* ":gs?pat?foo?" - global substitute */ 19592 if (src[*usedlen] == ':' 19593 && (src[*usedlen + 1] == 's' 19594 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19595 { 19596 char_u *str; 19597 char_u *pat; 19598 char_u *sub; 19599 int sep; 19600 char_u *flags; 19601 int didit = FALSE; 19602 19603 flags = (char_u *)""; 19604 s = src + *usedlen + 2; 19605 if (src[*usedlen + 1] == 'g') 19606 { 19607 flags = (char_u *)"g"; 19608 ++s; 19609 } 19610 19611 sep = *s++; 19612 if (sep) 19613 { 19614 /* find end of pattern */ 19615 p = vim_strchr(s, sep); 19616 if (p != NULL) 19617 { 19618 pat = vim_strnsave(s, (int)(p - s)); 19619 if (pat != NULL) 19620 { 19621 s = p + 1; 19622 /* find end of substitution */ 19623 p = vim_strchr(s, sep); 19624 if (p != NULL) 19625 { 19626 sub = vim_strnsave(s, (int)(p - s)); 19627 str = vim_strnsave(*fnamep, *fnamelen); 19628 if (sub != NULL && str != NULL) 19629 { 19630 *usedlen = (int)(p + 1 - src); 19631 s = do_string_sub(str, pat, sub, flags); 19632 if (s != NULL) 19633 { 19634 *fnamep = s; 19635 *fnamelen = (int)STRLEN(s); 19636 vim_free(*bufp); 19637 *bufp = s; 19638 didit = TRUE; 19639 } 19640 } 19641 vim_free(sub); 19642 vim_free(str); 19643 } 19644 vim_free(pat); 19645 } 19646 } 19647 /* after using ":s", repeat all the modifiers */ 19648 if (didit) 19649 goto repeat; 19650 } 19651 } 19652 19653 return valid; 19654 } 19655 19656 /* 19657 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19658 * "flags" can be "g" to do a global substitute. 19659 * Returns an allocated string, NULL for error. 19660 */ 19661 char_u * 19662 do_string_sub(str, pat, sub, flags) 19663 char_u *str; 19664 char_u *pat; 19665 char_u *sub; 19666 char_u *flags; 19667 { 19668 int sublen; 19669 regmatch_T regmatch; 19670 int i; 19671 int do_all; 19672 char_u *tail; 19673 garray_T ga; 19674 char_u *ret; 19675 char_u *save_cpo; 19676 19677 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19678 save_cpo = p_cpo; 19679 p_cpo = (char_u *)""; 19680 19681 ga_init2(&ga, 1, 200); 19682 19683 do_all = (flags[0] == 'g'); 19684 19685 regmatch.rm_ic = p_ic; 19686 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19687 if (regmatch.regprog != NULL) 19688 { 19689 tail = str; 19690 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19691 { 19692 /* 19693 * Get some space for a temporary buffer to do the substitution 19694 * into. It will contain: 19695 * - The text up to where the match is. 19696 * - The substituted text. 19697 * - The text after the match. 19698 */ 19699 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19700 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19701 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19702 { 19703 ga_clear(&ga); 19704 break; 19705 } 19706 19707 /* copy the text up to where the match is */ 19708 i = (int)(regmatch.startp[0] - tail); 19709 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19710 /* add the substituted text */ 19711 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19712 + ga.ga_len + i, TRUE, TRUE, FALSE); 19713 ga.ga_len += i + sublen - 1; 19714 /* avoid getting stuck on a match with an empty string */ 19715 if (tail == regmatch.endp[0]) 19716 { 19717 if (*tail == NUL) 19718 break; 19719 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19720 ++ga.ga_len; 19721 } 19722 else 19723 { 19724 tail = regmatch.endp[0]; 19725 if (*tail == NUL) 19726 break; 19727 } 19728 if (!do_all) 19729 break; 19730 } 19731 19732 if (ga.ga_data != NULL) 19733 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19734 19735 vim_free(regmatch.regprog); 19736 } 19737 19738 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19739 ga_clear(&ga); 19740 p_cpo = save_cpo; 19741 19742 return ret; 19743 } 19744 19745 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19746